Allow favorites to be sorted by type. Closes #314.

This commit is contained in:
Jack Kingsman
2026-07-08 14:57:29 -07:00
parent 2fcbefac3b
commit 84e6c34255
3 changed files with 158 additions and 24 deletions
+21 -6
View File
@@ -13,10 +13,24 @@ const SORT_ORDER_KEY = 'remoteterm-sortOrder';
const SIDEBAR_SECTION_SORT_ORDERS_KEY = 'remoteterm-sidebar-section-sort-orders';
export type ConversationTimes = Record<string, number>;
export type SortOrder = 'recent' | 'alpha';
// 'type-*' orders group by contact/channel type first, then apply the sub-order.
// They are only used by the Favorites section (every other section is single-type,
// so type grouping is meaningless there and its toggle stays recent<->alpha).
export type SortOrder = 'recent' | 'alpha' | 'type-recent' | 'type-alpha';
export type SidebarSortableSection = 'favorites' | 'channels' | 'contacts' | 'rooms' | 'repeaters';
export type SidebarSectionSortOrders = Record<SidebarSortableSection, SortOrder>;
// Full cycle for the Favorites sort toggle, in click order.
export const FAVORITES_SORT_CYCLE: SortOrder[] = ['recent', 'alpha', 'type-recent', 'type-alpha'];
function coerceFavoritesSortOrder(value: unknown): SortOrder {
return (FAVORITES_SORT_CYCLE as unknown[]).includes(value) ? (value as SortOrder) : 'recent';
}
function coerceBasicSortOrder(value: unknown): SortOrder {
return value === 'alpha' ? 'alpha' : 'recent';
}
// In-memory cache of last message times (loaded from server on init)
let lastMessageTimesCache: ConversationTimes = {};
@@ -106,11 +120,12 @@ export function loadLocalStorageSidebarSectionSortOrders(): SidebarSectionSortOr
const parsed = JSON.parse(stored) as Partial<SidebarSectionSortOrders>;
return {
favorites: parsed.favorites === 'alpha' ? 'alpha' : 'recent',
channels: parsed.channels === 'alpha' ? 'alpha' : 'recent',
contacts: parsed.contacts === 'alpha' ? 'alpha' : 'recent',
rooms: parsed.rooms === 'alpha' ? 'alpha' : 'recent',
repeaters: parsed.repeaters === 'alpha' ? 'alpha' : 'recent',
// Only Favorites may persist the type-grouped orders.
favorites: coerceFavoritesSortOrder(parsed.favorites),
channels: coerceBasicSortOrder(parsed.channels),
contacts: coerceBasicSortOrder(parsed.contacts),
rooms: coerceBasicSortOrder(parsed.rooms),
repeaters: coerceBasicSortOrder(parsed.repeaters),
};
} catch {
return null;