Skip to content

feat: split thumbnail previews#1760

Merged
justandras merged 11 commits into
Sofie-Automation:mainfrom
bbc:feat/split-thumbnail-previews
Jun 18, 2026
Merged

feat: split thumbnail previews#1760
justandras merged 11 commits into
Sofie-Automation:mainfrom
bbc:feat/split-thumbnail-previews

Conversation

@justandras

@justandras justandras commented May 27, 2026

Copy link
Copy Markdown
Member

About the Contributor

This pull request is posted on behalf of the BBC

Type of Contribution

This is a: Feature

Current Behavior

SPLITS pieces don't per-box previews/thumbnails.

Hover preview “scrub” behavior for splits is not available (or wasn’t consistently driven by per-box preview URLs).

New Behavior

Core now publishes status.boxPreviews[] for split pieces (aligned with boxSourceConfiguration order), enabling per-box thumbnail/preview URLs. WebUI uses boxPreviews to render SPLITS box media where applicable (notably dashboard shelf buttons and hover popups, including scrub when previewUrl is present).

2026-05-27.14-34-32.mp4

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

Affected areas

  • Core: Split content status publishing
  • Shared-lib: Split box media types, functions
  • WebUI:
    • Split preview rendering
    • Hover popup Split box layout + scrub
    • Dashboard buttons Split preview rendering + styling

Time Frame

Not urgent, but we would like to get this merged into the in-development release.

Status

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

@justandras justandras self-assigned this May 27, 2026
@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5cae6bbe-111c-4e3f-8d03-85abf087e172

📥 Commits

Reviewing files that changed from the base of the PR and between a6753e2 and 94812f1.

📒 Files selected for processing (36)
  • meteor/server/publications/pieceContentStatusUI/__tests__/checkPieceContentStatus.test.ts
  • meteor/server/publications/pieceContentStatusUI/checkPieceContentStatus.ts
  • packages/corelib/src/dataModel/PieceContentStatus.ts
  • packages/documentation/docs/for-developers/for-blueprint-developers/splits-box-previews.md
  • packages/shared-lib/src/package-manager/__tests__/splitBoxMedia.spec.ts
  • packages/shared-lib/src/package-manager/splitBoxMedia.ts
  • packages/webui/src/client/lib/SplitPreviewBox.tsx
  • packages/webui/src/client/lib/ui/splitPreview.ts
  • packages/webui/src/client/lib/ui/splitsPreviewVideo.ts
  • packages/webui/src/client/lib/ui/videoPreviewScrub.ts
  • packages/webui/src/client/styles/_checkerboard.scss
  • packages/webui/src/client/styles/main.scss
  • packages/webui/src/client/styles/rundownView.scss
  • packages/webui/src/client/styles/shelf/dashboard.scss
  • packages/webui/src/client/ui/ClockView/CameraScreen/Piece.tsx
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUp.scss
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUp.tsx
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUpContent.tsx
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUpContext.tsx
  • packages/webui/src/client/ui/PreviewPopUp/Previews/BoxLayoutPreview.tsx
  • packages/webui/src/client/ui/PreviewPopUp/Previews/VTPreview.tsx
  • packages/webui/src/client/ui/SegmentContainer/getSplitItems.tsx
  • packages/webui/src/client/ui/SegmentList/LinePartMainPiece/LinePartMainPiece.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartSecondaryPieces/Renderers/SplitsRenderer.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartSecondaryPieces/StoryboardSecondaryPiece.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/Renderers/SplitsThumbnailRenderer.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/StoryboardPartThumbnail.scss
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/StoryboardPartThumbnailInner.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/DashboardPieceButton.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/DashboardButtonTagStrip.scss
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/MediaBox.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/SplitButtonLayerBackground.scss
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/SplitButtonLayerBackground.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/useDashboardButtonInteractions.ts
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/usePreviewPopUpSession.ts
  • packages/webui/src/client/ui/Shelf/DashboardPieceButtonSplitPreview.tsx
✅ Files skipped from review due to trivial changes (3)
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/SplitButtonLayerBackground.scss
  • packages/webui/src/client/styles/main.scss
  • packages/documentation/docs/for-developers/for-blueprint-developers/splits-box-previews.md
