Skip to content

Comments

feat: support custom url in video embed block#222

Open
LucasXu0 wants to merge 5 commits intomainfrom
feat/support_custom_video_url
Open

feat: support custom url in video embed block#222
LucasXu0 wants to merge 5 commits intomainfrom
feat/support_custom_video_url

Conversation

@LucasXu0
Copy link
Contributor

@LucasXu0 LucasXu0 commented Jan 27, 2026

Description

Screenshot 2026-01-27 at 10 18 16

Checklist

General

  • I've included relevant documentation or comments for the changes introduced.
  • I've tested the changes in multiple environments (e.g., different browsers, operating systems).

Testing

  • I've added or updated tests to validate the changes introduced for AppFlowy Web.

Feature-Specific

  • For feature additions, I've added a preview (video, screenshot, or demo) in the "Feature Preview" section.
  • I've verified that this feature integrates seamlessly with existing functionality.

Summary by Sourcery

Support embedding and pasting a broader range of video URLs while improving validation and error feedback for video blocks.

New Features:

  • Allow custom video URLs using ReactPlayer's supported sources instead of a fixed host whitelist.
  • Validate video embed URLs when inserting via the video block popover.

Enhancements:

  • Add centralized video URL utilities for validation and context-aware error messages.
  • Enable player controls and provide more specific error messages when video loading fails.

@sourcery-ai
Copy link

sourcery-ai bot commented Jan 27, 2026

Reviewer's Guide

Implements generalized video URL support by centralizing video URL validation and error messaging, updating the video embed flow to use ReactPlayer’s capabilities, and improving the user-facing error handling for failed video loads.

Sequence diagram for video URL paste and embed insertion

sequenceDiagram
  actor User
  participant BrowserEditor
  participant withPasted
  participant VideoUrlUtils
  participant ReactPlayer
  participant Document

  User->>BrowserEditor: Paste URL
  BrowserEditor->>withPasted: handleURLPaste(editor, url)
  withPasted->>VideoUrlUtils: isValidVideoUrl(url)
  VideoUrlUtils->>UrlUtils: processUrl(url)
  UrlUtils-->>VideoUrlUtils: processedUrl
  alt processedUrl is http or https
    VideoUrlUtils->>ReactPlayer: canPlay(processedUrl)
    ReactPlayer-->>VideoUrlUtils: canPlayResult
  else invalid protocol or no processedUrl
    VideoUrlUtils-->>withPasted: false
  end
  VideoUrlUtils-->>withPasted: isVideoUrl
  alt isVideoUrl is true
    withPasted->>Document: insertBlock(type Video, url)
  else isVideoUrl is false
    withPasted-->>BrowserEditor: false (not handled)
  end
Loading

Class diagram for updated video embed utilities and components

classDiagram
  class VideoRender {
    +VideoBlockNode node
    +Function onError
    +ReactPlayer player
    +playerProps
    +onDragStart()
  }

  class VideoBlockPopoverContent {
    +string blockId
    +Function onClose
    +handleInsertEmbedLink(url)
  }

  class withPasted {
    +handleURLPaste(editor, url) boolean
  }

  class VideoUrlUtils {
    +isValidVideoUrl(url) boolean
    +getVideoErrorMessage(url) string
  }

  class ReactPlayer {
    +canPlay(url) boolean
  }

  class UrlUtils {
    +processUrl(url) string
  }

  VideoRender ..> ReactPlayer : uses
  VideoRender ..> VideoUrlUtils : getVideoErrorMessage

  VideoBlockPopoverContent ..> VideoUrlUtils : isValidVideoUrl

  withPasted ..> VideoUrlUtils : isValidVideoUrl

  VideoUrlUtils ..> ReactPlayer : canPlay
  VideoUrlUtils ..> UrlUtils : processUrl
Loading

File-Level Changes

