diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-29 20:19:34 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-29 20:19:34 +0300 |
| commit | 4a70c0ea083306cb79d0fa325d331ffa4333154a (patch) | |
| tree | 84df7e2f781974ef45ac8c34f1a59e80fdd5c41d /web/js/selection.js | |
| parent | cf30414c2a0696cc75c615f4da66ea85d0522c42 (diff) | |
feat: create web PWA frontend
Diffstat (limited to 'web/js/selection.js')
| -rw-r--r-- | web/js/selection.js | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/web/js/selection.js b/web/js/selection.js new file mode 100644 index 0000000..00b91b8 --- /dev/null +++ b/web/js/selection.js @@ -0,0 +1,43 @@ +let selectedIndex = -1; + +export function initSelection() { + const grid = document.getElementById('media-grid'); + if (!grid) return; + grid.addEventListener('click', (e) => { + const card = e.target.closest('.media-card, .media-row'); + if (!card) return; + selectByElement(card); + }); +} + +function refreshCards() { + return Array.from(document.querySelectorAll('.media-card, .media-row')); +} + +export function select(index) { + const cards = refreshCards(); + if (!cards.length) { selectedIndex = -1; return; } + selectedIndex = Math.max(0, Math.min(index, cards.length - 1)); + cards.forEach((c) => c.classList.remove('selected')); + const el = cards[selectedIndex]; + if (el) { + el.classList.add('selected'); + el.scrollIntoView({ block: 'nearest', behavior: 'smooth' }); + } +} + +export function selectByElement(el) { + const cards = refreshCards(); + const idx = cards.indexOf(el); + if (idx >= 0) select(idx); +} + +export function next(step = 1) { + const cards = refreshCards(); + if (!cards.length) return; + select((selectedIndex + step + cards.length) % cards.length); +} + +export function prev(step = 1) { next(-step); } +export function currentIndex() { return selectedIndex; } +export function currentElement() { return refreshCards()[selectedIndex] ?? null; } |