🚧 Files skipped from review as they are similar to previous changes (33)
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/usePreviewPopUpSession.ts
  • packages/webui/src/client/lib/ui/videoPreviewScrub.ts
  • packages/corelib/src/dataModel/PieceContentStatus.ts
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartSecondaryPieces/Renderers/SplitsRenderer.tsx
  • meteor/server/publications/pieceContentStatusUI/tests/checkPieceContentStatus.test.ts
  • packages/webui/src/client/lib/ui/splitPreview.ts
  • packages/webui/src/client/lib/SplitPreviewBox.tsx
  • packages/webui/src/client/ui/SegmentList/LinePartMainPiece/LinePartMainPiece.tsx
  • packages/webui/src/client/ui/PreviewPopUp/Previews/VTPreview.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButtonSplitPreview.tsx
  • packages/webui/src/client/ui/SegmentContainer/getSplitItems.tsx
  • packages/shared-lib/src/package-manager/tests/splitBoxMedia.spec.ts
  • packages/webui/src/client/styles/rundownView.scss
  • packages/webui/src/client/styles/_checkerboard.scss
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/MediaBox.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartSecondaryPieces/StoryboardSecondaryPiece.tsx
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUpContent.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/SplitButtonLayerBackground.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/DashboardButtonTagStrip.scss
  • packages/shared-lib/src/package-manager/splitBoxMedia.ts
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUp.scss
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/Renderers/SplitsThumbnailRenderer.tsx
  • packages/webui/src/client/ui/ClockView/CameraScreen/Piece.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/useDashboardButtonInteractions.ts
  • packages/webui/src/client/lib/ui/splitsPreviewVideo.ts
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/StoryboardPartThumbnail.scss
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/DashboardPieceButton.tsx
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUp.tsx
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUpContext.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/StoryboardPartThumbnailInner.tsx
  • packages/webui/src/client/ui/PreviewPopUp/Previews/BoxLayoutPreview.tsx
  • packages/webui/src/client/styles/shelf/dashboard.scss
  • meteor/server/publications/pieceContentStatusUI/checkPieceContentStatus.ts

Walkthrough

This PR implements per-box SPLITS previews end-to-end: data model and utilities, server resolution via expectedPackages and MediaObject fallback, UI plumbing for boxPreviews and scrub settings, shared video-scrub utilities, checkerboard styling, and tests/documentation.

Changes

SPLITS Box Previews Feature

