Skip to content

Commit 7af339d

Browse files
Remove progress for legacy clients (#1035)
* fix * create video upload entry for via web * yeet * a mess * reset * wip * better progress tracking * fix thumbnail on placeholder * wip * cleanup upload progress * improvements * disable progress by default * improvements * fixes * format * fix flagging logic * nit * fix * deploy plz
1 parent ef49d61 commit 7af339d

File tree

15 files changed

+283
-268
lines changed

15 files changed

+283
-268
lines changed

apps/desktop/src-tauri/src/upload.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,15 @@ impl UploadProgressUpdater {
186186
async fn send_api_update(app: &AppHandle, video_id: String, uploaded: u64, total: u64) {
187187
let response = app
188188
.authed_api_request("/api/desktop/video/progress", |client, url| {
189-
client.post(url).json(&json!({
190-
"videoId": video_id,
191-
"uploaded": uploaded,
192-
"total": total,
193-
"updatedAt": chrono::Utc::now().to_rfc3339()
194-
}))
189+
client
190+
.post(url)
191+
.header("X-Cap-Desktop-Version", env!("CARGO_PKG_VERSION"))
192+
.json(&json!({
193+
"videoId": video_id,
194+
"uploaded": uploaded,
195+
"total": total,
196+
"updatedAt": chrono::Utc::now().to_rfc3339()
197+
}))
195198
})
196199
.await;
197200

apps/web/actions/video/upload.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
import { db } from "@cap/database";
88
import { getCurrentUser } from "@cap/database/auth/session";
99
import { nanoId } from "@cap/database/helpers";
10-
import { s3Buckets, videos } from "@cap/database/schema";
10+
import { s3Buckets, videos, videoUploads } from "@cap/database/schema";
1111
import { buildEnv, NODE_ENV, serverEnv } from "@cap/env";
1212
import { userIsPro } from "@cap/utils";
1313
import { eq } from "drizzle-orm";
@@ -231,6 +231,10 @@ export async function createVideoAndGetUploadUrl({
231231

232232
await db().insert(videos).values(videoData);
233233

234+
await db().insert(videoUploads).values({
235+
videoId: idToUse,
236+
});
237+
234238
const fileKey = `${user.id}/${idToUse}/${
235239
isScreenshot ? "screenshot/screen-capture.jpg" : "result.mp4"
236240
}`;

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

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,7 @@ export const Caps = ({
7474
const previousCountRef = useRef<number>(0);
7575
const [selectedCaps, setSelectedCaps] = useState<Video.VideoId[]>([]);
7676
const [isDraggingCap, setIsDraggingCap] = useState(false);
77-
const {
78-
isUploading,
79-
setIsUploading,
80-
setUploadingCapId,
81-
setUploadProgress,
82-
uploadingCapId,
83-
setUploadingThumbnailUrl,
84-
} = useUploadingContext();
77+
const { uploadStatus } = useUploadingContext();
8578

8679
const anyCapSelected = selectedCaps.length > 0;
8780

@@ -262,11 +255,13 @@ export const Caps = ({
262255
toast.success("Cap deleted successfully");
263256
router.refresh();
264257
},
265-
onError: () => {
266-
toast.error("Failed to delete cap");
267-
},
258+
onError: () => toast.error("Failed to delete cap"),
268259
});
269260

261+
const isUploading = uploadStatus !== undefined;
262+
const uploadingCapId =
263+
uploadStatus && "capId" in uploadStatus ? uploadStatus.capId : undefined;
264+
270265
const visibleVideos = useMemo(
271266
() =>
272267
isUploading && uploadingCapId
@@ -293,21 +288,7 @@ export const Caps = ({
293288
<FontAwesomeIcon className="size-3.5" icon={faFolderPlus} />
294289
New Folder
295290
</Button>
296-
<UploadCapButton
297-
onStart={(id, thumbnailUrl) => {
298-
setIsUploading(true);
299-
setUploadingCapId(id);
300-
setUploadingThumbnailUrl(thumbnailUrl);
301-
setUploadProgress(0);
302-
}}
303-
size="sm"
304-
onComplete={() => {
305-
setIsUploading(false);
306-
setUploadingCapId(null);
307-
setUploadingThumbnailUrl(undefined);
308-
setUploadProgress(0);
309-
}}
310-
/>
291+
<UploadCapButton size="sm" />
311292
</div>
312293
{folders.length > 0 && (
313294
<>

apps/web/app/(org)/dashboard/caps/UploadingContext.tsx

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,73 @@
11
"use client";
22

33
import type React from "react";
4-
import { createContext, useContext, useState } from "react";
4+
import { createContext, useContext, useEffect, useState } from "react";
55

66
interface UploadingContextType {
7-
isUploading: boolean;
8-
setIsUploading: (value: boolean) => void;
9-
uploadingCapId: string | null;
10-
setUploadingCapId: (id: string | null) => void;
11-
uploadingThumbnailUrl: string | undefined;
12-
setUploadingThumbnailUrl: (url: string | undefined) => void;
13-
uploadProgress: number;
14-
setUploadProgress: (progress: number) => void;
7+
uploadStatus: UploadStatus | undefined;
8+
setUploadStatus: (state: UploadStatus | undefined) => void;
159
}
1610

11+
export type UploadStatus =
12+
| {
13+
status: "parsing";
14+
}
15+
| {
16+
status: "creating";
17+
}
18+
| {
19+
status: "converting";
20+
capId: string;
21+
progress: number;
22+
}
23+
| {
24+
status: "uploadingThumbnail";
25+
capId: string;
26+
progress: number;
27+
}
28+
| {
29+
status: "uploadingVideo";
30+
capId: string;
31+
progress: number;
32+
thumbnailUrl: string | undefined;
33+
};
34+
1735
const UploadingContext = createContext<UploadingContextType | undefined>(
1836
undefined,
1937
);
2038

2139
export function useUploadingContext() {
2240
const context = useContext(UploadingContext);
23-
if (!context) {
41+
if (!context)
2442
throw new Error(
2543
"useUploadingContext must be used within an UploadingProvider",
2644
);
27-
}
2845
return context;
2946
}
3047

3148
export function UploadingProvider({ children }: { children: React.ReactNode }) {
32-
const [isUploading, setIsUploading] = useState(false);
33-
const [uploadingCapId, setUploadingCapId] = useState<string | null>(null);
34-
const [uploadingThumbnailUrl, setUploadingThumbnailUrl] = useState<
35-
string | undefined
36-
>(undefined);
37-
const [uploadProgress, setUploadProgress] = useState(0);
49+
const [state, setState] = useState<UploadStatus>();
50+
51+
// Prevent the user closing the tab while uploading
52+
useEffect(() => {
53+
const handleBeforeUnload = (e: BeforeUnloadEvent) => {
54+
if (state?.status) {
55+
e.preventDefault();
56+
// Chrome requires returnValue to be set
57+
e.returnValue = "";
58+
return "";
59+
}
60+
};
61+
62+
window.addEventListener("beforeunload", handleBeforeUnload);
63+
return () => window.removeEventListener("beforeunload", handleBeforeUnload);
64+
}, [state]);
3865

3966
return (
4067
<UploadingContext.Provider
4168
value={{
42-
isUploading,
43-
setIsUploading,
44-
uploadingCapId,
45-
setUploadingCapId,
46-
uploadingThumbnailUrl,
47-
setUploadingThumbnailUrl,
48-
uploadProgress,
49-
setUploadProgress,
69+
uploadStatus: state,
70+
setUploadStatus: setState,
5071
}}
5172
>
5273
{children}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"use client";
2+
13
import {
24
Button,
35
Dialog,

0 commit comments

Comments
 (0)