Skip to content

add pager and image lightbox - #64

Merged
nschimme merged 13 commits into
MUME:masterfrom
nschimme:feat/tutorial-rewind-and-pager-4940812554662262833
Sep 21, 2026
Merged

nschimme merged 13 commits into
MUME:masterfrom
nschimme:feat/tutorial-rewind-and-pager-4940812554662262833

Conversation

@nschimme

@nschimme nschimme commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Implements step rewind replay, integrated reactive MUD output pager, click-to-enlarge image lightbox modal, relative image paths in Markdown files, and test validation.

Summary by Sourcery

Enhance the tutorial player with rewindable steps, automatic output paging, and image lightbox previews while validating and documenting embedded Markdown assets.

New Features:

  • Add interactive paging for overflowing tutorial output, including keyboard, touch, and prompt controls.
  • Add clickable inline Markdown images with an accessible lightbox preview and captions.
  • Allow tutorial step indicators to jump directly to earlier or later steps.

Bug Fixes:

  • Support relative Markdown image paths and preserve external and data URLs when rendering tutorial content.
  • Prevent stale automatic step advancement during navigation.

Enhancements:

  • Improve tutorial replay by rebuilding the log when rewinding to a selected step and support multiline Markdown content.

Documentation:

  • Document multiline tutorial content, embedded images, and automatic output paging for tutorial authors.
  • Update the journey tutorial to demonstrate streamed images and multiline responses.

Tests:

  • Validate relative Markdown image references and report missing assets in the link and asset path checks.

- Clear log and cleanly replay history up to the target step on back navigation
- Add reactive pager for multiline MUD outputs with desktop space/enter shortcuts and mobile tap bar
- Reposition Exit button to top-right header across viewports
- Reconstructed step history when navigating backward in tutorial steps to maintain a coherent log state.
- Added a reactive pager for chunking large MUD outputs into readable pages on constrained displays.
- Implemented keyboard (Space/Enter) and touch tap interactions for pager navigation.
- Fixed input handling to allow space bar typing within commands without inadvertently triggering the pager.
- Repositioned the tutorial Exit button anchored at top-right on header bar.
- Reconstruct terminal log and replay history on back step navigation
- Split large MUD outputs (>8 lines) into 6-line pages with sticky pager bar
- Add Space/Enter/PageDown keyboard paging and touch-friendly tap-to-advance
- Queue and defer next-step triggers while pager is active to preserve order
- Hide empty quest action cards on story beats without ask commands
- Position Exit Tutorial button at top right of header frame across viewports
…al pager

- Clear and replay log history up to target index when navigating backwards (`goToStep`).
- Implement reactive terminal pager supporting text chunking, weighted image lines, and live scroll overflow.
- Add keyboard (Space/Enter/PageDown) and touch/mobile (`.tut-pager-banner`) advancement controls.
- Defer queued step advancement until remaining pages/scroll overflow are fully revealed.
- Ensure Exit button position is anchored at top-right across viewports.
- Clean step log rewind and state replay on step back/pill navigation
- Implement reactive terminal pager measuring DOM scroll overflow
- Support Space, Enter, PageDown key navigation and mobile/touch tap banner
- Position Exit Tutorial button in top-right header corner
… pager

- Clear terminal log and reconstruct step history when navigating backward in tutorial player
- Add reactive terminal output pager for overflow content handling desktop keyboard and mobile tap controls
- Debounce scroll detection to hide pager banner while actively scrolling
- Rewind step navigation (`goToStep`) now cancels auto-advance timers, resets `log.value`, and cleanly replays step elements up to target step without orphan prompts.
- Integrate reactive terminal pager directly into the input bar when log overflows, handling keyboard (Space/PageDown/Enter) and touch/mouse interactions without virtual keyboard pops on mobile.
- Add dynamic DOM scroll monitoring via `ResizeObserver` and scroll events.
- Rewind step navigation (`goToStep`) now cancels auto-advance timers, resets `log.value`, and cleanly replays step elements up to target step without orphan prompts.
- Integrate reactive terminal pager directly into the input bar when log overflows, handling keyboard (Space/PageDown/Enter) and touch/mouse interactions without virtual keyboard pops on mobile.
- Support inline markdown images (`![alt](url)`) in frontmatter story beats and step responses with dynamic pager state recalculations on image load.
- Stream Chapter 15 screenshots via step story beats to keep initial load compact and enable step-by-step keyboard pagination.
- Update `TUTORIAL.md` contributor documentation.
…move escaped newlines

