2024-05-31 19:49:46 +05:30
|
|
|
import { MatrixClient } from 'matrix-js-sdk';
|
2026-07-24 17:22:23 -04:00
|
|
|
import { Unread } from '../../types/matrix/room';
|
2024-05-31 19:49:46 +05:30
|
|
|
|
|
|
|
|
export type SortFunc<T> = (a: T, b: T) => number;
|
|
|
|
|
|
|
|
|
|
export const factoryRoomIdByActivity =
|
|
|
|
|
(mx: MatrixClient): SortFunc<string> =>
|
|
|
|
|
(a, b) => {
|
|
|
|
|
const room1 = mx.getRoom(a);
|
|
|
|
|
const room2 = mx.getRoom(b);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
(room2?.getLastActiveTimestamp() ?? Number.MIN_SAFE_INTEGER) -
|
|
|
|
|
(room1?.getLastActiveTimestamp() ?? Number.MIN_SAFE_INTEGER)
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const factoryRoomIdByAtoZ =
|
|
|
|
|
(mx: MatrixClient): SortFunc<string> =>
|
|
|
|
|
(a, b) => {
|
|
|
|
|
let aName = mx.getRoom(a)?.name ?? '';
|
|
|
|
|
let bName = mx.getRoom(b)?.name ?? '';
|
|
|
|
|
|
|
|
|
|
// remove "#" from the room name
|
|
|
|
|
// To ignore it in sorting
|
|
|
|
|
aName = aName.replace(/#/g, '');
|
|
|
|
|
bName = bName.replace(/#/g, '');
|
|
|
|
|
|
|
|
|
|
if (aName.toLowerCase() < bName.toLowerCase()) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
if (aName.toLowerCase() > bName.toLowerCase()) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const factoryRoomIdByUnreadCount =
|
|
|
|
|
(getUnreadCount: (roomId: string) => number): SortFunc<string> =>
|
|
|
|
|
(a, b) => {
|
|
|
|
|
const aT = getUnreadCount(a) ?? 0;
|
|
|
|
|
const bT = getUnreadCount(b) ?? 0;
|
|
|
|
|
return bT - aT;
|
|
|
|
|
};
|
|
|
|
|
|
2026-07-24 17:22:23 -04:00
|
|
|
// "Unread First": rooms with unread sort before those without, then by unread
|
|
|
|
|
// count desc, then — crucially for the large all-read tail where counts tie —
|
|
|
|
|
// by recent activity, so it isn't left in arbitrary order.
|
|
|
|
|
export const factoryRoomIdByUnread = (
|
|
|
|
|
roomToUnread: Map<string, Unread>,
|
|
|
|
|
mx: MatrixClient,
|
|
|
|
|
): SortFunc<string> => {
|
|
|
|
|
const byActivity = factoryRoomIdByActivity(mx);
|
|
|
|
|
return (a, b) => {
|
|
|
|
|
const aUnread = roomToUnread.get(a);
|
|
|
|
|
const bUnread = roomToUnread.get(b);
|
|
|
|
|
const aHas = (aUnread?.total ?? 0) > 0;
|
|
|
|
|
const bHas = (bUnread?.total ?? 0) > 0;
|
|
|
|
|
if (aHas !== bHas) return aHas ? -1 : 1;
|
|
|
|
|
const byCount = (bUnread?.total ?? 0) - (aUnread?.total ?? 0);
|
|
|
|
|
if (byCount !== 0) return byCount;
|
|
|
|
|
return byActivity(a, b);
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2024-05-31 19:49:46 +05:30
|
|
|
export const byTsOldToNew: SortFunc<number> = (a, b) => a - b;
|
|
|
|
|
|
|
|
|
|
export const byOrderKey: SortFunc<string | undefined> = (a, b) => {
|
|
|
|
|
if (!a && !b) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!b) return -1;
|
|
|
|
|
if (!a) return 1;
|
|
|
|
|
|
|
|
|
|
if (a < b) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
};
|