Skip to content

feat: product fixes, naming, usage, providers and cores#151

Open
WINOFFRG wants to merge 3 commits into
mainfrom
feat/3105
Open

feat: product fixes, naming, usage, providers and cores#151
WINOFFRG wants to merge 3 commits into
mainfrom
feat/3105

Conversation

@WINOFFRG
Copy link
Copy Markdown
Owner

@WINOFFRG WINOFFRG commented May 30, 2026

Summary by CodeRabbit

  • New Features

    • Added Audio Player block with full UI (controls, playlist, volume, timeline) and demo playlist
    • Added Video Player block with HLS/DASH/DRM-ready demo assets and picture-in-picture support
    • Introduced playback-source controller hook for normalized source/playlist loading
  • Documentation

    • New Audio Player and Video Player docs and hook guides; Quick Start updated
  • Refactor

    • Replaced prior linear/basic player surface with new video/audio player implementations and updated site showcase

Copilot AI review requested due to automatic review settings May 30, 2026 21:58
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 30, 2026

📝 Walkthrough

Walkthrough

Replaces the old linear-player/youtube-music demos with new audio-player and video-player blocks, refactors asset identity and source-resolution (use-asset), adds a playback-source controller (use-playback-source), implements audio/video player components and demos, and updates registry, docs, and home integration.

Changes

Audio/Video Player Block Replacement with Asset Orchestration Refactoring

Layer / File(s) Summary
Home & block showcase integration
apps/www/app/(home)/page.tsx, apps/www/components/players/*, apps/www/components/blocks/block-showcase.tsx
Home page swaps PlayerContainerVideoPlayerContainer, YouTubeMusicHoverPlayerAudioPlayerHover; block showcase registry now registers audio-player and video-player previews wired to AudioPlayerDemo and VideoPlayer.
Block UI, preview, and MDX components
apps/www/components/blocks/info-pane.tsx, preview-pane.tsx, apps/www/components/mdx-components.tsx, apps/www/components/hero-buttons.tsx, apps/www/registry/default/ui/limeplay-logo.tsx
Responsive DocsTitle/DocsDescription styling, preview-pane panelRect defaults/casts updated, Attribution/License MDX components added, hero command/link updated to @limeplay/video-player, logo class simplified.
Audio demo & fetch
apps/www/components/players/audio-player/demo.ts, demo-player.tsx
New demo playlist fetcher that queries worker API and maps response into AudioPlayerAsset; AudioPlayerDemo component fetches and renders the playlist.
AudioSourceProvider & helpers
apps/www/registry/default/blocks/audio-player/components/audio-source.tsx
Adds AudioSourceProvider, types (AudioPlayerAsset, PlaybackUrls), resolveSource wiring (fetch playbackUrls.primary with raw=true), fetchPlaybackUrl helper, useAudioSource context.
Audio player UI components
apps/www/registry/default/blocks/audio-player/components/{media-player,playback-controls,playback-mode-controls,playlist,track-info,volume-group-control,action-controls,fixed-timeline-control,button,icons}.tsx
Implements AudioPlayer and many UI pieces: playback controls with animated icons, repeat/shuffle, queue dropdown, track info/poster, volume/mute, like/dislike, timeline slider, button primitive, and SVG icons.
Audio media-kit & CSS
apps/www/registry/default/blocks/audio-player/lib/media-kit.ts, audio-player.module.css
Composes media kit via createMediaKit and exports MediaProvider; adds .dark theme variables and timeline track height.
Video demo assets & VideoPlayer
apps/www/components/players/video-player/demo-assets.ts, apps/www/registry/default/blocks/video-player/components/media-player.tsx, player-container.tsx
Adds VIDEO_PLAYER_DEMO_ASSETS (4 demo entries, including Widevine config) and implements VideoPlayer component (MediaProvider + PlaybackSourceController + video element + controls). VideoPlayerContainer renders demo playlist.
Video controls & playlist refactor
apps/www/registry/default/blocks/video-player/components/*
Switches control imports from linear-playervideo-player, refactors video Playlist to derive items from store (orderedItems), use id-based skipToId, and gate hover preloads via preloadManagers.
Registry: blocks & hooks
apps/www/registry/collection/registry-blocks.ts, registry-hooks.ts
Renames first block to video-player, introduces VIDEO_PLAYER_SRC_URL, replaces basic-player with audio-player, extends registryDependencies with use-media and use-playback-source, and registers use-playback-source hook.
use-asset refactor
apps/www/registry/default/hooks/use-asset.ts
Major refactor: Asset fields optional (id?, src?, poster?, title?), adds ResolveSource/PlaybackSource types, per-owner options (setOptions(ownerId)/clearOptions), previousError/retryCount, normalized asset id hashing, rewritten loadAsset/preloadAsset flows, preload abort controller management, and helper utilities. useAsset uses useId() for option ownership.
use-playback-source hook
apps/www/registry/default/hooks/use-playback-source.ts
Adds usePlaybackSource and PlaybackSourceController: normalizes asset/playlist/mediaSrc inputs, computes deterministic resolvedSourceKey, memoizes useAsset options (getAssetId/resolveSource), and triggers loadPlaylist when key changes.
MediaProvider/player minor changes
apps/www/registry/default/ui/media-provider.tsx, use-player.ts, use-playlist.ts, media.tsx
MediaProviderProps accepts debug and syncs to store; Shaka player attach now passes initializeMediaSource=false; playlist.load clamps startIndex; MediaProps video variant as made optional.
Docs & quick start
apps/www/content/docs/*, apps/www/content/docs/hooks/meta.json, quick-start.mdx
Adds audio-player.mdx and video-player.mdx, updates use-asset.mdx and adds use-playback-source.mdx, removes old linear-player/youtube-music docs, and updates quick-start to @limeplay/video-player.

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

"I'm a rabbit who hops on keys and strings,
I fetch playlists and hum while coding things.
Assets get sorted, sources resolve true,
Audio and video now play just for you. 🐰🎶🎬"

✨ 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/3105

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 18

Caution

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

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

453-497: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

preloadAsset() can publish stale managers out of order.

AbortController is created here but never used to cancel or reject older work, and there is no guard after any await before writing back to preloadManagers. Two overlapping preloads for the same normalized asset can therefore resolve out of order, letting an older request destroy or replace a newer manager.

As per coding guidelines, "Async functions must include abort/generation guards after each await statement."

Also applies to: 500-515

🤖 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-asset.ts` around lines 453 - 497,
preloadAsset can publish stale shaka.media.PreloadManager instances because a
new AbortController is created but previous controllers aren't aborted and there
are no generation/abort guards after awaits; fix by: when starting a preload (in
the preloadAsset flow that uses preloadDefault, resolveSourceValue, etc.)
acquire or increment a per-asset generation/token or store the new
AbortController in the preloadManagers map keyed by the normalized asset, abort
the previous controller (if any) before starting, capture the current
generation/token and localAbortController, pass localAbortController.signal into
resolveSourceValue/preloadDefault, and after every await check that the stored
controller/generation in preloadManagers still matches the local one before
writing back manager; reference symbols: preloadDefault, abortController,
preloadManagers, resolveSourceValue (and the enclosing preloadAsset flow) to
implement these guards and cancellation.
apps/www/content/docs/hooks/use-asset.mdx (1)

63-113: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add the required hook doc sections (Store, Actions, Events).

The page is missing the required hook-structure sections for Store (with State table), Actions table, and Events table in the current content flow (Lines 63–113).
As per coding guidelines, apps/www/content/docs/hooks/**/*.mdx: "Hook documentation must include: Installation section, Feature registration code block, Store section with State table, Actions table, Events table, and AutoTypeTable component".