- Rewind step navigation (`goToStep`) now cancels auto-advance timers, resets `log.value`, and cleanly replays step elements up to target step without orphan prompts.
- Integrate reactive terminal pager directly into the input bar when log overflows, handling keyboard (Space/PageDown/Enter) and touch/mouse interactions without virtual keyboard pops on mobile.
- Support inline markdown images (`![alt](url)`) in frontmatter story beats and step responses with dynamic pager state recalculations on image load.
- Stream Chapter 15 screenshots via step story beats to keep initial load compact and enable step-by-step keyboard pagination.
- Convert all literal `\n` newlines in tutorial chapter files to natural YAML multiline scalars (`|`).
- Update `TUTORIAL.md` authoring guide to advise contributors on using YAML block scalars instead of `\n`.
@sourcery-ai

sourcery-ai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Reviewer's Guide

The tutorial player now rebuilds and rewinds interactive steps, provides reactive paging for overflowing terminal output, renders relative Markdown images with a click-to-enlarge lightbox, and updates tutorial content and validation to support multiline image-bearing story beats.

Sequence diagram for tutorial output paging and step rewind

sequenceDiagram
    participant User
    participant TutorialPlayer
    participant Log as TerminalLog
    participant Pager

    User->>TutorialPlayer: goToStep(targetIdx)
    TutorialPlayer->>TutorialPlayer: clearAutoAdvanceTimer()
    TutorialPlayer->>TutorialPlayer: rebuild log through target step
    TutorialPlayer->>Log: scrollLog()
    Log-->>Pager: overflow detected
    Pager->>Pager: updatePagerState()
    User->>TutorialPlayer: pageForward() via Space, Enter, or PageDown
    TutorialPlayer->>Log: scrollBy()
    Log-->>Pager: scroll event
    Pager->>Pager: updatePagerState()
    Pager-->>User: show current page and More prompt
Loading

Sequence diagram for tutorial image lightbox preview

sequenceDiagram
    participant User
    participant TutorialPlayer
    participant Log as TerminalLog
    participant Lightbox

    TutorialPlayer->>Log: render Markdown image
    User->>Log: click tut-img-embed
    Log->>TutorialPlayer: handleLogClick(event)
    TutorialPlayer->>Lightbox: openImageModal(src, alt)
    Lightbox-->>User: display enlarged image and caption
    User->>TutorialPlayer: press Escape or close button
    TutorialPlayer->>Lightbox: closeImageModal()
    Lightbox-->>User: hide preview
Loading

Flow diagram for relative Markdown image rendering

flowchart LR
    A[Markdown image in story beat] --> B[formatInlineMarkdown]
    B --> C[Normalize assets path]
    C --> D[Apply withBase]
    D --> E[Render tut-img-embed]
    E --> F[Click opens lightbox]
Loading

File-Level Changes

Change Details Files
Added interactive step rewind and direct step navigation by rebuilding the terminal log from the selected step history.
  • Introduced a reusable step-index navigation path for rewind, replay, and step-pill clicks.
  • Reconstructed prior prompts, responses, examples, and story beats when jumping backward or forward.
  • Added timer cancellation to prevent delayed automatic story advancement after navigation or route changes.
docs/.vitepress/theme/components/TutorialPlayer.vue
Added reactive terminal paging for overflowing tutorial output with keyboard, button, input, and touch-device controls.
  • Tracked scroll overflow, current/total pages, scrolling state, and container resizing.
  • Added smooth page-forward and flush-to-bottom behavior for paging and command submission.
  • Added Space/PageDown and empty-submit interactions while preserving normal command entry behavior.
docs/.vitepress/theme/components/TutorialPlayer.vue
Implemented inline Markdown image rendering and a click-to-enlarge lightbox within the tutorial player.
  • Parsed and sanitized Markdown image syntax alongside inline code and line breaks.
  • Normalized relative asset paths through the VitePress base path.
  • Added delegated image click handling, modal preview/caption rendering, backdrop and button dismissal, and Escape-key closing.
