From 88f1fc172082bddc78065d6a4ee33d3ca5103b95 Mon Sep 17 00:00:00 2001 From: krille-chan Date: Sat, 17 Feb 2024 08:41:28 +0100 Subject: [PATCH] fix: BuildContext crash when joining room --- lib/pages/archive/archive_view.dart | 3 + lib/pages/chat_list/chat_list_body.dart | 6 +- lib/pages/chat_list/chat_list_item.dart | 126 +------------------- lib/pages/chat_list/space_view.dart | 2 + lib/pages/chat_list/utils/on_chat_tap.dart | 127 +++++++++++++++++++++ 5 files changed, 139 insertions(+), 125 deletions(-) create mode 100644 lib/pages/chat_list/utils/on_chat_tap.dart diff --git a/lib/pages/archive/archive_view.dart b/lib/pages/archive/archive_view.dart index fc5c3e25..dc73addb 100644 --- a/lib/pages/archive/archive_view.dart +++ b/lib/pages/archive/archive_view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/archive/archive.dart'; @@ -59,6 +60,8 @@ class ArchiveView extends StatelessWidget { itemBuilder: (BuildContext context, int i) => ChatListItem( controller.archive[i], onForget: () => controller.forgetRoomAction(i), + onTap: () => context + .go('/rooms/archive/${controller.archive[i].id}'), ), ); } diff --git a/lib/pages/chat_list/chat_list_body.dart b/lib/pages/chat_list/chat_list_body.dart index 52637d89..8d93febb 100644 --- a/lib/pages/chat_list/chat_list_body.dart +++ b/lib/pages/chat_list/chat_list_body.dart @@ -11,6 +11,7 @@ import 'package:fluffychat/pages/chat_list/chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/search_title.dart'; import 'package:fluffychat/pages/chat_list/space_view.dart'; import 'package:fluffychat/pages/chat_list/status_msg_list.dart'; +import 'package:fluffychat/pages/chat_list/utils/on_chat_tap.dart'; import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; @@ -251,6 +252,7 @@ class ChatListViewBody extends StatelessWidget { )) { return const SizedBox.shrink(); } + final activeChat = controller.activeChat == rooms[i].id; return ChatListItem( rooms[i], key: Key('chat_list_item_${rooms[i].id}'), @@ -258,10 +260,10 @@ class ChatListViewBody extends StatelessWidget { controller.selectedRoomIds.contains(rooms[i].id), onTap: controller.selectMode == SelectMode.select ? () => controller.toggleSelection(rooms[i].id) - : null, + : () => onChatTap(rooms[i], context), onLongPress: () => controller.toggleSelection(rooms[i].id), - activeChat: controller.activeChat == rooms[i].id, + activeChat: activeChat, ); }, childCount: rooms.length, diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart index 8b1cc753..48c3cfaa 100644 --- a/lib/pages/chat_list/chat_list_item.dart +++ b/lib/pages/chat_list/chat_list_item.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; -import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; @@ -14,7 +13,6 @@ import '../../config/themes.dart'; import '../../utils/date_time_extension.dart'; import '../../widgets/avatar.dart'; import '../../widgets/matrix.dart'; -import '../chat/send_file_dialog.dart'; enum ArchivedRoomAction { delete, rejoin } @@ -22,132 +20,20 @@ class ChatListItem extends StatelessWidget { final Room room; final bool activeChat; final bool selected; - final void Function()? onTap; final void Function()? onLongPress; final void Function()? onForget; + final void Function() onTap; const ChatListItem( this.room, { this.activeChat = false, this.selected = false, - this.onTap, + required this.onTap, this.onLongPress, this.onForget, super.key, }); - void clickAction(BuildContext context) async { - if (onTap != null) return onTap!(); - if (activeChat) return; - if (room.membership == Membership.invite) { - final inviterId = - room.getState(EventTypes.RoomMember, room.client.userID!)?.senderId; - final inviteAction = await showModalActionSheet( - context: context, - message: room.isDirectChat - ? L10n.of(context)!.invitePrivateChat - : L10n.of(context)!.inviteGroupChat, - title: room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), - actions: [ - SheetAction( - key: InviteActions.accept, - label: L10n.of(context)!.accept, - icon: Icons.check_outlined, - isDefaultAction: true, - ), - SheetAction( - key: InviteActions.decline, - label: L10n.of(context)!.decline, - icon: Icons.close_outlined, - isDestructiveAction: true, - ), - SheetAction( - key: InviteActions.block, - label: L10n.of(context)!.block, - icon: Icons.block_outlined, - isDestructiveAction: true, - ), - ], - ); - if (inviteAction == null) return; - if (inviteAction == InviteActions.block) { - context.go('/rooms/settings/security/ignorelist', extra: inviterId); - return; - } - if (inviteAction == InviteActions.decline) { - await showFutureLoadingDialog( - context: context, - future: room.leave, - ); - return; - } - final joinResult = await showFutureLoadingDialog( - context: context, - future: () async { - final waitForRoom = room.client.waitForRoomInSync( - room.id, - join: true, - ); - await room.join(); - await waitForRoom; - }, - ); - if (joinResult.error != null) return; - } - - if (room.membership == Membership.ban) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(L10n.of(context)!.youHaveBeenBannedFromThisChat), - ), - ); - return; - } - - if (room.membership == Membership.leave) { - context.go('/rooms/archive/${room.id}'); - return; - } - - // Share content into this room - final shareContent = Matrix.of(context).shareContent; - if (shareContent != null) { - final shareFile = shareContent.tryGet('file'); - if (shareContent.tryGet('msgtype') == 'chat.fluffy.shared_file' && - shareFile != null) { - await showDialog( - context: context, - useRootNavigator: false, - builder: (c) => SendFileDialog( - files: [shareFile], - room: room, - ), - ); - Matrix.of(context).shareContent = null; - } else { - final consent = await showOkCancelAlertDialog( - context: context, - title: L10n.of(context)!.forward, - message: L10n.of(context)!.forwardMessageTo( - room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), - ), - okLabel: L10n.of(context)!.forward, - cancelLabel: L10n.of(context)!.cancel, - ); - if (consent == OkCancelResult.cancel) { - Matrix.of(context).shareContent = null; - return; - } - if (consent == OkCancelResult.ok) { - room.sendEvent(shareContent); - Matrix.of(context).shareContent = null; - } - } - } - - context.go('/rooms/${room.id}'); - } - Future archiveAction(BuildContext context) async { { if ([Membership.leave, Membership.ban].contains(room.membership)) { @@ -391,7 +277,7 @@ class ChatListItem extends StatelessWidget { ), ], ), - onTap: () => clickAction(context), + onTap: onTap, trailing: onForget == null ? hovered || selected ? IconButton( @@ -417,9 +303,3 @@ class ChatListItem extends StatelessWidget { ); } } - -enum InviteActions { - accept, - decline, - block, -} diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index aacb82ba..d0b57a83 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -11,6 +11,7 @@ import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/search_title.dart'; +import 'package:fluffychat/pages/chat_list/utils/on_chat_tap.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/avatar.dart'; import '../../utils/localized_exception_extension.dart'; @@ -429,6 +430,7 @@ class _SpaceViewState extends State { onLongPress: () => _onSpaceChildContextMenu(spaceChild, room), activeChat: widget.controller.activeChat == room.id, + onTap: () => onChatTap(room, context), ); } final isSpace = spaceChild.roomType == 'm.space'; diff --git a/lib/pages/chat_list/utils/on_chat_tap.dart b/lib/pages/chat_list/utils/on_chat_tap.dart new file mode 100644 index 00000000..d24af1fb --- /dev/null +++ b/lib/pages/chat_list/utils/on_chat_tap.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; + +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pages/chat/send_file_dialog.dart'; +import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +void onChatTap(Room room, BuildContext context) async { + if (room.membership == Membership.invite) { + final inviterId = + room.getState(EventTypes.RoomMember, room.client.userID!)?.senderId; + final inviteAction = await showModalActionSheet( + context: context, + message: room.isDirectChat + ? L10n.of(context)!.invitePrivateChat + : L10n.of(context)!.inviteGroupChat, + title: room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), + actions: [ + SheetAction( + key: InviteActions.accept, + label: L10n.of(context)!.accept, + icon: Icons.check_outlined, + isDefaultAction: true, + ), + SheetAction( + key: InviteActions.decline, + label: L10n.of(context)!.decline, + icon: Icons.close_outlined, + isDestructiveAction: true, + ), + SheetAction( + key: InviteActions.block, + label: L10n.of(context)!.block, + icon: Icons.block_outlined, + isDestructiveAction: true, + ), + ], + ); + if (inviteAction == null) return; + if (inviteAction == InviteActions.block) { + context.go('/rooms/settings/security/ignorelist', extra: inviterId); + return; + } + if (inviteAction == InviteActions.decline) { + await showFutureLoadingDialog( + context: context, + future: room.leave, + ); + return; + } + final joinResult = await showFutureLoadingDialog( + context: context, + future: () async { + final waitForRoom = room.client.waitForRoomInSync( + room.id, + join: true, + ); + await room.join(); + await waitForRoom; + }, + ); + if (joinResult.error != null) return; + } + + if (room.membership == Membership.ban) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.youHaveBeenBannedFromThisChat), + ), + ); + return; + } + + if (room.membership == Membership.leave) { + context.go('/rooms/archive/${room.id}'); + return; + } + + // Share content into this room + final shareContent = Matrix.of(context).shareContent; + if (shareContent != null) { + final shareFile = shareContent.tryGet('file'); + if (shareContent.tryGet('msgtype') == 'chat.fluffy.shared_file' && + shareFile != null) { + await showDialog( + context: context, + useRootNavigator: false, + builder: (c) => SendFileDialog( + files: [shareFile], + room: room, + ), + ); + Matrix.of(context).shareContent = null; + } else { + final consent = await showOkCancelAlertDialog( + context: context, + title: L10n.of(context)!.forward, + message: L10n.of(context)!.forwardMessageTo( + room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), + ), + okLabel: L10n.of(context)!.forward, + cancelLabel: L10n.of(context)!.cancel, + ); + if (consent == OkCancelResult.cancel) { + Matrix.of(context).shareContent = null; + return; + } + if (consent == OkCancelResult.ok) { + room.sendEvent(shareContent); + Matrix.of(context).shareContent = null; + } + } + } + + context.go('/rooms/${room.id}'); +} + +enum InviteActions { + accept, + decline, + block, +}