From 0f5c19b0ce35c8c054018c10b3ae091957fa2c73 Mon Sep 17 00:00:00 2001 From: OfficialDakari Date: Sun, 2 Nov 2025 12:33:34 +0500 Subject: [PATCH] horrible implementation of thread list in room --- lib/config/routes.dart | 9 +- lib/pages/chat/chat.dart | 6 + lib/pages/chat/chat_event_list.dart | 11 +- lib/pages/chat/chat_view.dart | 4 +- lib/pages/chat_details/chat_details.dart | 1 - lib/pages/chat_details/chat_details_view.dart | 2 +- lib/pages/chat_thread/chat_threads.dart | 53 --------- lib/pages/chat_thread/chat_threads_view.dart | 110 ------------------ 8 files changed, 21 insertions(+), 175 deletions(-) delete mode 100644 lib/pages/chat_thread/chat_threads.dart delete mode 100644 lib/pages/chat_thread/chat_threads_view.dart diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 2841c06..fa32d04 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -1,6 +1,5 @@ import 'dart:async'; -import 'package:extera_next/pages/chat_thread/chat_threads.dart'; import 'package:extera_next/pages/chat_thread/thread.dart'; import 'package:flutter/material.dart'; @@ -153,13 +152,6 @@ abstract class AppRoutes { routes: [ GoRoute( path: 'threads', - pageBuilder: (context, state) => defaultPageBuilder( - context, - state, - ChatThreads( - roomId: state.pathParameters['roomid']!, - ), - ), redirect: loggedOutRedirect, routes: [ GoRoute( @@ -377,6 +369,7 @@ abstract class AppRoutes { roomId: state.pathParameters['roomid']!, shareItems: shareItems, eventId: state.uri.queryParameters['event'], + showThreadRoots: state.uri.queryParameters['threads'] == 'true', ), ); }, diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index b6eef99..91e914a 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -51,12 +51,14 @@ class ChatPage extends StatelessWidget { final String roomId; final List? shareItems; final String? eventId; + final bool? showThreadRoots; const ChatPage({ super.key, required this.roomId, this.eventId, this.shareItems, + this.showThreadRoots, }); @override @@ -79,6 +81,7 @@ class ChatPage extends StatelessWidget { room: room, shareItems: shareItems, eventId: eventId, + showThreadRoots: showThreadRoots, ); } } @@ -88,6 +91,7 @@ class ChatPageWithRoom extends StatefulWidget { final Thread? thread; final List? shareItems; final String? eventId; + final bool? showThreadRoots; const ChatPageWithRoom({ super.key, @@ -95,6 +99,7 @@ class ChatPageWithRoom extends StatefulWidget { this.thread, this.shareItems, this.eventId, + this.showThreadRoots, }); @override @@ -104,6 +109,7 @@ class ChatPageWithRoom extends StatefulWidget { class ChatController extends State with WidgetsBindingObserver { Room get room => sendingClient.getRoomById(roomId) ?? widget.room; + bool get showThreadRoots => (widget.showThreadRoots ?? false); Thread? get thread => sendingClient.getRoomById(roomId)?.threads[threadRootEventId] ?? widget.room.threads[threadRootEventId]; diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart index 54f2a14..9fd9539 100644 --- a/lib/pages/chat/chat_event_list.dart +++ b/lib/pages/chat/chat_event_list.dart @@ -15,10 +15,12 @@ import 'package:extera_next/utils/platform_infos.dart'; class ChatEventList extends StatelessWidget { final ChatController controller; + final bool showThreadRoots; const ChatEventList({ super.key, required this.controller, + this.showThreadRoots = false, }); @override @@ -37,7 +39,14 @@ class ChatEventList extends StatelessWidget { final horizontalPadding = FluffyThemes.isColumnMode(context) ? 8.0 : 0.0; - final events = timeline.events.filterByVisibleInGui().filterByThreaded(controller.thread != null); + var events = timeline.events.filterByVisibleInGui(); + + if (showThreadRoots) { + events = events.filterThreadRoots(); + } else { + events = events.filterByThreaded(controller.thread != null); + } + final animateInEventIndex = controller.animateInEventIndex; final threads = controller.room.threads; diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 76cab5d..f9d7c71 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -330,6 +330,7 @@ class ChatView extends StatelessWidget { onTap: controller.clearSingleSelectedEvent, child: ChatEventList( controller: controller, + showThreadRoots: controller.showThreadRoots, ), ), ), @@ -349,7 +350,8 @@ class ChatView extends StatelessWidget { ), ) else if (controller.room.canSendDefaultMessages && - controller.room.membership == Membership.join) + controller.room.membership == Membership.join && + !controller.showThreadRoots) Container( margin: EdgeInsets.all(bottomSheetPadding), constraints: const BoxConstraints( diff --git a/lib/pages/chat_details/chat_details.dart b/lib/pages/chat_details/chat_details.dart index c3cc32c..a0efa8c 100644 --- a/lib/pages/chat_details/chat_details.dart +++ b/lib/pages/chat_details/chat_details.dart @@ -1,4 +1,3 @@ -import 'package:extera_next/pages/chat_thread/chat_threads_view.dart'; import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index e990f40..21df5fc 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -271,7 +271,7 @@ class ChatDetailsView extends StatelessWidget { subtitle: Text(L10n.of(context).chatThreadsDescription), onTap: () => - context.push('/rooms/${room.id}/threads'), + context.push('/rooms/${room.id}?threads=true'), trailing: const Icon(Icons.chevron_right_outlined), ), ListTile( diff --git a/lib/pages/chat_thread/chat_threads.dart b/lib/pages/chat_thread/chat_threads.dart deleted file mode 100644 index ff0d001..0000000 --- a/lib/pages/chat_thread/chat_threads.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:extera_next/pages/chat_thread/chat_threads_view.dart'; -import 'package:extera_next/widgets/matrix.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:matrix/matrix.dart'; -import 'package:scroll_to_index/scroll_to_index.dart'; - -class ChatThreads extends StatefulWidget { - final String roomId; - - const ChatThreads({ - super.key, - required this.roomId, - }); - - @override - ChatThreadsController createState() => ChatThreadsController(); -} - -class ChatThreadsController extends State { - String get roomId => widget.roomId; - Room? get room => Matrix.of(context).client.getRoomById(roomId); - - bool isLoadingThreads = false; - - final AutoScrollController scrollController = AutoScrollController(); - - @override - Widget build(BuildContext context) => ChatThreadsView(this); - - void loadThreads([dynamic _]) async { - final room = Matrix.of(context).client.getRoomById(roomId); - - if (room == null) { - return; - } - - isLoadingThreads = true; - - await room.loadThreadsFromServer(); - - isLoadingThreads = false; - } - - List? get threads => room?.threads.values.toList(); - - Stream get onChanged => Matrix.of(context).client.onSync.stream.where( - (e) => - (e.rooms?.join?.containsKey(roomId) ?? false) && - (e.rooms!.join![roomId]?.timeline?.events - ?.any((s) => s.type == EventTypes.Message && s.content['m.relates_to'] != null) ?? - false), - ); -} \ No newline at end of file diff --git a/lib/pages/chat_thread/chat_threads_view.dart b/lib/pages/chat_thread/chat_threads_view.dart deleted file mode 100644 index 15ef1d2..0000000 --- a/lib/pages/chat_thread/chat_threads_view.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'package:extera_next/config/themes.dart'; -import 'package:extera_next/generated/l10n/l10n.dart'; -import 'package:extera_next/pages/chat_thread/chat_threads.dart'; -import 'package:extera_next/utils/platform_infos.dart'; -import 'package:extera_next/widgets/avatar.dart'; -import 'package:extera_next/widgets/layouts/max_width_body.dart'; -import 'package:flutter/material.dart'; -import 'package:matrix/matrix.dart'; -import 'package:scroll_to_index/scroll_to_index.dart'; - -class ChatThreadsView extends StatelessWidget { - final ChatThreadsController controller; - - const ChatThreadsView(this.controller, {super.key}); - - @override - Widget build(BuildContext context) { - final horizontalPadding = FluffyThemes.isColumnMode(context) ? 8.0 : 0.0; - - return Scaffold( - appBar: AppBar( - leading: const Center(child: BackButton()), - title: Text(L10n.of(context).chatThreads), - ), - body: MaxWidthBody( - child: ListView.custom( - padding: EdgeInsets.only( - top: 16, - bottom: 8, - left: horizontalPadding, - right: horizontalPadding, - ), - reverse: true, - controller: controller.scrollController, - keyboardDismissBehavior: PlatformInfos.isIOS - ? ScrollViewKeyboardDismissBehavior.onDrag - : ScrollViewKeyboardDismissBehavior.manual, - childrenDelegate: SliverChildBuilderDelegate( - (BuildContext context, int i) { - if (i == (controller.threads?.length ?? 0) + 1) { - if (controller.isLoadingThreads) { - return const Center( - child: CircularProgressIndicator.adaptive(strokeWidth: 2), - ); - } else if (!(controller.room?.loadedAllThreads ?? false)) { - return Builder( - builder: (context) { - WidgetsBinding.instance - .addPostFrameCallback(controller.loadThreads); - return Center( - child: IconButton( - onPressed: controller.loadThreads, - icon: const Icon(Icons.refresh_outlined), - ), - ); - }, - ); - } - i--; - - final thread = controller.threads![i]; - - return AutoScrollTag( - key: ValueKey(thread.rootEvent.eventId), - index: i, - controller: controller.scrollController, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - FutureBuilder( - future: thread.rootEvent.fetchSenderUser(), - builder: (context, snapshot) { - final user = snapshot.data ?? - thread.rootEvent.senderFromMemoryOrFallback; - - return Avatar( - mxContent: user.avatarUrl, - name: user.calcDisplayname(), - size: 48, - ); - }, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(thread.rootEvent.senderFromMemoryOrFallback.calcDisplayname()), - ], - ), - ), - const SizedBox(height: 4.0), - Text(thread.rootEvent.text), - ], - ), - ), - ); - } - }, - childCount: (controller.threads?.length ?? 0) + 1, - ), - ), - ), - ); - } -}