add support for altering room ordering

Fixes #115
This commit is contained in:
Henry Hiles 2026-10-14 22:58:10 -04:00
commit a5fef138dd
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
4 changed files with 48 additions and 13 deletions

View file

@ -18,6 +18,7 @@ import "package:nexus/controllers/unified_push_allowed.dart";
import "package:nexus/controllers/unified_push_distributors.dart"; import "package:nexus/controllers/unified_push_distributors.dart";
import "package:nexus/helpers/extensions/distributor_name.dart"; import "package:nexus/helpers/extensions/distributor_name.dart";
import "package:nexus/models/account_data.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/models/settings_category.dart";
import "package:nexus/main.dart"; import "package:nexus/main.dart";
import "package:nexus/widgets/settings/dialog_list_tile.dart"; import "package:nexus/widgets/settings/dialog_list_tile.dart";
@ -94,6 +95,26 @@ class SettingsSectionsController
.onError(showError), .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<RoomOrder>(
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) if (!Platform.isAndroid && !Platform.isIOS)
.new( .new(
title: "Show Minimize Button", title: "Show Minimize Button",

View file

@ -8,6 +8,7 @@ import "package:nexus/controllers/settings.dart";
import "package:nexus/controllers/top_level_spaces.dart"; import "package:nexus/controllers/top_level_spaces.dart";
import "package:nexus/controllers/space_edges.dart"; import "package:nexus/controllers/space_edges.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
import "package:nexus/models/room_metadata.dart";
import "package:nexus/models/space.dart"; import "package:nexus/models/space.dart";
import "package:nexus/models/subspace.dart"; import "package:nexus/models/subspace.dart";
@ -135,22 +136,32 @@ class SpacesController extends AsyncNotifier<IList<Space>> {
...spaces, ...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 return allSpaces
.map( .map(
(space) => space.copyWith( (space) => space.copyWith(
children: .new( children: space.children.sort((a, b) {
space.children if (roomOrder == .unreadFirst) {
.sortedBy( final byUnread = unreadPriority(a).compareTo(unreadPriority(b));
(element) => if (byUnread != 0) return byUnread;
element }
.metadata
?.sortingTimestamp // Most recent activity first
.millisecondsSinceEpoch ?? return (b.metadata?.sortingTimestamp ?? DateTime(0)).compareTo(
0, a.metadata?.sortingTimestamp ?? DateTime(0),
) );
.sortedBy((room) => room.metadata?.unreadMessages ?? 0) }),
.reversed,
),
), ),
) )
.toIList(); .toIList();

View file

@ -0,0 +1 @@
enum RoomOrder { unreadFirst, recentActivity }

View file

@ -1,5 +1,6 @@
import "package:material_ui/material_ui.dart"; import "package:material_ui/material_ui.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/room_order.dart";
part "settings.freezed.dart"; part "settings.freezed.dart";
part "settings.g.dart"; part "settings.g.dart";
@ -12,6 +13,7 @@ class const Settings({
final bool linuxMobileMode = false, final bool linuxMobileMode = false,
final bool showAllInHome = false, final bool showAllInHome = false,
final bool showMinimizeButton = false, final bool showMinimizeButton = false,
final RoomOrder roomOrder = .unreadFirst,
}) with _$Settings { }) with _$Settings {
Map<String, Object?> toJson() => _$SettingsToJson(this); Map<String, Object?> toJson() => _$SettingsToJson(this);