Skip to content

share feature#10

Open
Maviya13 wants to merge 1 commit intopiyushdhoka:mainfrom
Maviya13:main
Open

share feature#10
Maviya13 wants to merge 1 commit intopiyushdhoka:mainfrom
Maviya13:main

Conversation

@Maviya13
Copy link
Copy Markdown
Collaborator

@Maviya13 Maviya13 commented Feb 3, 2026

No description provided.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Feb 3, 2026

@Maviya13 is attempting to deploy a commit to the piyushdhoka's projects Team on Vercel.

A member of the Team first needs to authorize it.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @Maviya13, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request delivers a significant new feature that empowers users to share their generated animations and chat histories with others. It involves a full-stack implementation, from database schema modifications and new backend API routes to dedicated frontend pages and interactive UI components, ensuring a seamless sharing experience and tracking of public content engagement.

Highlights

  • Sharing Functionality: Introduced the ability to make individual videos and entire chat conversations publicly shareable via unique URLs.
  • Backend API Endpoints: Added new FastAPI endpoints to toggle the public status of videos and chats, and to retrieve public video and chat data without authentication. These endpoints also handle incrementing view counts.
  • Frontend Sharing UI: Implemented new React components (ShareChatButton, ShareVideoButton) for the dashboard to allow users to easily toggle sharing, copy links, and view sharing status. Also added dedicated public-facing pages (/share/video/[videoId], /share/chat/[chatId]) to display shared content.
  • Database Schema Updates: Modified the videos and chats tables to include is_public, share_token, view_count, and shared_at columns, along with appropriate indexes and unique constraints to support the new sharing features.
Changelog
  • backend/app/main.py
    • Imported the new share router.
    • Included the share router in the FastAPI application with a /api/share prefix.
  • backend/app/routers/animations.py
    • Updated imports to include toggle_video_sharing and toggle_chat_sharing from database_service.
    • Added new POST endpoints /videos/{video_id}/share and /chats/{chat_id}/share to handle toggling the public status of videos and chats, respectively.
  • backend/app/routers/share.py
    • Added a new router file to define public-facing API endpoints.
    • Implemented /video/{video_id} endpoint to fetch public video details and increment its view count.
    • Implemented /chat/{chat_id} endpoint to fetch public chat details, including all associated tasks, and increment its view count.
  • backend/app/services/database_service.py
    • Added toggle_video_sharing function to update a video's public status and shared_at timestamp.
    • Added get_public_video function to retrieve a video if it's marked as public.
    • Added increment_video_views function to increase a video's view count.
    • Added toggle_chat_sharing function to update a chat's public status and shared_at timestamp.
    • Added get_public_chat function to retrieve a chat if it's marked as public.
    • Added get_public_chat_tasks function to fetch all tasks associated with a public chat.
    • Added increment_chat_views function to increase a chat's view count.
  • frontend/app/share/chat/[chatId]/page.tsx
    • Created a new Next.js page for displaying shared chat conversations.
    • Includes dynamic metadata generation based on chat content.
    • Renders chat title, creation date, view count, and an enumerated list of associated tasks/videos.
    • Provides a call-to-action to create new animations.
  • frontend/app/share/video/[videoId]/page.tsx
    • Created a new Next.js page for displaying shared videos.
    • Includes dynamic metadata generation for video previews.
    • Renders the video player, video prompt, creation date, view count, and an optional generated script.
    • Provides a call-to-action to create new animations.
  • frontend/components/VideoPlayer.tsx
    • Added a new React component VideoPlayer that wraps plyr-react for consistent video playback.
  • frontend/components/dashboard/AppSidebar.tsx
    • Imported the new ShareChatButton component.
    • Replaced the static 'Share' dropdown menu item with the interactive ShareChatButton for chat entries.
  • frontend/components/dashboard/ShareChatButton.tsx
    • Created a new React component for managing chat sharing.
    • Allows users to toggle a chat's public status with a confirmation dialog.
    • Provides functionality to copy the public share link and displays view count.
  • frontend/components/dashboard/ShareVideoButton.tsx
    • Created a new React component for managing video sharing.
    • Enables users to toggle a video's public status with a confirmation dialog.
    • Provides functionality to copy the public share link and displays view count.
  • frontend/lib/api.ts
    • Added toggleVideoSharing and toggleChatSharing functions to interact with the backend API for updating sharing status.
    • Added getPublicVideo and getPublicChat functions for fetching public content without authentication.
  • frontend/lib/db/migrations/0004_add_sharing.sql
    • Added is_public (boolean), share_token (text), view_count (integer), and shared_at (timestamp) columns to both videos and chats tables.
    • Added unique constraints on share_token for both tables.
    • Created btree indexes on share_token and is_public columns for optimized queries.
  • frontend/lib/db/schema.ts
    • Updated the Drizzle schema for videos and chats tables to reflect the new sharing-related columns and their properties.
    • Added shareTokenIdx to both videos and chats schema definitions.
  • frontend/package.json
    • Updated @types/node to ^22.19.7.
    • Updated @types/react to ^19.2.10.
    • Updated @types/react-dom to ^19.2.3.
Activity
  • The author, Maviya13, has introduced a new 'share feature' to the application.
  • This pull request represents the initial implementation of making videos and chats publicly accessible.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new sharing feature for videos and chats, which is a great addition. The implementation spans both the backend and frontend, including new API endpoints, database schema changes, and public-facing pages. My review focuses on several key areas: improving database query atomicity to prevent race conditions, enhancing API performance with background tasks, increasing frontend component reusability and UI consistency, and standardizing logging and error handling. Addressing these points will make the new feature more robust, performant, and maintainable.