Change Details Files
Add centralized utilities for validating video URLs and generating contextual error messages.
  • Introduce isValidVideoUrl that normalizes URLs, restricts to http/https, and delegates playability checks to ReactPlayer.canPlay
  • Add getVideoErrorMessage to return more specific error text based on URL patterns (Facebook, direct video files, or generic cases)
src/utils/video-url.ts
Update video block rendering to use enhanced error handling and player controls.
  • Extend ReactPlayer props to always show playback controls
  • Replace hardcoded error string with getVideoErrorMessage, deriving error messages from the current video URL on player error
src/components/editor/components/blocks/video/VideoRender.tsx
Wire new video URL validation into paste handling and the video block popover UI.
  • Replace host-whitelist-based URL detection with isValidVideoUrl in paste handler to allow a wider set of video sources
  • Pass isValidVideoUrl as the validator to the EmbedLink component so only supported video URLs are accepted in the UI
src/components/editor/plugins/withPasted.ts
src/components/editor/components/block-popover/VideoBlockPopoverContent.tsx

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The user-facing strings in getVideoErrorMessage are hard-coded English while the rest of the video UI appears to be localized; consider routing these through your i18n layer so error messages are consistent with the rest of the app.
  • getVideoErrorMessage currently inspects the raw url string (e.g., includes('facebook.com'), extension regex) while isValidVideoUrl first normalizes with processUrl; using the normalized URL for both validation and error classification would avoid edge cases where processed/validated URLs don’t match the error logic.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The user-facing strings in `getVideoErrorMessage` are hard-coded English while the rest of the video UI appears to be localized; consider routing these through your i18n layer so error messages are consistent with the rest of the app.
- `getVideoErrorMessage` currently inspects the raw `url` string (e.g., `includes('facebook.com')`, extension regex) while `isValidVideoUrl` first normalizes with `processUrl`; using the normalized URL for both validation and error classification would avoid edge cases where processed/validated URLs don’t match the error logic.

## Individual Comments

### Comment 1
<location> `src/utils/video-url.ts:25-32` </location>
<code_context>
+/**
+ * Enhanced error message for video loading failures
+ */
+export function getVideoErrorMessage(url: string): string {
+  if (url.includes('facebook.com')) {
+    return 'Facebook video couldn\'t be loaded. Check privacy settings.';
+  }
+  if (url.match(/\.(mp4|webm|mov|ogv)$/i)) {
+    return 'Video file couldn\'t be loaded. Check URL and CORS settings.';
+  }
+  return 'The video embed couldn\'t be loaded. Check URL and privacy settings.';
+}
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Error classification uses raw URLs while validation uses `processUrl`, which can lead to inconsistent behavior.

`isValidVideoUrl` normalizes via `processUrl`, but `getVideoErrorMessage` inspects the raw `url`. If `processUrl` alters the URL (e.g., protocol, case, domain), you can end up with URLs that validate successfully but don’t match the specific error checks (Facebook or file extensions). Please reuse `processUrl` (or equivalent normalization) in `getVideoErrorMessage` so error classification stays aligned with the validation logic.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@github-actions
Copy link

github-actions bot commented Jan 27, 2026

🥷 Ninja i18n – 🛎️ Translations need to be updated

Project /project.inlang

lint rule new reports level link
Missing translation 112 warning contribute (via Fink 🐦)

- Add type assertion for dynamic translation key in t() call
- Remove unnecessary React fragment wrapper
@LucasXu0 LucasXu0 force-pushed the feat/support_custom_video_url branch from 377a86e to 7f18620 Compare January 27, 2026 02:39
- Add eslint-disable-next-line for necessary any type in VideoEmpty.tsx
- Fix padding-line-between-statements errors by adding blank lines
- Ensure consistent code formatting across video-related files
@LucasXu0 LucasXu0 force-pushed the feat/support_custom_video_url branch from eae7c29 to 48df2f6 Compare January 27, 2026 04:53
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