1+ "use client" ;
2+
13import type { VideoMetadata } from "@cap/database/types" ;
24import { buildEnv , NODE_ENV } from "@cap/env" ;
35import {
@@ -13,6 +15,7 @@ import {
1315 faCopy ,
1416 faDownload ,
1517 faEllipsis ,
18+ faGear ,
1619 faLink ,
1720 faLock ,
1821 faTrash ,
@@ -40,6 +43,7 @@ import {
4043import { useEffectMutation } from "@/lib/EffectRuntime" ;
4144import { withRpc } from "@/lib/Rpcs" ;
4245import { PasswordDialog } from "../PasswordDialog" ;
46+ import { SettingsDialog } from "../SettingsDialog" ;
4347import { SharingDialog } from "../SharingDialog" ;
4448import { CapCardAnalytics } from "./CapCardAnalytics" ;
4549import { CapCardButton } from "./CapCardButton" ;
@@ -70,6 +74,14 @@ export interface CapCardProps extends PropsWithChildren {
7074 hasPassword ?: boolean ;
7175 hasActiveUpload : boolean | undefined ;
7276 duration ?: number ;
77+ settings ?: {
78+ disableComments ?: boolean ;
79+ disableSummary ?: boolean ;
80+ disableCaptions ?: boolean ;
81+ disableChapters ?: boolean ;
82+ disableReactions ?: boolean ;
83+ disableTranscript ?: boolean ;
84+ } ;
7385 } ;
7486 analytics : number ;
7587 isLoadingAnalytics : boolean ;
@@ -111,6 +123,7 @@ export const CapCard = ({
111123 ) ;
112124 const [ copyPressed , setCopyPressed ] = useState ( false ) ;
113125 const [ isDragging , setIsDragging ] = useState ( false ) ;
126+ const [ isSettingsDialogOpen , setIsSettingsDialogOpen ] = useState ( false ) ;
114127 const { isSubscribed, setUpgradeModalOpen } = useDashboardContext ( ) ;
115128
116129 const [ confirmOpen , setConfirmOpen ] = useState ( false ) ;
@@ -285,6 +298,12 @@ export const CapCard = ({
285298 onSharingUpdated = { handleSharingUpdated }
286299 isPublic = { cap . public }
287300 />
301+ < SettingsDialog
302+ isOpen = { isSettingsDialogOpen }
303+ settingsData = { cap . settings }
304+ capId = { cap . id }
305+ onClose = { ( ) => setIsSettingsDialogOpen ( false ) }
306+ />
288307 < PasswordDialog
289308 isOpen = { isPasswordDialogOpen }
290309 onClose = { ( ) => setIsPasswordDialogOpen ( false ) }
@@ -323,6 +342,31 @@ export const CapCard = ({
323342 "top-2 right-2 flex-col gap-2 z-[51]" ,
324343 ) }
325344 >
345+ { isOwner ? (
346+ < CapCardButton
347+ tooltipContent = "Settings"
348+ onClick = { ( e ) => {
349+ e . stopPropagation ( ) ;
350+ setIsSettingsDialogOpen ( true ) ;
351+ } }
352+ className = "delay-0"
353+ icon = { ( ) => {
354+ return < FontAwesomeIcon className = "size-4" icon = { faGear } /> ;
355+ } }
356+ />
357+ ) : (
358+ < CapCardButton
359+ tooltipContent = "Download Cap"
360+ onClick = { ( e ) => {
361+ e . stopPropagation ( ) ;
362+ handleDownload ( ) ;
363+ } }
364+ className = "delay-0"
365+ icon = { ( ) => (
366+ < FontAwesomeIcon className = "size-4" icon = { faDownload } />
367+ ) }
368+ />
369+ ) }
326370 < CapCardButton
327371 tooltipContent = "Copy link"
328372 onClick = { ( e ) => {
@@ -363,54 +407,10 @@ export const CapCard = ({
363407 ) ;
364408 } }
365409 />
366- < CapCardButton
367- tooltipContent = "Download Cap"
368- onClick = { ( e ) => {
369- e . stopPropagation ( ) ;
370- handleDownload ( ) ;
371- } }
372- disabled = {
373- downloadMutation . isPending ||
374- ( enableBetaUploadProgress && cap . hasActiveUpload )
375- }
376- className = "delay-25"
377- icon = { ( ) => {
378- return downloadMutation . isPending ? (
379- < div className = "animate-spin size-3" >
380- < svg
381- className = "size-3"
382- xmlns = "http://www.w3.org/2000/svg"
383- fill = "none"
384- viewBox = "0 0 24 24"
385- aria-hidden = "true"
386- >
387- < circle
388- className = "opacity-25"
389- cx = "12"
390- cy = "12"
391- r = "10"
392- stroke = "currentColor"
393- strokeWidth = "4"
394- > </ circle >
395- < path
396- className = "opacity-75"
397- fill = "currentColor"
398- d = "m2 12c0-5.523 4.477-10 10-10v3c-3.866 0-7 3.134-7 7s3.134 7 7 7 7-3.134 7-7c0-1.457-.447-2.808-1.208-3.926l2.4-1.6c1.131 1.671 1.808 3.677 1.808 5.526 0 5.523-4.477 10-10 10s-10-4.477-10-10z"
399- > </ path >
400- </ svg >
401- </ div >
402- ) : (
403- < FontAwesomeIcon
404- className = "text-gray-12 size-3"
405- icon = { faDownload }
406- />
407- ) ;
408- } }
409- />
410410
411411 { isOwner && (
412412 < DropdownMenu modal = { false } onOpenChange = { setIsDropdownOpen } >
413- < DropdownMenuTrigger asChild >
413+ < DropdownMenuTrigger asChild suppressHydrationWarning >
414414 < div >
415415 < CapCardButton
416416 tooltipContent = "More options"
@@ -421,7 +421,21 @@ export const CapCard = ({
421421 />
422422 </ div >
423423 </ DropdownMenuTrigger >
424- < DropdownMenuContent align = "end" sideOffset = { 5 } >
424+ < DropdownMenuContent
425+ align = "end"
426+ sideOffset = { 5 }
427+ suppressHydrationWarning
428+ >
429+ < DropdownMenuItem
430+ onClick = { ( e ) => {
431+ e . stopPropagation ( ) ;
432+ handleDownload ( ) ;
433+ } }
434+ className = "flex gap-2 items-center rounded-lg"
435+ >
436+ < FontAwesomeIcon className = "size-3" icon = { faDownload } />
437+ < p className = "text-sm text-gray-12" > Download</ p >
438+ </ DropdownMenuItem >
425439 < DropdownMenuItem
426440 onClick = { ( ) => {
427441 toast . promise ( duplicateMutation . mutateAsync ( ) , {
@@ -522,8 +536,8 @@ export const CapCard = ({
522536 href = { `/s/${ cap . id } ` }
523537 >
524538 { imageStatus !== "success" && uploadProgress ? (
525- < div className = "relative inset-0 w-full h-full z-20 " >
526- < div className = "overflow-hidden relative mx-auto w-full h-full rounded-t-xl border-b border-gray-3 aspect-video bg-black z-5" >
539+ < div className = "relative inset-0 z-20 w-full h-full" >
540+ < div className = "overflow-hidden relative mx-auto w-full h-full bg-black rounded-t-xl border-b border-gray-3 aspect-video z-5" >
527541 < div className = "flex absolute inset-0 justify-center items-center rounded-t-xl" >
528542 { uploadProgress . status === "failed" ? (
529543 < div className = "flex flex-col items-center" >
0 commit comments