Comment on lines +333 to +354
async def increment_video_views(video_id: str) -> bool:
"""Increment view count for a video."""
client = get_supabase()

try:
# Get current view count
video = client.table("videos").select("view_count").eq("id", video_id).single().execute()
if not video.data:
return False

current_views = video.data.get("view_count", 0)

# Increment
client.table("videos").update({
"view_count": current_views + 1,
"updated_at": datetime.now(timezone.utc).isoformat()
}).eq("id", video_id).execute()

return True
except Exception as e:
print(f"[Views] Failed to increment video views: {e}")
return False
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

This function implements a 'read-then-write' pattern to increment the view count, which can lead to a race condition under concurrent requests. Two requests could read the same value, increment it, and write back, resulting in a lost view count. This should be an atomic operation.

I recommend creating a PostgreSQL RPC function that performs an atomic update, like UPDATE videos SET view_count = view_count + 1 WHERE id = video_id;. You can then call this function from your service, similar to how deduct_user_credit is implemented. This will guarantee atomicity and prevent incorrect view counts.

Comment on lines +410 to +431
async def increment_chat_views(chat_id: str) -> bool:
"""Increment view count for a chat."""
client = get_supabase()

try:
# Get current view count
chat = client.table("chats").select("view_count").eq("id", chat_id).single().execute()
if not chat.data:
return False

current_views = chat.data.get("view_count", 0)

# Increment
client.table("chats").update({
"view_count": current_views + 1,
"updated_at": datetime.now(timezone.utc).isoformat()
}).eq("id", chat_id).execute()

return True
except Exception as e:
print(f"[Views] Failed to increment chat views: {e}")
return False
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

This function has the same race condition issue as increment_video_views. It reads the current view count and then writes an updated value, which is not an atomic operation. To ensure data integrity, especially with concurrent access, this should be handled atomically in the database.

Please create a dedicated RPC function in PostgreSQL to handle the increment, for example: UPDATE chats SET view_count = view_count + 1 WHERE id = chat_id;. Calling this RPC will ensure each view is correctly and safely counted.

increment_video_views,
increment_chat_views
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To enable structured logging, you need to import the logging module and instantiate a logger.

Suggested change
import logging
logger = logging.getLogger(__name__)

<header className="border-b border-white/10 backdrop-blur-sm">
<div className="container mx-auto px-4 py-4">
<Link href="/" className="inline-flex items-center gap-2 text-xl font-bold text-white">
<img src="/logo.png" alt="MovingLines" className="h-8 w-8" />
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

For better performance and to adhere to Next.js best practices, you should use the next/image component instead of the standard <img> tag. The Image component provides automatic image optimization, resizing, and lazy loading, which will improve your page's load times. You'll also need to import it.

Suggested change
<img src="/logo.png" alt="MovingLines" className="h-8 w-8" />
<Image src="/logo.png" alt="MovingLines" width={32} height={32} />

@@ -0,0 +1,51 @@
from fastapi import APIRouter, HTTPException
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To support background tasks for non-blocking operations like incrementing view counts, BackgroundTasks needs to be imported from fastapi.

Suggested change
from fastapi import APIRouter, HTTPException
from fastapi import APIRouter, HTTPException, BackgroundTasks

@@ -0,0 +1,140 @@
import { Metadata } from 'next'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

To use the optimized Image component, you need to import it from next/image.

Suggested change
import { Metadata } from 'next'
import { Metadata } from 'next'
import Image from 'next/image'

Comment on lines +177 to +186
<div onClick={(e) => e.stopPropagation()}>
<ShareChatButton
chatId={chat.id}
isPublic={false} // Will be populated after migration
viewCount={0}
onShareToggle={() => {
// Optionally reload chats to refresh share status
}}
/>
</div>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The current implementation of the share button, by rendering a <Button> inside a <div>, breaks the visual and keyboard navigation consistency of the DropdownMenu.

A better approach would be to refactor ShareChatButton to be a composable component that wraps its children with the Dialog and DialogTrigger. This would allow you to use a standard DropdownMenuItem here, preserving the menu's look, feel, and accessibility.

Example of the improved usage here:

<ShareChatButton chatId={chat.id} isPublic={chat.isPublic} ...>
  <DropdownMenuItem onSelect={(e) => e.preventDefault()}>
    <Share className="h-3.5 w-3.5" />
    Share
  </DropdownMenuItem>
</ShareChatButton>

This would require modifying ShareChatButton.tsx to accept and render children inside the DialogTrigger.

Comment on lines +180 to +181
isPublic={false} // Will be populated after migration
viewCount={0}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The isPublic and viewCount props are currently hardcoded. The comment indicates this is temporary, but to complete the feature, you should update the Chat interface in this file to include is_public and view_count, and then pass the actual values from the chat object. This will ensure the share button reflects the correct state.

Suggested change
isPublic={false} // Will be populated after migration
viewCount={0}
isPublic={chat.isPublic}
viewCount={chat.viewCount}

}
} catch (error) {
console.error('Failed to toggle sharing:', error)
alert('Failed to update sharing settings. Please try again.')
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using alert() for error notifications can be disruptive to the user experience. Consider implementing a more subtle feedback mechanism, such as a toast notification or an inline error message within the dialog, to provide a smoother and more professional feel.

}
} catch (error) {
console.error('Failed to toggle sharing:', error)
alert('Failed to update sharing settings. Please try again.')
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Using alert() for error feedback provides a jarring user experience. It would be better to use a less intrusive method, like a toast notification component or displaying an error message directly within the UI, to handle API failures gracefully.

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