Files
toolbox-portal/src/preferences.ts
T

85 lines
2.3 KiB
TypeScript

import {
TOOLBOX_PREFERENCES_KEY,
defaultToolboxPreferences,
parseToolboxPreferences,
readToolboxPreferences,
writeToolboxPreferences,
type ToolboxPreferences,
} from '@add-ideas/toolbox-contract';
export const PREFERENCES_KEY = TOOLBOX_PREFERENCES_KEY;
export type Preferences = ToolboxPreferences;
export const defaultPreferences: Preferences = {
...defaultToolboxPreferences,
pinned: [],
order: [],
hidden: [],
};
export const parsePreferences = parseToolboxPreferences;
export function readPreferences(storage: Storage = localStorage): Preferences {
return readToolboxPreferences(storage);
}
export function writePreferences(
preferences: Preferences,
storage: Storage = localStorage
): void {
writeToolboxPreferences(preferences, storage);
}
export function cleanPreferences(
preferences: Preferences,
appIds: string[]
): Preferences {
const known = new Set(appIds);
return {
...preferences,
pinned: preferences.pinned.filter((id) => known.has(id)),
hidden: preferences.hidden.filter((id) => known.has(id)),
order: [
...preferences.order.filter((id) => known.has(id)),
...appIds.filter((id) => !preferences.order.includes(id)),
],
};
}
export function sortAppIds(
appIds: string[],
preferences: Preferences
): string[] {
const order = new Map(preferences.order.map((id, index) => [id, index]));
return [...appIds].sort(
(left, right) =>
(order.get(left) ?? Number.MAX_SAFE_INTEGER) -
(order.get(right) ?? Number.MAX_SAFE_INTEGER)
);
}
export function reorderWithinIds(
order: string[],
activeId: string,
overId: string,
peerIds: readonly string[]
): string[] {
if (activeId === overId) return order;
const peers = new Set(peerIds);
if (!peers.has(activeId) || !peers.has(overId)) return order;
const orderedPeers = order.filter((id) => peers.has(id));
for (const id of peerIds) {
if (!orderedPeers.includes(id)) orderedPeers.push(id);
}
const from = orderedPeers.indexOf(activeId);
const to = orderedPeers.indexOf(overId);
if (from < 0 || to < 0) return order;
const [moved] = orderedPeers.splice(from, 1);
if (!moved) return order;
orderedPeers.splice(to, 0, moved);
let peerIndex = 0;
return order.map((id) =>
peers.has(id) ? (orderedPeers[peerIndex++] ?? id) : id
);
}