import { MatrixClient } from 'matrix-js-sdk'; import { Unread } from '../../types/matrix/room'; export type SortFunc = (a: T, b: T) => number; export const factoryRoomIdByActivity = (mx: MatrixClient): SortFunc => (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 => (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 => (a, b) => { const aT = getUnreadCount(a) ?? 0; const bT = getUnreadCount(b) ?? 0; return bT - aT; }; // "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, mx: MatrixClient, ): SortFunc => { 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); }; }; export const byTsOldToNew: SortFunc = (a, b) => a - b; export const byOrderKey: SortFunc = (a, b) => { if (!a && !b) { return 0; } if (!b) return -1; if (!a) return 1; if (a < b) { return -1; } return 1; };