Skip to content

Conversation

@saseungmin
Copy link
Member

@saseungmin saseungmin commented Jul 15, 2025

  • Extend YouTubeSource type to accept undefined values
  • Add defensive logic for undefined source handling
  • Enable async video ID loading patterns
  • Maintain backward compatibility with existing usage

Summary by CodeRabbit

  • New Features

    • Added support for optional and dynamically loaded YouTube sources, allowing video IDs to be undefined initially for asynchronous loading patterns.
  • Bug Fixes

    • Improved error handling and validation to prevent runtime errors when video IDs or URLs are missing or invalid.
    • Enhanced player and hook logic to safely handle cases where YouTube source or video ID is undefined or null.
  • Refactor

    • Centralized and memoized logic for constructing WebView sources, improving maintainability and clarity.
    • Updated error messaging and styling for invalid YouTube IDs in player components.

- Extend YouTubeSource type to accept undefined values
- Add defensive logic for undefined source handling
- Enable async video ID loading patterns
- Maintain backward compatibility with existing usage
@changeset-bot
Copy link

changeset-bot bot commented Jul 15, 2025

🦋 Changeset detected

Latest commit: 1b6d919

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
react-native-youtube-bridge Minor
@react-native-youtube-bridge/react Minor
@react-native-youtube-bridge/core Minor
@react-native-youtube-bridge/web Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Jul 15, 2025

Walkthrough

This update expands the flexibility of YouTube video source handling across several packages. The type definitions and related logic now support undefined and null values for video IDs and sources, enabling asynchronous loading patterns. Defensive checks and early returns are added throughout to prevent errors when sources are not yet available or invalid.

Changes