docs/.vitepress/theme/components/TutorialPlayer.vue
Migrated tutorial content to multiline YAML story and response blocks with images embedded at the relevant journey steps.
  • Replaced escaped newline response strings with YAML literal blocks.
  • Moved web client and mapper screenshots into sequential story beats using relative Markdown paths.
  • Documented image syntax, authoring guidance, and automatic paging behavior.
docs/play/TUTORIAL.md
docs/play/tutorial/15-journey.md
Extended link and asset validation to verify Markdown image references throughout the documentation tree.
  • Recursively scanned docs Markdown files for image links.
  • Resolved absolute asset paths against docs/public and relative paths against each Markdown file.
  • Reported missing Markdown images and included their count in the test summary.
scripts/test-link-and-asset-paths.js

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 4 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="docs/.vitepress/theme/components/TutorialPlayer.vue" line_range="319" />
<code_context>

-function renderStepLog() {
-  subStepIdx.value = 0
+function goToStep(targetIdx) {
+  clearAutoAdvanceTimer()
+  if (targetIdx < 0) targetIdx = 0
</code_context>
<issue_to_address>
**issue (bug_risk):** goToStep does not clear `entry.value`, so navigating with a step pill or rewind leaves a partially typed command in the input and allows that stale command to be submitted against the newly selected step.

**Triggers:** When the user has typed a command and then navigates backward or selects another step before submitting it.

**Suggested fix:** Set `entry.value = ''` while reconstructing the step state in `goToStep`.

```suggestion
  finished.value = false
  entry.value = ''
```
</issue_to_address>

### Comment 2
<location path="docs/.vitepress/theme/components/TutorialPlayer.vue" line_range="338-339" />
<code_context>
+    if (step) {
+      if (step.ask) {
+        newLog.push({ kind: 'echo', text: step.ask })
+        const rawRes = step.response || step.example || mumeResponses.value[step.ask.toLowerCase()] || ''
+        const body = rawRes ? rawRes.replace(/^>[^\n]*\n?/, '') : ''
+        if (body) {
+          newLog.push({ kind: 'example', body })
</code_context>
<issue_to_address>
**issue (broader_impact):** The rewind replay looks up a response using the canonical `step.ask` rather than the accepted command that originally produced it, so a step whose response exists only under an accepted alias is replayed without its MUD output.

**Triggers:** When a step has an accepted alias and `step.response` is absent, while `mumeResponses` is keyed by that alias instead of the canonical `ask`.

**Suggested fix:** Persist or derive the actual accepted command used for each completed step, or search all accepted aliases when reconstructing the response.
</issue_to_address>

### Comment 3
<location path="docs/.vitepress/theme/components/TutorialPlayer.vue" line_range="31-33" />
<code_context>
+    const cleanAlt = alt.replace(/"/g, '&quot;')
+    let cleanSrc = src.trim().replace(/"/g, '&quot;')
+
+    if (cleanSrc.includes('assets/')) {
+      cleanSrc = '/assets/' + cleanSrc.split('assets/')[1]
+    }
+
</code_context>
<issue_to_address>
**issue (bug_risk):** Any image URL containing `assets/` is forcibly rewritten to a site-local `/assets/...` path, so external URLs such as `https://cdn.example.com/assets/image.png` are changed to `/assets/image.png` and fail to load.

**Triggers:** When tutorial Markdown contains an external image URL whose hostname or path includes `assets/`.

**Suggested fix:** Normalize only the intended relative `public/assets` paths and leave absolute `http://`, `https://`, and data URLs unchanged.

```suggestion
    if (/^(?:\.\.\/|\.\/)*public\/assets\//.test(cleanSrc)) {
      cleanSrc = '/assets/' + cleanSrc.split('public/assets/')[1]
    }
```
</issue_to_address>

### Comment 4
<location path="docs/.vitepress/theme/components/TutorialPlayer.vue" line_range="188" />
<code_context>
+  }
+
+  // Intercept Space or PageDown for paging if output overflow is active and input is empty or unfocused
+  if (isScrollOverflowActive.value && !isScrolling.value) {
+    const isInputFocused = document.activeElement === inputEl.value
+    if (e.key === 'PageDown' || (e.key === ' ' && (!isInputFocused || !entry.value.trim()))) {
+      e.preventDefault()
+      pageForward()
     }
   }
</code_context>
<issue_to_address>
**nitpick (bug_risk):** The global key handler intercepts `PageDown` whenever pager overflow is active, even when the command input is focused and contains text, so PageDown cannot be used normally while entering a command and is always converted into pager navigation.

**Triggers:** When output is overflowing and the user presses PageDown while the input is focused.

**Suggested fix:** Apply the same empty-or-unfocused input guard to PageDown that is applied to Space, unless pager navigation is explicitly intended to override input editing.

```suggestion
    if ((e.key === 'PageDown' || e.key === ' ') && (!isInputFocused || !entry.value.trim())) {
```
</issue_to_address>

Sourcery assessment

Approval pending. 3 findings to address first.

Blocking findings: docs/.vitepress/theme/components/TutorialPlayer.vue:319, docs/.vitepress/theme/components/TutorialPlayer.vue:339, docs/.vitepress/theme/components/TutorialPlayer.vue:33


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread docs/.vitepress/theme/components/TutorialPlayer.vue
Comment thread docs/.vitepress/theme/components/TutorialPlayer.vue Outdated
Comment thread docs/.vitepress/theme/components/TutorialPlayer.vue Outdated
Comment thread docs/.vitepress/theme/components/TutorialPlayer.vue Outdated

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sourcery assessment

Approved.

@nschimme
nschimme merged commit 84ffa3e into MUME:master Sep 21, 2026
3 checks passed
adhocmedia added a commit to adhocmedia/mume.github.io that referenced this pull request Sep 21, 2026
Rebuild the interactive tutorial as a real-map walkthrough of Black Hill
Village, on top of Nils's upstream engine (pager + image lightbox, MUME#64).

- 16 chapters: adds a "What is MUME?" intro; reorders so Movement & Doors
  (ch4, Common Room -> Kitchen -> open trapdoor -> Cellar) precedes
  Examining (ch5, in the cellar); real room descriptions throughout.
- Maps are inline story-beat images per the new TUTORIAL.md guidance
  (dropped the custom `map:` frontmatter and its bespoke figure code).
- Rooms auto-displayed after `change spam all off` are brief (name +
  occupants + exits); explicit `look` stays full.
- Fixes: spam command, equipment vs inventory ordering, parry (not dodge)
  on wimpy mood, snake combat text, give-to-Irelm, bare-command accepts.
- Update MumeCommandGuide + Newcomers/home/play links to the new numbering.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
adhocmedia added a commit to adhocmedia/mume.github.io that referenced this pull request Sep 21, 2026
Rebuild the interactive tutorial as a real-map walkthrough of Black Hill
Village, on top of Nils's upstream engine (pager + image lightbox, MUME#64).

- 16 chapters: adds a "What is MUME?" intro; reorders so Movement & Doors
  (ch4, Common Room -> Kitchen -> open trapdoor -> Cellar) precedes
  Examining (ch5, in the cellar); real room descriptions throughout.
- Maps are inline story-beat images per the new TUTORIAL.md guidance
  (dropped the custom `map:` frontmatter and its bespoke figure code).
- Rooms auto-displayed after `change spam all off` are brief (name +
  occupants + exits); explicit `look` stays full.
- Fixes: spam command, equipment vs inventory ordering, parry (not dodge)
  on wimpy mood, snake combat text, give-to-Irelm, bare-command accepts.
- Update MumeCommandGuide + Newcomers/home/play links to the new numbering.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
adhocmedia added a commit to adhocmedia/mume.github.io that referenced this pull request Sep 22, 2026
Rebuild the interactive tutorial as a real-map walkthrough of Black Hill
Village, on top of Nils's upstream engine (pager + image lightbox, MUME#64).

- 16 chapters: adds a "What is MUME?" intro; reorders so Movement & Doors
  (ch4, Common Room -> Kitchen -> open trapdoor -> Cellar) precedes
  Examining (ch5, in the cellar); real room descriptions throughout.
- Maps are inline story-beat images per the new TUTORIAL.md guidance
  (dropped the custom `map:` frontmatter and its bespoke figure code).
- Rooms auto-displayed after `change spam all off` are brief (name +
  occupants + exits); explicit `look` stays full.
- Fixes: spam command, equipment vs inventory ordering, parry (not dodge)
  on wimpy mood, snake combat text, give-to-Irelm, bare-command accepts.
- Update MumeCommandGuide + Newcomers/home/play links to the new numbering.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
pr-64 — 1d9ec5ca Deployed Sep 20, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant