Skip to content

Conversation

@mogita
Copy link
Contributor

@mogita mogita commented Aug 4, 2025

Changes:

  • Set video public by default and allow overriding with '.env'
  • A descriptive message and a more visually aligned style for private video on sharing and embedding pages
  • A toggle for setting the video public or private
  • Fixed space related functionalities on video sharing page (displaying available spaces, saving to selected spaces)
  • Fixed "Shared" and "Not shared" label to reflect sharing status

Test build: ghcr.io/mogita/cap-web:video-privacy.2

Summary by CodeRabbit

  • New Features

    • Added the ability to set videos as public or private, including a toggle in the sharing dialog for public sharing.
    • Videos can now be shared at the space level, not just with organizations.
    • Enhanced sharing dialog and UI to reflect public/private status and space-level sharing options.
    • New environment variable allows configuring whether new videos are public or private by default.
  • Improvements

    • Updated UI to clearly indicate sharing status, including public visibility.
    • Enhanced messaging and access checks for private videos, with improved prompts for owners to sign in and manage sharing.
    • Embed code now uses the correct environment-based URL.
  • Documentation

    • Updated example environment file to document the new privacy setting variable.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 6, 2025

Walkthrough

This change introduces public/private sharing controls for videos ("caps"), allowing users to toggle the public visibility of videos in addition to sharing with organizations and spaces. It updates backend data models, API actions, UI components, and environment variable handling to support and reflect the new public sharing state throughout the application.

Changes

Cohort / File(s) Change Summary
Backend: Video Public Field Support
apps/web/actions/video/upload.ts, apps/web/app/api/desktop/[...route]/video.ts, packages/env/server.ts, .env.example
Added support for a public boolean field on videos, controlled by a new CAP_VIDEOS_DEFAULT_PUBLIC environment variable. The field is included during video creation and documented in the environment example file.
Backend: Cap Sharing Action
apps/web/actions/caps/share.ts
Extended the cap sharing action to accept and update the public status of a video when sharing, modifying both the parameter interface and the function logic.
Data Fetching: Video Public Field
apps/web/app/(org)/dashboard/caps/page.tsx
Updated the main video data query to select and include the public field from the database.
Frontend Types and Props
apps/web/app/(org)/dashboard/caps/Caps.tsx, apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx
Extended the VideoData type and CapCardProps interface to include a public boolean, propagating the public status through UI components.
Frontend: Cap Card Content
apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardContent.tsx
Refactored the shared status rendering logic to account for the new public field, showing "Shared" if the video is public or shared with any space/org.
Frontend: Sharing Dialog
apps/web/app/(org)/dashboard/caps/components/SharingDialog.tsx
Enhanced the sharing dialog to include a toggle for public sharing, updated UI labels and logic, and improved embed URL handling.
Frontend: Share Page and Header
apps/web/app/s/[videoId]/page.tsx, apps/web/app/s/[videoId]/_components/ShareHeader.tsx
Added support for displaying and managing sharing at both the space and organization level, including the public field in access checks and sharing dialogs.
Frontend: Embed Page
apps/web/app/embed/[videoId]/page.tsx
Improved private video messaging and access checks, adding a sign-in prompt for owners and adjusting metadata logic to account for public/private status.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI (CapCard/SharingDialog)
    participant Backend (shareCap)
    participant DB

    User->>UI (CapCard/SharingDialog): Opens sharing dialog for a video
    UI->>User: Displays sharing options (spaces, orgs, public toggle)
    User->>UI: Updates sharing (selects spaces/orgs, toggles public)
    UI->>Backend (shareCap): Sends sharing update (spaces/orgs/public)
    Backend (shareCap)->>DB: Updates sharing associations and public field
    Backend (shareCap)-->>UI: Confirms sharing update
    UI->>User: Shows updated sharing status and notifications
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

A bunny hopped to share a cap,
Now toggles "public" with a tap!
Spaces, orgs, and privacy—
All in one, so easily.
With every field and UI tweak,
Sharing’s never been so sleek.
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

🪧 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.
  • 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.

Support

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

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 generate unit tests to generate unit tests for 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.

Copy link
Contributor

@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

♻️ Duplicate comments (1)
packages/database/schema.ts (1)

