From 31870d6e6f5267d21844f45acb7511bba39e8340 Mon Sep 17 00:00:00 2001 From: 3dtours Date: Mon, 5 Oct 2026 18:22:22 +0700 Subject: [PATCH] fix(library): fix Olympus ORF raw color conversion and add custom photo context menu modal --- docker/frontend/src/Library.tsx | 123 ++++++++++++++++++++++- docker/frontend/src/engine/rawDevelop.ts | 10 +- docker/frontend/src/i18n/en.ts | 4 + docker/frontend/src/i18n/vi.ts | 4 + 4 files changed, 130 insertions(+), 11 deletions(-) diff --git a/docker/frontend/src/Library.tsx b/docker/frontend/src/Library.tsx index 4b14855..3bba480 100644 --- a/docker/frontend/src/Library.tsx +++ b/docker/frontend/src/Library.tsx @@ -228,6 +228,7 @@ export function Library() { // one more folder; `root` means it landed on a row at the top level — the head // of a tree — which also carries folding the whole tree. const [menu, setMenu] = useState<{ folder: LibraryFolder | null; root?: boolean; rel?: string; node?: string; x: number; y: number } | null>(null); + const [photoMenu, setPhotoMenu] = useState<{ photo: LibraryPhoto; x: number; y: number } | null>(null); // A reading of this roll that is still waiting its turn. The menu is where // that wait is called off, so it has to know one exists. const queued = menu?.folder ? scanQueue().some((j) => j.folder === menu.folder!.name) : false; @@ -574,13 +575,17 @@ export function Library() { // behind a full-screen scrim: a scrim would eat the click that opens the next // folder, which is half of how this screen is used. useEffect(() => { - if (!menu) return; + if (!menu && !photoMenu) return; const away = (e: Event) => { if (e.target instanceof Element && e.target.closest('.lib-menu')) return; setMenu(null); + setPhotoMenu(null); }; const key = (e: KeyboardEvent) => { - if (e.key === 'Escape') setMenu(null); + if (e.key === 'Escape') { + setMenu(null); + setPhotoMenu(null); + } }; document.addEventListener('pointerdown', away); document.addEventListener('keydown', key); @@ -588,7 +593,7 @@ export function Library() { document.removeEventListener('pointerdown', away); document.removeEventListener('keydown', key); }; - }, [menu]); + }, [menu, photoMenu]); // A reading asked for here is a request, not a reading: one walk runs at a time, // and a folder asked for while another is being read waits its turn — which is @@ -1517,7 +1522,19 @@ export function Library() {
{wall.above > 0 ?