🤖 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/content/docs/hooks/use-asset.mdx` around lines 63 - 113, The doc is
missing the required hook-structure sections; add a "Store" section (with a
State table), an "Actions" section (with an Actions table), and an "Events"
section (with an Events table) into the content flow after the Options/Returns
block (where lines 63–113 are). Use the AutoTypeTable component to reference the
hook types from ./registry/default/hooks/use-asset.ts (for example AutoTypeTable
path="./registry/default/hooks/use-asset.ts" name="UseAssetStore",
name="UseAssetActions", and name="UseAssetEvents" or the actual exported type
names in that file), and ensure each section has the required heading and table
so the page conforms to the project's hook documentation structure.
🤖 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/components/players/audio-player/demo-player.tsx`:
- Around line 26-32: The promise returned by
fetchAudioPlayerDemoPlaylist(playlistId, abortController.signal) is used without
a rejection handler; update the call in demo-player.tsx to append a .catch(...)
that ignores AbortError (or checks error.name === 'AbortError') and otherwise
logs or handles other errors and prevents unhandled promise rejections; keep the
existing then(...) behavior that checks abortController.signal.aborted and calls
setPlaylist(items).

In `@apps/www/content/docs/blocks/audio-player.mdx`:
- Around line 19-23: Update the import path for the audio player example to use
the limeplay component namespace: replace the current import of AudioPlayer and
AudioPlayerAsset from "`@/components/audio-player/components/media-player`" with
the equivalent "`@/components/limeplay/`..." path (e.g., import AudioPlayer, type
AudioPlayerAsset from "`@/components/limeplay/`...") and ensure any related hook
imports use "`@/hooks/limeplay/`..." so the example follows the docs guideline of
using `@/components/limeplay/`* and `@/hooks/limeplay/`*.