231-231: Consider implementing the configurable default as previously discussed.

Based on the past review comments, there was discussion about making the default privacy setting configurable via environment variables rather than hardcoding it to false. This would provide flexibility for different deployment scenarios while maintaining the privacy-first approach.

Consider implementing this as:

-    public: boolean("public").notNull().default(false),
+    public: boolean("public").notNull().default(process.env.DEFAULT_VIDEO_PUBLIC === 'true'),

This would allow teams to configure the default behavior while maintaining privacy-first as the safe default.

🧹 Nitpick comments (2)
apps/web/app/(org)/dashboard/caps/components/SharingDialog.tsx (1)

170-186: Review the space filtering logic for potential improvements.

The current filtering logic that separates organization entries from spaces based on space.id === space.organizationId && space.primary === true seems fragile and could be improved:

  1. Consider using a more explicit property to identify organization entries
  2. The nested conditions with extra parentheses on lines 172-173 and 176-177 could be simplified

Consider refactoring to use a more explicit approach:

-  const organizationEntries = spacesData?.filter((space) =>
-    space.id === space.organizationId && space.primary === true
-  ) || [];
-
-  const realSpaces = spacesData?.filter((space) =>
-    !(space.id === space.organizationId && space.primary === true)
-  ) || [];
+  const organizationEntries = spacesData?.filter((space) =>
+    space.primary === true
+  ) || [];
+
+  const realSpaces = spacesData?.filter((space) =>
+    space.primary !== true
+  ) || [];

Or better yet, add a discriminator property to the Spaces type to make this distinction clearer.

apps/web/app/s/[videoId]/page.tsx (1)

38-92: Consider refactoring the helper function for better maintainability.

The getSharedSpacesForVideo function works correctly but could be simplified and potentially moved to a shared utility file for reuse.

Simplify the array building logic:

-  const sharedSpaces: Array<{
-    id: string;
-    name: string;
-    organizationId: string;
-    iconUrl?: string;
-  }> = [];
-
-  // Add space-level sharing
-  spaceSharing.forEach(space => {
-    sharedSpaces.push({
-      id: space.id,
-      name: space.name,
-      organizationId: space.organizationId,
-      iconUrl: space.iconUrl || undefined,
-    });
-  });
-
-  // Add organization-level sharing
-  orgSharing.forEach(org => {
-    sharedSpaces.push({
-      id: org.id,
-      name: org.name,
-      organizationId: org.organizationId,
-      iconUrl: org.iconUrl || undefined,
-    });
-  });
-
-  return sharedSpaces;
+  return [
+    ...spaceSharing.map(space => ({
+      id: space.id,
+      name: space.name,
+      organizationId: space.organizationId,
+      iconUrl: space.iconUrl || undefined,
+    })),
+    ...orgSharing.map(org => ({
+      id: org.id,
+      name: org.name,
+      organizationId: org.organizationId,
+      iconUrl: org.iconUrl || undefined,
+    }))
+  ];

Also consider extracting this to a shared utilities file since it might be useful in other components.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 96570d9 and 4a24195.

📒 Files selected for processing (10)
  • apps/web/actions/caps/share.ts (2 hunks)
  • apps/web/app/(org)/dashboard/caps/Caps.tsx (1 hunks)
  • apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx (2 hunks)
  • apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardContent.tsx (1 hunks)
  • apps/web/app/(org)/dashboard/caps/components/SharingDialog.tsx (12 hunks)
  • apps/web/app/(org)/dashboard/caps/page.tsx (1 hunks)
  • apps/web/app/embed/[videoId]/page.tsx (3 hunks)
  • apps/web/app/s/[videoId]/_components/ShareHeader.tsx (5 hunks)
  • apps/web/app/s/[videoId]/page.tsx (8 hunks)
  • packages/database/schema.ts (1 hunks)
⏰ 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). (3)
  • GitHub Check: Clippy
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
🔇 Additional comments (14)
apps/web/app/embed/[videoId]/page.tsx (2)

45-62: LGTM! Excellent access control improvement.

The addition of user access verification in metadata generation is a crucial security enhancement. This prevents private and password-protected videos from exposing metadata to unauthorized users, search engines, and social media crawlers.


