✨ Completed friend list
This commit is contained in:
		| @@ -5,7 +5,7 @@ import 'package:solian/exts.dart'; | |||||||
| import 'package:solian/models/friendship.dart'; | import 'package:solian/models/friendship.dart'; | ||||||
| import 'package:solian/providers/auth.dart'; | import 'package:solian/providers/auth.dart'; | ||||||
| import 'package:solian/providers/friend.dart'; | import 'package:solian/providers/friend.dart'; | ||||||
| import 'package:solian/widgets/account/account_avatar.dart'; | import 'package:solian/widgets/account/friend_list.dart'; | ||||||
|  |  | ||||||
| class FriendScreen extends StatefulWidget { | class FriendScreen extends StatefulWidget { | ||||||
|   const FriendScreen({super.key}); |   const FriendScreen({super.key}); | ||||||
| @@ -24,15 +24,6 @@ class _FriendScreenState extends State<FriendScreen> { | |||||||
|     return _friendships.where((x) => x.status == status).toList(); |     return _friendships.where((x) => x.status == status).toList(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   DismissDirection getDismissDirection(Friendship relation) { |  | ||||||
|     if (relation.status == 2) return DismissDirection.endToStart; |  | ||||||
|     if (relation.status == 1) return DismissDirection.startToEnd; |  | ||||||
|     if (relation.status == 0 && relation.relatedId != _accountId) { |  | ||||||
|       return DismissDirection.startToEnd; |  | ||||||
|     } |  | ||||||
|     return DismissDirection.horizontal; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   Future<void> getFriendship() async { |   Future<void> getFriendship() async { | ||||||
|     setState(() => _isBusy = true); |     setState(() => _isBusy = true); | ||||||
|  |  | ||||||
| @@ -48,6 +39,41 @@ class _FriendScreenState extends State<FriendScreen> { | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   void showScopedListPopup(String title, int status) { | ||||||
|  |     showModalBottomSheet( | ||||||
|  |       useRootNavigator: true, | ||||||
|  |       isScrollControlled: true, | ||||||
|  |       context: context, | ||||||
|  |       builder: (context) { | ||||||
|  |         return SizedBox( | ||||||
|  |           height: MediaQuery.of(context).size.height * 0.85, | ||||||
|  |           child: Column( | ||||||
|  |             crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |             children: [ | ||||||
|  |               Text( | ||||||
|  |                 title, | ||||||
|  |                 style: Theme.of(context).textTheme.headlineSmall, | ||||||
|  |               ).paddingOnly(left: 24, right: 24, top: 32, bottom: 16), | ||||||
|  |               Expanded( | ||||||
|  |                 child: CustomScrollView( | ||||||
|  |                   slivers: [ | ||||||
|  |                     SliverFriendList( | ||||||
|  |                       accountId: _accountId!, | ||||||
|  |                       items: filterWithStatus(status), | ||||||
|  |                       onUpdate: () { | ||||||
|  |                         getFriendship(); | ||||||
|  |                       }, | ||||||
|  |                     ), | ||||||
|  |                   ], | ||||||
|  |                 ), | ||||||
|  |               ), | ||||||
|  |             ], | ||||||
|  |           ), | ||||||
|  |         ); | ||||||
|  |       }, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   void promptAddFriend() async { |   void promptAddFriend() async { | ||||||
|     final FriendProvider provider = Get.find(); |     final FriendProvider provider = Get.find(); | ||||||
|  |  | ||||||
| @@ -117,46 +143,6 @@ class _FriendScreenState extends State<FriendScreen> { | |||||||
|     Future.delayed(Duration.zero, () => getFriendship()); |     Future.delayed(Duration.zero, () => getFriendship()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   Widget buildFriendshipItem(context, index, status) { |  | ||||||
|     final element = filterWithStatus(status)[index]; |  | ||||||
|     final otherside = element.getOtherside(_accountId!); |  | ||||||
|  |  | ||||||
|     final randomId = DateTime.now().microsecondsSinceEpoch >> 10; |  | ||||||
|  |  | ||||||
|     return Dismissible( |  | ||||||
|       key: Key(randomId.toString()), |  | ||||||
|       background: Container( |  | ||||||
|         color: Colors.red, |  | ||||||
|         padding: const EdgeInsets.symmetric(horizontal: 20), |  | ||||||
|         alignment: Alignment.centerLeft, |  | ||||||
|         child: const Icon(Icons.close, color: Colors.white), |  | ||||||
|       ), |  | ||||||
|       secondaryBackground: Container( |  | ||||||
|         color: Colors.green, |  | ||||||
|         padding: const EdgeInsets.symmetric(horizontal: 20), |  | ||||||
|         alignment: Alignment.centerRight, |  | ||||||
|         child: const Icon(Icons.check, color: Colors.white), |  | ||||||
|       ), |  | ||||||
|       direction: getDismissDirection(element), |  | ||||||
|       child: ListTile( |  | ||||||
|         title: Text(otherside.nick), |  | ||||||
|         subtitle: Text(otherside.name), |  | ||||||
|         leading: AccountAvatar(content: otherside.avatar), |  | ||||||
|       ), |  | ||||||
|       onDismissed: (direction) async { |  | ||||||
|         final FriendProvider provider = Get.find(); |  | ||||||
|         if (direction == DismissDirection.startToEnd) { |  | ||||||
|           await provider.updateFriendship(element, 2); |  | ||||||
|           await getFriendship(); |  | ||||||
|         } |  | ||||||
|         if (direction == DismissDirection.endToStart) { |  | ||||||
|           await provider.updateFriendship(element, 1); |  | ||||||
|           await getFriendship(); |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|     ); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     return Material( |     return Material( | ||||||
| @@ -183,7 +169,8 @@ class _FriendScreenState extends State<FriendScreen> { | |||||||
|                   title: Text( |                   title: Text( | ||||||
|                     '${'accountFriendPending'.tr} (${filterWithStatus(0).length})', |                     '${'accountFriendPending'.tr} (${filterWithStatus(0).length})', | ||||||
|                   ), |                   ), | ||||||
|                   onTap: () {}, |                   onTap: () => | ||||||
|  |                       showScopedListPopup('accountFriendPending'.tr, 0), | ||||||
|                 ), |                 ), | ||||||
|               ), |               ), | ||||||
|               SliverToBoxAdapter( |               SliverToBoxAdapter( | ||||||
| @@ -195,32 +182,26 @@ class _FriendScreenState extends State<FriendScreen> { | |||||||
|                   title: Text( |                   title: Text( | ||||||
|                     '${'accountFriendBlocked'.tr} (${filterWithStatus(2).length})', |                     '${'accountFriendBlocked'.tr} (${filterWithStatus(2).length})', | ||||||
|                   ), |                   ), | ||||||
|                   onTap: () {}, |                   onTap: () => | ||||||
|  |                       showScopedListPopup('accountFriendBlocked'.tr, 2), | ||||||
|                 ), |                 ), | ||||||
|               ), |               ), | ||||||
|               SliverList.builder( |               SliverFriendList( | ||||||
|                 itemCount: filterWithStatus(1).length, |                 accountId: _accountId!, | ||||||
|                 itemBuilder: (_, __) => buildFriendshipItem(_, __, 1), |                 items: filterWithStatus(1), | ||||||
|  |                 onUpdate: () { | ||||||
|  |                   getFriendship(); | ||||||
|  |                 }, | ||||||
|  |               ), | ||||||
|  |               const SliverToBoxAdapter( | ||||||
|  |                 child: Divider(thickness: 0.3, height: 0.3), | ||||||
|               ), |               ), | ||||||
|               SliverToBoxAdapter( |               SliverToBoxAdapter( | ||||||
|                 child: Container( |  | ||||||
|                   decoration: BoxDecoration( |  | ||||||
|                     border: Border( |  | ||||||
|                         top: BorderSide( |  | ||||||
|                       color: Theme.of(context) |  | ||||||
|                           .colorScheme |  | ||||||
|                           .surfaceVariant |  | ||||||
|                           .withOpacity(0.8), |  | ||||||
|                       width: 0.3, |  | ||||||
|                     )), |  | ||||||
|                   ), |  | ||||||
|                   padding: const EdgeInsets.only(top: 16, bottom: 32), |  | ||||||
|                 child: Text( |                 child: Text( | ||||||
|                   'accountFriendListHint'.tr, |                   'accountFriendListHint'.tr, | ||||||
|                   textAlign: TextAlign.center, |                   textAlign: TextAlign.center, | ||||||
|                   style: Theme.of(context).textTheme.bodySmall, |                   style: Theme.of(context).textTheme.bodySmall, | ||||||
|                   ), |                 ).paddingOnly(top: 16, bottom: 32), | ||||||
|                 ), |  | ||||||
|               ), |               ), | ||||||
|             ], |             ], | ||||||
|           ), |           ), | ||||||
|   | |||||||
							
								
								
									
										73
									
								
								lib/widgets/account/friend_list.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								lib/widgets/account/friend_list.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:get/get.dart'; | ||||||
|  | import 'package:solian/models/friendship.dart'; | ||||||
|  | import 'package:solian/providers/friend.dart'; | ||||||
|  | import 'package:solian/widgets/account/account_avatar.dart'; | ||||||
|  |  | ||||||
|  | class SliverFriendList extends StatelessWidget { | ||||||
|  |   final int accountId; | ||||||
|  |   final List<Friendship> items; | ||||||
|  |   final Function onUpdate; | ||||||
|  |  | ||||||
|  |   const SliverFriendList({ | ||||||
|  |     super.key, | ||||||
|  |     required this.accountId, | ||||||
|  |     required this.items, | ||||||
|  |     required this.onUpdate, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   DismissDirection getDismissDirection(Friendship relation) { | ||||||
|  |     if (relation.status == 2) return DismissDirection.endToStart; | ||||||
|  |     if (relation.status == 1) return DismissDirection.startToEnd; | ||||||
|  |     if (relation.status == 0 && relation.relatedId != accountId) { | ||||||
|  |       return DismissDirection.startToEnd; | ||||||
|  |     } | ||||||
|  |     return DismissDirection.horizontal; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget buildItem(context, index) { | ||||||
|  |     final element = items[index]; | ||||||
|  |     final otherside = element.getOtherside(accountId); | ||||||
|  |  | ||||||
|  |     final randomId = DateTime.now().microsecondsSinceEpoch >> 10; | ||||||
|  |  | ||||||
|  |     return Dismissible( | ||||||
|  |       key: Key(randomId.toString()), | ||||||
|  |       background: Container( | ||||||
|  |         color: Colors.red, | ||||||
|  |         padding: const EdgeInsets.symmetric(horizontal: 20), | ||||||
|  |         alignment: Alignment.centerLeft, | ||||||
|  |         child: const Icon(Icons.close, color: Colors.white), | ||||||
|  |       ), | ||||||
|  |       secondaryBackground: Container( | ||||||
|  |         color: Colors.green, | ||||||
|  |         padding: const EdgeInsets.symmetric(horizontal: 20), | ||||||
|  |         alignment: Alignment.centerRight, | ||||||
|  |         child: const Icon(Icons.check, color: Colors.white), | ||||||
|  |       ), | ||||||
|  |       direction: getDismissDirection(element), | ||||||
|  |       child: ListTile( | ||||||
|  |         title: Text(otherside.nick), | ||||||
|  |         subtitle: Text(otherside.name), | ||||||
|  |         leading: AccountAvatar(content: otherside.avatar), | ||||||
|  |       ), | ||||||
|  |       onDismissed: (direction) { | ||||||
|  |         final FriendProvider provider = Get.find(); | ||||||
|  |         if (direction == DismissDirection.startToEnd) { | ||||||
|  |           provider.updateFriendship(element, 2).then((_) => onUpdate()); | ||||||
|  |         } | ||||||
|  |         if (direction == DismissDirection.endToStart) { | ||||||
|  |           provider.updateFriendship(element, 1).then((_) => onUpdate()); | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return SliverList.builder( | ||||||
|  |       itemCount: items.length, | ||||||
|  |       itemBuilder: (_, __) => buildItem(_, __), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user