Skip to content

Commit ab9ec1e

Browse files
yeet
1 parent aa00f70 commit ab9ec1e

File tree

5 files changed

+116
-64
lines changed

5 files changed

+116
-64
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ export const UploadCapButton = ({
338338
if (xhr.status >= 200 && xhr.status < 300) {
339339
setUploadProgress(100);
340340
onProgress?.(uploadId, 100, 100);
341-
sendProgressUpdate(uploadId, uploadState.total, uploadState.total);
341+
sendProgressUpdate(uploadId, 100, 100);
342342
resolve();
343343
} else {
344344
reject(new Error(`Upload failed with status ${xhr.status}`));
Lines changed: 108 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,136 @@
11
"use client";
22

33
import { LogoSpinner } from "@cap/ui";
4-
import {
5-
calculateStrokeDashoffset,
6-
getProgressCircleConfig,
7-
getUploadStatus,
8-
} from "@cap/utils";
4+
import { getUploadStatus } from "@cap/utils";
5+
import type { Video } from "@cap/web-domain";
6+
import { faVideo } from "@fortawesome/free-solid-svg-icons";
7+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
8+
import ProgressCircle, {
9+
useUploadProgress,
10+
} from "@/app/s/[videoId]/_components/ProgressCircle";
911
import { useUploadingContext } from "../UploadingContext";
1012

1113
export const UploadPlaceholderCard = () => {
12-
const { uploadingThumbnailUrl, uploadProgress } = useUploadingContext();
13-
const { circumference } = getProgressCircleConfig();
14+
const { uploadingCapId, uploadingThumbnailUrl, uploadProgress } =
15+
useUploadingContext();
1416
const status = getUploadStatus(uploadProgress);
15-
const strokeDashoffset = calculateStrokeDashoffset(
16-
uploadProgress,
17-
circumference,
17+
18+
// Always call useUploadProgress hook, but pass empty string when no capId
19+
const progressStatus = useUploadProgress(
20+
(uploadingCapId as Video.VideoId) || ("" as Video.VideoId),
21+
!!uploadingCapId,
1822
);
1923

2024
return (
21-
<div className="flex flex-col gap-4 w-full h-full rounded-xl bg-gray-1 border-gray-3 border-[1px]">
22-
<div className="overflow-hidden relative w-full bg-black rounded-t-xl border-b border-gray-3 aspect-video group">
23-
{uploadingThumbnailUrl ? (
24-
<img
25-
src={uploadingThumbnailUrl}
26-
alt="Uploading thumbnail"
27-
className="object-cover w-full h-full"
28-
/>
29-
) : (
30-
<div className="flex justify-center items-center w-full h-full">
31-
<LogoSpinner className="w-8 h-8 animate-spin" />
32-
</div>
33-
)}
34-
35-
<div className="absolute inset-0 transition-all duration-300 bg-black/60"></div>
36-
37-
<div className="flex absolute bottom-3 left-3 gap-2 items-center">
38-
<span className="text-sm font-semibold text-white">{status}</span>
39-
<svg className="w-4 h-4 transform -rotate-90" viewBox="0 0 20 20">
40-
<circle
41-
cx="10"
42-
cy="10"
43-
r="8"
44-
stroke="currentColor"
45-
strokeWidth="3"
46-
fill="none"
47-
className="text-white/30"
48-
/>
49-
<circle
50-
cx="10"
51-
cy="10"
52-
r="8"
53-
stroke="currentColor"
54-
strokeWidth="3"
55-
fill="none"
56-
strokeLinecap="round"
57-
className="text-white transition-all duration-200 ease-out"
58-
style={{
59-
strokeDasharray: `${circumference} ${circumference}`,
60-
strokeDashoffset: `${strokeDashoffset}`,
61-
}}
25+
<div className="flex relative transition-colors duration-200 flex-col gap-4 w-full h-full rounded-xl cursor-default bg-gray-1 border border-gray-3 group border-px">
26+
<div className="relative">
27+
<div className="overflow-hidden relative w-full bg-black rounded-t-xl aspect-video">
28+
{uploadingThumbnailUrl ? (
29+
// eslint-disable-next-line @next/next/no-img-element
30+
<img
31+
src={uploadingThumbnailUrl}
32+
alt="Uploading thumbnail"
33+
className="object-cover w-full h-full opacity-30 transition-opacity duration-200"
6234
/>
63-
</svg>
35+
) : (
36+
<div className="flex justify-center items-center w-full h-full">
37+
<LogoSpinner className="w-8 h-8 animate-spin" />
38+
</div>
39+
)}
40+
</div>
41+
42+
<div className="flex absolute inset-0 z-50 justify-center items-center bg-black rounded-t-xl">
43+
{progressStatus && uploadingCapId ? (
44+
<UploadCircleWithProgress progress={progressStatus} />
45+
) : status === "Processing" ? (
46+
<div className="relative size-20 md:size-16">
47+
<ProgressCircle
48+
progressTextClassName="md:!text-[11px]"
49+
subTextClassName="!mt-0 md:!text-[7px] !text-[10px] mb-1"
50+
className="md:scale-[1.5] scale-[1.2]"
51+
progress={0}
52+
subText="Processing..."
53+
/>
54+
</div>
55+
) : status === "Uploading" ? (
56+
<div className="relative size-20 md:size-16">
57+
<ProgressCircle
58+
progressTextClassName="md:!text-[11px]"
59+
subTextClassName="!mt-0 md:!text-[7px] !text-[10px] mb-1"
60+
className="md:scale-[1.5] scale-[1.2]"
61+
progress={0}
62+
/>
63+
</div>
64+
) : (
65+
<div className="relative size-20 md:size-16">
66+
<ProgressCircle
67+
progressTextClassName="md:!text-[11px]"
68+
subTextClassName="!mt-0 md:!text-[7px] !text-[10px] mb-1"
69+
className="md:scale-[1.5] scale-[1.2]"
70+
progress={0}
71+
/>
72+
</div>
73+
)}
6474
</div>
6575
</div>
76+
6677
<div className="flex flex-col flex-grow gap-3 px-4 pb-4 w-full">
6778
<div>
6879
<div className="h-[1.25rem] mb-1">
69-
<div className="h-4 rounded animate-pulse bg-gray-3"></div>
80+
<div className="h-4 rounded animate-pulse bg-gray-3" />
7081
</div>
7182
<div className="mb-1 h-[1.25rem]">
72-
<div className="w-24 h-3 rounded animate-pulse bg-gray-3"></div>
83+
<div className="w-24 h-3 rounded animate-pulse bg-gray-3" />
7384
</div>
7485
<div className="mb-1 h-[1.5rem]">
75-
<div className="w-20 h-3 rounded animate-pulse bg-gray-3"></div>
86+
<div className="w-20 h-3 rounded animate-pulse bg-gray-3" />
7687
</div>
7788
</div>
7889
<div className="flex gap-4 items-center text-sm text-gray-10">
79-
<div className="w-16 h-3 rounded animate-pulse bg-gray-3"></div>
90+
<div className="w-16 h-3 rounded animate-pulse bg-gray-3" />
8091
</div>
8192
</div>
8293
</div>
8394
);
8495
};
96+
97+
function UploadCircleWithProgress(props: {
98+
progress: ReturnType<typeof useUploadProgress>;
99+
}) {
100+
const { progress } = props;
101+
102+
if (!progress) {
103+
return (
104+
<div className="relative size-20 md:size-16">
105+
<ProgressCircle
106+
progressTextClassName="md:!text-[11px]"
107+
subTextClassName="!mt-0 md:!text-[7px] !text-[10px] mb-1"
108+
className="md:scale-[1.5] scale-[1.2]"
109+
progress={0}
110+
/>
111+
</div>
112+
);
113+
}
114+
115+
if (progress.status === "failed") {
116+
return (
117+
<div className="flex flex-col items-center">
118+
<div className="flex justify-center items-center mb-2 w-8 h-8 bg-red-500 rounded-full">
119+
<FontAwesomeIcon icon={faVideo} className="text-white size-3" />
120+
</div>
121+
<p className="text-xs text-center text-white">Upload failed</p>
122+
</div>
123+
);
124+
}
125+
126+
return (
127+
<div className="relative size-20 md:size-16">
128+
<ProgressCircle
129+
progressTextClassName="md:!text-[11px]"
130+
subTextClassName="!mt-0 md:!text-[7px] !text-[10px] mb-1"
131+
className="md:scale-[1.5] scale-[1.2]"
132+
progress={progress.status === "uploading" ? progress.progress : 0}
133+
/>
134+
</div>
135+
);
136+
}

apps/web/app/api/desktop/[...route]/video.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -334,9 +334,9 @@ function isGreaterThanSemver(
334334
}
335335

336336
const [, vMajor, vMinor, vPatch, prerelease] = match;
337-
const parsedMajor = parseInt(vMajor, 10);
338-
const parsedMinor = parseInt(vMinor, 10);
339-
const parsedPatch = parseInt(vPatch, 10);
337+
const parsedMajor = vMajor ? parseInt(vMajor, 10) : 0;
338+
const parsedMinor = vMinor ? parseInt(vMinor, 10) : 0;
339+
const parsedPatch = vPatch ? parseInt(vPatch, 10) : 0;
340340

341341
// Compare major.minor.patch
342342
if (parsedMajor !== major) return parsedMajor > major;

apps/web/app/s/[videoId]/_components/ProgressCircle.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,13 @@ const ProgressCircle = ({
6666
className,
6767
progressTextClassName,
6868
subTextClassName,
69+
subText,
6970
}: {
7071
progress: number;
7172
className?: string;
7273
progressTextClassName?: string;
7374
subTextClassName?: string;
75+
subText?: string;
7476
}) => {
7577
return (
7678
<div
@@ -118,7 +120,7 @@ const ProgressCircle = ({
118120
subTextClassName,
119121
)}
120122
>
121-
Uploading...
123+
{subText || "Uploading..."}
122124
</p>
123125
</div>
124126
</div>

packages/utils/src/helpers.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,7 @@ export const calculateStrokeDashoffset = (
7575
};
7676

7777
export const getUploadStatus = (uploadProgress?: number) => {
78-
if (uploadProgress !== undefined) {
79-
return "Uploading";
80-
}
78+
if (uploadProgress !== undefined) return "Uploading";
8179
return "Processing";
8280
};
8381

0 commit comments

Comments
 (0)