166-171: Enhanced private video messaging improves user experience.

The updated private video message provides clearer guidance with a proper heading and sign-in link, making it more actionable for video owners compared to the previous simple paragraph.

apps/web/app/(org)/dashboard/caps/Caps.tsx (1)

29-29: LGTM! Type extension aligns with public sharing feature.

The addition of the public boolean property to the VideoData type properly supports the new public sharing functionality introduced across the application.

apps/web/app/(org)/dashboard/caps/page.tsx (1)

148-148: LGTM! Database query correctly includes public field.

The addition of public: videos.public to the select statement properly fetches the public sharing state from the database, enabling the UI components to display and manage the public visibility of videos.

apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx (2)

37-37: LGTM! Interface extension supports public sharing.

The addition of the optional public boolean property to CapCardProps properly extends the interface to support the new public sharing feature while maintaining backward compatibility.


260-260: LGTM! Proper integration with SharingDialog.

Passing cap.public as the isPublic prop to the SharingDialog component enables the sharing dialog to correctly display and manage the public sharing state of the video.

apps/web/app/s/[videoId]/_components/ShareHeader.tsx (1)

21-180: LGTM! Well-implemented public sharing and space-level sharing features.

The changes properly integrate the new public visibility state and space-level sharing:

  • Correctly combines organization and space sharing checks into hasSpaceSharing
  • Appropriately displays "Not shared" only when both space sharing and public visibility are false
  • Props are properly typed with sensible defaults
apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardContent.tsx (1)

147-150: LGTM! Consistent implementation with ShareHeader.

The shared status logic correctly:

  • Uses nullish coalescing operator (?? 0) for safe array length checks
  • Maintains consistency with the ShareHeader component's logic
  • Properly reflects both space-level and public sharing states
apps/web/actions/caps/share.ts (1)

7-133: LGTM! Clean implementation of public sharing backend logic.

The changes properly handle the public visibility toggle:

  • Correctly uses type guard (typeof isPublic === 'boolean') to only update when explicitly provided
  • Maintains backward compatibility by making the parameter optional
  • Properly structured database update using drizzle ORM
apps/web/app/(org)/dashboard/caps/components/SharingDialog.tsx (2)

48-77: LGTM! Well-structured state management for public sharing.

The component properly initializes and tracks public sharing state alongside space sharing, with appropriate defaults and reset logic when the dialog opens.


237-251: LGTM! Clean UI implementation for public sharing toggle.

The public sharing toggle UI is well-designed with:

  • Clear visual hierarchy using icons and descriptive text
  • Dynamic description based on toggle state
  • Proper integration with the Cap UI Switch component
apps/web/app/s/[videoId]/page.tsx (3)

132-217: LGTM! Proper access control in metadata generation.

The metadata generation correctly restricts information exposure for private and password-protected videos, only showing full metadata when the user has access.


315-324: Good UX improvement for private video message.

The enhanced UI with styled message and sign-in link provides a better user experience compared to plain text.


352-366: LGTM! Robust error handling for spaces data fetching.

The code properly handles potential errors when fetching dashboard data and provides a sensible fallback.

Copy link
Contributor

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4a24195 and 8d9080a.

📒 Files selected for processing (5)
  • .env.example (1 hunks)
  • apps/web/actions/video/upload.ts (1 hunks)
  • apps/web/app/(org)/dashboard/caps/Caps.tsx (1 hunks)
  • apps/web/app/api/desktop/[...route]/video.ts (1 hunks)
  • packages/env/server.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • apps/web/app/api/desktop/[...route]/video.ts
  • packages/env/server.ts
  • .env.example
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/app/(org)/dashboard/caps/Caps.tsx
⏰ 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). (3)
  • GitHub Check: Build Desktop (aarch64-apple-darwin, macos-latest)
  • GitHub Check: Clippy
  • GitHub Check: Build Desktop (x86_64-pc-windows-msvc, windows-latest)

@ameer2468 ameer2468 merged commit 5dd10f7 into CapSoftware:main Aug 7, 2025
7 checks passed
@mogita mogita deleted the video-privacy branch August 7, 2025 07:08
@coderabbitai coderabbitai bot mentioned this pull request Sep 30, 2025
4 tasks
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