Skip to content

feat: pro blocks and setup#159

Open
WINOFFRG wants to merge 3 commits into
mainfrom
feat/pro-block
Open

feat: pro blocks and setup#159
WINOFFRG wants to merge 3 commits into
mainfrom
feat/pro-block

Conversation

@WINOFFRG

@WINOFFRG WINOFFRG commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added pro blocks for Ambient Player and Immersive Player, including live previews and installation info in block documentation.
    • Added a pro installation notice used by MDX content.
  • Bug Fixes
    • Improved copy-to-clipboard behavior across hero and block toolbar actions (including install command copying).
    • Adjusted video playback status handling to avoid Safari stalled-state issues.
    • Refined captions switching/visibility behavior.
  • Style
    • Updated player/media visuals for cleaner slider and video layering.
  • Documentation
    • Added Ambient/Immersive player setup, usage, and configuration docs.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds Ambient Player and Immersive Player pro blocks with registry, showcase, and documentation wiring; replaces react-use clipboard usage with a local hook; centralizes API URLs; and updates player styling, playback, and caption behavior.

Changes

Pro Blocks Feature

Layer / File(s) Summary
Install command generation and clipboard integration
apps/www/components/block-viewer.tsx
Computes pro or standard registry commands and copies them through the local clipboard hook.
Registry definitions for pro players
apps/www/registry/collection/registry-blocks.ts, apps/www/registry/collection/registry-ui.ts
Registers the new player blocks and supporting pro media components.
Showcase wiring for pro players
apps/www/components/blocks/block-showcase.tsx
Adds AmbientPlayer and ImmersivePlayer showcase entries using BlockStreamSync.
Pro player documentation
apps/www/content/docs/blocks/*.mdx, apps/www/content/docs/blocks/meta.json
Adds documentation and navigation entries for both blocks.
Pro installation note
apps/www/components/mdx/pro-installation-note.tsx, apps/www/components/mdx-components.tsx
Adds and registers a lock-icon installation notice.
Pro registry revision
apps/www/registry/pro
Updates the registry subproject reference.

Copy-to-Clipboard Hook Migration

Layer / File(s) Summary
Local clipboard hook implementation
apps/www/hooks/use-copy-to-clipboard.ts
Adds copied-state tracking, clipboard writes, callbacks, error handling, and timeout reset.
Clipboard hook consumers
apps/www/components/copy-button.tsx, apps/www/components/hero-buttons.tsx
Migrates consumers to the hook’s object-based return value.

API Base URL Centralization

Layer / File(s) Summary
Shared API base URL consumers
apps/www/lib/constants.ts, apps/www/lib/catalogs/*, apps/www/components/players/audio-player/demo.ts
Adds LIMEPLAY_API_BASE_URL and derives API endpoints from it.

Player Styling and Playback Behavior Fixes

Layer / File(s) Summary
Player styling updates
apps/www/registry/default/blocks/audio-player/components/*, apps/www/registry/default/blocks/video-player/player.tsx
Updates slider track colors and video media stacking styles.
Disable stalled event handling
apps/www/registry/default/hooks/use-playback.ts
Removes stalled-event buffering logic and wiring.
Caption track visibility synchronization
apps/www/registry/default/hooks/use-captions.ts, apps/www/registry/default/examples/captions-state-control-demo.tsx
Derives caption visibility from selected tracks and removes explicit visibility toggling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant BlockViewerToolbar
  participant getRegistryInstallCommand
  participant useCopyToClipboard

  User->>BlockViewerToolbar: Click install button
  BlockViewerToolbar->>getRegistryInstallCommand: item
  getRegistryInstallCommand-->>BlockViewerToolbar: installCommand
  BlockViewerToolbar->>useCopyToClipboard: copyToClipboard(installCommand)
  useCopyToClipboard-->>BlockViewerToolbar: isCopied = true
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the PR’s main theme: adding pro blocks plus related setup and docs changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/pro-block

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.

@cubic-dev-ai cubic-dev-ai 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.

6 issues found and verified against the latest diff

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/www/lib/constants.ts">

<violation number="1" location="apps/www/lib/constants.ts:11">
P2: `LIMEPLAY_API_BASE_URL` is hardcoded to a production Workers URL with no environment-variable override. In local development this will hit the production API, and there is no way to point to a local or preview API instance. Consider following the pattern used by `PROD_BASE_HOST` and allowing an `process.env.LIMEPLAY_API_BASE_URL` override.</violation>
</file>

<file name="apps/www/components/blocks/block-showcase.tsx">

<violation number="1" location="apps/www/components/blocks/block-showcase.tsx:22">
P2: the ambient-player and immersive-player showcase entries are structurally identical, and all three video-player entries share the same wrapper layout — consider extracting a shared helper like `renderVideoBlock(Component)` to reduce duplication and keep future block additions consistent</violation>
</file>

<file name="apps/www/hooks/use-copy-to-clipboard.ts">

<violation number="1" location="apps/www/hooks/use-copy-to-clipboard.ts:31">
P1: Rapid successive copies within the timeout window cause premature `isCopied` reset. Each `copyToClipboard` call schedules a new timeout without clearing the previous one: if the user copies at t=0 and t=500ms (with default 2000ms timeout), the first timeout fires at t=2000ms and flips `isCopied` to false, even though the second copy's timeout should keep it true until t=2500ms. Track the timeout ID in a ref and clear it before scheduling a new one.</violation>
</file>

<file name="apps/www/components/block-viewer.tsx">

<violation number="1" location="apps/www/components/block-viewer.tsx:489">
P0: The `?token=<token>` in the pro-block install URL is a placeholder that never gets resolved — users will literally copy `?token=<token>` to their clipboard, and running that command will fail with an auth error. This blocks installation of all pro blocks (ambient-player, immersive-player). Either wire in an actual token (from env, config, or user input) or remove the placeholder logic until auth is ready.</violation>
</file>

<file name="apps/www/content/docs/blocks/ambient-player.mdx">

<violation number="1" location="apps/www/content/docs/blocks/ambient-player.mdx:5">
P1: The `preview: ambient-player` frontmatter references a preview component whose source file doesn't exist yet. The block-showcase tries to import from `@/registry/pro/blocks/ambient-player/player`, but `registry/pro/blocks/` has no files. Either create the source component as part of this PR or remove/skip the preview field until the component is ready to avoid a broken doc page.</violation>
</file>

<file name="apps/www/scripts/registry-dev.mts">

<violation number="1" location="apps/www/scripts/registry-dev.mts:435">
P2: The generated `proRegistryItems` lookup can include a bogus `registry` entry because this loop imports every `.json` file from the shadcn output, including the tier-level `registry.json` that `validateTierRegistries()` expects in `registry/.generated/pro`. Skipping `registry.json` here would keep the runtime module limited to actual pro item JSON files.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic


function getRegistryInstallCommand(item: RegistryItem) {
const itemName = item.categories?.includes("pro")
? `"https://limeplay.winoffrg.dev/r/pro/${item.name}.json?token=<token>"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P0: The ?token=<token> in the pro-block install URL is a placeholder that never gets resolved — users will literally copy ?token=<token> to their clipboard, and running that command will fail with an auth error. This blocks installation of all pro blocks (ambient-player, immersive-player). Either wire in an actual token (from env, config, or user input) or remove the placeholder logic until auth is ready.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/www/components/block-viewer.tsx, line 489:

<comment>The `?token=<token>` in the pro-block install URL is a placeholder that never gets resolved — users will literally copy `?token=<token>` to their clipboard, and running that command will fail with an auth error. This blocks installation of all pro blocks (ambient-player, immersive-player). Either wire in an actual token (from env, config, or user input) or remove the placeholder logic until auth is ready.</comment>

<file context>
@@ -483,6 +484,14 @@ function BlockViewerView() {
 
+function getRegistryInstallCommand(item: RegistryItem) {
+  const itemName = item.categories?.includes("pro")
+    ? `"https://limeplay.winoffrg.dev/r/pro/${item.name}.json?token=<token>"`
+    : `@limeplay/${item.name}`
+
</file context>

onCopy()
}

setTimeout(() => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: Rapid successive copies within the timeout window cause premature isCopied reset. Each copyToClipboard call schedules a new timeout without clearing the previous one: if the user copies at t=0 and t=500ms (with default 2000ms timeout), the first timeout fires at t=2000ms and flips isCopied to false, even though the second copy's timeout should keep it true until t=2500ms. Track the timeout ID in a ref and clear it before scheduling a new one.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/www/hooks/use-copy-to-clipboard.ts, line 31:

<comment>Rapid successive copies within the timeout window cause premature `isCopied` reset. Each `copyToClipboard` call schedules a new timeout without clearing the previous one: if the user copies at t=0 and t=500ms (with default 2000ms timeout), the first timeout fires at t=2000ms and flips `isCopied` to false, even though the second copy's timeout should keep it true until t=2500ms. Track the timeout ID in a ref and clear it before scheduling a new one.</comment>

<file context>
@@ -0,0 +1,38 @@
+        onCopy()
+      }
+
+      setTimeout(() => {
+        setIsCopied(false)
+      }, timeout)
</file context>

title: Ambient Player
description: A pro video player block that layers YouTube-style cinematic ambient lighting behind the standard Limeplay video player.
component: ambient-player
preview: ambient-player

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: The preview: ambient-player frontmatter references a preview component whose source file doesn't exist yet. The block-showcase tries to import from @/registry/pro/blocks/ambient-player/player, but registry/pro/blocks/ has no files. Either create the source component as part of this PR or remove/skip the preview field until the component is ready to avoid a broken doc page.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/www/content/docs/blocks/ambient-player.mdx, line 5:

<comment>The `preview: ambient-player` frontmatter references a preview component whose source file doesn't exist yet. The block-showcase tries to import from `@/registry/pro/blocks/ambient-player/player`, but `registry/pro/blocks/` has no files. Either create the source component as part of this PR or remove/skip the preview field until the component is ready to avoid a broken doc page.</comment>

<file context>
@@ -0,0 +1,66 @@
+title: Ambient Player
+description: A pro video player block that layers YouTube-style cinematic ambient lighting behind the standard Limeplay video player.
+component: ambient-player
+preview: ambient-player
+registry: pro
+status: pro
</file context>

Comment thread apps/www/lib/constants.ts
process.env.VERCEL_ENV === "preview"
? `https://${process.env.VERCEL_URL ?? "limeplay.winoffrg.dev"}`
: "https://limeplay.winoffrg.dev"
export const LIMEPLAY_API_BASE_URL = "https://limeplay.winoffrg.workers.dev"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: LIMEPLAY_API_BASE_URL is hardcoded to a production Workers URL with no environment-variable override. In local development this will hit the production API, and there is no way to point to a local or preview API instance. Consider following the pattern used by PROD_BASE_HOST and allowing an process.env.LIMEPLAY_API_BASE_URL override.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/www/lib/constants.ts, line 11:

<comment>`LIMEPLAY_API_BASE_URL` is hardcoded to a production Workers URL with no environment-variable override. In local development this will hit the production API, and there is no way to point to a local or preview API instance. Consider following the pattern used by `PROD_BASE_HOST` and allowing an `process.env.LIMEPLAY_API_BASE_URL` override.</comment>

<file context>
@@ -8,3 +8,4 @@ export const PROD_BASE_HOST =
   process.env.VERCEL_ENV === "preview"
     ? `https://${process.env.VERCEL_URL ?? "limeplay.winoffrg.dev"}`
     : "https://limeplay.winoffrg.dev"
+export const LIMEPLAY_API_BASE_URL = "https://limeplay.winoffrg.workers.dev"
</file context>
Suggested change
export const LIMEPLAY_API_BASE_URL = "https://limeplay.winoffrg.workers.dev"
export const LIMEPLAY_API_BASE_URL = process.env.LIMEPLAY_API_BASE_URL ?? "https://limeplay.winoffrg.workers.dev"

@@ -2,6 +2,8 @@ import type { ReactNode } from "react"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: the ambient-player and immersive-player showcase entries are structurally identical, and all three video-player entries share the same wrapper layout — consider extracting a shared helper like renderVideoBlock(Component) to reduce duplication and keep future block additions consistent

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/www/components/blocks/block-showcase.tsx, line 22:

<comment>the ambient-player and immersive-player showcase entries are structurally identical, and all three video-player entries share the same wrapper layout — consider extracting a shared helper like `renderVideoBlock(Component)` to reduce duplication and keep future block additions consistent</comment>

<file context>
@@ -12,6 +14,19 @@ type BlockShowcaseDefinition = {
+      <BlockPreviewWithToolbar>
+        <div className="flex size-full">
+          <BlockPreviewPane>
+            <AmbientPlayer layout="fill">
+              <BlockStreamSync playerType="video" />
+            </AmbientPlayer>
</file context>

if (outputDir) {
const entries = await fs.readdir(outputDir)
for (const entry of entries) {
if (!entry.endsWith(".json")) continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The generated proRegistryItems lookup can include a bogus registry entry because this loop imports every .json file from the shadcn output, including the tier-level registry.json that validateTierRegistries() expects in registry/.generated/pro. Skipping registry.json here would keep the runtime module limited to actual pro item JSON files.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/www/scripts/registry-dev.mts, line 435:

<comment>The generated `proRegistryItems` lookup can include a bogus `registry` entry because this loop imports every `.json` file from the shadcn output, including the tier-level `registry.json` that `validateTierRegistries()` expects in `registry/.generated/pro`. Skipping `registry.json` here would keep the runtime module limited to actual pro item JSON files.</comment>

<file context>
@@ -401,6 +418,47 @@ function startWatcher() {
+  if (outputDir) {
+    const entries = await fs.readdir(outputDir)
+    for (const entry of entries) {
+      if (!entry.endsWith(".json")) continue
+
+      const filePath = path.join(outputDir, entry)
</file context>
Suggested change
if (!entry.endsWith(".json")) continue
if (!entry.endsWith(".json") || entry === "registry.json") continue

@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: 1

🧹 Nitpick comments (1)
apps/www/registry/default/hooks/use-playback.ts (1)

347-362: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove commented-out dead code; keep a concise TODO instead.

The full stalledHandler implementation is commented out along with its registration and cleanup. Dead code in comments degrades maintainability and can silently rot. Replace the block with a brief TODO referencing the Safari issue and the URL, then delete the implementation.

♻️ Proposed cleanup
-    /**
-     *
-        TODO: Breaks on Safari, stalled is not handled correctly
-        `@ref`: https://medium.com/@nathan5x/event-lifecycle-of-html-video-element-part-1-f63373c981d3#:~:text=Lifecycle%20in%20Safari-,Safari,-%2C%20in%20general%2C%20is
-
-        const stalledHandler = () => {
-          const prevStatus = store.getState().playback.status
-
-          store.setState(({ playback }) => {
-            playback.status = "buffering"
-          })
-
-          events.emit("buffering", { isBuffering: true })
-          events.emit("statuschange", { prevStatus, status: "buffering" })
-        }
-     */
+    // TODO: "stalled" handler disabled — breaks on Safari due to stalled lifecycle issues.
+    // Ref: https://medium.com/@nathan5x/event-lifecycle-of-html-video-element-part-1-f63373c981d3#:~:text=Lifecycle%20in%20Safari-,Safari,-%2C%20in%20general%2C%20is