Layer / File(s) Summary
Data model and shared utilities
packages/corelib/src/dataModel/PieceContentStatus.ts, packages/shared-lib/src/package-manager/splitBoxMedia.ts, packages/shared-lib/src/package-manager/__tests__/splitBoxMedia.spec.ts
Adds SplitBoxPreviewUrls and boxPreviews to piece content status; utilities normalize/extract media IDs from split boxes and expected packages and build index-aligned preview lookup arrays; tests cover normalization, extraction, lookup, and array-building.
Backend SPLITS preview resolution
meteor/server/publications/pieceContentStatusUI/checkPieceContentStatus.ts
Extends checkPieceContentStatus to populate status.boxPreviews[] using expected-package URL resolution plus MediaObject fallbacks, computes contentDuration from streams when needed, and clears piece-level thumbnail/preview for SPLITS.
Server tests and documentation
meteor/server/publications/pieceContentStatusUI/__tests__/checkPieceContentStatus.test.ts, packages/documentation/docs/for-developers/for-blueprint-developers/splits-box-previews.md
Adds SPLITS-specific Jest tests validating fallback behavior, URL-encoding, case-insensitive matching, and comprehensive developer documentation covering blueprint config, Core resolution paths, published shape, and UI surfaces.
Frontend preview data structure and utilities
packages/webui/src/client/lib/ui/splitPreview.ts, packages/webui/src/client/lib/ui/splitsPreviewVideo.ts
Extends SplitSubItem with thumbnailUrl, previewUrl, and seek; getSplitPreview accepts optional boxPreviews to populate per-item URLs and seek; adds getSplitsBoxLayoutScrubSettings and getPieceScrubDurationMs to drive scrub behavior.
Video scrubbing utilities
packages/webui/src/client/lib/ui/videoPreviewScrub.ts
Adds setVideoElementPosition to centralize time computation and looping/clamping behavior for preview videos.
Checkerboard and layout styling
packages/webui/src/client/styles/_checkerboard.scss, packages/webui/src/client/styles/{main,rundownView}.scss, packages/webui/src/client/styles/shelf/dashboard.scss
Introduces checkerboard-background mixin and applies it across preview popup, rundown, dashboard thumbnails, and split-layout variants; adds .video-preview__image absolute cover layering.
Split preview rendering
packages/webui/src/client/lib/SplitPreviewBox.tsx
RenderSplitPreview gains flatLayout to omit outer wrapper and now renders per-box images when available.
Box layout preview with time-based scrubbing
packages/webui/src/client/ui/PreviewPopUp/Previews/BoxLayoutPreview.tsx
BoxLayoutPreview uses internal SplitBoxMedia to render time-based video scrubbing or image fallback, accepts top-level time, and consumes content.boxPreviews and scrub.
Preview popup virtual anchor and interactions
packages/webui/src/client/ui/PreviewPopUp/PreviewPopUp.tsx, packages/webui/src/client/ui/PreviewPopUp/PreviewPopUp.scss
Refactors virtual-anchor behavior to preserve fixed width via popper modifier and track mouse; refactors layout with getAnchorY helper and re-synchronized bounding rect on preview session start.
Preview popup content and SPLITS integration
packages/webui/src/client/ui/PreviewPopUp/PreviewPopUpContext.tsx, packages/webui/src/client/ui/PreviewPopUp/PreviewPopUpContent.tsx
Updates PreviewPopUpContext to compute splits scrub settings and attach boxPreviews to boxLayout preview content; extends VT/LIVE_SPEAK video previews with item duration and seek; PreviewPopUpContent forwards time into BoxLayoutPreview.
VT preview scrubbing consolidation
packages/webui/src/client/ui/PreviewPopUp/Previews/VTPreview.tsx
VT/LIVE_SPEAK preview uses shared setVideoElementPosition utility, removing local duplication.
Dashboard button SPLITS styling and layer background
packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/{SplitButtonLayerBackground.tsx,.scss}, packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/DashboardButtonTagStrip.scss
Introduces SplitButtonLayerBackground component and SCSS for stacked color stripes and positioning rules for compact/non-compact tag-strip layouts.
Dashboard piece button SPLITS support
packages/webui/src/client/ui/Shelf/DashboardPieceButton/{DashboardPieceButton.tsx,DashboardPieceButtonSplitPreview.tsx,subcomponents/MediaBox.tsx}
Dashboard button detects SPLITS layers, derives contentStatus, special-cases thumbnail eligibility for SPLITS, conditionally renders SplitButtonLayerBackground, and forwards contentStatus.boxPreviews and flatLayout into split preview components.
Dashboard preview interaction scrub and time mapping
packages/webui/src/client/ui/Shelf/DashboardPieceButton/{useDashboardButtonInteractions.ts,usePreviewPopUpSession.ts}
Preview interaction hooks compute scrubDurationMs via getPieceScrubDurationMs, introduce timeFromClientX helper to map pointer/touch X to preview time, and update open preview sessions when previewRequest changes.
Segment container and splits items integration
packages/webui/src/client/ui/SegmentContainer/getSplitItems.tsx, packages/webui/src/client/ui/SegmentList/LinePartMainPiece/LinePartMainPiece.tsx, packages/webui/src/client/ui/SegmentStoryboard/..., packages/webui/src/client/ui/ClockView/CameraScreen/Piece.tsx`
Updates getSplitItems to accept optional boxPreviews and conditionally render per-item images; passes contentStatus?.boxPreviews through split preview generators; normalizes pointer positions for scrub time.
Storyboard thumbnail SPLITS rendering and scrub
packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/...
Refactors SplitsThumbnailRenderer to use getSplitPreview with boxPreviews and render via flat layout; enhances StoryboardPartThumbnailInner with scrub duration calculation, pointer tracking, session updates, and layer-background integration.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • Julusian
  • jstarpl
  • rjmunro
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.89% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main feature addition of per-box thumbnail and preview support for SPLITS pieces.
Description check ✅ Passed The description comprehensively explains the current behavior, new behavior, affected areas, and testing approach related to the SPLITS thumbnail preview feature.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

codecov Bot commented May 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 45.99303% with 155 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ns/pieceContentStatusUI/checkPieceContentStatus.ts 31.60% 145 Missing ⚠️
...es/shared-lib/src/package-manager/splitBoxMedia.ts 86.66% 9 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@justandras justandras added the Contribution from BBC Contributions sponsored by BBC (bbc.co.uk) label May 27, 2026
@justandras

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
✅ Actions performed

Full review triggered.

@justandras

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/webui/src/client/lib/SplitPreviewBox.tsx`:
- Around line 48-50: The current JSX in SplitPreviewBox.tsx uses item.previewUrl
as an <img> fallback which is a video URL and causes broken images; change the
logic so the <img> is only rendered when item.thumbnailUrl exists (use
item.thumbnailUrl exclusively for the img src in the video-preview__image) and,
if you need to show a preview when thumbnailUrl is absent, render a <video>
element (or a dedicated video-preview component) using item.previewUrl as its
src/poster instead of passing previewUrl to the <img>. Target the conditional
rendering around item.thumbnailUrl / item.previewUrl in SplitPreviewBox.tsx to
implement this fallback change.

