Skip to content

fix(PrompterView): prevent jumping/scrolling to undesired positions#1615

Open
ianshade wants to merge 2 commits intoSofie-Automation:mainfrom
tv2norge-collab:contribute/EAV-693_2
Open

fix(PrompterView): prevent jumping/scrolling to undesired positions#1615
ianshade wants to merge 2 commits intoSofie-Automation:mainfrom
tv2norge-collab:contribute/EAV-693_2

Conversation

@ianshade
Copy link
Contributor

@ianshade ianshade commented Jan 24, 2026

About the Contributor

This pull request is posted on behalf of TV 2 Norge

Type of Contribution

This is a:

Bug fix

Current Behavior

  • Data updates during a pending scrollTo triggered anchor restoration, which led to scroll ending at an undesired position
  • When a script continued as an infinite piece into another part, the prompter would scroll to the beginning of that part, making it hard for the presenter to continue reading a script that spans multiple parts without readjusting the position after every take.

New Behavior

  • Anchor restoration is deferred till after the pending scroll completes
  • The prompter stays focused on the active script, hiding the original script when it's continued into the current part, and avoids unnecessary jumps by making the new part take over seamlessly

Testing

  • I have added one or more unit tests for this PR
  • I have updated the relevant unit tests
  • No unit test changes are needed for this PR

Unit tests are needed, but the existing components don't look very testable without significant refactoring - help to get this covered by tests is welcome

Affected areas

  • Prompter View

Time Frame

Other Information

  • A frozen state prevents scroll anchor restoration during animations. The prompter is marked as "frozen" when an animation starts and unfrozen when it completes. Force updates are throttled at 50ms while frozen, so anchor restoration is deferred until the animation finishes.
  • The code now tracks continuations of infinite script pieces using continuationOfId and data-live-continuation-of attributes. When a part takes over an infinite script, the original script is hidden from the original part. The prompter also avoids scrolling to parts that are merely continuing a script (using the scrollToPartInstanceIfNotContinuation method), and scroll anchors prioritize the continuation over the original piece.

Status

  • PR is ready to be reviewed.
  • The functionality has been tested by the author. (before porting to release53)
  • Relevant unit tests has been added / updated.
  • Relevant documentation (code comments, system documentation) has been added / updated.

Summary

This PR addresses undesired scrolling and jumping behavior in the Prompter View component by deferring scroll-anchor restoration during animations and properly handling script continuations across parts.

Problem

Two specific issues were occurring:

  1. Data updates during a pending scroll operation could trigger scroll-anchor restoration, causing the view to settle at an undesired position
  2. When a script continued as an infinite piece into another part, the prompter would jump to the beginning of that continuation part, disrupting the presenter's workflow

Solution

Scroll Animation Freezing

  • Introduced a PrompterStore mechanism with a PrompterStoreContext and PrompterStoreProvider component to coordinate scroll animation state across components
  • The isFrozen flag is set to true at the start of scroll animations and reset to false upon completion
  • While frozen, update operations are throttled at 50ms intervals to prevent unintended scroll-anchor restoration
  • This ensures scroll anchors are only restored after pending scrolls have fully completed

Continuation Handling

  • Extended the PrompterDataPiece interface with continuationOf and startPartId fields to track script continuations
  • Modified the prompter assembly logic to create continuation pieces when a piece's ID is already included, rather than skipping it
  • Continuation pieces maintain a reference to their original piece via continuationOf and inherit the startPartId
  • New scrollToPartInstanceIfNotContinuation method prevents scrolling directly to continuation pieces
  • Continuation pieces are marked with PIECE_CONTINUATION_CLASS and data-live-continuation-of attributes in the DOM
  • Scroll anchor restoration logic prioritizes continuation pieces, allowing seamless focus on the active script while hiding the original script in its original part location

Related Implementation Details

  • Added global UI constants: FROZEN_UPDATE_THROTTLE (50ms) and PIECE_CONTINUATION_CLASS for managing throttling and styling
  • Enhanced getScrollAnchors and restoreScrollAnchor logic to account for live continuations
  • Updated segment and part rendering to compute and apply continuation-aware statuses
  • Text anchors and scroll anchors now track continuationOfId to support intelligent restoration prioritization
  • End-of-script markers are rendered with stable keys to prevent unnecessary React reconciliation