In `@apps/www/content/docs/blocks/video-player.mdx`:
- Around line 19-23: The import lines for VideoPlayer and type VideoPlayerAsset
currently use "`@/components/video-player/components/media-player`"; update them
to follow limeplay docs conventions by importing from the limeplay components
surface (e.g., change the module path to "`@/components/limeplay/`..." so
VideoPlayer and VideoPlayerAsset are imported from the limeplay component
module), ensuring documentation files use "`@/components/limeplay/`*" instead of
"`@/components/video-player/`*".

In `@apps/www/content/docs/hooks/use-playback-source.mdx`:
- Around line 17-56: The documentation for the new hook is missing the required
sections: add an "Installation" snippet, a Feature registration code block that
shows how to register PlaybackSourceController/UsePlaybackSourceOptions with the
feature registry, and add the Store (State) table, Actions table, and Events
table documenting the hook's state shape, public actions, and emitted events;
keep the existing AutoTypeTable (path
"./registry/default/hooks/use-playback-source.ts", name
"UsePlaybackSourceOptions") and ensure the tables reference the hook API symbols
PlaybackSourceController and UsePlaybackSourceOptions so readers can map
state/actions/events to the implementation.

In `@apps/www/registry/default/blocks/audio-player/components/audio-source.tsx`:
- Around line 130-139: The provider currently exposes placeholder fields (error,
isLoading, refetch) in the value object that overwrite the real asset state from
usePlaylistAsset, preventing pending/error transitions and making refetch a
no-op; fix this by either removing those placeholder fields from the value (so
the provider only exposes items) or by wiring the real controller state into the
provider (use the actual loading/error/refetch from usePlaylistAsset and pass
those through instead of the null/false/refetch stub); update the value
construction where refetch and value are defined (the refetch callback and the
value const) so they either omit error/isLoading/refetch or source them from the
real controller returned by usePlaylistAsset.
- Around line 106-127: The resolvedSource async callback can return a stale
source if the asset changes while fetchPlaybackUrl is in flight; after awaiting
fetchPlaybackUrl(asset.playbackUrls.primary, signal) add an abort/generation
guard (check signal.aborted or equivalent) and immediately throw or return to
bail if the operation was aborted before returning the resolved { config, src }
so resolvedSource does not produce a stale result.

In `@apps/www/registry/default/blocks/audio-player/components/button.tsx`:
- Around line 12-54: The Button component currently lets real <button> elements
inherit the browser default type="submit"; update the JSX in the
React.forwardRef implementation (Button, Comp, render, Slot) so that when Comp
resolves to "button" you ensure a default type of "button" if no type prop was
provided (e.g., compute a localType = props.type ?? "button" or conditionally
set type="button" on the element) before spreading {...props} and passing ref;
this guarantees native buttons rendered by Button won't submit forms
unexpectedly while still allowing callers to override type.

In `@apps/www/registry/default/blocks/audio-player/components/media-player.tsx`:
- Line 63: The Media element is hard-coded to autoPlay (<Media as="audio"
autoPlay />), causing unwanted immediate playback; update the exported component
(MediaPlayer / default export in media-player.tsx) to accept an optional prop
(e.g., autoPlay?: boolean = false) and pass that prop through to the Media
element instead of hard-coding it, ensuring the default is off and that source
changes only auto-play when the caller explicitly sets autoPlay to true.
- Around line 1-18: Add "use client" as the very first line of media-player.tsx
to make the module a client component (required because it passes function props
like getAssetId and resolveSource into client-side components
AudioSourceProvider and MediaProvider). Then add an optional autoPlay:boolean
prop to the AudioPlayerProps (default false) and update the Media JSX so it uses
that prop (e.g. <Media as="audio" autoPlay={autoPlay} ... />) instead of the
hard-coded <Media as="audio" autoPlay /> so callers can opt out of autoplay;
ensure any places that render the media-player component are updated or rely on
the new default to preserve existing behavior.

In
`@apps/www/registry/default/blocks/audio-player/components/playback-controls.tsx`:
- Around line 106-123: The effect that controls the delayed spinner uses
lastIntentRef.current but doesn't rerun when the playback intent/status changes,
so lingering timeouts can show the spinner incorrectly; update the useEffect
dependency array to include the reactive intent/status variable (e.g., status or
playbackStatus) so the effect re-evaluates when intent changes, and ensure
lastIntentRef is updated before the effect runs; keep the existing timeoutRef
and cleanup logic in the same useEffect (symbols: useEffect, lastIntentRef,
timeoutRef, isBuffering, delayMs, status/playbackStatus).

In `@apps/www/registry/default/blocks/audio-player/components/playlist.tsx`:
- Around line 181-185: The <img> in playlist.tsx currently uses
src={asset.poster ?? ""}, which produces an empty src when asset.poster is
missing; change this to render the <img> only when asset.poster is truthy (e.g.
conditionally return or inline conditional render using asset.poster) so no
<img> with an empty src is emitted; keep the same alt and className attributes
and src set to asset.poster when present.