And remove the commented-out subscription/cleanup lines:

-    // on(media, "stalled", stalledHandler)
-      // off(media, "stalled", stalledHandler)

Also applies to: 378-378, 394-394

🤖 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 `@apps/www/registry/default/hooks/use-playback.ts` around lines 347 - 362,
Remove the commented-out stalled handling dead code around use-playback’s Safari
TODO, including the stalledHandler implementation and its commented
registration/cleanup, and replace it with a short TODO note referencing the
Safari stalled-event issue and the linked URL. Keep the reference in
use-playback’s playback event handling area so the existing stalled logic can be
restored later without leaving commented implementation blocks behind.
🤖 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 `@apps/www/hooks/use-copy-to-clipboard.ts`:
- Around line 31-33: The copy-state reset in useCopyToClipboard is using an
untracked setTimeout, which can race and leak. Update the useCopyToClipboard
hook to store the timeout ID in a ref, clear any existing timer before
scheduling a new one when copying, and add cleanup on unmount to cancel the
pending timer. Keep the fix localized around the setTimeout/setIsCopied(false)
logic in useCopyToClipboard so repeated copies and component teardown are
handled safely.

---

Nitpick comments:
In `@apps/www/registry/default/hooks/use-playback.ts`:
- Around line 347-362: Remove the commented-out stalled handling dead code
around use-playback’s Safari TODO, including the stalledHandler implementation
and its commented registration/cleanup, and replace it with a short TODO note
referencing the Safari stalled-event issue and the linked URL. Keep the
reference in use-playback’s playback event handling area so the existing stalled
logic can be restored later without leaving commented implementation blocks
behind.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0f009cff-f2c6-4f94-ba09-913446cf4046