File(s) Change Summary
packages/core/src/types/index.ts Expanded YouTubeSource type to accept undefined and optional videoId/url.
packages/core/src/utils.ts validateVideoId now accepts `string
packages/react-native-youtube-bridge/src/modules/YoutubePlayer.ts YoutubePlayer class and methods now accept and return nullable/undefined videoId.
packages/react-native-youtube-bridge/src/hooks/useCreateLocalPlayerHtml.ts videoId parameter accepts `string
packages/react-native-youtube-bridge/src/utils/youtube.ts getYoutubeWebViewUrl now accepts nullable/undefined videoId and may return undefined.
packages/react-native-youtube-bridge/src/YoutubeView.tsx Refactored and memoized WebView source prop construction; internal logic only.
packages/react-native-youtube-bridge/src/YoutubeView.web.tsx Added guard to skip player setup if video ID is falsy.
packages/react/src/hooks/useYoutubeOEmbed.ts url parameter is now optional; skips fetch if url is falsy.
packages/react/src/hooks/useYoutubeVideoId.ts Return type now `string
packages/web/src/YoutubePlayer.tsx Added guard to skip player setup if youtubeVideoId is falsy.
.changeset/eight-wolves-swim.md Changeset summary describing the above updates.

Sequence Diagram(s)

sequenceDiagram
    participant ReactComponent
    participant useYouTubePlayer
    participant useYouTubeVideoId
    participant YoutubePlayer
    participant WebView/DOM

    ReactComponent->>useYouTubePlayer: Passes source (may be undefined)
    useYouTubePlayer->>useYouTubeVideoId: Extracts videoId (returns string/null/undefined)
    useYouTubeVideoId->>useYouTubePlayer: Returns videoId or undefined
    useYouTubePlayer->>YoutubePlayer: Initializes with videoId (may be undefined)
    alt videoId is defined
        YoutubePlayer->>WebView/DOM: Sets up player with videoId
    else videoId is undefined/null
        YoutubePlayer-->>WebView/DOM: Skips setup, waits for valid videoId
    end
Loading

Possibly related PRs

Poem

A rabbit hopped by the YouTube stream,
Now sources can wait, or load in a dream.
Undefined, null, or a string in the air—
The player is patient, it simply won’t care.
With types more forgiving and guards all around,
Async video loading is safe and sound!
🐇📺✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 66610c1 and 1b6d919.

📒 Files selected for processing (1)
  • packages/react-native-youtube-bridge/src/YoutubeView.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/react-native-youtube-bridge/src/YoutubeView.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jul 15, 2025

Deploying react-native-youtube-bridge-example with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1b6d919
Status: ✅  Deploy successful!
Preview URL: https://fba8a209.react-native-youtube-bridge-example.pages.dev
Branch Preview URL: https://feat-optional-youtube-source.react-native-youtube-bridge-example.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link

Deploying react-native-youtube-bridge with  Cloudflare Pages  Cloudflare Pages

Latest commit: 66610c1
Status: ✅  Deploy successful!
Preview URL: https://c1cbebb6.react-native-youtube-bridge.pages.dev
Branch Preview URL: https://feat-optional-youtube-source.react-native-youtube-bridge.pages.dev

View logs

Copy link

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

🧹 Nitpick comments (2)
packages/react-native-youtube-bridge/src/YoutubeView.tsx (1)

39-39: Address the exhaustive dependencies warning.

The biome-ignore comment lacks a proper explanation. Consider either adding the missing dependencies to the dependency array or providing a clear explanation of why they should be omitted.

-  // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
+  // biome-ignore lint/correctness/useExhaustiveDependencies: webViewProps.source is intentionally excluded to prevent unnecessary re-renders
packages/react/src/hooks/useYoutubeVideoId.ts (1)

31-37: Consider simplifying with optional chaining.

The dependency array logic correctly implements safe property access, but could be more concise using optional chaining.

-    typeof source === 'string'
-      ? source
-      : source && 'videoId' in source
-        ? source.videoId
-        : source && 'url' in source
-          ? source.url
-          : null,
+    typeof source === 'string'
+      ? source
+      : source?.videoId || source?.url || null,
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 323c409 and 66610c1.

📒 Files selected for processing (11)
  • .changeset/eight-wolves-swim.md (1 hunks)
  • packages/core/src/types/index.ts (1 hunks)
  • packages/core/src/utils.ts (1 hunks)
  • packages/react-native-youtube-bridge/src/YoutubeView.tsx (2 hunks)
  • packages/react-native-youtube-bridge/src/YoutubeView.web.tsx (1 hunks)
  • packages/react-native-youtube-bridge/src/hooks/useCreateLocalPlayerHtml.ts (1 hunks)
  • packages/react-native-youtube-bridge/src/modules/YoutubePlayer.ts (1 hunks)
  • packages/react-native-youtube-bridge/src/utils/youtube.ts (1 hunks)
  • packages/react/src/hooks/useYoutubeOEmbed.ts (2 hunks)
  • packages/react/src/hooks/useYoutubeVideoId.ts (3 hunks)
  • packages/web/src/YoutubePlayer.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/react-native-youtube-bridge/src/utils/youtube.ts (1)
packages/core/src/types/index.ts (1)
  • YoutubePlayerVars (100-146)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Cloudflare Pages: react-native-youtube-bridge
🔇 Additional comments (24)
packages/web/src/YoutubePlayer.tsx (1)

46-46: LGTM! Defensive check prevents initialization with falsy video IDs.

The addition of !youtubeVideoId to the conditional check correctly prevents player initialization when no valid video ID is available, supporting the asynchronous loading pattern while maintaining backward compatibility.

packages/react-native-youtube-bridge/src/YoutubeView.web.tsx (1)

30-32: LGTM! Early return prevents player setup without valid video ID.

The defensive check correctly prevents further player initialization when no valid video ID is available, aligning with the asynchronous loading pattern support.

packages/react-native-youtube-bridge/src/utils/youtube.ts (2)

5-5: LGTM! Parameter type expanded to support nullable video IDs.

The parameter type change correctly supports the asynchronous loading pattern by accepting null and undefined values.


11-11: Verified: undefined return handled by downstream consumer

I checked all usages of getYoutubeWebViewUrl and found a single consumer in packages/react-native-youtube-bridge/src/YoutubeView.tsx (around line 37). The code wraps its result in a truthy check:

  • If useInlineHtml is true, it always returns an inline HTML source.
  • Otherwise, it only constructs { uri: webViewUrl } when webViewUrl is truthy (if (webViewUrl)).

Since undefined is falsy, the branch guards ensure we never pass an invalid URI to <WebView>. No further handling is required.

packages/core/src/utils.ts (3)

13-13: LGTM! Parameter type expanded to include null.

The type expansion correctly supports the broader pattern of accepting nullable video IDs throughout the codebase.


14-16: LGTM! Explicit falsy check improves readability.

The explicit falsy check makes the logic clearer and ensures proper handling of null/undefined values before proceeding with regex validation.


19-19: LGTM! Nullish coalescing removal is correct.

Removing the nullish coalescing operator is appropriate since the earlier falsy check guarantees that videoId is a defined string at this point.

packages/react/src/hooks/useYoutubeOEmbed.ts (3)

24-24: LGTM! Parameter made optional to support async loading.

Making the url parameter optional correctly supports the asynchronous loading pattern where the URL may initially be undefined.


30-32: LGTM! Early return prevents unnecessary fetch attempts.

The defensive check correctly prevents the fetch operation from running when no valid URL is provided, avoiding potential errors and unnecessary network requests.


68-68: LGTM! Redundant conditional check removed.

The unconditional call to fetchOEmbed() is now safe since the early return guard ensures this code only runs with valid URLs.

packages/react-native-youtube-bridge/src/hooks/useCreateLocalPlayerHtml.ts (3)

18-18: Type expansion correctly supports optional video IDs.

The parameter type update to string | null | undefined aligns with the PR objective to support optional YouTube sources for dynamic loading.


20-22: Defensive check prevents unnecessary HTML generation.

Good defensive programming - returning early when videoId is undefined prevents unnecessary HTML generation and aligns with the new optional source support.


25-25: Enhanced error message with improved styling.

The error message update includes inline CSS for better visual presentation (centered, white text) and clearer messaging ("Invalid YouTube ID" instead of "Invalid video ID").

packages/core/src/types/index.ts (1)

6-6: Type expansion enables flexible async loading patterns.

The YouTubeSource type expansion to include undefined values at multiple levels (entire source, videoId, and url properties) correctly supports the PR's goal of enabling asynchronous video ID loading while maintaining backward compatibility with existing string and object sources.

packages/react-native-youtube-bridge/src/modules/YoutubePlayer.ts (3)

23-23: Property type updated for nullable video ID support.

The videoId property type change to string | null | undefined aligns with the expanded YouTubeSource type and enables the class to handle optional video IDs.


26-29: Constructor properly accepts optional video IDs.

The constructor parameter type update maintains consistency with the property type and enables instantiation with undefined video IDs for async loading scenarios.


31-33: Getter method signature updated for consistency.

The getVideoId() method return type update to string | null | undefined maintains API consistency with the internal property type and constructor parameter.

packages/react-native-youtube-bridge/src/YoutubeView.tsx (2)

40-50: Refactored source construction improves maintainability.

The refactor centralizes the WebView source construction logic into a memoized value, making it more maintainable and eliminating the previous inline conditional expression. The logic properly handles both inline HTML and external URL cases with appropriate fallback to undefined.


162-162: Direct usage of memoized source value.

Using the webViewSource directly simplifies the JSX and leverages the centralized memoization logic.

.changeset/eight-wolves-swim.md (1)

1-22: Changeset accurately documents the feature addition.

The changeset properly documents the new optional YouTube source support across all affected packages. The feature description is clear and the usage example effectively demonstrates the new async loading patterns enabled by the type system updates.

packages/react/src/hooks/useYoutubeVideoId.ts (4)

10-10: LGTM: Function signature correctly implements tri-state return type.

The updated return type string | null | undefined properly supports the new dynamic loading pattern while maintaining type safety.


13-16: LGTM: Defensive early return for optional source.

The early return for falsy source values correctly handles the dynamic loading scenario where source may initially be undefined, preventing unnecessary processing.


41-52: LGTM: Explicit tri-state logic implementation.

The explicit handling of null vs undefined states is well-implemented:

  • null: Invalid source triggers error callback
  • undefined: Missing source returns undefined (no error)
  • Valid string: Proceeds with validation

This design properly supports asynchronous loading patterns.


47-47: LGTM: Consistent error return values.

Returning null instead of empty string for error cases maintains consistency with the tri-state design and provides clearer error signaling.

Also applies to: 66-66

@saseungmin saseungmin merged commit 601dbe0 into main Jul 15, 2025
5 checks passed
@saseungmin saseungmin deleted the feat/optional-youtube-source branch July 15, 2025 09:56
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