In `@apps/www/registry/default/blocks/audio-player/components/track-info.tsx`:
- Around line 45-48: The subtitle currently includes a hard-coded year string
("• 2026") in the TrackInfo component; remove that literal and instead render a
real metadata field (e.g., use props.track.year, props.track.releaseYear,
metadata.year or similar) or omit the year suffix entirely when no year is
available—update the JSX around the genre variable in track-info.tsx to
conditionally append the actual year metadata if present rather than the
constant "2026".

In
`@apps/www/registry/default/blocks/audio-player/components/volume-group-control.tsx`:
- Around line 52-61: The mute/unmute SVG icons in the VolumeGroupControl
component are announced redundantly by assistive tech despite the button already
having an aria-label; update the rendering of VolumeMutedIcon and VolumeFullIcon
so they are treated as decorative (add aria-hidden="true" to the SVG elements or
wrap them in an element with aria-hidden) so screen readers do not announce the
icons — locate the conditional that renders VolumeMutedIcon / VolumeFullIcon
inside the AnimatePresence/motion span and ensure the icon components or their
root SVG elements include aria-hidden="true".

In `@apps/www/registry/default/blocks/video-player/components/media-player.tsx`:
- Around line 27-50: Remove the banned mediaRef prop from the public API: delete
the mediaRef field from the VideoPlayerProps interface and remove any
usage/forwarding of mediaRef elsewhere in this file (including the other
occurrence around the 88-95 range) so the component no longer accepts or exposes
mediaRef; update any prop destructuring, prop spreading, and types that
referenced mediaRef, and instead ensure callers access the underlying video
element via the supported hooks/components (e.g., useVideoPlayer hook or
internal media element refs) rather than passing mediaRef.

In `@apps/www/registry/default/blocks/video-player/components/playlist.tsx`:
- Around line 20-21: The component currently destructures currentItem,
isPreloaded, orderedItems, preloadAsset, and skipToId from useAsset(), which
subscribes the whole asset slice; replace that with granular selector
hooks—e.g., call the per-feature selector hook for each symbol (useAssetStore(s
=> s.currentItem), useAssetStore(s => s.isPreloaded), useAssetStore(s =>
s.orderedItems), and for actions useAssetStore(s => s.preloadAsset) and
useAssetStore(s => s.skipToId)) so the playlist only subscribes to the specific
fields it needs and avoids full-slice rerenders; update references in this file
to use the new selected values.

In `@apps/www/registry/default/hooks/use-asset.ts`:
- Around line 182-195: The store currently uses a single
installedOptions/optionsOwnerId slot which causes newer unmounts to wipe configs
still needed by other mounted useAsset() hooks; change the implementation to
maintain a per-owner map (e.g., optionsByOwner: Map<string,
UseAssetOptions<Asset>>) and update setOptions(ownerId, options) to store into
that map and set installedOptions/optionsOwnerId to that owner's value; change
clearOptions(ownerId) to remove only that owner's entry and, if the removed
owner was the active optionsOwnerId, select and restore another still-mounted
owner's options (e.g., most-recently-set or remaining map entry) into
installedOptions/optionsOwnerId so remaining hooks keep their
getAssetId/resolveSource/error handlers; update any other places referencing
installedOptions/optionsOwnerId (including preloadNext, loadAsset, and any logic
around retryCount/previousError) to read from the per-owner map or
installedOptions as restored.

In `@apps/www/registry/default/hooks/use-playback-source.ts`:
- Around line 50-60: loadedSourceKeyRef persists across player teardown so when
the player instance is recreated (via usePlayerStore -> player) the unchanged
resolvedSourceKey can short-circuit loadPlaylist; detect player changes and
reset loadedSourceKeyRef.current to null when a new player instance appears (for
example inside the effect that depends on player or where you initialize
resolveSource/loadPlaylist) so that loadPlaylist is allowed to run for the new
player; refer to loadedSourceKeyRef, player (from usePlayerStore),
resolvedSourceKey and loadPlaylist to locate where to add the reset.

In `@apps/www/registry/pro`:
- Line 1: The submodule update for apps/www/registry/pro removed TypeScript
sources required by the registry-dev flow; verify that the checked-out commit
53d1af0f... actually contains the expected .ts/.tsx files and if it does not,
either update the submodule to a commit that includes those sources or modify
the consumer in apps/www/scripts/registry-dev.mts to handle the new tree (remove
or adapt the code that assumes recursive .ts/.tsx files). Locate references to
the registry submodule usage in apps/www/scripts/registry-dev.mts (the code that
previously iterated/checked for .ts/.tsx under apps/www/registry/pro) and update
it to either read the new file layout or fail fast with a clear error message so
downstream flows aren't broken.

---

