summaryrefslogtreecommitdiff
path: root/web/js/selection.js
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-29 20:19:34 +0300
committerPaul Buetow <paul@buetow.org>2026-04-29 20:19:34 +0300
commit4a70c0ea083306cb79d0fa325d331ffa4333154a (patch)
tree84df7e2f781974ef45ac8c34f1a59e80fdd5c41d /web/js/selection.js
parentcf30414c2a0696cc75c615f4da66ea85d0522c42 (diff)
feat: create web PWA frontend
Diffstat (limited to 'web/js/selection.js')
-rw-r--r--web/js/selection.js43
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; }