From e591ce3a4d3e02dfa7676791266d4eb2a9953109 Mon Sep 17 00:00:00 2001 From: ggurdin <46800240+ggurdin@users.noreply.github.com> Date: Thu, 20 Feb 2025 09:25:28 -0500 Subject: [PATCH] fix: dynamically update input bar height to offset event list (#1859) --- lib/pages/chat/chat.dart | 7 + lib/pages/chat/chat_view.dart | 151 ++++-------------- lib/pangea/chat/widgets/chat_input_bar.dart | 80 ++++++++++ .../chat/widgets/chat_input_bar_header.dart | 50 ++++++ 4 files changed, 170 insertions(+), 118 deletions(-) create mode 100644 lib/pangea/chat/widgets/chat_input_bar.dart create mode 100644 lib/pangea/chat/widgets/chat_input_bar_header.dart diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index b8f00cf21..115361d77 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -1829,6 +1829,13 @@ class ChatController extends State onSelectMessage(event); }); } + + double inputBarHeight = 64; + void updateInputBarHeight(double height) { + if (mounted && height != inputBarHeight) { + setState(() => inputBarHeight = height); + } + } // Pangea# late final ValueNotifier _displayChatDetailsColumn; diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 9ef3a62d5..1af946cae 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -7,22 +7,16 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/pages/chat/chat_app_bar_list_tile.dart'; import 'package:fluffychat/pages/chat/chat_app_bar_title.dart'; import 'package:fluffychat/pages/chat/chat_event_list.dart'; import 'package:fluffychat/pages/chat/pinned_events.dart'; -import 'package:fluffychat/pages/chat/reply_display.dart'; import 'package:fluffychat/pangea/activity_planner/activity_plan_page_launch_icon_button.dart'; -import 'package:fluffychat/pangea/analytics_misc/gain_points_animation.dart'; -import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart'; -import 'package:fluffychat/pangea/chat/widgets/chat_floating_action_button.dart'; +import 'package:fluffychat/pangea/chat/widgets/chat_input_bar.dart'; +import 'package:fluffychat/pangea/chat/widgets/chat_input_bar_header.dart'; import 'package:fluffychat/pangea/chat/widgets/chat_view_background.dart'; -import 'package:fluffychat/pangea/chat/widgets/input_bar_wrapper.dart'; -import 'package:fluffychat/pangea/choreographer/widgets/it_bar.dart'; -import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/utils/account_config.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:fluffychat/widgets/future_loading_dialog.dart'; @@ -30,7 +24,6 @@ import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/mxc_image.dart'; import 'package:fluffychat/widgets/unread_rooms_badge.dart'; import '../../utils/stream_extension.dart'; -import 'chat_emoji_picker.dart'; enum _EventContextAction { info, report } @@ -118,33 +111,10 @@ class ChatView extends StatelessWidget { ), ]; // #Pangea - } else { - return [ - IconButton( - icon: const Icon(Icons.search_outlined), - tooltip: L10n.of(context).search, - onPressed: () { - context.go('/rooms/${controller.room.id}/search'); - }, - ), - ActivityPlanPageLaunchIconButton(controller: controller), - IconButton( - icon: const Icon(Icons.settings_outlined), - tooltip: L10n.of(context).chatDetails, - onPressed: () { - if (GoRouterState.of(context).uri.path.endsWith('/details')) { - context.go('/rooms/${controller.room.id}'); - } else { - context.go('/rooms/${controller.room.id}/details'); - } - }, - ), - ]; } // } else if (!controller.room.isArchived) { // return [ - // if (AppConfig.experimentalVoip && - // Matrix.of(context).voipPlugin != null && + // if (Matrix.of(context).voipPlugin != null && // controller.room.isDirectChat) // IconButton( // onPressed: controller.onPhoneButtonTap, @@ -156,6 +126,27 @@ class ChatView extends StatelessWidget { // ]; // } // return []; + return [ + IconButton( + icon: const Icon(Icons.search_outlined), + tooltip: L10n.of(context).search, + onPressed: () { + context.go('/rooms/${controller.room.id}/search'); + }, + ), + ActivityPlanPageLaunchIconButton(controller: controller), + IconButton( + icon: const Icon(Icons.settings_outlined), + tooltip: L10n.of(context).chatDetails, + onPressed: () { + if (GoRouterState.of(context).uri.path.endsWith('/details')) { + context.go('/rooms/${controller.room.id}'); + } else { + context.go('/rooms/${controller.room.id}/details'); + } + }, + ), + ]; // Pangea# } @@ -168,11 +159,6 @@ class ChatView extends StatelessWidget { future: () => controller.room.join(), exceptionContext: ExceptionContext.joinRoom, ); - // #Pangea - controller.room.leaveIfFull().then( - (full) => full ? context.go('/rooms') : null, - ); - // Pangea# } final bottomSheetPadding = FluffyThemes.isColumnMode(context) ? 16.0 : 8.0; final scrollUpBannerEventId = controller.scrollUpBannerEventId; @@ -229,12 +215,7 @@ class ChatView extends StatelessWidget { .stream .where((syncUpdate) => syncUpdate.hasRoomUpdate), builder: (context, _) => UnreadRoomsBadge( - filter: (r) => - r.id != controller.roomId - // #Pangea - && - !r.isAnalyticsRoom, - // Pangea# + filter: (r) => r.id != controller.roomId, badgePosition: BadgePosition.topEnd(end: 8, top: 4), child: const Center(child: BackButton()), ), @@ -417,9 +398,7 @@ class ChatView extends StatelessWidget { ), // #Pangea // Keep messages above minimum input bar height - const SizedBox( - height: 60, - ), + SizedBox(height: controller.inputBarHeight), // Pangea# ], ), @@ -433,77 +412,13 @@ class ChatView extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ - if (!controller.selectMode) - Container( - margin: EdgeInsets.only( - bottom: 10, - left: bottomSheetPadding, - right: bottomSheetPadding, - ), - constraints: const BoxConstraints( - maxWidth: FluffyThemes.columnWidth * 2.4, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - const PointsGainedAnimation( - gainColor: AppConfig.gold, - origin: - AnalyticsUpdateOrigin.sendMessage, - ), - const SizedBox(width: 100), - ChatFloatingActionButton( - controller: controller, - ), - ], - ), - ), - Container( - margin: EdgeInsets.only( - bottom: bottomSheetPadding, - left: bottomSheetPadding, - right: bottomSheetPadding, - ), - constraints: const BoxConstraints( - maxWidth: FluffyThemes.columnWidth * 2.5, - ), - alignment: Alignment.center, - child: Material( - clipBehavior: Clip.hardEdge, - // #Pangea - // color: Theme.of(context) - // .colorScheme - // .surfaceContainerHighest, - type: MaterialType.transparency, - // Pangea# - borderRadius: const BorderRadius.all( - Radius.circular(24), - ), - - child: Column( - children: [ - ITBar( - choreographer: controller.choreographer, - ), - DecoratedBox( - decoration: BoxDecoration( - color: Theme.of(context) - .colorScheme - .surfaceContainerHighest, - ), - child: Column( - children: [ - ReplyDisplay(controller), - ChatInputRowWrapper( - controller: controller, - ), - ChatEmojiPicker(controller), - ], - ), - ), - ], - ), - ), + ChatInputBarHeader( + controller: controller, + padding: bottomSheetPadding, + ), + ChatInputBar( + controller: controller, + padding: bottomSheetPadding, ), ], ), diff --git a/lib/pangea/chat/widgets/chat_input_bar.dart b/lib/pangea/chat/widgets/chat_input_bar.dart new file mode 100644 index 000000000..968b7f53b --- /dev/null +++ b/lib/pangea/chat/widgets/chat_input_bar.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pages/chat/chat.dart'; +import 'package:fluffychat/pages/chat/chat_emoji_picker.dart'; +import 'package:fluffychat/pages/chat/reply_display.dart'; +import 'package:fluffychat/pangea/chat/widgets/input_bar_wrapper.dart'; +import 'package:fluffychat/pangea/choreographer/widgets/it_bar.dart'; + +class ChatInputBar extends StatefulWidget { + final ChatController controller; + final double padding; + + const ChatInputBar({ + required this.controller, + required this.padding, + super.key, + }); + + @override + State createState() => ChatInputBarState(); +} + +class ChatInputBarState extends State { + void updateHeight() { + final renderBox = context.findRenderObject() as RenderBox?; + if (renderBox == null || !renderBox.hasSize) return; + widget.controller.updateInputBarHeight(renderBox.size.height); + } + + @override + Widget build(BuildContext context) { + return NotificationListener( + onNotification: (SizeChangedLayoutNotification notification) { + WidgetsBinding.instance.addPostFrameCallback((_) => updateHeight()); + return true; + }, + child: SizeChangedLayoutNotifier( + child: Container( + padding: EdgeInsets.only( + bottom: widget.padding, + left: widget.padding, + right: widget.padding, + ), + constraints: const BoxConstraints( + maxWidth: FluffyThemes.columnWidth * 2.5, + ), + alignment: Alignment.center, + child: Material( + clipBehavior: Clip.hardEdge, + type: MaterialType.transparency, + borderRadius: const BorderRadius.all( + Radius.circular(24), + ), + child: Column( + children: [ + ITBar(choreographer: widget.controller.choreographer), + DecoratedBox( + decoration: BoxDecoration( + color: + Theme.of(context).colorScheme.surfaceContainerHighest, + ), + child: Column( + children: [ + ReplyDisplay(widget.controller), + ChatInputRowWrapper( + controller: widget.controller, + ), + ChatEmojiPicker(widget.controller), + ], + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/pangea/chat/widgets/chat_input_bar_header.dart b/lib/pangea/chat/widgets/chat_input_bar_header.dart new file mode 100644 index 000000000..274c26da1 --- /dev/null +++ b/lib/pangea/chat/widgets/chat_input_bar_header.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pages/chat/chat.dart'; +import 'package:fluffychat/pangea/analytics_misc/gain_points_animation.dart'; +import 'package:fluffychat/pangea/analytics_misc/put_analytics_controller.dart'; +import 'package:fluffychat/pangea/chat/widgets/chat_floating_action_button.dart'; + +class ChatInputBarHeader extends StatelessWidget { + final ChatController controller; + final double padding; + + const ChatInputBarHeader({ + required this.controller, + required this.padding, + super.key, + }); + + @override + Widget build(BuildContext context) { + if (controller.selectMode) { + return const SizedBox.shrink(); + } + + return Container( + margin: EdgeInsets.only( + bottom: 10, + left: padding, + right: padding, + ), + constraints: const BoxConstraints( + maxWidth: FluffyThemes.columnWidth * 2.4, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + const PointsGainedAnimation( + gainColor: AppConfig.gold, + origin: AnalyticsUpdateOrigin.sendMessage, + ), + const SizedBox(width: 100), + ChatFloatingActionButton( + controller: controller, + ), + ], + ), + ); + } +}