In `@packages/webui/src/client/lib/ui/videoPreviewScrub.ts`:
- Around line 8-15: The loop wrapping uses mismatched units (an extra *1000) and
doesn't guard against negative targetTime; compute the loop window in
milliseconds once using vEl.duration*1000 (call it loopWindowMs = itemDuration>0
? Math.min(vEl.duration*1000, itemDuration) : vEl.duration*1000), then wrap
targetTime into [0, loopWindowMs) with a proper modulus that handles negatives
(e.g. ((targetTime % loopWindowMs) + loopWindowMs) % loopWindowMs) when loop is
true; otherwise clamp targetTime to the [0, itemDuration] range if
itemDuration>0; finally set vEl.currentTime = targetTime / 1000. Use the
existing symbols targetTime, timePosition, seek, loop, itemDuration, and vEl to
locate the change.

In
`@packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/StoryboardPartThumbnail.scss`:
- Line 64: The SCSS include uses empty parentheses which violates the
scss/at-mixin-argumentless-call-parentheses rule; update the include of the
mixin item-type-colors by removing the empty parentheses so the line uses an
argumentless mixin call (replace the `@include` item-type-colors(); usage with the
argumentless form) in StoryboardPartThumbnail.scss.

In
`@packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/DashboardButtonTagStrip.scss`:
- Line 18: Move the `@import` of SplitButtonLayerBackground so it appears at the
very top of DashboardButtonTagStrip.scss (before any rules or declarations) and
change the import to use the partial format without the .scss extension (i.e.,
import the partial name only), ensuring the import line reads the partial
reference rather than importing the literal filename with extension.

