Widen the media panel, support skinny full-page mode, keep jump-to-latest and return-to-previous reliable, and stop same-room event jumps from remounting the outlet or yanking the sidebar.
47 lines
1.2 KiB
TypeScript
47 lines
1.2 KiB
TypeScript
export type RoomScrollRange = {
|
|
start: number;
|
|
end: number;
|
|
};
|
|
|
|
export type RoomScrollState = {
|
|
top: number;
|
|
atBottom: boolean;
|
|
range: RoomScrollRange;
|
|
};
|
|
|
|
const cache = new Map<string, RoomScrollState>();
|
|
|
|
const MAX_ENTRIES = 20;
|
|
|
|
export const getRoomScrollState = (roomId: string): RoomScrollState | undefined =>
|
|
cache.get(roomId);
|
|
|
|
export const saveRoomScrollState = (roomId: string, state: RoomScrollState): void => {
|
|
if (cache.has(roomId)) cache.delete(roomId);
|
|
cache.set(roomId, state);
|
|
|
|
while (cache.size > MAX_ENTRIES) {
|
|
const oldest = cache.keys().next().value as string | undefined;
|
|
if (!oldest) break;
|
|
cache.delete(oldest);
|
|
}
|
|
};
|
|
|
|
export const clearRoomScrollState = (roomId: string): void => {
|
|
cache.delete(roomId);
|
|
};
|
|
|
|
/** Survives RoomTimeline remounts (e.g. clearing an event permalink URL). */
|
|
const returnAnchors = new Map<string, string>();
|
|
|
|
export const getRoomReturnAnchor = (roomId: string): string | undefined =>
|
|
returnAnchors.get(roomId);
|
|
|
|
export const setRoomReturnAnchor = (roomId: string, eventId: string): void => {
|
|
returnAnchors.set(roomId, eventId);
|
|
};
|
|
|
|
export const clearRoomReturnAnchor = (roomId: string): void => {
|
|
returnAnchors.delete(roomId);
|
|
};
|