Outside diff comments:
In `@apps/www/content/docs/hooks/use-asset.mdx`:
- Around line 63-113: The doc is missing the required hook-structure sections;
add a "Store" section (with a State table), an "Actions" section (with an
Actions table), and an "Events" section (with an Events table) into the content
flow after the Options/Returns block (where lines 63–113 are). Use the
AutoTypeTable component to reference the hook types from
./registry/default/hooks/use-asset.ts (for example AutoTypeTable
path="./registry/default/hooks/use-asset.ts" name="UseAssetStore",
name="UseAssetActions", and name="UseAssetEvents" or the actual exported type
names in that file), and ensure each section has the required heading and table
so the page conforms to the project's hook documentation structure.

In `@apps/www/registry/default/hooks/use-asset.ts`:
- Around line 453-497: preloadAsset can publish stale shaka.media.PreloadManager
instances because a new AbortController is created but previous controllers
aren't aborted and there are no generation/abort guards after awaits; fix by:
when starting a preload (in the preloadAsset flow that uses preloadDefault,
resolveSourceValue, etc.) acquire or increment a per-asset generation/token or
store the new AbortController in the preloadManagers map keyed by the normalized
asset, abort the previous controller (if any) before starting, capture the
current generation/token and localAbortController, pass
localAbortController.signal into resolveSourceValue/preloadDefault, and after
every await check that the stored controller/generation in preloadManagers still
matches the local one before writing back manager; reference symbols:
preloadDefault, abortController, preloadManagers, resolveSourceValue (and the
enclosing preloadAsset flow) to implement these guards and cancellation.
🪄 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: 7d589ede-72fe-46bd-b116-e6584d854876

📥 Commits

Reviewing files that changed from the base of the PR and between 3594e6a and 554a0c5.

⛔ Files ignored due to path filters (4)
  • apps/www/next-env.d.ts is excluded by none and included by none
  • apps/www/scripts/test-registry-install.ts 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
📒 Files selected for processing (69)
  • apps/www/app/(home)/page.tsx
  • apps/www/components/blocks/block-showcase.tsx
  • apps/www/components/blocks/info-pane.tsx
  • apps/www/components/blocks/preview-pane.tsx
  • apps/www/components/hero-buttons.tsx
  • apps/www/components/mdx-components.tsx
  • apps/www/components/players/audio-player/demo-player.tsx
  • apps/www/components/players/audio-player/demo.ts
  • apps/www/components/players/audio-player/hover-player.tsx
  • apps/www/components/players/video-player/demo-assets.ts
  • apps/www/components/players/video-player/player-container.tsx
  • apps/www/content/docs/blocks/audio-player.mdx
  • apps/www/content/docs/blocks/linear-player.mdx
  • apps/www/content/docs/blocks/video-player.mdx
  • apps/www/content/docs/blocks/youtube-music.mdx
  • apps/www/content/docs/hooks/meta.json
  • apps/www/content/docs/hooks/use-asset.mdx
  • apps/www/content/docs/hooks/use-playback-source.mdx
  • apps/www/content/docs/quick-start.mdx
  • apps/www/registry/collection/registry-blocks.ts
  • apps/www/registry/collection/registry-hooks.ts
  • apps/www/registry/default/blocks/audio-player/audio-player.module.css
  • apps/www/registry/default/blocks/audio-player/components/action-controls.tsx
  • apps/www/registry/default/blocks/audio-player/components/audio-source.tsx
  • apps/www/registry/default/blocks/audio-player/components/button.tsx
  • apps/www/registry/default/blocks/audio-player/components/controls.tsx
  • apps/www/registry/default/blocks/audio-player/components/fixed-timeline-control.tsx
  • apps/www/registry/default/blocks/audio-player/components/icons.tsx
  • apps/www/registry/default/blocks/audio-player/components/media-player.tsx
  • apps/www/registry/default/blocks/audio-player/components/playback-controls.tsx
  • apps/www/registry/default/blocks/audio-player/components/playback-mode-controls.tsx
  • apps/www/registry/default/blocks/audio-player/components/playlist.tsx
  • apps/www/registry/default/blocks/audio-player/components/track-info.tsx
  • apps/www/registry/default/blocks/audio-player/components/volume-group-control.tsx
  • apps/www/registry/default/blocks/audio-player/hooks/use-playlist-asset.ts
  • apps/www/registry/default/blocks/audio-player/lib/media-kit.ts
  • apps/www/registry/default/blocks/basic-player/components/media-element.tsx
  • apps/www/registry/default/blocks/basic-player/components/media-player.tsx
  • apps/www/registry/default/blocks/basic-player/components/playback-state-control.tsx
  • apps/www/registry/default/blocks/basic-player/lib/media-kit.ts
  • apps/www/registry/default/blocks/basic-player/page.tsx
  • apps/www/registry/default/blocks/linear-player/components/media-player.tsx
  • apps/www/registry/default/blocks/linear-player/page.tsx
  • apps/www/registry/default/blocks/video-player/components/bottom-controls.tsx
  • apps/www/registry/default/blocks/video-player/components/button.tsx
  • apps/www/registry/default/blocks/video-player/components/captions-state-control.tsx
  • apps/www/registry/default/blocks/video-player/components/media-player.tsx
  • apps/www/registry/default/blocks/video-player/components/pip-control.tsx
  • apps/www/registry/default/blocks/video-player/components/playback-rate-control.tsx
  • apps/www/registry/default/blocks/video-player/components/playback-state-control.tsx
  • apps/www/registry/default/blocks/video-player/components/playlist.tsx
  • apps/www/registry/default/blocks/video-player/components/timeline-slider-control.tsx
  • apps/www/registry/default/blocks/video-player/components/volume-group-control.tsx
  • apps/www/registry/default/blocks/video-player/components/volume-slider-control.tsx
  • apps/www/registry/default/blocks/video-player/components/volume-state-control.tsx
  • apps/www/registry/default/blocks/video-player/lib/media-kit.ts
  • apps/www/registry/default/blocks/video-player/page.tsx
  • apps/www/registry/default/blocks/video-player/ui/toggle.tsx
  • apps/www/registry/default/examples/picture-in-picture-control-demo.tsx
  • apps/www/registry/default/hooks/use-asset.ts
  • apps/www/registry/default/hooks/use-media.ts
  • apps/www/registry/default/hooks/use-playback-source.ts
  • apps/www/registry/default/hooks/use-player.ts
  • apps/www/registry/default/hooks/use-playlist.ts
  • apps/www/registry/default/ui/limeplay-logo.tsx
  • apps/www/registry/default/ui/media-provider.tsx
  • apps/www/registry/default/ui/media.tsx
  • apps/www/registry/pro
  • prompts/ide.md
