♻️ Refactored friend module

This commit is contained in:
2024-07-24 01:17:41 +08:00
parent 39c8597428
commit 8366bda846
18 changed files with 250 additions and 272 deletions

View File

@ -1,87 +0,0 @@
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';
import 'package:solian/widgets/account/account_profile_popup.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: GestureDetector(
child: AccountAvatar(content: otherside.avatar),
onTap: () {
showModalBottomSheet(
useRootNavigator: true,
isScrollControlled: true,
backgroundColor: Theme.of(context).colorScheme.surface,
context: context,
builder: (context) => AccountProfilePopup(
account: otherside,
),
);
},
),
),
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: (context, idx) => buildItem(context, idx),
);
}
}

View File

@ -0,0 +1,83 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:solian/models/relations.dart';
import 'package:solian/providers/relation.dart';
import 'package:solian/widgets/account/account_avatar.dart';
import 'package:solian/widgets/account/account_profile_popup.dart';
class SilverRelativeList extends StatelessWidget {
final List<Relationship> items;
final Function onUpdate;
final bool isHandleable;
const SilverRelativeList({
super.key,
required this.items,
required this.onUpdate,
this.isHandleable = true,
});
Widget buildItem(context, index) {
final element = items[index];
return ListTile(
title: Text(element.related.nick),
subtitle: Text(element.related.name),
leading: GestureDetector(
child: AccountAvatar(content: element.related.avatar),
onTap: () {
showModalBottomSheet(
useRootNavigator: true,
isScrollControlled: true,
backgroundColor: Theme
.of(context)
.colorScheme
.surface,
context: context,
builder: (context) =>
AccountProfilePopup(
account: element.related,
),
);
},
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
if(element.status != 1 && element.status != 3)
IconButton(
icon: const Icon(Icons.check),
onPressed: () {
final RelationshipProvider provider = Get.find();
if (element.status == 0) {
provider.handleRelation(element, true).then((_) => onUpdate());
} else {
provider.editRelation(element, 1).then((_) => onUpdate());
}
},
),
if(element.status != 2 && element.status != 3)
IconButton(
icon: const Icon(Icons.close),
onPressed: () {
final RelationshipProvider provider = Get.find();
if (element.status == 0) {
provider.handleRelation(element, false).then((_) => onUpdate());
} else {
provider.editRelation(element, 2).then((_) => onUpdate());
}
},
),
],
),
contentPadding: const EdgeInsets.symmetric(horizontal: 24),
);
}
@override
Widget build(BuildContext context) {
return SliverList.builder(
itemCount: items.length,
itemBuilder: (context, idx) => buildItem(context, idx),
);
}
}

View File

@ -1,39 +1,39 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:solian/models/account.dart';
import 'package:solian/models/friendship.dart';
import 'package:solian/models/relations.dart';
import 'package:solian/providers/auth.dart';
import 'package:solian/providers/friend.dart';
import 'package:solian/providers/relation.dart';
import 'package:solian/widgets/account/account_avatar.dart';
class FriendSelect extends StatefulWidget {
class RelativeSelector extends StatefulWidget {
final String title;
final Widget? Function(Account item)? trailingBuilder;
const FriendSelect({super.key, required this.title, this.trailingBuilder});
const RelativeSelector({super.key, required this.title, this.trailingBuilder});
@override
State<FriendSelect> createState() => _FriendSelectState();
State<RelativeSelector> createState() => _RelativeSelectorState();
}
class _FriendSelectState extends State<FriendSelect> {
class _RelativeSelectorState extends State<RelativeSelector> {
int _accountId = 0;
final List<Friendship> _friends = List.empty(growable: true);
final List<Relationship> _friends = List.empty(growable: true);
getFriends() async {
final AuthProvider auth = Get.find();
final prof = await auth.getProfile();
_accountId = prof.body['id'];
final FriendProvider provider = Get.find();
final resp = await provider.listFriendshipWithStatus(1);
final RelationshipProvider provider = Get.find();
final resp = await provider.listRelationWithStatus(1);
setState(() {
_friends.addAll(resp.body
.map((e) => Friendship.fromJson(e))
.map((e) => Relationship.fromJson(e))
.toList()
.cast<Friendship>());
.cast<Relationship>());
});
}

View File

@ -7,7 +7,7 @@ import 'package:solian/providers/auth.dart';
import 'package:solian/services.dart';
import 'package:solian/widgets/account/account_avatar.dart';
import 'package:solian/widgets/account/account_profile_popup.dart';
import 'package:solian/widgets/account/friend_select.dart';
import 'package:solian/widgets/account/relative_select.dart';
class ChannelMemberListPopup extends StatefulWidget {
final Channel channel;
@ -62,7 +62,7 @@ class _ChannelMemberListPopupState extends State<ChannelMemberListPopup> {
final input = await showModalBottomSheet(
context: context,
builder: (context) {
return FriendSelect(title: 'channelMembersAdd'.tr);
return RelativeSelector(title: 'channelMembersAdd'.tr);
},
);
if (input == null) return;

View File

@ -6,7 +6,7 @@ import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:get/get.dart';
import 'package:livekit_client/livekit_client.dart';
import 'package:solian/exts.dart';
import 'package:solian/providers/content/call.dart';
import 'package:solian/providers/call.dart';
class ControlsWidget extends StatefulWidget {
final Room room;

View File

@ -6,7 +6,7 @@ import 'package:solian/exts.dart';
import 'package:solian/models/call.dart';
import 'package:solian/models/channel.dart';
import 'package:solian/providers/auth.dart';
import 'package:solian/providers/content/call.dart';
import 'package:solian/providers/call.dart';
class ChatCallPrejoinPopup extends StatefulWidget {
final Call ongoingCall;

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:solian/providers/content/call.dart';
import 'package:solian/providers/call.dart';
class ChatCallCurrentIndicator extends StatelessWidget {
const ChatCallCurrentIndicator({super.key});

View File

@ -7,7 +7,7 @@ import 'package:solian/providers/auth.dart';
import 'package:solian/services.dart';
import 'package:solian/widgets/account/account_avatar.dart';
import 'package:solian/widgets/account/account_profile_popup.dart';
import 'package:solian/widgets/account/friend_select.dart';
import 'package:solian/widgets/account/relative_select.dart';
class RealmMemberListPopup extends StatefulWidget {
final Realm realm;
@ -59,7 +59,7 @@ class _RealmMemberListPopupState extends State<RealmMemberListPopup> {
final input = await showModalBottomSheet(
context: context,
builder: (context) {
return FriendSelect(title: 'channelMembersAdd'.tr);
return RelativeSelector(title: 'channelMembersAdd'.tr);
},
);
if (input == null) return;