💄 Optimized chat room tile
This commit is contained in:
parent
401df0f49c
commit
641fcb4419
@ -80,6 +80,7 @@
|
|||||||
"chat": "Chat",
|
"chat": "Chat",
|
||||||
"chatMessageHint": "Message in {}",
|
"chatMessageHint": "Message in {}",
|
||||||
"chatDirectMessageHint": "Message to {}",
|
"chatDirectMessageHint": "Message to {}",
|
||||||
|
"directMessage": "Direct Message",
|
||||||
"loading": "Loading...",
|
"loading": "Loading...",
|
||||||
"descriptionNone": "No description yet.",
|
"descriptionNone": "No description yet.",
|
||||||
"invites": "Invites",
|
"invites": "Invites",
|
||||||
|
@ -28,6 +28,50 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
|
|
||||||
part 'chat.g.dart';
|
part 'chat.g.dart';
|
||||||
|
|
||||||
|
class ChatRoomListTile extends StatelessWidget {
|
||||||
|
final SnChatRoom room;
|
||||||
|
final bool isDirect;
|
||||||
|
final Widget? subtitle;
|
||||||
|
final Widget? trailing;
|
||||||
|
final VoidCallback? onTap;
|
||||||
|
|
||||||
|
const ChatRoomListTile({
|
||||||
|
super.key,
|
||||||
|
required this.room,
|
||||||
|
this.isDirect = false,
|
||||||
|
this.subtitle,
|
||||||
|
this.trailing,
|
||||||
|
this.onTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
leading:
|
||||||
|
isDirect
|
||||||
|
? ProfilePictureWidget(
|
||||||
|
fileId: room.members!.first.account.profile.pictureId,
|
||||||
|
)
|
||||||
|
: room.pictureId == null
|
||||||
|
? CircleAvatar(child: Text(room.name[0].toUpperCase()))
|
||||||
|
: ProfilePictureWidget(fileId: room.pictureId),
|
||||||
|
title: Text(isDirect ? room.members!.first.account.nick : room.name),
|
||||||
|
subtitle:
|
||||||
|
subtitle != null
|
||||||
|
? subtitle!
|
||||||
|
: isDirect
|
||||||
|
? Text('@${room.members!.first.account.name}')
|
||||||
|
: Text(room.description),
|
||||||
|
trailing: trailing,
|
||||||
|
onTap:
|
||||||
|
onTap ??
|
||||||
|
() {
|
||||||
|
context.pushRoute(ChatRoomRoute(id: room.id));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<List<SnChatRoom>> chatroomsJoined(Ref ref) async {
|
Future<List<SnChatRoom>> chatroomsJoined(Ref ref) async {
|
||||||
final client = ref.watch(apiClientProvider);
|
final client = ref.watch(apiClientProvider);
|
||||||
@ -47,6 +91,7 @@ class ChatListScreen extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final chats = ref.watch(chatroomsJoinedProvider);
|
final chats = ref.watch(chatroomsJoinedProvider);
|
||||||
|
final chatInvites = ref.watch(chatroomInvitesProvider);
|
||||||
|
|
||||||
Future<void> createDirectMessage() async {
|
Future<void> createDirectMessage() async {
|
||||||
final result = await showModalBottomSheet(
|
final result = await showModalBottomSheet(
|
||||||
@ -68,7 +113,21 @@ class ChatListScreen extends HookConsumerWidget {
|
|||||||
title: Text('chat').tr(),
|
title: Text('chat').tr(),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Symbols.email),
|
icon: Badge(
|
||||||
|
label: Text(
|
||||||
|
chatInvites.when(
|
||||||
|
data: (invites) => invites.length.toString(),
|
||||||
|
error: (_, __) => '0',
|
||||||
|
loading: () => '0',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
isLabelVisible: chatInvites.when(
|
||||||
|
data: (invites) => invites.isNotEmpty,
|
||||||
|
error: (_, __) => false,
|
||||||
|
loading: () => false,
|
||||||
|
),
|
||||||
|
child: const Icon(Symbols.email),
|
||||||
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
@ -156,31 +215,7 @@ class ChatListScreen extends HookConsumerWidget {
|
|||||||
itemCount: items.length,
|
itemCount: items.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final item = items[index];
|
final item = items[index];
|
||||||
if (item.type == 1) {
|
return ChatRoomListTile(room: item, isDirect: item.type == 1);
|
||||||
return ListTile(
|
|
||||||
leading: ProfilePictureWidget(
|
|
||||||
fileId: item.members!.first.account.profile.pictureId,
|
|
||||||
),
|
|
||||||
title: Text(item.members!.first.account.nick),
|
|
||||||
subtitle: Text("An direct message"),
|
|
||||||
onTap: () {
|
|
||||||
context.pushRoute(ChatRoomRoute(id: item.id));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return ListTile(
|
|
||||||
leading:
|
|
||||||
item.pictureId == null
|
|
||||||
? CircleAvatar(
|
|
||||||
child: Text(item.name[0].toUpperCase()),
|
|
||||||
)
|
|
||||||
: ProfilePictureWidget(fileId: item.pictureId),
|
|
||||||
title: Text(item.name),
|
|
||||||
subtitle: Text(item.description),
|
|
||||||
onTap: () {
|
|
||||||
context.pushRoute(ChatRoomRoute(id: item.id));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -535,14 +570,14 @@ class _ChatInvitesSheet extends HookConsumerWidget {
|
|||||||
itemCount: items.length,
|
itemCount: items.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final invite = items[index];
|
final invite = items[index];
|
||||||
return ListTile(
|
return ChatRoomListTile(
|
||||||
leading: ProfilePictureWidget(
|
room: invite.chatRoom!,
|
||||||
fileId: invite.chatRoom!.pictureId,
|
isDirect: invite.chatRoom!.type == 1,
|
||||||
radius: 24,
|
subtitle: Row(
|
||||||
fallbackIcon: Symbols.group,
|
spacing: 6,
|
||||||
),
|
children: [
|
||||||
title: Text(invite.chatRoom!.name),
|
Flexible(
|
||||||
subtitle:
|
child:
|
||||||
Text(
|
Text(
|
||||||
invite.role >= 100
|
invite.role >= 100
|
||||||
? 'permissionOwner'
|
? 'permissionOwner'
|
||||||
@ -550,6 +585,21 @@ class _ChatInvitesSheet extends HookConsumerWidget {
|
|||||||
? 'permissionModerator'
|
? 'permissionModerator'
|
||||||
: 'permissionMember',
|
: 'permissionMember',
|
||||||
).tr(),
|
).tr(),
|
||||||
|
),
|
||||||
|
if (invite.chatRoom!.type == 1)
|
||||||
|
Badge(
|
||||||
|
label: Text('directMessage').tr(),
|
||||||
|
backgroundColor:
|
||||||
|
Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.primary,
|
||||||
|
textColor:
|
||||||
|
Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.onPrimary,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
trailing: Row(
|
trailing: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
|
@ -36,13 +36,28 @@ class RealmListScreen extends HookConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final realms = ref.watch(realmsJoinedProvider);
|
final realms = ref.watch(realmsJoinedProvider);
|
||||||
|
final realmInvites = ref.watch(realmInvitesProvider);
|
||||||
|
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('realms').tr(),
|
title: const Text('realms').tr(),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Symbols.email),
|
icon: Badge(
|
||||||
|
label: Text(
|
||||||
|
realmInvites.when(
|
||||||
|
data: (invites) => invites.length.toString(),
|
||||||
|
error: (_, __) => '0',
|
||||||
|
loading: () => '0',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
isLabelVisible: realmInvites.when(
|
||||||
|
data: (invites) => invites.isNotEmpty,
|
||||||
|
error: (_, __) => false,
|
||||||
|
loading: () => false,
|
||||||
|
),
|
||||||
|
child: const Icon(Symbols.email),
|
||||||
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user