💤 Files with no reviewable changes (9)
  • apps/www/registry/default/blocks/basic-player/components/playback-state-control.tsx
  • apps/www/content/docs/blocks/youtube-music.mdx
  • apps/www/content/docs/blocks/linear-player.mdx
  • apps/www/registry/default/blocks/basic-player/page.tsx
  • apps/www/registry/default/blocks/linear-player/page.tsx
  • apps/www/registry/default/blocks/basic-player/components/media-player.tsx
  • apps/www/registry/default/blocks/basic-player/components/media-element.tsx
  • apps/www/registry/default/blocks/basic-player/lib/media-kit.ts
  • apps/www/registry/default/blocks/linear-player/components/media-player.tsx

Comment thread apps/www/components/players/audio-player/demo-player.tsx Outdated
Comment thread apps/www/content/docs/blocks/audio-player.mdx
Comment thread apps/www/content/docs/blocks/video-player.mdx
Comment thread apps/www/content/docs/hooks/use-playback-source.mdx
Comment thread apps/www/registry/default/blocks/video-player/components/playlist.tsx Outdated
Comment thread apps/www/registry/default/hooks/use-asset.ts
Comment thread apps/www/registry/default/hooks/use-playback-source.ts
Comment thread apps/www/registry/pro
@@ -1 +1 @@
Subproject commit 7c47ec191091bcaa5a02df8f2eab484f0f85e1c6
Subproject commit 53d1af0f2fe113749cda35ca9133ae0ee5e68f8e
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

old_sha="7c47ec191091bcaa5a02df8f2eab484f0f85e1c6"
new_sha="53d1af0f2fe113749cda35ca9133ae0ee5e68f8e"

echo "Current gitlink:"
git ls-tree HEAD apps/www/registry/pro

submodule_key="$(
  git config -f .gitmodules --get-regexp '^submodule\..*\.path$' \
    | awk '$2=="apps/www/registry/pro" { print $1 }' \
    | sed 's/\.path$//'
)"

if [ -z "${submodule_key:-}" ]; then
  echo "Could not find apps/www/registry/pro in .gitmodules" >&2
  exit 1
fi

submodule_url="$(git config -f .gitmodules --get "${submodule_key}.url")"
owner_repo="$(printf '%s' "$submodule_url" | sed -E 's#(git@github.com:|https://github.com/)##; s#\.git$##')"

echo
echo "Submodule metadata:"
printf '  key: %s\n  url: %s\n' "$submodule_key" "$submodule_url"

echo
echo "Verify both revisions exist in the remote:"
git ls-remote "$submodule_url" "$old_sha" "$new_sha"

echo
echo "Changed files between the two submodule revisions:"
curl -fsSL "https://api.github.com/repos/${owner_repo}/compare/${old_sha}...${new_sha}" \
  | jq -r '.files[]?.filename'

echo
echo "Count TS/TSX files in the new submodule tree:"
curl -fsSL "https://api.github.com/repos/${owner_repo}/git/trees/${new_sha}?recursive=1" \
  | jq -r '[.tree[]? | select(.type == "blob" and (.path | endswith(".ts") or endswith(".tsx")))] | length'

Repository: WINOFFRG/limeplay

Length of output: 484


🏁 Script executed:

