✨ Completed friend list
This commit is contained in:
parent
15ed75b04e
commit
806ae602d5
@ -5,7 +5,7 @@ import 'package:solian/exts.dart';
|
||||
import 'package:solian/models/friendship.dart';
|
||||
import 'package:solian/providers/auth.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 {
|
||||
const FriendScreen({super.key});
|
||||
@ -24,15 +24,6 @@ class _FriendScreenState extends State<FriendScreen> {
|
||||
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 {
|
||||
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 {
|
||||
final FriendProvider provider = Get.find();
|
||||
|
||||
@ -117,46 +143,6 @@ class _FriendScreenState extends State<FriendScreen> {
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
@ -183,7 +169,8 @@ class _FriendScreenState extends State<FriendScreen> {
|
||||
title: Text(
|
||||
'${'accountFriendPending'.tr} (${filterWithStatus(0).length})',
|
||||
),
|
||||
onTap: () {},
|
||||
onTap: () =>
|
||||
showScopedListPopup('accountFriendPending'.tr, 0),
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
@ -195,32 +182,26 @@ class _FriendScreenState extends State<FriendScreen> {
|
||||
title: Text(
|
||||
'${'accountFriendBlocked'.tr} (${filterWithStatus(2).length})',
|
||||
),
|
||||
onTap: () {},
|
||||
onTap: () =>
|
||||
showScopedListPopup('accountFriendBlocked'.tr, 2),
|
||||
),
|
||||
),
|
||||
SliverList.builder(
|
||||
itemCount: filterWithStatus(1).length,
|
||||
itemBuilder: (_, __) => buildFriendshipItem(_, __, 1),
|
||||
SliverFriendList(
|
||||
accountId: _accountId!,
|
||||
items: filterWithStatus(1),
|
||||
onUpdate: () {
|
||||
getFriendship();
|
||||
},
|
||||
),
|
||||
const SliverToBoxAdapter(
|
||||
child: Divider(thickness: 0.3, height: 0.3),
|
||||
),
|
||||
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(
|
||||
'accountFriendListHint'.tr,
|
||||
textAlign: TextAlign.center,
|
||||
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(_, __),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user