From a5fef138dd01ac1b2620adbda2021841f3ba46ea Mon Sep 17 00:00:00 2001 From: Henry-Hiles Date: Wed, 14 Oct 2026 22:58:10 -0400 Subject: [PATCH] add support for altering room ordering Fixes #115 --- lib/controllers/settings_sections.dart | 21 +++++++++++++++ lib/controllers/spaces.dart | 37 +++++++++++++++++--------- lib/models/room_order.dart | 1 + lib/models/settings.dart | 2 ++ 4 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 lib/models/room_order.dart diff --git a/lib/controllers/settings_sections.dart b/lib/controllers/settings_sections.dart index 26288a9..f782b86 100644 --- a/lib/controllers/settings_sections.dart +++ b/lib/controllers/settings_sections.dart @@ -18,6 +18,7 @@ import "package:nexus/controllers/unified_push_allowed.dart"; import "package:nexus/controllers/unified_push_distributors.dart"; import "package:nexus/helpers/extensions/distributor_name.dart"; import "package:nexus/models/account_data.dart"; +import "package:nexus/models/room_order.dart"; import "package:nexus/models/settings_category.dart"; import "package:nexus/main.dart"; import "package:nexus/widgets/settings/dialog_list_tile.dart"; @@ -94,6 +95,26 @@ class SettingsSectionsController .onError(showError), ), ), + .new( + title: "Room Ordering", + description: "Sort rooms by recent activity, optionally showing mentioned and unread rooms first.", + icon: Icons.sort, + builder: (title, description, icon) => DialogListTile( + icon: Icon(icon), + title: title, + subtitle: Text(description), + initialValue: settings.roomOrder, + options: RoomOrder.values, + getName: (option) => switch (option) { + .unreadFirst => "Mentioned, then unread", + .recentActivity => "Recent activity only", + }, + onChanged: (value) => ref + .read(SettingsController.provider.notifier) + .set(settings.copyWith(roomOrder: value)) + .onError(showError), + ), + ), if (!Platform.isAndroid && !Platform.isIOS) .new( title: "Show Minimize Button", diff --git a/lib/controllers/spaces.dart b/lib/controllers/spaces.dart index 02d6476..0dae863 100644 --- a/lib/controllers/spaces.dart +++ b/lib/controllers/spaces.dart @@ -8,6 +8,7 @@ import "package:nexus/controllers/settings.dart"; import "package:nexus/controllers/top_level_spaces.dart"; import "package:nexus/controllers/space_edges.dart"; import "package:nexus/models/room.dart"; +import "package:nexus/models/room_metadata.dart"; import "package:nexus/models/space.dart"; import "package:nexus/models/subspace.dart"; @@ -135,22 +136,32 @@ class SpacesController extends AsyncNotifier> { ...spaces, ]; + final roomOrder = await ref.watch( + SettingsController.provider.selectAsync((data) => data.roomOrder), + ); + + // Mentioned -> Unread -> Other + int unreadPriority(Room room) => switch (room.metadata) { + RoomMetadata(unreadHighlights: > 0) => 0, + RoomMetadata(unreadNotifications: > 0) || + RoomMetadata(unreadMessages: > 0) => 1, + _ => 2, + }; + return allSpaces .map( (space) => space.copyWith( - children: .new( - space.children - .sortedBy( - (element) => - element - .metadata - ?.sortingTimestamp - .millisecondsSinceEpoch ?? - 0, - ) - .sortedBy((room) => room.metadata?.unreadMessages ?? 0) - .reversed, - ), + children: space.children.sort((a, b) { + if (roomOrder == .unreadFirst) { + final byUnread = unreadPriority(a).compareTo(unreadPriority(b)); + if (byUnread != 0) return byUnread; + } + + // Most recent activity first + return (b.metadata?.sortingTimestamp ?? DateTime(0)).compareTo( + a.metadata?.sortingTimestamp ?? DateTime(0), + ); + }), ), ) .toIList(); diff --git a/lib/models/room_order.dart b/lib/models/room_order.dart new file mode 100644 index 0000000..c0b5166 --- /dev/null +++ b/lib/models/room_order.dart @@ -0,0 +1 @@ +enum RoomOrder { unreadFirst, recentActivity } diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 97cd6ca..407aa19 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -1,5 +1,6 @@ import "package:material_ui/material_ui.dart"; import "package:freezed_annotation/freezed_annotation.dart"; +import "package:nexus/models/room_order.dart"; part "settings.freezed.dart"; part "settings.g.dart"; @@ -12,6 +13,7 @@ class const Settings({ final bool linuxMobileMode = false, final bool showAllInHome = false, final bool showMinimizeButton = false, + final RoomOrder roomOrder = .unreadFirst, }) with _$Settings { Map toJson() => _$SettingsToJson(this);