Completed friend list

This commit is contained in:
LittleSheep 2024-05-25 00:40:05 +08:00
parent 15ed75b04e
commit 806ae602d5
2 changed files with 127 additions and 73 deletions

View File

@ -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( child: Text(
decoration: BoxDecoration( 'accountFriendListHint'.tr,
border: Border( textAlign: TextAlign.center,
top: BorderSide( style: Theme.of(context).textTheme.bodySmall,
color: Theme.of(context) ).paddingOnly(top: 16, bottom: 32),
.colorScheme
.surfaceVariant
.withOpacity(0.8),
width: 0.3,
)),
),
padding: const EdgeInsets.only(top: 16, bottom: 32),
child: Text(
'accountFriendListHint'.tr,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodySmall,
),
),
), ),
], ],
), ),

View 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(_, __),
);
}
}