#!/bin/bash
set -euo pipefail

old_sha="7c47ec191091bcaa5a02df8f2eab484f0f85e1c6"
new_sha="53d1af0f2fe113749cda35ca9133ae0ee5e68f8e"

submodule_url="$(git config -f .gitmodules --get 'submodule.apps/www/registry/pro.url')"
owner_repo="$(printf '%s' "$submodule_url" | sed -E 's#(git@github.com:|https://github.com/)##; s#\.git$##')"

echo "Submodule URL: $submodule_url"
echo "owner/repo: $owner_repo"

echo
echo "Changed files between the two submodule revisions:"
curl -fsSL "https://api.github.com/repos/${owner_repo}/compare/${old_sha}...${new_sha}" \
  | jq -r '.files[]?.filename'

echo
echo "Count TS/TSX files in the new submodule tree:"
count="$(curl -fsSL "https://api.github.com/repos/${owner_repo}/git/trees/${new_sha}?recursive=1" \
  | jq -r '[.tree[]? | select(.type == "blob" and (.path | endswith(".ts") or endswith(".tsx")))] | length')"

echo "TS/TSX blob count: $count"
if [ "$count" -le 0 ]; then
  echo "Expected > 0 TS/TSX blobs to satisfy `apps/www/scripts/registry-dev.mts`." >&2
  exit 1
fi

Repository: WINOFFRG/limeplay

Length of output: 271


🏁 Script executed:

#!/bin/bash
set -euo pipefail

new_sha="53d1af0f2fe113749cda35ca9133ae0ee5e68f8e"

echo "Submodule status:"
git submodule status || true

echo
echo "Is the submodule directory present in the working tree?"
if [ -d "apps/www/registry/pro" ]; then
  echo "YES"
  echo "Count .ts/.tsx files in current submodule checkout:"
  find apps/www/registry/pro -type f \( -name '*.ts' -o -name '*.tsx' \) | wc -l

  echo
  if [ -d "apps/www/registry/pro/.git" ] || [ -d ".git/modules/apps/www/registry/pro" ]; then
    echo "Current submodule HEAD:"
    (cd apps/www/registry/pro && git rev-parse HEAD) || true
  else
    echo "Submodule git metadata not present; cannot confirm local HEAD."
  fi
else
  echo "NO (submodule not checked out locally)."
fi

Repository: WINOFFRG/limeplay

Length of output: 322


Submodule bump likely breaks registry/pro TypeScript contract (Line 1)

