Skip to content

Commit cc1d0de

Browse files
UI for uploading state + errors
1 parent c411b02 commit cc1d0de

File tree

1 file changed

+98
-48
lines changed

1 file changed

+98
-48
lines changed

apps/desktop/src/routes/(window-chrome)/settings/recordings.tsx

Lines changed: 98 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,15 @@ export default function Recordings() {
119119
};
120120

121121
const [uploadProgress, setUploadProgress] = createStore<
122-
Record<string, number>
122+
Record</* video_id */ string, number>
123123
>({});
124124
// TODO: Cleanup subscription
125125
events.uploadProgressEvent.listen((e) => {
126+
// TODO: Make this cleanup
127+
// if (e.payload.uploaded === e.payload.total) {
128+
// setUploadProgress(e.payload.video_id, undefined);
129+
// }
130+
126131
setUploadProgress(
127132
e.payload.video_id,
128133
Number(e.payload.uploaded) / Number(e.payload.total),
@@ -145,8 +150,6 @@ export default function Recordings() {
145150
</p>
146151
}
147152
>
148-
<pre>{JSON.stringify(uploadProgress)}</pre>
149-
150153
<div class="flex gap-3 items-center pb-4 w-full border-b border-gray-2">
151154
<For each={Tabs}>
152155
{(tab) => (
@@ -183,6 +186,11 @@ export default function Recordings() {
183186
onCopyVideoToClipboard={() =>
184187
handleCopyVideoToClipboard(recording.path)
185188
}
189+
uploadProgress={
190+
recording.meta.sharing?.id
191+
? uploadProgress[recording.meta.sharing.id]
192+
: undefined
193+
}
186194
/>
187195
)}
188196
</For>
@@ -199,6 +207,7 @@ function RecordingItem(props: {
199207
onOpenFolder: () => void;
200208
onOpenEditor: () => void;
201209
onCopyVideoToClipboard: () => void;
210+
uploadProgress: number | undefined;
202211
}) {
203212
const [imageExists, setImageExists] = createSignal(true);
204213
const mode = () => props.recording.meta.mode || "other"; // TODO: Fix this
@@ -224,36 +233,79 @@ function RecordingItem(props: {
224233
/>
225234
</Show>
226235
<div class="flex flex-col gap-2">
227-
{"recording" in props.recording.meta ? "TRUE" : "FALSE"}
228-
{"error" in props.recording.meta ? props.recording.meta.error : ""}
229-
{JSON.stringify(props.recording.meta?.upload || {})}
230-
231236
<span>{props.recording.prettyName}</span>
232-
<div
233-
class={cx(
234-
"px-2 py-0.5 flex items-center gap-1.5 font-medium text-[11px] text-gray-12 rounded-full w-fit",
235-
mode() === "instant" ? "bg-blue-100" : "bg-gray-3",
236-
)}
237-
>
238-
{mode() === "instant" ? (
239-
<IconCapInstant class="invert size-2.5 dark:invert-0" />
240-
) : (
241-
<IconCapFilmCut class="invert size-2.5 dark:invert-0" />
242-
)}
243-
<p>{firstLetterUpperCase()}</p>
237+
<div class="flex">
238+
<div
239+
class={cx(
240+
"px-2 py-0.5 flex items-center gap-1.5 font-medium text-[11px] text-gray-12 rounded-full w-fit",
241+
mode() === "instant" ? "bg-blue-100" : "bg-gray-3",
242+
)}
243+
>
244+
{mode() === "instant" ? (
245+
<IconCapInstant class="invert size-2.5 dark:invert-0" />
246+
) : (
247+
<IconCapFilmCut class="invert size-2.5 dark:invert-0" />
248+
)}
249+
<p>{firstLetterUpperCase()}</p>
250+
</div>
251+
252+
<Show
253+
when={
254+
"error" in props.recording.meta
255+
? props.recording.meta.error
256+
: undefined
257+
}
258+
>
259+
{(error) => (
260+
<div
261+
class={cx(
262+
"px-2 py-0.5 flex items-center gap-1.5 font-medium text-[11px] text-gray-12 rounded-full w-fit",
263+
mode() === "instant" ? "bg-blue-100" : "bg-gray-3",
264+
)}
265+
>
266+
{/* TODO: Get a proper icon here */}
267+
{/* TODO: Show the error in a tooltip */}
268+
<IconCapInstant class="invert size-2.5 dark:invert-0" />
269+
<p>FAILED: {error()}</p>
270+
</div>
271+
)}
272+
</Show>
273+
274+
{/* TODO: Show a badge for when recording fails */}
244275
</div>
245276
</div>
246277
</div>
247278
<div class="flex gap-2 items-center">
248279
<Show when={mode() === "studio"}>
249280
<Show when={props.recording.meta.sharing}>
250281
{(sharing) => (
251-
<TooltipIconButton
252-
tooltipText="Open link"
253-
onClick={() => shell.open(sharing().link)}
254-
>
255-
<IconCapLink class="size-4" />
256-
</TooltipIconButton>
282+
<>
283+
{/* // TODO: Add something here like instant mode */}
284+
{/*<Show
285+
when={props.uploadProgress || reupload.isPending}
286+
fallback={
287+
<TooltipIconButton
288+
tooltipText="Reupload"
289+
onClick={() => reupload.mutate()}
290+
>
291+
<IconLucideRotateCcw class="size-4" />
292+
</TooltipIconButton>
293+
}
294+
>
295+
<ProgressCircle
296+
variant="primary"
297+
progress={props.uploadProgress || 0}
298+
size="sm"
299+
/>
300+
</Show>*/}
301+
302+
<TooltipIconButton
303+
tooltipText="Open link"
304+
onClick={() => shell.open(sharing().link)}
305+
>
306+
<IconCapLink class="size-4" />
307+
</TooltipIconButton>
308+
</>
257309
)}
258310
</Show>
259311
<TooltipIconButton
@@ -265,39 +317,37 @@ function RecordingItem(props: {
265317
</Show>
266318
<Show when={mode() === "instant"}>
267319
{(_) => {
268-
const [progress, setProgress] = createSignal(0);
269320
const reupload = createMutation(() => ({
270-
mutationFn: async () => {
271-
setProgress(0);
272-
return await commands.uploadExportedVideo(
321+
mutationFn: () =>
322+
commands.uploadExportedVideo(
273323
props.recording.path,
274324
"Reupload",
275-
new Channel<UploadProgress>((progress) =>
276-
setProgress(Math.round(progress.progress * 100)),
277-
),
278-
);
279-
},
280-
onSettled: () => setProgress(0),
325+
new Channel<UploadProgress>((progress) => {}),
326+
),
281327
}));
282328

283329
return (
284330
<Show when={props.recording.meta.sharing}>
285331
{(sharing) => (
286332
<>
287-
<TooltipIconButton
288-
tooltipText="Reupload"
289-
onClick={() => reupload.mutate()}
333+
<Show
334+
when={props.uploadProgress || reupload.isPending}
335+
fallback={
336+
<TooltipIconButton
337+
tooltipText="Reupload"
338+
onClick={() => reupload.mutate()}
339+
>
340+
<IconLucideRotateCcw class="size-4" />
341+
</TooltipIconButton>
342+
}
290343
>
291-
{reupload.isPending ? (
292-
<ProgressCircle
293-
variant="primary"
294-
progress={progress()}
295-
size="sm"
296-
/>
297-
) : (
298-
<IconLucideRotateCcw class="size-4" />
299-
)}
300-
</TooltipIconButton>
344+
<ProgressCircle
345+
variant="primary"
346+
progress={props.uploadProgress || 0}
347+
size="sm"
348+
/>
349+
</Show>
350+
301351
<TooltipIconButton
302352
tooltipText="Open link"
303353
onClick={() => shell.open(sharing().link)}

0 commit comments

Comments
 (0)