From d48da531346be7e64667476eddff15d843df323e Mon Sep 17 00:00:00 2001 From: Krille Date: Sun, 2 Mar 2025 15:18:19 +0100 Subject: [PATCH] feat: Room Previews --- lib/config/routes.dart | 7 ++- lib/pages/chat/chat.dart | 2 +- lib/pages/chat/chat_app_bar_title.dart | 8 +-- lib/pages/chat/chat_view.dart | 21 ++++++- lib/pages/chat_details/chat_details.dart | 21 +++---- lib/pages/chat_details/chat_details_view.dart | 17 +---- lib/widgets/chat_settings_popup_menu.dart | 63 ++++++++++--------- lib/widgets/room_loader.dart | 4 +- 8 files changed, 76 insertions(+), 67 deletions(-) diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 277ba25f3..fc9947259 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix_api_lite.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/archive/archive.dart'; @@ -37,7 +38,6 @@ import 'package:fluffychat/widgets/log_view.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/room_loader.dart'; import 'package:fluffychat/widgets/share_scaffold_dialog.dart'; -import 'package:matrix/matrix_api_lite.dart'; abstract class AppRoutes { static FutureOr loggedInRedirect( @@ -390,8 +390,11 @@ abstract class AppRoutes { pageBuilder: (context, state) => defaultPageBuilder( context, state, - ChatDetails( + RoomLoader( roomId: state.pathParameters['roomid']!, + builder: (context, room) => ChatDetails( + room: room, + ), ), ), routes: [ diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index fac2ff998..cce8d31b8 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -1295,7 +1295,7 @@ class ChatController extends State with WidgetsBindingObserver { ), ), child: ChatDetails( - roomId: roomId, + room: room, embeddedCloseButton: IconButton( icon: const Icon(Icons.close), onPressed: toggleDisplayChatDetailsColumn, diff --git a/lib/pages/chat/chat_app_bar_title.dart b/lib/pages/chat/chat_app_bar_title.dart index fe78ab533..68a35df43 100644 --- a/lib/pages/chat/chat_app_bar_title.dart +++ b/lib/pages/chat/chat_app_bar_title.dart @@ -31,11 +31,9 @@ class ChatAppBarTitle extends StatelessWidget { hoverColor: Colors.transparent, splashColor: Colors.transparent, highlightColor: Colors.transparent, - onTap: controller.isArchived - ? null - : () => FluffyThemes.isThreeColumnMode(context) - ? controller.toggleDisplayChatDetailsColumn() - : context.go('/rooms/${room.id}/details'), + onTap: () => FluffyThemes.isThreeColumnMode(context) + ? controller.toggleDisplayChatDetailsColumn() + : context.go('/rooms/${room.id}/details'), child: Row( children: [ Hero( diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index f9bdcd8b7..ed88528b4 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -19,6 +19,7 @@ import 'package:fluffychat/pages/chat/reactions_picker.dart'; import 'package:fluffychat/pages/chat/reply_display.dart'; import 'package:fluffychat/utils/account_config.dart'; import 'package:fluffychat/widgets/chat_settings_popup_menu.dart'; +import 'package:fluffychat/widgets/future_loading_dialog.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/mxc_image.dart'; import 'package:fluffychat/widgets/unread_rooms_badge.dart'; @@ -125,7 +126,9 @@ class ChatView extends StatelessWidget { ChatSettingsPopupMenu(controller.room, true), ]; } - return []; + return [ + ChatSettingsPopupMenu(controller.room, true), + ]; } @override @@ -292,6 +295,22 @@ class ChatView extends StatelessWidget { child: ChatEventList(controller: controller), ), ), + if (controller.room.membership != Membership.join && + (controller.room.membership == + Membership.invite || + controller.room.joinRules == + JoinRules.public)) + Container( + padding: EdgeInsets.all(bottomSheetPadding), + width: double.infinity, + child: ElevatedButton( + onPressed: () => showFutureLoadingDialog( + context: context, + future: controller.room.join, + ), + child: Text(L10n.of(context).joinRoom), + ), + ), if (controller.room.canSendDefaultMessages && controller.room.membership == Membership.join) Container( diff --git a/lib/pages/chat_details/chat_details.dart b/lib/pages/chat_details/chat_details.dart index 5d5ef3069..c2848a62e 100644 --- a/lib/pages/chat_details/chat_details.dart +++ b/lib/pages/chat_details/chat_details.dart @@ -14,17 +14,16 @@ import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/adaptive_dialogs/show_modal_action_popup.dart'; import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; -import 'package:fluffychat/widgets/matrix.dart'; enum AliasActions { copy, delete, setCanonical } class ChatDetails extends StatefulWidget { - final String roomId; + final Room room; final Widget? embeddedCloseButton; const ChatDetails({ super.key, - required this.roomId, + required this.room, this.embeddedCloseButton, }); @@ -38,10 +37,8 @@ class ChatDetailsController extends State { void toggleDisplaySettings() => setState(() => displaySettings = !displaySettings); - String? get roomId => widget.roomId; - void setDisplaynameAction() async { - final room = Matrix.of(context).client.getRoomById(roomId!)!; + final room = widget.room; final input = await showTextInputDialog( context: context, title: L10n.of(context).changeTheNameOfTheGroup, @@ -66,7 +63,7 @@ class ChatDetailsController extends State { } void setTopicAction() async { - final room = Matrix.of(context).client.getRoomById(roomId!)!; + final room = widget.room; final input = await showTextInputDialog( context: context, title: L10n.of(context).setChatDescription, @@ -92,7 +89,7 @@ class ChatDetailsController extends State { } void goToEmoteSettings() async { - final room = Matrix.of(context).client.getRoomById(roomId!)!; + final room = widget.room; // okay, we need to test if there are any emote state events other than the default one // if so, we need to be directed to a selection screen for which pack we want to look at // otherwise, we just open the normal one. @@ -106,7 +103,7 @@ class ChatDetailsController extends State { } void setAvatarAction() async { - final room = Matrix.of(context).client.getRoomById(roomId!); + final room = widget.room; final actions = [ if (PlatformInfos.isMobile) AdaptiveModalAction( @@ -120,7 +117,7 @@ class ChatDetailsController extends State { label: L10n.of(context).openGallery, icon: const Icon(Icons.photo_outlined), ), - if (room?.avatar != null) + if (room.avatar != null) AdaptiveModalAction( value: AvatarAction.remove, label: L10n.of(context).delete, @@ -140,7 +137,7 @@ class ChatDetailsController extends State { if (action == AvatarAction.remove) { await showFutureLoadingDialog( context: context, - future: () => room!.setAvatar(null), + future: () => room.setAvatar(null), ); return; } @@ -172,7 +169,7 @@ class ChatDetailsController extends State { } await showFutureLoadingDialog( context: context, - future: () => room!.setAvatar(file), + future: () => room.setAvatar(file), ); } diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index 43b8d70e6..e3c292a8c 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -12,7 +12,6 @@ import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/chat_settings_popup_menu.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; -import 'package:fluffychat/widgets/matrix.dart'; import '../../utils/url_launcher.dart'; import '../../widgets/qr_code_viewer.dart'; @@ -25,17 +24,7 @@ class ChatDetailsView extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); - final room = Matrix.of(context).client.getRoomById(controller.roomId!); - if (room == null) { - return Scaffold( - appBar: AppBar( - title: Text(L10n.of(context).oopsSomethingWentWrong), - ), - body: Center( - child: Text(L10n.of(context).youAreNoLongerParticipatingInThisChat), - ), - ); - } + final room = controller.widget.room; return StreamBuilder( stream: room.client.onRoomState.stream @@ -163,7 +152,7 @@ class ChatDetailsView extends StatelessWidget { onPressed: () => room.isDirectChat ? null : context.push( - '/rooms/${controller.roomId}/details/members', + '/rooms/${controller.widget.room.id}/details/members', ), icon: const Icon( Icons.group_outlined, @@ -335,7 +324,7 @@ class ChatDetailsView extends StatelessWidget { ), ), onTap: () => context.push( - '/rooms/${controller.roomId!}/details/members', + '/rooms/${controller.widget.room.id}/details/members', ), trailing: const Icon(Icons.chevron_right_outlined), ), diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index bb0bdc856..ebe858340 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -107,28 +107,30 @@ class ChatSettingsPopupMenuState extends State { ], ), ), - if (widget.room.pushRuleState == PushRuleState.notify) - PopupMenuItem( - value: ChatPopupMenuActions.mute, - child: Row( - children: [ - const Icon(Icons.notifications_off_outlined), - const SizedBox(width: 12), - Text(L10n.of(context).muteChat), - ], - ), - ) - else - PopupMenuItem( - value: ChatPopupMenuActions.unmute, - child: Row( - children: [ - const Icon(Icons.notifications_on_outlined), - const SizedBox(width: 12), - Text(L10n.of(context).unmuteChat), - ], + if (widget.room.membership == Membership.join) ...[ + if (widget.room.pushRuleState == PushRuleState.notify) + PopupMenuItem( + value: ChatPopupMenuActions.mute, + child: Row( + children: [ + const Icon(Icons.notifications_off_outlined), + const SizedBox(width: 12), + Text(L10n.of(context).muteChat), + ], + ), + ) + else + PopupMenuItem( + value: ChatPopupMenuActions.unmute, + child: Row( + children: [ + const Icon(Icons.notifications_on_outlined), + const SizedBox(width: 12), + Text(L10n.of(context).unmuteChat), + ], + ), ), - ), + ], PopupMenuItem( value: ChatPopupMenuActions.search, child: Row( @@ -139,16 +141,17 @@ class ChatSettingsPopupMenuState extends State { ], ), ), - PopupMenuItem( - value: ChatPopupMenuActions.leave, - child: Row( - children: [ - const Icon(Icons.delete_outlined), - const SizedBox(width: 12), - Text(L10n.of(context).leave), - ], + if (widget.room.membership == Membership.join) + PopupMenuItem( + value: ChatPopupMenuActions.leave, + child: Row( + children: [ + const Icon(Icons.delete_outlined), + const SizedBox(width: 12), + Text(L10n.of(context).leave), + ], + ), ), - ), ], ), ], diff --git a/lib/widgets/room_loader.dart b/lib/widgets/room_loader.dart index 8e94f8186..6b707e7cd 100644 --- a/lib/widgets/room_loader.dart +++ b/lib/widgets/room_loader.dart @@ -1,9 +1,9 @@ -import 'package:fluffychat/utils/localized_exception_extension.dart'; -import 'package:fluffychat/utils/room_from_public_rooms_chunk.dart'; import 'package:flutter/material.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/utils/localized_exception_extension.dart'; +import 'package:fluffychat/utils/room_from_public_rooms_chunk.dart'; import 'package:fluffychat/widgets/matrix.dart'; class RoomLoader extends StatelessWidget {