apps/www/registry/pro is bumped to 53d1af0f2fe113749cda35ca9133ae0ee5e68f8e, but the checked-out apps/www/registry/pro directory contains 0 *.ts/*.tsx files (recursive). If apps/www/scripts/registry-dev.mts:311-323 expects those files, this change will break the downstream registry-dev flow—please confirm the new submodule tree still includes the expected TypeScript sources (or adjust the consumer).

🤖 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/pro` at line 1, The submodule update for
apps/www/registry/pro removed TypeScript sources required by the registry-dev
flow; verify that the checked-out commit 53d1af0f... actually contains the
expected .ts/.tsx files and if it does not, either update the submodule to a
commit that includes those sources or modify the consumer in
apps/www/scripts/registry-dev.mts to handle the new tree (remove or adapt the
code that assumes recursive .ts/.tsx files). Locate references to the registry
submodule usage in apps/www/scripts/registry-dev.mts (the code that previously
iterated/checked for .ts/.tsx under apps/www/registry/pro) and update it to
either read the new file layout or fail fast with a clear error message so
downstream flows aren't broken.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
apps/www/registry/default/blocks/audio-player/components/playlist.tsx (2)

24-26: ⚖️ Poor tradeoff

Use granular store selectors instead of the whole-slice useAsset() destructure.

Destructuring currentItem, orderedItems, and skipToId from useAsset() subscribes this dropdown to the entire asset/playlist slice, so unrelated mutations rerender it. The sibling video-player/components/playlist.tsx already reads these via usePlaylistStore(s => s.field). Mirror that here (isPreloaded can be derived from usePlayerStore(s => s.preloadManagers)).

As per coding guidelines: "Always use granular per-feature selectors like useXxxStore(s => s.field) for state access—never access entire slices".

🤖 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/blocks/audio-player/components/playlist.tsx` around
lines 24 - 26, The component currently destructures currentItem, isPreloaded,
orderedItems, and skipToId from useAsset(), which subscribes this dropdown to
the entire asset slice; replace those with granular selectors: read currentItem,
orderedItems, and skipToId via usePlaylistStore(s => s.currentItem),
usePlaylistStore(s => s.orderedItems), and usePlaylistStore(s => s.skipToId)
respectively, and derive isPreloaded from usePlayerStore(s => s.preloadManagers)
(or the specific preload flag for this audio asset); keep useAudioSource() for
items. Ensure you remove the useAsset() destructure and import/use the
usePlaylistStore and usePlayerStore selectors so only the needed fields trigger
rerenders.

106-141: 💤 Low value

TrackRow ignores index and preloaded.

preloaded={isPreloaded(id)} is computed for every row but TrackRow never reads preloaded (or index), so it's wasted work and no preload state is surfaced — the video-player sibling renders a preloaded indicator. Either drop both props or wire preloaded into the UI.

Want me to add a preloaded indicator to TrackRow, or strip the unused props?

🤖 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/blocks/audio-player/components/playlist.tsx` around
lines 106 - 141, TrackRow currently ignores the passed index and preloaded
props; update TrackRow (the function/component named TrackRow) to accept and use
preloaded and index: use preloaded to render a small preloaded indicator (e.g.,
an icon or text badge next to the track title) so the
preloaded={isPreloaded(id)} work isn't wasted, and use index to set
aria-posinset/aria-setsize or a visible track number to improve accessibility
and UX; remove neither prop from the call site (the map that renders TrackRow)
so isPreloaded(id) remains useful and ensure the TrackRow prop types include
preloaded: boolean and index: number.
🤖 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.

Nitpick comments:
In `@apps/www/registry/default/blocks/audio-player/components/playlist.tsx`:
- Around line 24-26: The component currently destructures currentItem,
isPreloaded, orderedItems, and skipToId from useAsset(), which subscribes this
dropdown to the entire asset slice; replace those with granular selectors: read
currentItem, orderedItems, and skipToId via usePlaylistStore(s =>
s.currentItem), usePlaylistStore(s => s.orderedItems), and usePlaylistStore(s =>
s.skipToId) respectively, and derive isPreloaded from usePlayerStore(s =>
s.preloadManagers) (or the specific preload flag for this audio asset); keep
useAudioSource() for items. Ensure you remove the useAsset() destructure and
import/use the usePlaylistStore and usePlayerStore selectors so only the needed
fields trigger rerenders.
- Around line 106-141: TrackRow currently ignores the passed index and preloaded
props; update TrackRow (the function/component named TrackRow) to accept and use
preloaded and index: use preloaded to render a small preloaded indicator (e.g.,
an icon or text badge next to the track title) so the
preloaded={isPreloaded(id)} work isn't wasted, and use index to set
aria-posinset/aria-setsize or a visible track number to improve accessibility
and UX; remove neither prop from the call site (the map that renders TrackRow)
so isPreloaded(id) remains useful and ensure the TrackRow prop types include
preloaded: boolean and index: number.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 813a3f44-7d6f-44c1-adb5-0375f06cc2ee

📥 Commits

Reviewing files that changed from the base of the PR and between 554a0c5 and 5436ea9.

📒 Files selected for processing (17)
  • apps/www/components/players/audio-player/demo-player.tsx
  • apps/www/content/docs/blocks/audio-player.mdx
  • apps/www/content/docs/blocks/video-player.mdx
  • apps/www/content/docs/hooks/use-asset.mdx
  • apps/www/content/docs/hooks/use-playback-source.mdx
  • apps/www/registry/default/blocks/audio-player/components/audio-source.tsx
  • apps/www/registry/default/blocks/audio-player/components/button.tsx
  • apps/www/registry/default/blocks/audio-player/components/media-player.tsx
  • apps/www/registry/default/blocks/audio-player/components/playback-controls.tsx
  • apps/www/registry/default/blocks/audio-player/components/playlist.tsx
  • apps/www/registry/default/blocks/audio-player/components/track-info.tsx
  • apps/www/registry/default/blocks/audio-player/components/volume-group-control.tsx
  • apps/www/registry/default/blocks/audio-player/hooks/use-playlist-asset.ts
  • apps/www/registry/default/blocks/video-player/components/media-player.tsx
  • apps/www/registry/default/blocks/video-player/components/playlist.tsx
  • apps/www/registry/default/hooks/use-asset.ts
  • apps/www/registry/default/hooks/use-playback-source.ts
💤 Files with no reviewable changes (2)
  • apps/www/registry/default/blocks/audio-player/hooks/use-playlist-asset.ts
  • apps/www/registry/default/blocks/video-player/components/media-player.tsx
✅ Files skipped from review due to trivial changes (4)
  • apps/www/content/docs/blocks/audio-player.mdx
  • apps/www/content/docs/hooks/use-asset.mdx
  • apps/www/content/docs/hooks/use-playback-source.mdx
  • apps/www/content/docs/blocks/video-player.mdx
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/www/registry/default/blocks/audio-player/components/volume-group-control.tsx
  • apps/www/registry/default/blocks/audio-player/components/media-player.tsx
  • apps/www/components/players/audio-player/demo-player.tsx
  • apps/www/registry/default/blocks/audio-player/components/button.tsx
  • apps/www/registry/default/blocks/audio-player/components/playback-controls.tsx

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.

2 participants