Backend: - expose cover thumbnail URL on album responses (LEFT JOIN + presign) - auto-assign cover only when empty; FK cover_photo_id -> photos ON DELETE SET NULL - add photos_count / members_count to album responses; cover repo test Frontend: - split layouts into (app) shell (resizable rail + contextual panel) and (public) - album rail + create-album dialog; album panel with cover picker / make-cover - photo viewer route with filmstrip, replacing lightbox; share reuses it - grid density slider, toolbar + drag-and-drop upload, dark graphite default OpenSpec: add lightroom-workspace-ui change (proposal, design, specs, tasks)
21 lines
475 B
TypeScript
21 lines
475 B
TypeScript
const KEY = 'grid-cols';
|
|
const MIN = 2;
|
|
const MAX = 8;
|
|
|
|
class DensityStore {
|
|
cols = $state(5);
|
|
|
|
init() {
|
|
if (typeof window === 'undefined') return;
|
|
const v = parseInt(localStorage.getItem(KEY) ?? '', 10);
|
|
if (v >= MIN && v <= MAX) this.cols = v;
|
|
}
|
|
|
|
set(value: number) {
|
|
this.cols = Math.min(MAX, Math.max(MIN, Math.round(value)));
|
|
if (typeof window !== 'undefined') localStorage.setItem(KEY, String(this.cols));
|
|
}
|
|
}
|
|
|
|
export const density = new DensityStore();
|