From c93b314a68a3540e88dff1d2487d1de6d9ae2365 Mon Sep 17 00:00:00 2001 From: Roscoe Rubin-Rottenberg Date: Mon, 16 Mar 2026 22:28:14 -0400 Subject: [PATCH] style: design system gradient & glass purge --- assets/icons/grid_filled.svg | 2 +- assets/icons/like_filled.svg | 2 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- ios/ci_scripts/ci_post_clone.sh | 3 + .../atoms/buttons/accent_button.dart | 6 +- .../atoms/buttons/follow_pill_button.dart | 7 +-- .../components/atoms/profile_tab_item.dart | 8 +-- .../atoms/toggles/glass_follow_button.dart | 56 ----------------- .../components/molecules/glass_avatar.dart | 60 ------------------- .../molecules/known_interactions_bar.dart | 7 +-- .../components/organisms/side_action_bar.dart | 5 +- .../templates/chat_list_page_template.dart | 5 +- .../core/design_system/tokens/gradients.dart | 25 -------- lib/src/core/ui/widgets/heart_animation.dart | 5 +- .../profile/ui/pages/profile_page.dart | 13 ++-- pubspec.lock | 8 --- pubspec.yaml | 1 - .../lib/atoms/follow_buttons_and_toggle.dart | 28 +-------- 19 files changed, 38 insertions(+), 211 deletions(-) delete mode 100644 lib/src/core/design_system/components/atoms/toggles/glass_follow_button.dart delete mode 100644 lib/src/core/design_system/components/molecules/glass_avatar.dart diff --git a/assets/icons/grid_filled.svg b/assets/icons/grid_filled.svg index 2aadcae8..686ca548 100644 --- a/assets/icons/grid_filled.svg +++ b/assets/icons/grid_filled.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/assets/icons/like_filled.svg b/assets/icons/like_filled.svg index 25f42c94..bf4ee183 100644 --- a/assets/icons/like_filled.svg +++ b/assets/icons/like_filled.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index d0ea3b2d..5519ba38 100644 --- a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -131,8 +131,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/PostHog/posthog-ios", "state" : { - "revision" : "d23e03625642e42b7358aa6e5ae9cfe71cd7c3e5", - "version" : "3.46.0" + "revision" : "09da1be6a614325a6a464c6d2017a9ac858d1b5a", + "version" : "3.47.0" } }, { diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved index d0ea3b2d..5519ba38 100644 --- a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -131,8 +131,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/PostHog/posthog-ios", "state" : { - "revision" : "d23e03625642e42b7358aa6e5ae9cfe71cd7c3e5", - "version" : "3.46.0" + "revision" : "09da1be6a614325a6a464c6d2017a9ac858d1b5a", + "version" : "3.47.0" } }, { diff --git a/ios/ci_scripts/ci_post_clone.sh b/ios/ci_scripts/ci_post_clone.sh index 79181220..43908143 100755 --- a/ios/ci_scripts/ci_post_clone.sh +++ b/ios/ci_scripts/ci_post_clone.sh @@ -10,6 +10,9 @@ cd $CI_PRIMARY_REPOSITORY_PATH # change working directory to the root of your cl git clone https://github.com/flutter/flutter.git --depth 1 -b stable $HOME/flutter export PATH="$PATH:$HOME/flutter/bin" +# Enable Swift Package Manager support. +flutter config --enable-swift-package-manager + # Install Flutter artifacts for iOS (--ios), or macOS (--macos) platforms. flutter precache --ios diff --git a/lib/src/core/design_system/components/atoms/buttons/accent_button.dart b/lib/src/core/design_system/components/atoms/buttons/accent_button.dart index 8252d9cf..22c79a22 100644 --- a/lib/src/core/design_system/components/atoms/buttons/accent_button.dart +++ b/lib/src/core/design_system/components/atoms/buttons/accent_button.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:gradient_borders/box_borders/gradient_box_border.dart'; import 'package:spark/src/core/design_system/components/atoms/buttons/interactive_pressable.dart'; import 'package:spark/src/core/design_system/tokens/colors.dart'; import 'package:spark/src/core/design_system/tokens/gradients.dart'; @@ -26,9 +25,8 @@ class AccentButton extends StatelessWidget { decoration: BoxDecoration( gradient: AppGradients.accent, borderRadius: BorderRadius.circular(500), // pill shape - border: const GradientBoxBorder( - gradient: AppGradients.glassStroke, - width: 2, + border: const Border.fromBorderSide( + BorderSide(color: Color(0x25FFFFFF), width: 2), ), ), child: Align( diff --git a/lib/src/core/design_system/components/atoms/buttons/follow_pill_button.dart b/lib/src/core/design_system/components/atoms/buttons/follow_pill_button.dart index eae430fe..604403b6 100644 --- a/lib/src/core/design_system/components/atoms/buttons/follow_pill_button.dart +++ b/lib/src/core/design_system/components/atoms/buttons/follow_pill_button.dart @@ -1,10 +1,8 @@ import 'dart:ui'; import 'package:flutter/material.dart'; -import 'package:gradient_borders/box_borders/gradient_box_border.dart'; import 'package:spark/src/core/design_system/components/atoms/buttons/interactive_pressable.dart'; import 'package:spark/src/core/design_system/tokens/colors.dart'; -import 'package:spark/src/core/design_system/tokens/gradients.dart'; import 'package:spark/src/core/design_system/tokens/typography.dart'; class FollowPillButton extends StatelessWidget { @@ -34,9 +32,8 @@ class FollowPillButton extends StatelessWidget { decoration: const BoxDecoration( color: Color(0x33FFFFFF), borderRadius: BorderRadius.all(Radius.circular(500)), - border: GradientBoxBorder( - gradient: AppGradients.glassStroke, - width: 2, + border: Border.fromBorderSide( + BorderSide(color: Color(0x25FFFFFF), width: 1), ), ), child: Text( diff --git a/lib/src/core/design_system/components/atoms/profile_tab_item.dart b/lib/src/core/design_system/components/atoms/profile_tab_item.dart index f1defdbe..5c584c29 100644 --- a/lib/src/core/design_system/components/atoms/profile_tab_item.dart +++ b/lib/src/core/design_system/components/atoms/profile_tab_item.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:spark/src/core/design_system/components/atoms/tab_item.dart'; -import 'package:spark/src/core/design_system/tokens/gradients.dart'; class ProfileTabItem extends StatelessWidget { const ProfileTabItem({ @@ -20,12 +19,7 @@ class ProfileTabItem extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); return AppTabItem( - activeChild: ShaderMask( - shaderCallback: (bounds) => - AppGradients.gradientLinearPrimaryGradient.createShader(bounds), - blendMode: BlendMode.srcIn, - child: filledIcon, - ), + activeChild: filledIcon, inactiveChild: icon, isSelected: isSelected, onTap: onTap, diff --git a/lib/src/core/design_system/components/atoms/toggles/glass_follow_button.dart b/lib/src/core/design_system/components/atoms/toggles/glass_follow_button.dart deleted file mode 100644 index e534ab3f..00000000 --- a/lib/src/core/design_system/components/atoms/toggles/glass_follow_button.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'dart:ui'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:spark/src/core/design_system/tokens/typography.dart'; - -class GlassFollowButton extends StatelessWidget { - const GlassFollowButton({ - required this.isFollowing, - required this.onFollow, - required this.onUnfollow, - required this.followText, - required this.unfollowText, - super.key, - }); - - final bool isFollowing; - final VoidCallback onFollow; - final VoidCallback onUnfollow; - final String followText; - final String unfollowText; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: () { - HapticFeedback.mediumImpact(); - if (isFollowing) { - onUnfollow(); - } else { - onFollow(); - } - }, - child: ClipRRect( - borderRadius: BorderRadius.circular(100), - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), - child: Container( - constraints: const BoxConstraints(maxWidth: 80, maxHeight: 30), - padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), - decoration: BoxDecoration( - color: Colors.white.withAlpha(51), - borderRadius: BorderRadius.circular(100), - border: Border.all(color: Colors.white.withAlpha(37)), - ), - child: Center( - child: Text( - isFollowing ? unfollowText : followText, - style: AppTypography.textExtraSmallMedium, - ), - ), - ), - ), - ), - ); - } -} diff --git a/lib/src/core/design_system/components/molecules/glass_avatar.dart b/lib/src/core/design_system/components/molecules/glass_avatar.dart deleted file mode 100644 index 9adfc7a6..00000000 --- a/lib/src/core/design_system/components/molecules/glass_avatar.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; -import 'package:spark/src/core/ui/widgets/user_avatar.dart'; - -/// Circular avatar with subtle glass border similar to selected FeedTag style. -class GlassAvatar extends StatelessWidget { - const GlassAvatar({ - required this.imageUrl, - required this.username, - super.key, - this.size = 50.45, - this.borderWidth = 1.5, - }); - - final String imageUrl; - final String username; - final double size; // outer diameter including glass stroke - final double borderWidth; - - @override - Widget build(BuildContext context) { - // Glass gradient stroke around the image (mimics Figma Glass/Stroke) - const gradient = LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: [ - Color.fromARGB(77, 255, 255, 255), // 0.3 - Color.fromARGB(38, 255, 255, 255), // 0.15 - Color.fromARGB(26, 255, 255, 255), // 0.10 - Color.fromARGB(77, 255, 255, 255), // 0.3 - ], - stops: [0.0, 0.5, 0.8, 1.0], - ); - - return ClipOval( - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), - child: Container( - width: size, - height: size, - decoration: const BoxDecoration( - gradient: gradient, - shape: BoxShape.circle, - ), - child: Padding( - padding: EdgeInsets.all(borderWidth), - child: ClipOval( - child: UserAvatar( - imageUrl: imageUrl, - username: username, - size: size - (borderWidth * 2), - ), - ), - ), - ), - ), - ); - } -} diff --git a/lib/src/core/design_system/components/molecules/known_interactions_bar.dart b/lib/src/core/design_system/components/molecules/known_interactions_bar.dart index 3a822f33..c8643749 100644 --- a/lib/src/core/design_system/components/molecules/known_interactions_bar.dart +++ b/lib/src/core/design_system/components/molecules/known_interactions_bar.dart @@ -1,10 +1,8 @@ import 'dart:ui'; import 'package:flutter/material.dart'; -import 'package:gradient_borders/box_borders/gradient_box_border.dart'; import 'package:spark/src/core/design_system/components/atoms/avatar_stack.dart'; import 'package:spark/src/core/design_system/components/atoms/icons.dart'; -import 'package:spark/src/core/design_system/tokens/gradients.dart'; import 'package:spark/src/core/network/atproto/data/models/feed_models.dart'; import 'package:spark/src/core/ui/theme/theme.dart'; @@ -88,9 +86,8 @@ class _InteractionPill extends StatelessWidget { decoration: const BoxDecoration( color: Color(0x33FFFFFF), borderRadius: BorderRadius.all(Radius.circular(500)), - border: GradientBoxBorder( - gradient: AppGradients.glassStroke, - width: 2, + border: Border.fromBorderSide( + BorderSide(color: Color(0x25FFFFFF), width: 1), ), ), child: Row( diff --git a/lib/src/core/design_system/components/organisms/side_action_bar.dart b/lib/src/core/design_system/components/organisms/side_action_bar.dart index cf350317..83518c43 100644 --- a/lib/src/core/design_system/components/organisms/side_action_bar.dart +++ b/lib/src/core/design_system/components/organisms/side_action_bar.dart @@ -157,7 +157,10 @@ class _SparkSideActionBarState extends State { isActive: widget.isLiked, label: widget.likeCount, icon: widget.isLiked - ? AppIcons.likeFilled(size: 32) + ? AppIcons.likeFilled( + size: 32, + color: Theme.of(context).colorScheme.primary, + ) : AppIcons.like(size: 32), onTap: widget.onLike, ), diff --git a/lib/src/core/design_system/templates/chat_list_page_template.dart b/lib/src/core/design_system/templates/chat_list_page_template.dart index f4903450..2b05c134 100644 --- a/lib/src/core/design_system/templates/chat_list_page_template.dart +++ b/lib/src/core/design_system/templates/chat_list_page_template.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:spark/src/core/design_system/components/atoms/icons.dart'; -import 'package:spark/src/core/design_system/components/molecules/glass_avatar.dart'; import 'package:spark/src/core/design_system/tokens/typography.dart'; +import 'package:spark/src/core/ui/widgets/user_avatar.dart'; class ChatListItemData { const ChatListItemData({ @@ -98,9 +98,10 @@ class _ChatTile extends StatelessWidget { onTap: onTap, horizontalTitleGap: 12, contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), - leading: GlassAvatar( + leading: UserAvatar( imageUrl: data.avatarUrl ?? '', username: data.handle, + size: 50.45, ), title: Row( children: [ diff --git a/lib/src/core/design_system/tokens/gradients.dart b/lib/src/core/design_system/tokens/gradients.dart index 79575127..7f59cace 100644 --- a/lib/src/core/design_system/tokens/gradients.dart +++ b/lib/src/core/design_system/tokens/gradients.dart @@ -118,31 +118,6 @@ class AppGradients { ], ); - static const glassStroke = LinearGradient( - begin: Alignment(-0.8200000000000001, -0.8), - end: Alignment(0.72, 0.8200000000000001), - transform: GradientRotation(45 * (math.pi / 180)), - stops: [0, 0.3702, 0.7212, 1], - colors: [ - Color(0x3FFFFFFF), // was 6 * 5, now 9 * 7 - Color(0x1CFFFFFF), // was 3 * 5, now 4 * 7 - Color(0x15FFFFFF), // was 2 * 5, now 3 * 7 - Color(0x31FFFFFF), // was 6 * 5, now 7 * 7 - ], - ); - - static const glassStrokeLight = LinearGradient( - begin: Alignment(-0.8200000000000001, -0.8), - end: Alignment(0.72, 0.8200000000000001), - stops: [0, 0.3702, 0.7212, 1], - colors: [ - Color(0x4d000000), - Color(0x26000000), - Color(0x1a000000), - Color(0x4d000000), - ], - ); - static const darkStroke = LinearGradient( begin: Alignment(-0.8200000000000001, -0.8), end: Alignment(0.72, 0.8200000000000001), diff --git a/lib/src/core/ui/widgets/heart_animation.dart b/lib/src/core/ui/widgets/heart_animation.dart index 62a884d8..c6044c95 100644 --- a/lib/src/core/ui/widgets/heart_animation.dart +++ b/lib/src/core/ui/widgets/heart_animation.dart @@ -84,7 +84,10 @@ class _HeartAnimationState extends State scale: _scaleAnimation.value, child: Opacity( opacity: _opacityAnimation.value, - child: AppIcons.likeFilled(size: 100), + child: AppIcons.likeFilled( + size: 100, + color: Theme.of(context).colorScheme.primary, + ), ), ); }, diff --git a/lib/src/features/profile/ui/pages/profile_page.dart b/lib/src/features/profile/ui/pages/profile_page.dart index 8698165a..9eb5b142 100644 --- a/lib/src/features/profile/ui/pages/profile_page.dart +++ b/lib/src/features/profile/ui/pages/profile_page.dart @@ -537,7 +537,9 @@ class _ProfilePageState extends ConsumerState { final tabs = [ ProfileTabItem( icon: AppIcons.grid(color: inactiveColor), - filledIcon: AppIcons.gridFilled(), + filledIcon: AppIcons.gridFilled( + color: Theme.of(context).colorScheme.primary, + ), isSelected: activeIndex == 0, onTap: () { setState(() { @@ -547,8 +549,9 @@ class _ProfilePageState extends ConsumerState { ), ProfileTabItem( icon: AppIcons.repost(color: inactiveColor), - filledIcon: - AppIcons.repost(), // No filled variant exists, use same icon + filledIcon: AppIcons.repost( + color: Theme.of(context).colorScheme.primary, + ), // No filled variant exists, use same icon isSelected: activeIndex == 1, onTap: () { setState(() { @@ -563,7 +566,9 @@ class _ProfilePageState extends ConsumerState { tabs.add( ProfileTabItem( icon: AppIcons.profileLiked(color: inactiveColor), - filledIcon: AppIcons.likeFilled(), + filledIcon: AppIcons.likeFilled( + color: Theme.of(context).colorScheme.primary, + ), isSelected: activeIndex == 2, onTap: () { setState(() { diff --git a/pubspec.lock b/pubspec.lock index 42f8b87a..0addac71 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -837,14 +837,6 @@ packages: url: "https://pub.dev" source: hosted version: "8.0.2" - gradient_borders: - dependency: "direct main" - description: - name: gradient_borders - sha256: "492bc88ab8d88a4117a7f00e525a669b65f19973bea7ee677f9d9de7603bf037" - url: "https://pub.dev" - source: hosted - version: "1.0.2" graphs: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 43477415..2eb30557 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,7 +46,6 @@ dependencies: fvp: ^0.35.2 get_it: ^9.2.1 google_fonts: ^8.0.2 - gradient_borders: ^1.0.1 http: ^1.2.0 image: ^4.8.0 image_picker: ^1.0.7 diff --git a/widgetbook/lib/atoms/follow_buttons_and_toggle.dart b/widgetbook/lib/atoms/follow_buttons_and_toggle.dart index 49f5dfee..37d9d2d5 100644 --- a/widgetbook/lib/atoms/follow_buttons_and_toggle.dart +++ b/widgetbook/lib/atoms/follow_buttons_and_toggle.dart @@ -1,8 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:widgetbook_annotation/widgetbook_annotation.dart'; -import 'package:widgetbook/widgetbook.dart'; import 'package:spark/src/core/design_system/components/atoms/toggles/follow_button.dart'; -import 'package:spark/src/core/design_system/components/atoms/toggles/glass_follow_button.dart'; +import 'package:widgetbook/widgetbook.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart'; @UseCase(name: 'follow_states', type: FollowButton) Widget buildFollowButtonFollowStatesUseCase(BuildContext context) { @@ -26,26 +25,3 @@ Widget buildFollowButtonFollowStatesUseCase(BuildContext context) { ), ); } - -@UseCase(name: 'glass_follow_states', type: GlassFollowButton) -Widget buildGlassFollowButtonGlassFollowStatesUseCase(BuildContext context) { - final isFollowing = context.knobs.boolean( - label: 'is_following', - initialValue: false, - ); - return Center( - child: GlassFollowButton( - isFollowing: isFollowing, - onFollow: () => print('Follow pressed'), - onUnfollow: () => print('Unfollow pressed'), - followText: context.knobs.string( - label: 'follow_text', - initialValue: 'Follow', - ), - unfollowText: context.knobs.string( - label: 'unfollow_text', - initialValue: 'Unfollow', - ), - ), - ); -} -- 2.51.2