[READ ONLY MIRROR] Open Source TikTok alternative built on AT Protocol github.com/sprksocial/client
flutter atproto video dart
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: format

+164 -75
+4 -5
lib/src/core/design_system/components/atoms/buttons/tappable_text.dart
··· 7 7 final VoidCallback onTap; 8 8 9 9 const TappableText({ 10 - required this.text, required this.onTap, super.key, 10 + required this.text, 11 + required this.onTap, 12 + super.key, 11 13 }); 12 14 13 15 @override ··· 18 20 width: 41, 19 21 height: 14, 20 22 child: Center( 21 - child: Text( 22 - text, 23 - style: AppTypography.textExtraSmallThin 24 - ), 23 + child: Text(text, style: AppTypography.textExtraSmallThin), 25 24 ), 26 25 ), 27 26 );
-1
lib/src/core/design_system/components/atoms/tags/tag.dart
··· 22 22 onTap: onTap, 23 23 borderRadius: BorderRadius.circular(13), 24 24 child: Container( 25 - 26 25 // width: 107, 27 26 // height: 35, 28 27 padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8),
-1
lib/src/core/design_system/templates/image_review_page_template.dart
··· 77 77 leading: AppLeadingButton(color: theme.textTheme.titleLarge?.color, tooltip: 'Back'), 78 78 title: Text( 79 79 title, 80 - 81 80 ), 82 81 centerTitle: false, 83 82 ),
+9 -2
lib/src/core/ui/widgets/image_content.dart
··· 57 57 placeholder: (context, url) => Container( 58 58 color: Colors.grey[850]?.withValues(alpha: 128), 59 59 child: const Center( 60 - child: SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white54)), 60 + child: SizedBox( 61 + width: 20, 62 + height: 20, 63 + child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white54), 64 + ), 61 65 ), 62 66 ), 63 67 errorWidget: (context, url, error) => ColoredBox( ··· 72 76 right: 4, 73 77 child: Container( 74 78 padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), 75 - decoration: BoxDecoration(color: Colors.black.withValues(alpha: 179), borderRadius: BorderRadius.circular(10)), 79 + decoration: BoxDecoration( 80 + color: Colors.black.withValues(alpha: 179), 81 + borderRadius: BorderRadius.circular(10), 82 + ), 76 83 child: Text( 77 84 '+${imageUrls.length - 1}', 78 85 style: const TextStyle(color: Colors.white, fontSize: 10, fontWeight: FontWeight.bold),
-1
lib/src/features/messages/ui/pages/chat_page.dart
··· 67 67 } 68 68 } 69 69 70 - 71 70 @override 72 71 Widget build(BuildContext context) { 73 72 final state = ref.watch(conversationProvider(widget.conversationId));
+1 -1
lib/src/features/search/providers/suggested_feeds_provider.dart
··· 31 31 /// Refresh the suggested feeds 32 32 Future<void> refresh() async { 33 33 state = const AsyncValue.loading(); 34 - 34 + 35 35 try { 36 36 _logger.d('Refreshing suggested Spark feeds...'); 37 37 // Only fetch Spark feeds
+7 -1
widgetbook/lib/atoms/icons_showcase.dart
··· 5 5 6 6 @UseCase(name: 'grid', type: AppIcons) 7 7 Widget buildAppIconsGridUseCase(BuildContext context) { 8 - final size = context.knobs.double.slider(label: 'icon_size', initialValue: 28, min: 12, max: 64, divisions: 52); 8 + final size = context.knobs.double.slider( 9 + label: 'icon_size', 10 + initialValue: 28, 11 + min: 12, 12 + max: 64, 13 + divisions: 52, 14 + ); 9 15 final color = context.knobs.colorOrNull(label: 'tint_color'); 10 16 final icons = <Widget>[ 11 17 AppIcons.add(size: size, color: color),
+4 -14
widgetbook/lib/atoms/long_button.dart
··· 5 5 // Assuming the LongButton component is located at this path 6 6 import 'package:sparksocial/src/core/design_system/components/atoms/buttons/long_button.dart'; 7 7 8 - @UseCase( 9 - name: 'no_ui', 10 - type: LongButton, 11 - ) 8 + @UseCase(name: 'no_ui', type: LongButton) 12 9 Widget buildLongButtonNoUIUseCase(BuildContext context) { 13 10 return LongButton( 14 - label: context.knobs.string( 15 - label: 'Label', 16 - initialValue: 'Continue', 17 - ), 11 + label: context.knobs.string(label: 'Label', initialValue: 'Continue'), 18 12 onPressed: () => print('LongButton was pressed.'), 19 13 ); 20 14 } 21 15 22 - 23 - @UseCase( 24 - name: 'resizable_parent', 25 - type: LongButton, 26 - ) 16 + @UseCase(name: 'resizable_parent', type: LongButton) 27 17 Widget buildLongButtonInAResizableContainerUseCase(BuildContext context) { 28 18 return Center( 29 19 child: Container( ··· 56 46 ), 57 47 ), 58 48 ); 59 - } 49 + }
+18 -5
widgetbook/lib/atoms/profile_tab_item.dart
··· 7 7 Widget buildProfileTabItemSelectedUseCase(BuildContext context) { 8 8 return Container( 9 9 color: Theme.of(context).colorScheme.surface, 10 - child: ProfileTabItem(icon: AppIcons.grid(), filledIcon: AppIcons.gridFilled(), isSelected: true, onTap: () => print('Tab tapped')), 10 + child: ProfileTabItem( 11 + icon: AppIcons.grid(), 12 + filledIcon: AppIcons.gridFilled(), 13 + isSelected: true, 14 + onTap: () => print('Tab tapped'), 15 + ), 11 16 ); 12 17 } 13 18 ··· 31 36 32 37 class _InteractiveProfileTabItemDemo extends StatefulWidget { 33 38 @override 34 - State<_InteractiveProfileTabItemDemo> createState() => _InteractiveProfileTabItemDemoState(); 39 + State<_InteractiveProfileTabItemDemo> createState() => 40 + _InteractiveProfileTabItemDemoState(); 35 41 } 36 42 37 - class _InteractiveProfileTabItemDemoState extends State<_InteractiveProfileTabItemDemo> { 43 + class _InteractiveProfileTabItemDemoState 44 + extends State<_InteractiveProfileTabItemDemo> { 38 45 bool _isSelected = false; 39 46 40 47 @override ··· 54 61 }, 55 62 ), 56 63 const SizedBox(height: 16), 57 - Text('Status: ${_isSelected ? "Selected" : "Unselected"}', style: Theme.of(context).textTheme.bodyMedium), 64 + Text( 65 + 'Status: ${_isSelected ? "Selected" : "Unselected"}', 66 + style: Theme.of(context).textTheme.bodyMedium, 67 + ), 58 68 ], 59 69 ), 60 70 ); ··· 113 123 ], 114 124 ), 115 125 const SizedBox(height: 16), 116 - Text('Selected tab: $_selectedIndex', style: Theme.of(context).textTheme.bodyMedium), 126 + Text( 127 + 'Selected tab: $_selectedIndex', 128 + style: Theme.of(context).textTheme.bodyMedium, 129 + ), 117 130 ], 118 131 ), 119 132 );
+1 -1
widgetbook/lib/main.dart
··· 4 4 // no main = no custom fonts hahaha 5 5 void main() { 6 6 runApp(const WidgetbookApp()); 7 - } 7 + }
+70 -15
widgetbook/lib/molecules/glass_input.dart
··· 6 6 import 'package:widgetbook/widgetbook.dart'; 7 7 import 'package:widgetbook_annotation/widgetbook_annotation.dart'; 8 8 9 - final _chatControllerProvider = Provider.autoDispose<TextEditingController>((ref) { 9 + final _chatControllerProvider = Provider.autoDispose<TextEditingController>(( 10 + ref, 11 + ) { 10 12 final c = TextEditingController(); 11 13 ref.onDispose(c.dispose); 12 14 return c; 13 15 }); 14 - final _chatMessagesProvider = StateProvider.autoDispose<List<String>>((_) => const []); 16 + final _chatMessagesProvider = StateProvider.autoDispose<List<String>>( 17 + (_) => const [], 18 + ); 15 19 16 20 @UseCase(name: 'comment', type: GlassInput) 17 21 Widget buildGlassInputCommentUseCase(BuildContext context) { 18 22 return Center( 19 23 child: Container( 20 - constraints: BoxConstraints(maxWidth: context.knobs.double.slider(label: 'width', initialValue: 210, min: 160, max: 400, divisions: 24)), 24 + constraints: BoxConstraints( 25 + maxWidth: context.knobs.double.slider( 26 + label: 'width', 27 + initialValue: 210, 28 + min: 160, 29 + max: 400, 30 + divisions: 24, 31 + ), 32 + ), 21 33 child: GlassInput.comment( 22 - hintText: context.knobs.string(label: 'hint', initialValue: 'Add a comment...'), 23 - leadingWidgets: [if (context.knobs.boolean(label: 'show_avatar', initialValue: true)) const CircleAvatar(radius: 10)], 24 - actionWidgets: [if (context.knobs.boolean(label: 'show_action_icon', initialValue: true)) AppIcons.smiley()], 34 + hintText: context.knobs.string( 35 + label: 'hint', 36 + initialValue: 'Add a comment...', 37 + ), 38 + leadingWidgets: [ 39 + if (context.knobs.boolean(label: 'show_avatar', initialValue: true)) 40 + const CircleAvatar(radius: 10), 41 + ], 42 + actionWidgets: [ 43 + if (context.knobs.boolean( 44 + label: 'show_action_icon', 45 + initialValue: true, 46 + )) 47 + AppIcons.smiley(), 48 + ], 25 49 ), 26 50 ), 27 51 ); ··· 31 55 Widget buildGlassInputSearchUseCase(BuildContext context) { 32 56 return Center( 33 57 child: SizedBox( 34 - width: context.knobs.double.slider(label: 'width', initialValue: 280, min: 160, max: 400, divisions: 24), 58 + width: context.knobs.double.slider( 59 + label: 'width', 60 + initialValue: 280, 61 + min: 160, 62 + max: 400, 63 + divisions: 24, 64 + ), 35 65 child: GlassInput.search( 36 - hintText: context.knobs.string(label: 'hint', initialValue: 'Search...'), 37 - leadingWidgets: [const Icon(Icons.search, size: 18, color: Colors.white70)], 66 + hintText: context.knobs.string( 67 + label: 'hint', 68 + initialValue: 'Search...', 69 + ), 70 + leadingWidgets: [ 71 + const Icon(Icons.search, size: 18, color: Colors.white70), 72 + ], 38 73 actionWidgets: [ 39 74 if (context.knobs.boolean(label: 'show_clear', initialValue: true)) 40 75 GestureDetector( ··· 53 88 child: Center( 54 89 child: _ChatDemo( 55 90 showSend: context.knobs.boolean(label: 'show_send', initialValue: true), 56 - placeholder: context.knobs.string(label: 'hint', initialValue: 'Message...'), 91 + placeholder: context.knobs.string( 92 + label: 'hint', 93 + initialValue: 'Message...', 94 + ), 57 95 ), 58 96 ), 59 97 ); ··· 90 128 child: Padding( 91 129 padding: const EdgeInsets.symmetric(vertical: 2), 92 130 child: DecoratedBox( 93 - decoration: BoxDecoration(color: Colors.white.withAlpha(30), borderRadius: BorderRadius.circular(8)), 131 + decoration: BoxDecoration( 132 + color: Colors.white.withAlpha(30), 133 + borderRadius: BorderRadius.circular(8), 134 + ), 94 135 child: Padding( 95 - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), 96 - child: Text(msg, style: const TextStyle(fontSize: 11, color: Colors.white)), 136 + padding: const EdgeInsets.symmetric( 137 + horizontal: 8, 138 + vertical: 4, 139 + ), 140 + child: Text( 141 + msg, 142 + style: const TextStyle( 143 + fontSize: 11, 144 + color: Colors.white, 145 + ), 146 + ), 97 147 ), 98 148 ), 99 149 ), ··· 108 158 child: GlassInput.chat( 109 159 controller: controller, 110 160 hintText: placeholder, 111 - leadingWidgets: const [Icon(Icons.chat_bubble_outline, size: 18, color: Colors.white70)], 161 + leadingWidgets: const [ 162 + Icon(Icons.chat_bubble_outline, size: 18, color: Colors.white70), 163 + ], 112 164 onSendMessage: showSend 113 165 ? () { 114 166 final text = controller.text.trim(); 115 167 if (text.isEmpty) return; 116 - ref.read(_chatMessagesProvider.notifier).state = [...messages, text]; 168 + ref.read(_chatMessagesProvider.notifier).state = [ 169 + ...messages, 170 + text, 171 + ]; 117 172 controller.clear(); 118 173 } 119 174 : null,
+28 -5
widgetbook/lib/molecules/post_tile.dart
··· 9 9 Widget buildPostTileUseCase(BuildContext context) { 10 10 return Center( 11 11 child: SizedBox( 12 - width: context.knobs.double.slider(label: 'width', initialValue: 150, min: 100, max: 300), 13 - height: context.knobs.double.slider(label: 'height', initialValue: 200, min: 150, max: 400), 12 + width: context.knobs.double.slider( 13 + label: 'width', 14 + initialValue: 150, 15 + min: 100, 16 + max: 300, 17 + ), 18 + height: context.knobs.double.slider( 19 + label: 'height', 20 + initialValue: 200, 21 + min: 150, 22 + max: 400, 23 + ), 14 24 child: PostTile( 15 - thumbnailUrl: context.knobs.string(label: 'thumbnailUrl', initialValue: _demoThumbnail), 16 - likes: context.knobs.int.slider(label: 'likes', initialValue: 1239, min: 0, max: 100000), 25 + thumbnailUrl: context.knobs.string( 26 + label: 'thumbnailUrl', 27 + initialValue: _demoThumbnail, 28 + ), 29 + likes: context.knobs.int.slider( 30 + label: 'likes', 31 + initialValue: 1239, 32 + min: 0, 33 + max: 100000, 34 + ), 17 35 seen: context.knobs.boolean(label: 'seen', initialValue: false), 18 36 nsfwBlur: context.knobs.boolean(label: 'nsfwBlur', initialValue: false), 19 37 onTap: () => print('PostTile tapped'), ··· 30 48 height: 200, 31 49 child: PostTile( 32 50 thumbnailUrl: _demoThumbnail, 33 - likes: context.knobs.int.slider(label: 'likes', initialValue: 5420, min: 0, max: 100000), 51 + likes: context.knobs.int.slider( 52 + label: 'likes', 53 + initialValue: 5420, 54 + min: 0, 55 + max: 100000, 56 + ), 34 57 seen: true, 35 58 nsfwBlur: false, 36 59 onTap: () => print('Seen PostTile tapped'),
+7 -10
widgetbook/lib/tokens/colors.dart
··· 4 4 import 'package:sparksocial/src/core/design_system/tokens/colors.dart'; 5 5 import 'package:widgetbook_workspace/tokens/colors_preview.dart'; 6 6 7 - @UseCase( 8 - name: 'Default', 9 - type: AppColors, 10 - ) 7 + @UseCase(name: 'Default', type: AppColors) 11 8 Widget buildAppColorsUseCase(BuildContext context) { 12 9 return const Padding( 13 10 padding: EdgeInsets.all(24), ··· 96 93 AppColors.rajah900, 97 94 ], 98 95 ), 99 - SizedBox(height: 24), 96 + SizedBox(height: 24), 100 97 ColorPalettePreview( 101 98 name: 'Indigo', 102 99 colors: [ ··· 112 109 AppColors.indigo900, 113 110 ], 114 111 ), 115 - SizedBox(height: 24), 112 + SizedBox(height: 24), 116 113 ColorPalettePreview( 117 114 name: 'Blue', 118 115 colors: [ ··· 128 125 AppColors.blue900, 129 126 ], 130 127 ), 131 - SizedBox(height: 24), 132 - ColorPalettePreview( 128 + SizedBox(height: 24), 129 + ColorPalettePreview( 133 130 name: 'Red', 134 131 colors: [ 135 132 AppColors.red50, ··· 144 141 AppColors.red900, 145 142 ], 146 143 ), 147 - SizedBox(height: 24), 148 - ColorPalettePreview( 144 + SizedBox(height: 24), 145 + ColorPalettePreview( 149 146 name: 'Green', 150 147 colors: [ 151 148 AppColors.green50,
+3 -10
widgetbook/lib/tokens/typography_preview.dart
··· 19 19 opacity: 0.64, 20 20 child: Text( 21 21 name.toUpperCase(), 22 - style: const TextStyle( 23 - fontSize: 11, 24 - fontWeight: FontWeight.w200, 25 - ), 22 + style: const TextStyle(fontSize: 11, fontWeight: FontWeight.w200), 26 23 ), 27 24 ), 28 - for (final style in styles.entries) 29 - Text( 30 - style.key, 31 - style: style.value, 32 - ), 25 + for (final style in styles.entries) Text(style.key, style: style.value), 33 26 ], 34 27 ); 35 28 } 36 - } 29 + }
+12 -3
widgetbook/lib/widgetbook_usecases_templates.dart
··· 40 40 ); 41 41 } 42 42 43 - Widget gradientBackground({required BuildContext context, required Widget child, required Color startColor, required Color endColor}) { 43 + Widget gradientBackground({ 44 + required BuildContext context, 45 + required Widget child, 46 + required Color startColor, 47 + required Color endColor, 48 + }) { 44 49 return _BackgroundWrapper( 45 50 background: Container( 46 51 decoration: BoxDecoration( ··· 55 60 ); 56 61 } 57 62 58 - Widget solidColorBackground({required BuildContext context, required Widget child, required Color color}) { 63 + Widget solidColorBackground({ 64 + required BuildContext context, 65 + required Widget child, 66 + required Color color, 67 + }) { 59 68 return _BackgroundWrapper( 60 69 background: Container(color: color), 61 70 child: Center(child: child), 62 71 ); 63 - } 72 + }