From 4e2b185f5d6c994d51e664e2ed54511975d0bcf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Sat, 6 Dec 2025 10:24:14 +0100 Subject: [PATCH 1/4] chore: Follow up better request history button --- lib/pages/chat/chat_event_list.dart | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart index e87a6413c..a6898f517 100644 --- a/lib/pages/chat/chat_event_list.dart +++ b/lib/pages/chat/chat_event_list.dart @@ -85,21 +85,19 @@ class ChatEventList extends StatelessWidget { // Request history button or progress indicator: if (i == events.length + 1) { - if (controller.activeThreadId != null) { + if (controller.activeThreadId != null || + !timeline.canRequestHistory) { return const SizedBox.shrink(); } return Builder( builder: (context) { - if (timeline.canRequestHistory) { - final visibleIndex = timeline.events.lastIndexWhere( - (event) => - !event.isCollapsedState && event.isVisibleInGui, + final visibleIndex = timeline.events.lastIndexWhere( + (event) => !event.isCollapsedState && event.isVisibleInGui, + ); + if (visibleIndex > timeline.events.length - 50) { + WidgetsBinding.instance.addPostFrameCallback( + controller.requestHistory, ); - if (visibleIndex > timeline.events.length - 50) { - WidgetsBinding.instance.addPostFrameCallback( - controller.requestHistory, - ); - } } return Center( child: TextButton.icon( From fc052c84ac023250d1b89aef662cebcd7c45b240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Sat, 6 Dec 2025 10:37:07 +0100 Subject: [PATCH 2/4] refactor: Adjust state event design --- lib/l10n/intl_en.arb | 2 + lib/pages/chat/events/message.dart | 4 -- .../events/room_creation_state_event.dart | 59 ------------------- lib/pages/chat/events/state_message.dart | 7 +-- .../matrix_sdk_extensions/matrix_locals.dart | 8 +-- 5 files changed, 8 insertions(+), 72 deletions(-) delete mode 100644 lib/pages/chat/events/room_creation_state_event.dart diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index b09d93862..f76710677 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -325,6 +325,7 @@ } } }, + "changedTheChatDescription": "{username} changed the chat description", "changedTheChatDescriptionTo": "{username} changed the chat description to: '{description}'", "@changedTheChatDescriptionTo": { "type": "String", @@ -337,6 +338,7 @@ } } }, + "changedTheChatName": "{username} changed the chat name", "changedTheChatNameTo": "{username} changed the chat name to: '{chatname}'", "@changedTheChatNameTo": { "type": "String", diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart index 9943eb6fe..69cb567a5 100644 --- a/lib/pages/chat/events/message.dart +++ b/lib/pages/chat/events/message.dart @@ -10,7 +10,6 @@ import 'package:swipe_to_action/swipe_to_action.dart'; import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/l10n/l10n.dart'; -import 'package:fluffychat/pages/chat/events/room_creation_state_event.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/date_time_extension.dart'; import 'package:fluffychat/utils/file_description.dart'; @@ -91,9 +90,6 @@ class Message extends StatelessWidget { if (event.type.startsWith('m.call.')) { return const SizedBox.shrink(); } - if (event.type == EventTypes.RoomCreate) { - return RoomCreationStateEvent(event: event); - } return StateMessage(event, onExpand: onExpand, isCollapsed: isCollapsed); } diff --git a/lib/pages/chat/events/room_creation_state_event.dart b/lib/pages/chat/events/room_creation_state_event.dart deleted file mode 100644 index f1358a3c8..000000000 --- a/lib/pages/chat/events/room_creation_state_event.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:matrix/matrix.dart'; - -import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/l10n/l10n.dart'; -import 'package:fluffychat/utils/date_time_extension.dart'; -import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; -import 'package:fluffychat/widgets/avatar.dart'; - -class RoomCreationStateEvent extends StatelessWidget { - final Event event; - - const RoomCreationStateEvent({required this.event, super.key}); - - @override - Widget build(BuildContext context) { - final l10n = L10n.of(context); - final matrixLocals = MatrixLocals(l10n); - final theme = Theme.of(context); - final roomName = event.room.getLocalizedDisplayname(matrixLocals); - return Padding( - padding: const EdgeInsets.only(bottom: 32.0), - child: Center( - child: ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 256), - child: Material( - color: theme.colorScheme.surfaceContainer, - borderRadius: BorderRadius.circular(AppConfig.borderRadius), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: .min, - children: [ - Avatar( - mxContent: event.room.avatar, - name: roomName, - size: Avatar.defaultSize * 2, - ), - Text( - roomName, - style: theme.textTheme.bodyLarge, - textAlign: TextAlign.center, - ), - const SizedBox(height: 8), - Text( - '${event.originServerTs.localizedTime(context)} | ${l10n.countParticipants((event.room.summary.mJoinedMemberCount ?? 1) + (event.room.summary.mInvitedMemberCount ?? 0))}', - style: theme.textTheme.labelSmall, - textAlign: TextAlign.center, - ), - ], - ), - ), - ), - ), - ), - ); - } -} diff --git a/lib/pages/chat/events/state_message.dart b/lib/pages/chat/events/state_message.dart index 196a85a02..9c8ad3da7 100644 --- a/lib/pages/chat/events/state_message.dart +++ b/lib/pages/chat/events/state_message.dart @@ -52,10 +52,7 @@ class StateMessage extends StatelessWidget { ), ), if (onExpand != null) ...[ - const TextSpan( - text: ' + ', - style: TextStyle(fontWeight: FontWeight.bold), - ), + const TextSpan(text: '\n'), TextSpan( style: TextStyle( color: theme.colorScheme.primary, @@ -70,7 +67,7 @@ class StateMessage extends StatelessWidget { ), textAlign: TextAlign.center, style: TextStyle( - fontSize: 12 * AppSettings.fontSizeFactor.value, + fontSize: 11 * AppSettings.fontSizeFactor.value, decoration: event.redacted ? TextDecoration.lineThrough : null, diff --git a/lib/utils/matrix_sdk_extensions/matrix_locals.dart b/lib/utils/matrix_sdk_extensions/matrix_locals.dart index 4f818d533..9a12d25f7 100644 --- a/lib/utils/matrix_sdk_extensions/matrix_locals.dart +++ b/lib/utils/matrix_sdk_extensions/matrix_locals.dart @@ -37,13 +37,13 @@ class MatrixLocals extends MatrixLocalizations { } @override - String changedTheChatDescriptionTo(String senderName, String content) { - return l10n.changedTheChatDescriptionTo(senderName, content); + String changedTheChatDescriptionTo(String senderName, _) { + return l10n.changedTheChatDescription(senderName); } @override - String changedTheChatNameTo(String senderName, String content) { - return l10n.changedTheChatNameTo(senderName, content); + String changedTheChatNameTo(String senderName, _) { + return l10n.changedTheChatName(senderName); } @override From e80e3273eabc31101a9f26fc0df33f196433f372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Sat, 6 Dec 2025 10:43:25 +0100 Subject: [PATCH 3/4] chore: Follow up scroll down in fragmented timeline --- lib/pages/chat/chat.dart | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 9e0af8e21..3deee3883 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -231,6 +231,17 @@ class ChatController extends State if (mostRecentEvent != null) { setReadMarker(eventId: mostRecentEvent.eventId); + WidgetsBinding.instance.addPostFrameCallback((_) { + final index = timeline.events.filterByVisibleInGui().indexOf( + mostRecentEvent, + ); + if (index >= 0) { + scrollController.scrollToIndex( + index, + preferPosition: AutoScrollPosition.begin, + ); + } + }); } } @@ -458,7 +469,7 @@ class ChatController extends State void onInsert(int i) { // setState will be called by updateView() anyway - if (i <= 5) animateInEventIndex = i; + if (timeline?.allowNewEvent == true) animateInEventIndex = i; } Future _getTimeline({String? eventContextId}) async { From 4f196b29bd475d7368608c88f4cf05073b942c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Sat, 6 Dec 2025 15:49:10 +0100 Subject: [PATCH 4/4] fix: Do not request hero users for rooms with name --- lib/pages/chat_list/chat_list_item.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart index c06c22509..fc9499cc3 100644 --- a/lib/pages/chat_list/chat_list_item.dart +++ b/lib/pages/chat_list/chat_list_item.dart @@ -71,8 +71,8 @@ class ChatListItem extends StatelessWidget { clipBehavior: Clip.hardEdge, color: backgroundColor, child: FutureBuilder( - future: room.loadHeroUsers(), - builder: (context, snapshot) => HoverBuilder( + future: room.name.isEmpty ? room.loadHeroUsers() : null, + builder: (context, _) => HoverBuilder( builder: (context, listTileHovered) => ListTile( visualDensity: const VisualDensity(vertical: -0.5), contentPadding: const EdgeInsets.symmetric(horizontal: 8),