From a46052c9a680b69f41c600c0da890d9e76061427 Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:29:36 +0300 Subject: [PATCH 1/7] update positioning of some buttons, show video owner on share page, and more --- apps/web/app/(org)/dashboard/caps/Caps.tsx | 2 +- .../caps/components/CapCard/CapCard.tsx | 147 ++++++++++-------- .../caps/components/CapCard/CapCardButton.tsx | 7 +- .../s/[videoId]/_components/ShareHeader.tsx | 69 +++++--- 4 files changed, 138 insertions(+), 87 deletions(-) diff --git a/apps/web/app/(org)/dashboard/caps/Caps.tsx b/apps/web/app/(org)/dashboard/caps/Caps.tsx index 10869c80a0..7c98c8b434 100644 --- a/apps/web/app/(org)/dashboard/caps/Caps.tsx +++ b/apps/web/app/(org)/dashboard/caps/Caps.tsx @@ -266,7 +266,7 @@ export const Caps = ({ [data, isUploading, uploadingCapId], ); - if (count === 0) return ; + if (count === 0 && folders.length === 0) return ; return (
diff --git a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx index 6fc8db838e..0e4fe6b2e9 100644 --- a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx +++ b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx @@ -18,6 +18,7 @@ import { faGear, faLink, faLock, + faShare, faTrash, faUnlock, faVideo, @@ -345,72 +346,71 @@ export const CapCard = ({ "top-2 right-2 flex-col gap-2 z-[51]", )} > - {isOwner ? ( - { - e.stopPropagation(); - setIsSettingsDialogOpen(true); - }} - className="delay-0" - icon={() => { - return ; - }} - /> - ) : ( - { - e.stopPropagation(); - handleDownload(); - }} - className="delay-0" - icon={() => ( - - )} - /> - )} { e.stopPropagation(); - handleCopy( - buildEnv.NEXT_PUBLIC_IS_CAP && - NODE_ENV === "production" && - customDomain && - domainVerified - ? `https://${customDomain}/s/${cap.id}` - : buildEnv.NEXT_PUBLIC_IS_CAP && NODE_ENV === "production" - ? `https://cap.link/${cap.id}` - : `${location.origin}/s/${cap.id}`, - ); + setIsSharingDialogOpen(true); }} className="delay-0" - icon={() => { - return !copyPressed ? ( - - ) : ( - - - - ); + icon={} + /> + + { + e.stopPropagation(); + handleDownload(); }} + className="delay-0" + icon={} /> + {!isOwner && ( + { + e.stopPropagation(); + handleCopy( + buildEnv.NEXT_PUBLIC_IS_CAP && + NODE_ENV === "production" && + customDomain && + domainVerified + ? `https://${customDomain}/s/${cap.id}` + : buildEnv.NEXT_PUBLIC_IS_CAP && NODE_ENV === "production" + ? `https://cap.link/${cap.id}` + : `${location.origin}/s/${cap.id}`, + ); + }} + className="delay-0" + icon={ + <> + {!copyPressed ? ( + + ) : ( + + + + )} + + } + /> + )} + {isOwner && ( @@ -418,9 +418,7 @@ export const CapCard = ({ ( - - )} + icon={} />
@@ -432,12 +430,33 @@ export const CapCard = ({ { e.stopPropagation(); - handleDownload(); + setIsSettingsDialogOpen(true); + }} + className="flex gap-2 items-center rounded-lg" + > + +

Settings

+
+ { + e.stopPropagation(); + handleCopy( + buildEnv.NEXT_PUBLIC_IS_CAP && + NODE_ENV === "production" && + customDomain && + domainVerified + ? `https://${customDomain}/s/${cap.id}` + : buildEnv.NEXT_PUBLIC_IS_CAP && + NODE_ENV === "production" + ? `https://cap.link/${cap.id}` + : `${location.origin}/s/${cap.id}`, + ); + toast.success("Link copied to clipboard"); }} className="flex gap-2 items-center rounded-lg" > - -

Download

+ +

Copy link

{ diff --git a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardButton.tsx b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardButton.tsx index 61868a1f9a..2af223edfb 100644 --- a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardButton.tsx +++ b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardButton.tsx @@ -2,7 +2,8 @@ import { Button } from "@cap/ui"; import clsx from "clsx"; -import type { MouseEvent, ReactNode } from "react"; +import type { MouseEvent } from "react"; +import React from "react"; import { Tooltip } from "@/components/Tooltip"; interface CapCardButtonProps { @@ -10,7 +11,7 @@ interface CapCardButtonProps { onClick?: (e: MouseEvent) => void; disabled?: boolean; className: string; - icon: () => ReactNode; + icon: React.JSX.Element; asChild?: boolean; } @@ -36,7 +37,7 @@ export const CapCardButton = ({ size="sm" aria-label={tooltipContent} > - {icon()} + {React.cloneElement(icon, { className: "size-3.5" })} ); diff --git a/apps/web/app/s/[videoId]/_components/ShareHeader.tsx b/apps/web/app/s/[videoId]/_components/ShareHeader.tsx index 1401f11b8b..57ab67e112 100644 --- a/apps/web/app/s/[videoId]/_components/ShareHeader.tsx +++ b/apps/web/app/s/[videoId]/_components/ShareHeader.tsx @@ -3,13 +3,14 @@ import type { userSelectProps } from "@cap/database/auth/session"; import type { videos } from "@cap/database/schema"; import { buildEnv, NODE_ENV } from "@cap/env"; -import { Button } from "@cap/ui"; +import { Avatar, Button } from "@cap/ui"; import { userIsPro } from "@cap/utils"; import { faChevronDown, faLock } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import clsx from "clsx"; import { Check, Copy, Globe2 } from "lucide-react"; import moment from "moment"; +import Image from "next/image"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import { toast } from "sonner"; @@ -70,7 +71,8 @@ export const ShareHeader = ({ const handleBlur = async () => { setIsEditing(false); - + const next = title.trim(); + if (next === "" || next === data.name) return; try { await editTitle(data.id, title); toast.success("Video title updated"); @@ -135,9 +137,6 @@ export const ShareHeader = ({ }; const renderSharedStatus = () => { - const baseClassName = - "text-sm text-gray-10 transition-colors duration-200 flex items-center"; - if (isOwner) { const hasSpaceSharing = sharedOrganizations?.length > 0 || effectiveSharedSpaces?.length > 0; @@ -145,27 +144,39 @@ export const ShareHeader = ({ if (!hasSpaceSharing && !isPublic) { return ( -

setIsSharingDialogOpen(true)} > Not shared{" "} -

+ ); } else { return ( -

setIsSharingDialogOpen(true)} > Shared{" "} -

+ ); } } else { - return

Shared with you

; + return ( + + ); } }; @@ -199,8 +210,8 @@ export const ShareHeader = ({
-
-
+
+
{isEditing ? ( ) : (

)}

- {user && renderSharedStatus()} -

- {moment(data.createdAt).fromNow()} -

+
+
+ {user?.image ? ( + {user.name + ) : ( + + )} +
+

+ {user?.name} +

+

+ {moment(data.createdAt).fromNow()} +

+
+
+ {user && renderSharedStatus()} +
{user !== null && ( From 0d2de4b02c5f8c11cbce1ddd1077d18663e22862 Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:35:38 +0300 Subject: [PATCH 2/7] Update CapCard.tsx --- .../(org)/dashboard/caps/components/CapCard/CapCard.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx index 0e4fe6b2e9..0e885c5803 100644 --- a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx +++ b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx @@ -372,12 +372,11 @@ export const CapCard = ({ onClick={(e) => { e.stopPropagation(); handleCopy( - buildEnv.NEXT_PUBLIC_IS_CAP && - NODE_ENV === "production" && - customDomain && - domainVerified + buildEnv.NEXT_PUBLIC_IS_CAP && customDomain && domainVerified ? `https://${customDomain}/s/${cap.id}` - : buildEnv.NEXT_PUBLIC_IS_CAP && NODE_ENV === "production" + : buildEnv.NEXT_PUBLIC_IS_CAP && + !customDomain && + !domainVerified ? `https://cap.link/${cap.id}` : `${location.origin}/s/${cap.id}`, ); From 2208204908e1ee0893fc650e83abf93e0e13f28a Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:37:36 +0300 Subject: [PATCH 3/7] Update CapCard.tsx --- .../caps/components/CapCard/CapCard.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx index 0e885c5803..a907272801 100644 --- a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx +++ b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCard.tsx @@ -43,6 +43,7 @@ import { } from "@/components/VideoThumbnail"; import { useEffectMutation } from "@/lib/EffectRuntime"; import { withRpc } from "@/lib/Rpcs"; +import { usePublicEnv } from "@/utils/public-env"; import { PasswordDialog } from "../PasswordDialog"; import { SettingsDialog } from "../SettingsDialog"; import { SharingDialog } from "../SharingDialog"; @@ -122,6 +123,8 @@ export const CapCard = ({ const [passwordProtected, setPasswordProtected] = useState( cap.hasPassword || false, ); + const { webUrl } = usePublicEnv(); + const [copyPressed, setCopyPressed] = useState(false); const [isDragging, setIsDragging] = useState(false); const [isSettingsDialogOpen, setIsSettingsDialogOpen] = useState(false); @@ -372,13 +375,17 @@ export const CapCard = ({ onClick={(e) => { e.stopPropagation(); handleCopy( - buildEnv.NEXT_PUBLIC_IS_CAP && customDomain && domainVerified - ? `https://${customDomain}/s/${cap.id}` + NODE_ENV === "development" + ? `${webUrl}/s/${cap.id}` : buildEnv.NEXT_PUBLIC_IS_CAP && - !customDomain && - !domainVerified - ? `https://cap.link/${cap.id}` - : `${location.origin}/s/${cap.id}`, + customDomain && + domainVerified + ? `https://${customDomain}/s/${cap.id}` + : buildEnv.NEXT_PUBLIC_IS_CAP && + !customDomain && + !domainVerified + ? `https://cap.link/${cap.id}` + : `${webUrl}/s/${cap.id}`, ); }} className="delay-0" From 8b88fd71de42a6f2dba0d57068873c9a5054a899 Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:48:56 +0300 Subject: [PATCH 4/7] correct data --- .../s/[videoId]/_components/ShareHeader.tsx | 20 +++++++++---------- apps/web/app/s/[videoId]/page.tsx | 6 ++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/apps/web/app/s/[videoId]/_components/ShareHeader.tsx b/apps/web/app/s/[videoId]/_components/ShareHeader.tsx index 57ab67e112..859d55be1c 100644 --- a/apps/web/app/s/[videoId]/_components/ShareHeader.tsx +++ b/apps/web/app/s/[videoId]/_components/ShareHeader.tsx @@ -7,7 +7,6 @@ import { Avatar, Button } from "@cap/ui"; import { userIsPro } from "@cap/utils"; import { faChevronDown, faLock } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import clsx from "clsx"; import { Check, Copy, Globe2 } from "lucide-react"; import moment from "moment"; import Image from "next/image"; @@ -30,7 +29,10 @@ export const ShareHeader = ({ sharedSpaces = [], spacesData = null, }: { - data: typeof videos.$inferSelect; + data: typeof videos.$inferSelect & { + ownerName?: string | null; + ownerImage?: string | null; + }; user: typeof userSelectProps | null; customDomain?: string | null; domainVerified?: boolean; @@ -236,21 +238,19 @@ export const ShareHeader = ({
- {user?.image ? ( + {data.ownerImage ? ( {user.name ) : ( - + )} -
-

- {user?.name} -

+
+

{data.ownerName}

{moment(data.createdAt).fromNow()}

diff --git a/apps/web/app/s/[videoId]/page.tsx b/apps/web/app/s/[videoId]/page.tsx index 94a44f0974..3a6a50987d 100644 --- a/apps/web/app/s/[videoId]/page.tsx +++ b/apps/web/app/s/[videoId]/page.tsx @@ -270,6 +270,8 @@ export default async function ShareVideoPage(props: PageProps<"/s/[videoId]">) { id: videos.id, name: videos.name, ownerId: videos.ownerId, + ownerName: users.name, + ownerImage: users.image, orgId: videos.orgId, createdAt: videos.createdAt, updatedAt: videos.updatedAt, @@ -363,6 +365,8 @@ async function AuthorizedContent({ sharedOrganization: { organizationId: Organisation.OrganisationId } | null; hasPassword: boolean; ownerIsPro?: boolean; + ownerName?: string | null; + ownerImage?: string | null; orgSettings?: OrganizationSettings | null; videoSettings?: OrganizationSettings | null; }; @@ -466,6 +470,8 @@ async function AuthorizedContent({ id: videos.id, name: videos.name, ownerId: videos.ownerId, + ownerName: users.name, + ownerImage: users.image, ownerIsPro: sql`${users.stripeSubscriptionStatus} IN ('active','trialing','complete','paid') OR ${users.thirdPartyStripeSubscriptionId} IS NOT NULL`.mapWith( Boolean, From aec884b0292f2fa7d79d964e6b8389d349bd0ef5 Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:53:34 +0300 Subject: [PATCH 5/7] make sure to show folders only created by the user himself --- apps/web/app/(org)/dashboard/caps/page.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/web/app/(org)/dashboard/caps/page.tsx b/apps/web/app/(org)/dashboard/caps/page.tsx index b71d6ce162..754d9665da 100644 --- a/apps/web/app/(org)/dashboard/caps/page.tsx +++ b/apps/web/app/(org)/dashboard/caps/page.tsx @@ -227,6 +227,7 @@ export default async function CapsPage(props: PageProps<"/dashboard/caps">) { .where( and( eq(folders.organizationId, user.activeOrganizationId), + eq(folders.createdById, user.id), isNull(folders.parentId), isNull(folders.spaceId), ), From 3b41e5481b2cd10e8da53612be3d158e22820034 Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:54:32 +0300 Subject: [PATCH 6/7] Update CapCardButton.tsx --- .../(org)/dashboard/caps/components/CapCard/CapCardButton.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardButton.tsx b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardButton.tsx index 2af223edfb..cf0724ed93 100644 --- a/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardButton.tsx +++ b/apps/web/app/(org)/dashboard/caps/components/CapCard/CapCardButton.tsx @@ -37,7 +37,9 @@ export const CapCardButton = ({ size="sm" aria-label={tooltipContent} > - {React.cloneElement(icon, { className: "size-3.5" })} + {React.cloneElement(icon, { + className: clsx(icon.props.className, "size-3.5"), + })} ); From 68abcd123927002cd4761fbc933f37c401ea747e Mon Sep 17 00:00:00 2001 From: ameer2468 <33054370+ameer2468@users.noreply.github.com> Date: Wed, 8 Oct 2025 11:56:21 +0300 Subject: [PATCH 7/7] Update ShareHeader.tsx --- apps/web/app/s/[videoId]/_components/ShareHeader.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/web/app/s/[videoId]/_components/ShareHeader.tsx b/apps/web/app/s/[videoId]/_components/ShareHeader.tsx index 859d55be1c..50989fb70b 100644 --- a/apps/web/app/s/[videoId]/_components/ShareHeader.tsx +++ b/apps/web/app/s/[videoId]/_components/ShareHeader.tsx @@ -243,6 +243,7 @@ export const ShareHeader = ({ src={data.ownerImage} alt={data.ownerName || ""} width={32} + unoptimized height={32} className="rounded-full" />