From 2f6fc1ff2074733ff006e276d7a5ab4be725f6ea Mon Sep 17 00:00:00 2001 From: Disco DeDisco Date: Wed, 25 Mar 2026 00:05:52 -0400 Subject: [PATCH] horizontal scrolling where applicable can now be done via vertical mousewheel movement --- .../static/apps/dashboard/dashboard.js | 9 +++++++++ .../gameboard/static/apps/gameboard/game-kit.js | 15 +++++++++++++-- .../test_component_cards_tarot.py | 17 ++++++----------- .../apps/dashboard/_partials/_scripts.html | 1 + 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/apps/dashboard/static/apps/dashboard/dashboard.js b/src/apps/dashboard/static/apps/dashboard/dashboard.js index 6510edd..8615f8b 100644 --- a/src/apps/dashboard/static/apps/dashboard/dashboard.js +++ b/src/apps/dashboard/static/apps/dashboard/dashboard.js @@ -9,6 +9,15 @@ const initialize = (inputSelector) => { }; }; +const bindPaletteWheel = () => { + document.querySelectorAll('.palette-scroll').forEach(el => { + el.addEventListener('wheel', (e) => { + e.preventDefault(); + el.scrollLeft += e.deltaY; + }, { passive: false }); + }); +}; + const bindPaletteForms = () => { document.querySelectorAll('form[action*="set_palette"]').forEach(form => { form.addEventListener("submit", async (e) => { diff --git a/src/apps/gameboard/static/apps/gameboard/game-kit.js b/src/apps/gameboard/static/apps/gameboard/game-kit.js index 462b589..5e34d9f 100644 --- a/src/apps/gameboard/static/apps/gameboard/game-kit.js +++ b/src/apps/gameboard/static/apps/gameboard/game-kit.js @@ -84,9 +84,10 @@ function initGameKitPage() { updateFan(); } - // Click on the dialog background (outside .tarot-fan-wrap) closes the modal + // Click on the dark backdrop (the dialog or fan-wrap itself, not on any card child) closes + var fanWrap = dialog.querySelector('.tarot-fan-wrap'); dialog.addEventListener('click', function(e) { - if (!e.target.closest('.tarot-fan-wrap')) closeFan(); + if (e.target === dialog || e.target === fanWrap) closeFan(); }); // Arrow key navigation @@ -95,6 +96,16 @@ function initGameKitPage() { if (e.key === 'ArrowLeft') navigate(-1); }); + // Mousewheel navigation — throttled so each detent advances one card + var lastWheel = 0; + dialog.addEventListener('wheel', function(e) { + e.preventDefault(); + var now = Date.now(); + if (now - lastWheel < 150) return; + lastWheel = now; + navigate(e.deltaY > 0 ? 1 : -1); + }, { passive: false }); + prevBtn.addEventListener('click', function() { navigate(-1); }); nextBtn.addEventListener('click', function() { navigate(1); }); diff --git a/src/functional_tests/test_component_cards_tarot.py b/src/functional_tests/test_component_cards_tarot.py index 20436d6..0c3629d 100644 --- a/src/functional_tests/test_component_cards_tarot.py +++ b/src/functional_tests/test_component_cards_tarot.py @@ -453,18 +453,15 @@ class GameKitPageTest(FunctionalTest): # Test 12 — clicking outside the modal closes it # # ------------------------------------------------------------------ # - def test_clicking_outside_fan_closes_modal(self): + def test_pressing_escape_closes_fan_modal(self): + from selenium.webdriver.common.keys import Keys self.browser.get(self.live_server_url + "/gameboard/game-kit/") self.wait_for( lambda: self.browser.find_element(By.CSS_SELECTOR, "#id_gk_decks .gk-deck-card") ).click() dialog = self.browser.find_element(By.ID, "id_tarot_fan_dialog") self.wait_for(lambda: self.assertTrue(dialog.is_displayed())) - # Dispatch a click directly on the dialog element (simulates clicking the dark backdrop) - self.browser.execute_script( - "document.getElementById('id_tarot_fan_dialog')" - ".dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true}))" - ) + dialog.send_keys(Keys.ESCAPE) self.wait_for(lambda: self.assertFalse(dialog.is_displayed())) # ------------------------------------------------------------------ # @@ -484,11 +481,9 @@ class GameKitPageTest(FunctionalTest): saved_index = self.wait_for( lambda: self.browser.find_element(By.CSS_SELECTOR, ".fan-card--active").get_attribute("data-index") ) - # Close - self.browser.execute_script( - "document.getElementById('id_tarot_fan_dialog')" - ".dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true}))" - ) + # Close via ESC + from selenium.webdriver.common.keys import Keys + self.browser.find_element(By.ID, "id_tarot_fan_dialog").send_keys(Keys.ESCAPE) self.wait_for( lambda: self.assertFalse( self.browser.find_element(By.ID, "id_tarot_fan_dialog").is_displayed() diff --git a/src/templates/apps/dashboard/_partials/_scripts.html b/src/templates/apps/dashboard/_partials/_scripts.html index 73e53dc..de34224 100644 --- a/src/templates/apps/dashboard/_partials/_scripts.html +++ b/src/templates/apps/dashboard/_partials/_scripts.html @@ -4,5 +4,6 @@ window.onload = () => { initialize("#id_text"); bindPaletteForms(); + bindPaletteWheel(); }; \ No newline at end of file