📥 Commits

Reviewing files that changed from the base of the PR and between a1c6556 and 31110ec.

⛔ Files ignored due to path filters (6)
  • .gitignore is excluded by none and included by none
  • apps/www/package.json is excluded by none and included by none
  • apps/www/scripts/registry-dev.mts is excluded by none and included by none
  • apps/www/scripts/validate-registries.ts is excluded by none and included by none
  • apps/www/vercel.json is excluded by none and included by none
  • bun.lock is excluded by !**/*.lock and included by none
📒 Files selected for processing (21)
  • apps/www/components/block-viewer.tsx
  • apps/www/components/blocks/block-showcase.tsx
  • apps/www/components/copy-button.tsx
  • apps/www/components/hero-buttons.tsx
  • apps/www/components/mdx-components.tsx
  • apps/www/components/mdx/pro-installation-note.tsx
  • apps/www/components/players/audio-player/demo.ts
  • apps/www/content/docs/blocks/ambient-player.mdx
  • apps/www/content/docs/blocks/immersive-player.mdx
  • apps/www/content/docs/blocks/meta.json
  • apps/www/hooks/use-copy-to-clipboard.ts
  • apps/www/lib/catalogs/apple-music.ts
  • apps/www/lib/catalogs/blender-open-films.ts
  • apps/www/lib/constants.ts
  • apps/www/registry/collection/registry-blocks.ts
  • apps/www/registry/collection/registry-ui.ts
  • apps/www/registry/default/blocks/audio-player/components/fixed-timeline-control.tsx
  • apps/www/registry/default/blocks/audio-player/components/volume-group-control.tsx
  • apps/www/registry/default/blocks/video-player/player.tsx
  • apps/www/registry/default/hooks/use-playback.ts
  • apps/www/registry/pro

Comment on lines +31 to +33
setTimeout(() => {
setIsCopied(false)
}, timeout)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Clear previous timeout to prevent race condition and timer leak.

The setTimeout is never tracked or cleared. If a user copies again before the timeout fires, the earlier timeout will prematurely reset isCopied to false, causing a visual flicker. Additionally, if the component unmounts, the orphaned timer leaks. Store the timeout ID in a ref, clear any existing timer before setting a new one, and clean up on unmount.

🛡️ Proposed fix
 export function useCopyToClipboard({
   onCopy,
   timeout = 2000,
 }: {
   onCopy?: () => void
   timeout?: number
 } = {}) {
   const [isCopied, setIsCopied] = React.useState(false)
+  const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null)
+
+  React.useEffect(() => {
+    return () => {
+      if (timeoutRef.current) clearTimeout(timeoutRef.current)
+    }
+  }, [])
 
   const copyToClipboard = (value: string) => {
     if (typeof window === "undefined") {
       return
     }
 
     const clipboard = "clipboard" in navigator ? navigator.clipboard : null
     if (!clipboard) return
 
     if (!value) return
 
     clipboard.writeText(value).then(() => {
       setIsCopied(true)
 
       if (onCopy) {
         onCopy()
       }
 
+      if (timeoutRef.current) clearTimeout(timeoutRef.current)
       setTimeout(() => {
         setIsCopied(false)
+        timeoutRef.current = null
       }, timeout)
     }, console.error)
   }
 
   return { copyToClipboard, isCopied }
 }
🤖 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 `@apps/www/hooks/use-copy-to-clipboard.ts` around lines 31 - 33, The copy-state
reset in useCopyToClipboard is using an untracked setTimeout, which can race and
leak. Update the useCopyToClipboard hook to store the timeout ID in a ref, clear
any existing timer before scheduling a new one when copying, and add cleanup on
unmount to cancel the pending timer. Keep the fix localized around the
setTimeout/setIsCopied(false) logic in useCopyToClipboard so repeated copies and
component teardown are handled safely.

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/www/package.json">

<violation number="1" location="apps/www/package.json:72">
P2: The dependency change still leaves installs on `shaka-player@5.1.13`: `^5.1.12` permits 5.1.13, and `bun.lock` is still resolved to 5.1.13. If this change is meant to roll back Shaka to 5.1.12, it would be safer to pin `"shaka-player": "5.1.12"` and regenerate/commit `bun.lock` so CI and deployments actually use that version.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread apps/www/package.json
"remark-gfm": "^4.0.1",
"remark-rehype": "^11.1.2",
"shaka-player": "^4.16.34",
"shaka-player": "^5.1.12",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The dependency change still leaves installs on shaka-player@5.1.13: ^5.1.12 permits 5.1.13, and bun.lock is still resolved to 5.1.13. If this change is meant to roll back Shaka to 5.1.12, it would be safer to pin "shaka-player": "5.1.12" and regenerate/commit bun.lock so CI and deployments actually use that version.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/www/package.json, line 72:

<comment>The dependency change still leaves installs on `shaka-player@5.1.13`: `^5.1.12` permits 5.1.13, and `bun.lock` is still resolved to 5.1.13. If this change is meant to roll back Shaka to 5.1.12, it would be safer to pin `"shaka-player": "5.1.12"` and regenerate/commit `bun.lock` so CI and deployments actually use that version.</comment>

<file context>
@@ -69,7 +69,7 @@
     "remark-gfm": "^4.0.1",
     "remark-rehype": "^11.1.2",
-    "shaka-player": "^5.1.13",
+    "shaka-player": "^5.1.12",
     "three": "^0.184.0",
     "ts-morph": "27.0.2",
</file context>

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/www/registry/default/hooks/use-captions.ts (1)

59-75: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Fix the toggle logic to prevent always hiding the captions.

The current implementation unconditionally calls player.selectTextTrack(null) at the end of the function, effectively overriding any attempt to turn the captions on. The nullification must be wrapped in an else block to ensure it only turns off the captions if they are already active.

🐛 Proposed fix for the toggle logic
           if (!captions.activeTrack) {
             const defaultTrack = findDefaultTrack(captions.tracks)
             if (defaultTrack) {
               player.selectTextTrack(defaultTrack)
 
               const activeTrack = player
                 .getTextTracks()
                 .find((track: shaka.extern.TextTrack) => track.active)
 
               set(({ captions }) => {
                 captions.activeTrack = activeTrack ?? null
               })
             }
-          }
-
-          player.selectTextTrack(null)
+          } else {
+            player.selectTextTrack(null)
+          }
         },
🤖 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 `@apps/www/registry/default/hooks/use-captions.ts` around lines 59 - 75, Update
the caption toggle logic so player.selectTextTrack(null) executes only in the
else branch when captions.activeTrack is already active; keep the existing
default-track selection and activeTrack state update in the if
(!captions.activeTrack) branch.
🧹 Nitpick comments (1)
apps/www/registry/default/hooks/use-captions.ts (1)

114-114: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the debug artifact.

This console.log statement was likely left behind during development and should be removed.

♻️ Proposed fix
-      console.log("Active track changed:", activeTrack)
🤖 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 `@apps/www/registry/default/hooks/use-captions.ts` at line 114, Remove the
development-only console.log statement from the active track change handling in
use-captions.ts, leaving the surrounding activeTrack logic unchanged.
🤖 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.

Outside diff comments:
In `@apps/www/registry/default/hooks/use-captions.ts`:
- Around line 59-75: Update the caption toggle logic so
player.selectTextTrack(null) executes only in the else branch when
captions.activeTrack is already active; keep the existing default-track
selection and activeTrack state update in the if (!captions.activeTrack) branch.

---

Nitpick comments:
In `@apps/www/registry/default/hooks/use-captions.ts`:
- Line 114: Remove the development-only console.log statement from the active
track change handling in use-captions.ts, leaving the surrounding activeTrack
logic unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c7f0b854-cb85-4c35-a8d6-f936c5bbd93f

📥 Commits

Reviewing files that changed from the base of the PR and between 31110ec and 3471312.

📒 Files selected for processing (2)
  • apps/www/registry/default/examples/captions-state-control-demo.tsx
  • apps/www/registry/default/hooks/use-captions.ts
💤 Files with no reviewable changes (1)
  • apps/www/registry/default/examples/captions-state-control-demo.tsx

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/www/registry/default/hooks/use-captions.ts">

<violation number="1" location="apps/www/registry/default/hooks/use-captions.ts:74">
P1: Turning captions on immediately deselects the default track because this call runs after `player.selectTextTrack(defaultTrack)`. Make deselection the active-track branch instead, so the toggle can enable captions.</violation>

<violation number="2" location="apps/www/registry/default/hooks/use-captions.ts:114">
P3: Caption changes emit a production console message, exposing track metadata and creating noisy logs during normal playback. Remove this debugging statement.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

}

player.setTextTrackVisibility(!captions.visible)
player.selectTextTrack(null)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: Turning captions on immediately deselects the default track because this call runs after player.selectTextTrack(defaultTrack). Make deselection the active-track branch instead, so the toggle can enable captions.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/www/registry/default/hooks/use-captions.ts, line 74:

<comment>Turning captions on immediately deselects the default track because this call runs after `player.selectTextTrack(defaultTrack)`. Make deselection the active-track branch instead, so the toggle can enable captions.</comment>

<file context>
@@ -71,7 +71,7 @@ export function captionsFeature(): MediaFeature<
           }
 
-          player.setTextTrackVisibility(!captions.visible)
+          player.selectTextTrack(null)
         },
         tracks: undefined,
</file context>

.getTextTracks()
.find((track: shaka.extern.TextTrack) => track.active)

console.log("Active track changed:", activeTrack)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: Caption changes emit a production console message, exposing track metadata and creating noisy logs during normal playback. Remove this debugging statement.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/www/registry/default/hooks/use-captions.ts, line 114:

<comment>Caption changes emit a production console message, exposing track metadata and creating noisy logs during normal playback. Remove this debugging statement.</comment>

<file context>
@@ -111,8 +111,16 @@ function CaptionsSetup() {
       .getTextTracks()
       .find((track: shaka.extern.TextTrack) => track.active)
 
+      console.log("Active track changed:", activeTrack)
+
     store.setState(({ captions }) => {
</file context>

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