[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.

fix: add fallback pfp

+78 -16
+10
lib/src/core/design_system/components/molecules/profile_card.dart
··· 91 91 width: 36, 92 92 height: 36, 93 93 fit: BoxFit.cover, 94 + errorWidget: (context, url, error) => Container( 95 + width: 36, 96 + height: 36, 97 + color: isDark ? AppColors.grey600 : AppColors.grey300, 98 + child: Icon( 99 + Icons.person, 100 + size: 20, 101 + color: isDark ? AppColors.grey400 : AppColors.grey600, 102 + ), 103 + ), 94 104 ) 95 105 : Container( 96 106 width: 36,
+28 -4
lib/src/core/design_system/components/molecules/story_circle.dart
··· 107 107 shape: BoxShape.circle, 108 108 color: Colors.transparent, 109 109 ), 110 - child: CircleAvatar( 111 - radius: _imageSize / 2, 112 - backgroundColor: const Color(0xFFD9D9D9), 113 - backgroundImage: CachedNetworkImageProvider(imageUrl), 110 + child: ClipOval( 111 + child: imageUrl.isNotEmpty 112 + ? CachedNetworkImage( 113 + imageUrl: imageUrl, 114 + width: _imageSize, 115 + height: _imageSize, 116 + fit: BoxFit.cover, 117 + errorWidget: (context, url, error) => Container( 118 + width: _imageSize, 119 + height: _imageSize, 120 + color: const Color(0xFFD9D9D9), 121 + child: const Icon( 122 + Icons.person, 123 + size: _imageSize * 0.5, 124 + color: Colors.grey, 125 + ), 126 + ), 127 + ) 128 + : Container( 129 + width: _imageSize, 130 + height: _imageSize, 131 + color: const Color(0xFFD9D9D9), 132 + child: const Icon( 133 + Icons.person, 134 + size: _imageSize * 0.5, 135 + color: Colors.grey, 136 + ), 137 + ), 114 138 ), 115 139 ), 116 140 ),
+37 -9
lib/src/features/feed/ui/widgets/action_buttons/share_panel.dart
··· 1 + import 'package:cached_network_image/cached_network_image.dart'; 1 2 import 'package:flutter/material.dart'; 2 3 import 'package:flutter/services.dart'; 3 4 import 'package:flutter_riverpod/flutter_riverpod.dart'; ··· 344 345 child: Stack( 345 346 alignment: Alignment.center, 346 347 children: [ 347 - CircleAvatar( 348 - radius: 22, 349 - backgroundColor: theme.colorScheme.surfaceContainerHighest, 350 - backgroundImage: (avatarUrl != null && avatarUrl!.isNotEmpty) 351 - ? NetworkImage(avatarUrl!) as ImageProvider 352 - : null, 353 - child: (avatarUrl == null || avatarUrl!.isEmpty) 354 - ? Text(displayName.isNotEmpty ? displayName.characters.first.toUpperCase() : '?') 355 - : null, 348 + ClipOval( 349 + child: (avatarUrl != null && avatarUrl!.isNotEmpty) 350 + ? CachedNetworkImage( 351 + imageUrl: avatarUrl!, 352 + width: 44, 353 + height: 44, 354 + fit: BoxFit.cover, 355 + errorWidget: (context, url, error) => Container( 356 + width: 44, 357 + height: 44, 358 + color: theme.colorScheme.surfaceContainerHighest, 359 + child: Center( 360 + child: Text( 361 + displayName.isNotEmpty ? displayName.characters.first.toUpperCase() : '?', 362 + style: TextStyle( 363 + color: theme.colorScheme.onSurface, 364 + fontWeight: FontWeight.bold, 365 + ), 366 + ), 367 + ), 368 + ), 369 + ) 370 + : Container( 371 + width: 44, 372 + height: 44, 373 + color: theme.colorScheme.surfaceContainerHighest, 374 + child: Center( 375 + child: Text( 376 + displayName.isNotEmpty ? displayName.characters.first.toUpperCase() : '?', 377 + style: TextStyle( 378 + color: theme.colorScheme.onSurface, 379 + fontWeight: FontWeight.bold, 380 + ), 381 + ), 382 + ), 383 + ), 356 384 ), 357 385 if (selected) 358 386 Container(
+1 -1
lib/src/features/profile/ui/widgets/user_list_view.dart
··· 47 47 return Padding( 48 48 padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), 49 49 child: ProfileCard( 50 - imageUrl: user.avatar.toString(), 50 + imageUrl: user.avatar?.toString() ?? '', 51 51 userName: user.displayName ?? user.handle, 52 52 userHandle: '@${user.handle}', 53 53 description: user.description,
+2 -2
lib/src/features/stories/ui/widgets/stories_list.dart
··· 74 74 final userAvatarUrl = ref 75 75 .read(profileProvider(did: currentUserDid!)) 76 76 .when( 77 - data: (profileData) => profileData.profile!.avatar.toString(), 77 + data: (profileData) => profileData.profile?.avatar?.toString() ?? '', 78 78 error: (error, stackTrace) => '', 79 79 loading: () => '', 80 80 ); ··· 108 108 padding: const EdgeInsets.only(right: 12), 109 109 child: StoryCircle.story( 110 110 userName: author.displayName ?? author.handle, 111 - imageUrl: author.avatar.toString(), 111 + imageUrl: author.avatar?.toString() ?? '', 112 112 ), 113 113 ), 114 114 );