diff --git a/src/apps/epic/static/apps/epic/room-views.js b/src/apps/epic/static/apps/epic/room-views.js index cd8ea0e..fac422c 100644 --- a/src/apps/epic/static/apps/epic/room-views.js +++ b/src/apps/epic/static/apps/epic/room-views.js @@ -1,6 +1,6 @@ // Game-views carousel — the "reelhouse" (the fivefold applet-scroll carousel) // in the table-hex aperture's 2nd vertical snap pane. -// Five horizontal views — ATLAS | SCROLL | POST | CHAT | PULSE — reached by +// Five horizontal views — ATLAS | SCROLL | YARN | POST | PULSE — reached by // scrolling DOWN from the hex, landing on SCROLL (the 2nd). This module owns // the HORIZONTAL axis; room-scroll.js still owns the vertical hex<->views // `.is-scroll` title toggle + the feed gear/filter. Responsibilities: @@ -18,7 +18,7 @@ (function () { 'use strict'; - var VIEW_ORDER = ['atlas', 'scroll', 'post', 'chat', 'pulse']; + var VIEW_ORDER = ['atlas', 'scroll', 'yarn', 'post', 'pulse']; var DEFAULT_VIEW = 'scroll'; // ── pure helpers (exposed for Jasmine) ───────────────────────────────── diff --git a/src/apps/epic/tests/integrated/test_views.py b/src/apps/epic/tests/integrated/test_views.py index 4af0a92..8de36b7 100644 --- a/src/apps/epic/tests/integrated/test_views.py +++ b/src/apps/epic/tests/integrated/test_views.py @@ -3438,20 +3438,21 @@ class RoomViewsCarouselTest(TestCase): def test_renders_five_view_panes_in_order(self): content = self.client.get(self.url).content.decode() self.assertIn("id_room_views", content) - for view in ("atlas", "scroll", "post", "chat", "pulse"): + for view in ("atlas", "scroll", "yarn", "post", "pulse"): self.assertIn(f'data-view="{view}"', content) - # Order: atlas precedes scroll precedes post precedes chat precedes pulse. + # Order: atlas precedes scroll precedes yarn precedes post precedes pulse. positions = [content.index(f'room-view--{v}') - for v in ("atlas", "scroll", "post", "chat", "pulse")] + for v in ("atlas", "scroll", "yarn", "post", "pulse")] self.assertEqual(positions, sorted(positions)) def test_renders_root_level_icon_strip(self): content = self.client.get(self.url).content.decode() self.assertIn("id_room_views_strip", content) - for view in ("atlas", "scroll", "post", "chat", "pulse"): + for view in ("atlas", "scroll", "yarn", "post", "pulse"): self.assertIn(f'data-view="{view}"', content) self.assertIn("fa-scroll", content) self.assertIn("fa-book-atlas", content) + self.assertIn("fa-route", content) def test_scroll_view_still_wraps_the_provenance_feed(self): content = self.client.get(self.url).content.decode() @@ -3472,7 +3473,7 @@ class RoomViewsCarouselTest(TestCase): content = self.client.get(self.url).content.decode() self.assertIn("opening move", content) - def test_chat_and_pulse_render_stubs(self): + def test_yarn_and_pulse_render_stubs(self): content = self.client.get(self.url).content.decode() self.assertIn("room-view-stub", content) diff --git a/src/functional_tests/test_game_room_views.py b/src/functional_tests/test_game_room_views.py index 42e748b..6e83416 100644 --- a/src/functional_tests/test_game_room_views.py +++ b/src/functional_tests/test_game_room_views.py @@ -32,7 +32,7 @@ from apps.drama.models import GameEvent from apps.epic.models import Room from apps.lyric.models import User -VIEW_ORDER = ["atlas", "scroll", "post", "chat", "pulse"] +VIEW_ORDER = ["atlas", "scroll", "yarn", "post", "pulse"] class GameViewsCarouselTest(FunctionalTest): @@ -91,7 +91,7 @@ class GameViewsCarouselTest(FunctionalTest): # ── tests ──────────────────────────────────────────────────────────── def test_icon_strip_hidden_at_hex_shown_in_views_with_scroll_active(self): """At the table-hex the strip is hidden; scrolling down reveals it with - five icons in order [atlas, scroll, post, chat, pulse] and SCROLL (2nd) + five icons in order [atlas, scroll, yarn, post, pulse] and SCROLL (2nd) active + glowing.""" self._open() self.assertFalse( @@ -134,11 +134,11 @@ class GameViewsCarouselTest(FunctionalTest): self._open() self._scroll_to_views() self.assertEqual(self._active_view(), "scroll") - # Horizontal wheel right → next view (post). + # Horizontal wheel right → next view in line (yarn, between scroll & post). self.browser.execute_script( "document.querySelector('#id_room_views').dispatchEvent(" "new WheelEvent('wheel', {deltaX: 120, deltaY: 0, bubbles: true}));") - self.wait_for(lambda: self.assertEqual(self._active_view(), "post")) + self.wait_for(lambda: self.assertEqual(self._active_view(), "yarn")) def test_text_btn_from_hex_swipes_down_to_the_reelhouse(self): """The burger fan's #id_text_btn (fa-keyboard) is active on the table; @@ -213,8 +213,8 @@ class GameViewsCarouselTest(FunctionalTest): self.assertTrue(atlas.find_elements( By.CSS_SELECTOR, "[data-source='post']")) - def test_chat_and_pulse_render_as_stubs(self): - """CHAT (fa-comments) + PULSE (fa-chart-pie) are stub views this sprint — + def test_yarn_and_pulse_render_as_stubs(self): + """YARN (fa-route) + PULSE (fa-chart-pie) are stub views this sprint — each renders a placeholder, no backing model yet. The watermark icon rests ABOVE the [Feature forthcoming] label (the shared partial centres itself absolutely, so without the stub override it would overlap the @@ -226,7 +226,7 @@ class GameViewsCarouselTest(FunctionalTest): return self.browser.execute_script( "return document.querySelector(arguments[0]).getBoundingClientRect();", css) - for view in ("chat", "pulse"): + for view in ("yarn", "pulse"): self._click_icon(view) self.wait_for(lambda v=view: self.assertTrue( self._in_viewport(f".room-view[data-view='{v}']"))) diff --git a/src/static/tests/RoomViewsSpec.js b/src/static/tests/RoomViewsSpec.js index 3e7b419..40d59cc 100644 --- a/src/static/tests/RoomViewsSpec.js +++ b/src/static/tests/RoomViewsSpec.js @@ -79,7 +79,7 @@ describe("RoomViews atlas row rendering", () => { // scrolling. (The descent beat itself + plain goToView are covered by the FT.) describe("RoomViews swipe machine", () => { let aperture, viewsEl, strip, textBtn; - const VIEWS = ["atlas", "scroll", "post", "chat", "pulse"]; + const VIEWS = ["atlas", "scroll", "yarn", "post", "pulse"]; function tag(name, attrs) { const n = document.createElement(name); diff --git a/src/static_src/scss/_base.scss b/src/static_src/scss/_base.scss index dd58f86..b81ea5c 100644 --- a/src/static_src/scss/_base.scss +++ b/src/static_src/scss/_base.scss @@ -410,12 +410,12 @@ body { .gr-word--base { transform: translateY(-100%); } // up & out .gr-views-reel { transform: translateY(0); } // rises in } - // Horizontal cell (VIEW_ORDER atlas|scroll|post|chat|pulse) — + // Horizontal cell (VIEW_ORDER atlas|scroll|yarn|post|pulse) — // keyed on the active view ALONE so it holds at the hex too. &[data-active-view="atlas"] .gr-views-track { transform: translateX(0); } &[data-active-view="scroll"] .gr-views-track { transform: translateX(-100%); } - &[data-active-view="post"] .gr-views-track { transform: translateX(-200%); } - &[data-active-view="chat"] .gr-views-track { transform: translateX(-300%); } + &[data-active-view="yarn"] .gr-views-track { transform: translateX(-200%); } + &[data-active-view="post"] .gr-views-track { transform: translateX(-300%); } &[data-active-view="pulse"] .gr-views-track { transform: translateX(-400%); } } } diff --git a/src/static_src/scss/_room.scss b/src/static_src/scss/_room.scss index 4f520d4..89f5886 100644 --- a/src/static_src/scss/_room.scss +++ b/src/static_src/scss/_room.scss @@ -238,13 +238,30 @@ html.sea-open #id_aperture_fill { flex-direction: column; .atlas-row { + display: flex; + align-items: baseline; + gap: 0.4rem; padding: 0.3rem 0; font-size: 0.9rem; border-inline-start: 2px solid transparent; padding-inline-start: 0.5rem; - .atlas-row-time { font-size: 0.7rem; opacity: 0.5; margin-inline-start: 0.4rem; } - .atlas-row-who { font-weight: bold; color: rgba(var(--quaUser), 1); margin-inline-end: 0.3rem; } + .atlas-row-who { font-weight: bold; color: rgba(var(--quaUser), 1); flex-shrink: 0; } + .atlas-row-body { flex: 1; min-width: 0; overflow-wrap: anywhere; } + // The merged rows carry the ORIGINAL