Files Modified

  • packages/webui/src/client/ui/Prompter/PrompterView.tsx (+143/-36 lines)
  • packages/webui/src/client/ui/Prompter/prompter.ts (+12/-1 lines)

Testing & Status

  • Functionality has been manually tested by the author
  • Unit tests are planned but require refactoring of existing components to make them testable
  • Ready for review

@ianshade ianshade requested a review from a team as a code owner January 24, 2026 09:27
@coderabbitai
Copy link

coderabbitai bot commented Jan 24, 2026

Walkthrough

This pull request introduces a continuation mechanism for prompter pieces and implements a context-based store for managing animation state. The prompter data structure is extended to track piece continuations and part IDs, while the view layer implements state management for scroll animations and enhanced rendering to handle continuation pieces.

Changes

Cohort / File(s) Summary
Context & Store Management
packages/webui/src/client/ui/Prompter/PrompterView.tsx
Introduced PrompterStore interface and PrompterStoreContext with PrompterStoreProvider component to manage animation freeze state. PrompterViewContent now consumes this context to coordinate frozen state during scroll animations. Added global constants FROZEN_UPDATE_THROTTLE and PIECE_CONTINUATION_CLASS for animation throttling and DOM marking.
Scroll & Animation Logic
packages/webui/src/client/ui/Prompter/PrompterView.tsx
Reworked scrolling to use scrollToPartInstanceIfNotContinuation, which avoids scrolling to continuation pieces via DOM selectors. Integrated freeze/unfreeze lifecycle: isFrozen = true at animation start, reset on completion. Updated anchor restoration to prioritize continuation-aware anchors and fallback to original anchors when needed.
Rendering & Continuations
packages/webui/src/client/ui/Prompter/PrompterView.tsx
Enhanced segment and part rendering to compute partStatuses for continuation detection. Implemented logic to hide initial script portions when live parts override infinite scripts (pieceIdToHideScript). Parts and lines annotated with data-live-continuation-of attributes and PIECE_CONTINUATION_CLASS. End-of-script marker now includes stable React key.
Data Structure Extensions
packages/webui/src/client/ui/Prompter/prompter.ts
Extended PrompterDataPiece interface with continuationOf?: PieceId and startPartId?: PartId | null fields. Modified piece assembly logic to create continuation pieces (with _continuation suffix) when a piece ID is already included, preserving original content and linking via continuationOf reference.

Sequence Diagram(s)

sequenceDiagram
    participant Component as PrompterViewContent
    participant Store as PrompterStore
    participant Animation as Animation Handler
    participant Scroll as Scroll Handler

    Animation->>Store: Animation starts
    Store->>Store: Set isFrozen = true
    Note over Store: Throttle updates during animation
    
    Animation->>Scroll: Trigger scroll to part
    Scroll->>Component: scrollToPartInstanceIfNotContinuation()
    Component->>Component: Query DOM (exclude continuation pieces)
    Component->>Component: Execute scrollTo
    
    Animation->>Animation: Animation completes
    Animation->>Store: Animation ends
    Store->>Store: Set isFrozen = false
    Note over Component: Resume normal updates
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 Hops excitedly
Continuation pieces dance so smooth and fine,
Frozen states keep animations in line,
Scrolls that skip and stores that know,
Our prompter view puts on quite a show!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: preventing unwanted scrolling/jumping in PrompterView, which aligns with the changeset's core objective of deferring anchor restoration and handling script continuations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Jan 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

this prevents from restoring scroll anchors during pending animations, which led to the content stopping at an undesired position
@ianshade ianshade force-pushed the contribute/EAV-693_2 branch from 9a2e470 to 3343913 Compare January 24, 2026 09:30
@ianshade ianshade added the Contribution from TV 2 Norge Contributions sponsored by TV 2 Norge (tv2.no) label Jan 24, 2026
@PeterC89
Copy link
Contributor

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jan 24, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@PeterC89 PeterC89 changed the base branch from release53 to main February 4, 2026 12:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Contribution from TV 2 Norge Contributions sponsored by TV 2 Norge (tv2.no)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants