RoomListStore: Sort low priority rooms to the bottom of the list (#30070)

* Sort low priority rooms to the bottom of the list

* Write test
This commit is contained in:
R Midhun Suresh
2025-06-04 23:21:49 +05:30
committed by GitHub
parent df4cf64ebe
commit 231ab20dcf
2 changed files with 75 additions and 5 deletions

View File

@@ -9,6 +9,7 @@ import type { Room } from "matrix-js-sdk/src/matrix";
import { type Sorter, SortingAlgorithm } from ".";
import { getLastTs } from "../../../room-list/algorithms/tag-sorting/RecentAlgorithm";
import { RoomNotificationStateStore } from "../../../notifications/RoomNotificationStateStore";
import { DefaultTagID } from "../../../room-list/models";
export class RecencySorter implements Sorter {
public constructor(private myUserId: string) {}
@@ -19,11 +20,9 @@ export class RecencySorter implements Sorter {
}
public comparator(roomA: Room, roomB: Room, cache?: any): number {
// Check mute status first; muted rooms should be at the bottom
const isRoomAMuted = RoomNotificationStateStore.instance.getRoomState(roomA).muted;
const isRoomBMuted = RoomNotificationStateStore.instance.getRoomState(roomB).muted;
if (isRoomAMuted && !isRoomBMuted) return 1;
if (isRoomBMuted && !isRoomAMuted) return -1;
// First check if the rooms are low priority or muted
const exceptionalOrdering = this.getScore(roomA) - this.getScore(roomB);
if (exceptionalOrdering !== 0) return exceptionalOrdering;
// Then check recency; recent rooms should be at the top
const roomALastTs = this.getTs(roomA, cache);
@@ -35,6 +34,28 @@ export class RecencySorter implements Sorter {
return SortingAlgorithm.Recency;
}
/**
* This sorter mostly sorts rooms by recency but there are two exceptions:
* 1. Muted rooms are sorted to the bottom of the list.
* 2. Low priority rooms are sorted to the bottom of the list but before muted rooms.
*
* The following method provides a numerical value that takes care of this
* exceptional ordering. For two rooms A and B, it works as follows:
* - If getScore(A) - getScore(B) > 0, A should come after B
* - If getScore(A) - getScore(B) < 0, A should come before B
* - If getScore(A) - getScore(B) = 0, no special ordering needed, just use recency
*/
private getScore(room: Room): number {
const isLowPriority = !!room.tags[DefaultTagID.LowPriority];
const isMuted = RoomNotificationStateStore.instance.getRoomState(room).muted;
// These constants are chosen so that the following order is maintained:
// Low priority rooms -> Low priority and muted rooms -> Muted rooms
if (isMuted && isLowPriority) return 5;
else if (isMuted) return 10;
else if (isLowPriority) return 2;
else return 0;
}
private getTs(room: Room, cache?: { [roomId: string]: number }): number {
const ts = cache?.[room.roomId] ?? getLastTs(room, this.myUserId);
if (cache) {