In
`@packages/webui/src/client/ui/Shelf/DashboardPieceButton/usePreviewPopUpSession.ts`:
- Around line 46-50: The effect only updates when previewRequest.contents is
non-empty, leaving a stale popup open when contents become empty; modify the
useEffect that references previewSessionRef, previewRequest and update so that
if previewSessionRef.current exists and previewRequest.contents.length === 0 you
explicitly close/terminate the session (e.g., call
previewSessionRef.current.close() or the session's dispose method), otherwise
call previewSessionRef.current.update(previewRequest.contents) for non-empty
contents; keep the effect tied to [previewRequest] and guard
previewSessionRef.current before invoking methods.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c49e61c7-02a1-4670-b299-edb99d6e5fb2

📥 Commits

Reviewing files that changed from the base of the PR and between dba153c and 1c4d1fa.

📒 Files selected for processing (36)
  • meteor/server/publications/pieceContentStatusUI/__tests__/checkPieceContentStatus.test.ts
  • meteor/server/publications/pieceContentStatusUI/checkPieceContentStatus.ts
  • packages/corelib/src/dataModel/PieceContentStatus.ts
  • packages/documentation/docs/for-developers/for-blueprint-developers/splits-box-previews.md
  • packages/shared-lib/src/package-manager/__tests__/splitBoxMedia.spec.ts
  • packages/shared-lib/src/package-manager/splitBoxMedia.ts
  • packages/webui/src/client/lib/SplitPreviewBox.tsx
  • packages/webui/src/client/lib/ui/splitPreview.ts
  • packages/webui/src/client/lib/ui/splitsPreviewVideo.ts
  • packages/webui/src/client/lib/ui/videoPreviewScrub.ts
  • packages/webui/src/client/styles/_checkerboard.scss
  • packages/webui/src/client/styles/main.scss
  • packages/webui/src/client/styles/rundownView.scss
  • packages/webui/src/client/styles/shelf/dashboard.scss
  • packages/webui/src/client/ui/ClockView/CameraScreen/Piece.tsx
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUp.scss
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUp.tsx
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUpContent.tsx
  • packages/webui/src/client/ui/PreviewPopUp/PreviewPopUpContext.tsx
  • packages/webui/src/client/ui/PreviewPopUp/Previews/BoxLayoutPreview.tsx
  • packages/webui/src/client/ui/PreviewPopUp/Previews/VTPreview.tsx
  • packages/webui/src/client/ui/SegmentContainer/getSplitItems.tsx
  • packages/webui/src/client/ui/SegmentList/LinePartMainPiece/LinePartMainPiece.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartSecondaryPieces/Renderers/SplitsRenderer.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartSecondaryPieces/StoryboardSecondaryPiece.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/Renderers/SplitsThumbnailRenderer.tsx
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/StoryboardPartThumbnail.scss
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/StoryboardPartThumbnailInner.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/DashboardPieceButton.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/DashboardButtonTagStrip.scss
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/MediaBox.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/SplitButtonLayerBackground.scss
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/SplitButtonLayerBackground.tsx
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/useDashboardButtonInteractions.ts
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/usePreviewPopUpSession.ts
  • packages/webui/src/client/ui/Shelf/DashboardPieceButtonSplitPreview.tsx

Comment thread packages/webui/src/client/lib/SplitPreviewBox.tsx Outdated
Comment thread packages/webui/src/client/lib/ui/videoPreviewScrub.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
packages/webui/src/client/lib/ui/videoPreviewScrub.ts (1)

12-14: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add explicit clamping for the non-looping, unlimited-duration case.

When !loop and itemDuration <= 0, targetTime can remain negative if seek is negative, leading to vEl.currentTime being assigned a negative value. While most browsers will clamp this to zero, it's cleaner to handle it explicitly.

🛡️ Proposed fix to guard against negative currentTime
 	} else if (itemDuration > 0) {
 		targetTime = Math.max(0, Math.min(targetTime, itemDuration))
+	} else {
+		targetTime = Math.max(0, targetTime)
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/webui/src/client/lib/ui/videoPreviewScrub.ts` around lines 12 - 14,
The code currently only clamps targetTime when itemDuration > 0, so in the
non-looping/unlimited-duration case (when loop is false and itemDuration <= 0) a
negative seek can leave targetTime negative and be assigned to vEl.currentTime;
update the logic in the function handling scrubbing (look for targetTime,
itemDuration, loop, seek, and vEl.currentTime) to explicitly clamp targetTime to
at least 0 when !loop and itemDuration <= 0 before assigning to vEl.currentTime
(e.g., ensure targetTime = Math.max(0, targetTime) in that branch).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@packages/webui/src/client/lib/ui/videoPreviewScrub.ts`:
- Around line 12-14: The code currently only clamps targetTime when itemDuration
> 0, so in the non-looping/unlimited-duration case (when loop is false and
itemDuration <= 0) a negative seek can leave targetTime negative and be assigned
to vEl.currentTime; update the logic in the function handling scrubbing (look
for targetTime, itemDuration, loop, seek, and vEl.currentTime) to explicitly
clamp targetTime to at least 0 when !loop and itemDuration <= 0 before assigning
to vEl.currentTime (e.g., ensure targetTime = Math.max(0, targetTime) in that
branch).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6414e90e-95ac-4cff-9a6b-5c5e93631a68

📥 Commits

Reviewing files that changed from the base of the PR and between 1c4d1fa and a6753e2.

📒 Files selected for processing (5)
  • packages/webui/src/client/lib/SplitPreviewBox.tsx
  • packages/webui/src/client/lib/ui/videoPreviewScrub.ts
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/StoryboardPartThumbnail.scss
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/DashboardButtonTagStrip.scss
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/usePreviewPopUpSession.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/usePreviewPopUpSession.ts
  • packages/webui/src/client/ui/SegmentStoryboard/StoryboardPartThumbnail/StoryboardPartThumbnail.scss
  • packages/webui/src/client/ui/Shelf/DashboardPieceButton/subcomponents/DashboardButtonTagStrip.scss

@justandras justandras force-pushed the feat/split-thumbnail-previews branch from a6753e2 to 94812f1 Compare June 18, 2026 09:06
@justandras justandras merged commit c1b10b6 into Sofie-Automation:main Jun 18, 2026
23 of 24 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Jun 23, 2026
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Contribution from BBC Contributions sponsored by BBC (bbc.co.uk)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant