@@ -58,13 +58,13 @@ const clipResolutionDefault = computed<"720p" | "1080p">(() => {
5858 )?.value ;
5959 return raw === " 720p" ? " 720p" : " 1080p" ;
6060});
61- const { seek } = useDemoPlayback ();
61+ const { seek, setHudVisible } = useDemoPlayback ();
6262const editor = useClipEditor ();
6363const nuxtApp = useNuxtApp ();
64- const { trackJob : trackRenderJob } = useClipRenderActive ();
64+ const { active : renderActive, trackJob : trackRenderJob } =
65+ useClipRenderActive ();
6566
6667const title = ref (" " );
67- const destination = ref <" library" | " download" >(" library" );
6868const resolution = ref <" 720p" | " 1080p" >(clipResolutionDefault .value );
6969watch (clipResolutionDefault , (v ) => {
7070 resolution .value = v ;
@@ -74,6 +74,23 @@ const submitError = ref<string | null>(null);
7474const renderingJobId = ref <string | null >(null );
7575watch (renderingJobId , (id ) => trackRenderJob (id ));
7676
77+ // The inline render captures the pod's live frames, so the JT HUD
78+ // overlay would otherwise be baked into the clip. Hide it for the
79+ // duration of the render and restore it once the job reaches a
80+ // terminal status (renderActive flips false). Only restore if we were
81+ // the ones who hid it, so we don't fight an operator who had the HUD
82+ // off already.
83+ const hudHiddenForRender = ref (false );
84+ function restoreHudAfterRender() {
85+ if (hudHiddenForRender .value ) {
86+ setHudVisible (true );
87+ hudHiddenForRender .value = false ;
88+ }
89+ }
90+ watch (renderActive , (active ) => {
91+ if (! active ) restoreHudAfterRender ();
92+ });
93+
7794const max = computed (() => Math .max (1 , store .totalTicks || 0 ));
7895const playheadPct = computed (
7996 () => ` ${(Math .min (store .currentTick , max .value ) / max .value ) * 100 }% ` ,
@@ -295,9 +312,15 @@ async function submit() {
295312 ... (s .pov_steam_id ? { pov_steam_id: s .pov_steam_id } : {}),
296313 })),
297314 output: { format: " mp4" , resolution: resolution .value , fps: clipFps .value },
298- destination: destination . value ,
315+ destination: " library " ,
299316 title: title .value || undefined ,
300317 };
318+ // Hide the JT HUD before the pod starts capturing; restored when the
319+ // job finishes (watch on renderActive) or if submission fails below.
320+ if (store .hudVisible ) {
321+ setHudVisible (false );
322+ hudHiddenForRender .value = true ;
323+ }
301324 try {
302325 const { data } = await nuxtApp .$apollo .defaultClient .mutate ({
303326 mutation: generateMutation ({
@@ -314,6 +337,7 @@ async function submit() {
314337 (e as any )?.graphQLErrors ?.[0 ]?.message ??
315338 (e as Error )?.message ??
316339 " Failed to submit clip" ;
340+ restoreHudAfterRender ();
317341 } finally {
318342 submitting .value = false ;
319343 }
@@ -341,82 +365,99 @@ function onRenderClose() {
341365
342366 <div v-else class =" space-y-3" >
343367 <div class =" flex items-center gap-3 flex-wrap" >
344- <div class =" flex items-center gap-2" >
345- <Film class="h-3.5 w-3.5 text-[hsl(var(--tac-amber))]" />
368+ <div class =" flex items-center gap-2.5" >
346369 <span
347- class =" font-mono text-[0.65rem] uppercase tracking-[0.2em] text-foreground/80"
370+ class =" inline-flex h-6 w-6 items-center justify-center rounded-[4px] border border-[hsl(var(--tac-amber)/0.4)] bg-[hsl(var(--tac-amber)/0.08)]"
371+ >
372+ <Film class="h-3.5 w-3.5 text-[hsl(var(--tac-amber))]" />
373+ </span >
374+ <span
375+ class =" font-mono text-[0.7rem] uppercase tracking-[0.22em] text-foreground/90"
348376 >
349377 {{ $t("clips.editor.title") }}
350378 </span >
351379 </div >
352- <span
353- class =" font-mono text-[0.65rem] tabular-nums text-muted-foreground"
380+
381+ <!-- Stat readout: segment count + total duration as discrete
382+ fields, duration promoted to amber as the focal number. -->
383+ <div
384+ class =" flex items-center gap-2 font-mono text-[0.62rem] tabular-nums text-muted-foreground"
354385 >
355- {{ editor.segments.value.length }}
356- {{ editor.segments.value.length === 1 ? "segment" : "segments" }}
357- · {{ formatSeconds(ticksToSeconds(editor.totalSelectedTicks.value)) }}
358- </span >
386+ <span >
387+ {{ editor.segments.value.length }}
388+ {{ editor.segments.value.length === 1 ? "segment" : "segments" }}
389+ </span >
390+ <span class =" h-3 w-px bg-border/60" />
391+ <span class =" text-[hsl(var(--tac-amber)/0.85)]" >
392+ {{
393+ formatSeconds(ticksToSeconds(editor.totalSelectedTicks.value))
394+ }}
395+ </span >
396+ </div >
359397
360- <div class =" ml-auto flex items-center gap-1.5" >
361- <Button
362- type="button"
363- size="sm"
364- variant="outline"
365- class="h-7 text-xs"
366- @click =" addAtPlayhead "
367- >
368- <Plus class="h-3.5 w-3.5 mr-1" />
369- Add
370- </Button >
371- <Button
372- type="button"
373- size="sm"
374- variant="outline"
375- class="h-7 text-xs"
376- :disabled =" ! editor .selectedId .value "
377- @click =" splitSelected "
378- >
379- <Scissors class="h-3.5 w-3.5 mr-1" />
380- {{ $t("clips.editor.split") }}
381- </Button >
382- <Button
383- type="button"
384- size="sm"
385- variant="outline"
386- class="h-7 text-xs"
387- :disabled =" ! editor .selectedId .value "
388- @click =" deleteSelected "
398+ <div class =" ml-auto flex items-center gap-2" >
399+ <!-- Segment edit ops — one connected control instead of three
400+ free-floating buttons. -->
401+ <div
402+ class =" inline-flex items-center rounded-md border border-border/60 bg-card/40 p-0.5"
389403 >
390- <Trash2 class="h-3.5 w-3.5 mr-1" />
391- {{ $t("clips.editor.delete") }}
392- </Button >
393- <Button
404+ <button
405+ type =" button"
406+ class =" inline-flex h-6 items-center gap-1 rounded-[3px] px-2 font-mono text-[0.62rem] uppercase tracking-[0.14em] text-muted-foreground transition-colors cursor-pointer hover:bg-[hsl(var(--tac-amber)/0.1)] hover:text-[hsl(var(--tac-amber))]"
407+ @click =" addAtPlayhead"
408+ >
409+ <Plus class="h-3.5 w-3.5 " />
410+ Add
411+ </button >
412+ <span class =" h-4 w-px bg-border/50" />
413+ <button
414+ type =" button"
415+ :disabled =" !editor.selectedId.value"
416+ class =" inline-flex h-6 items-center gap-1 rounded-[3px] px-2 font-mono text-[0.62rem] uppercase tracking-[0.14em] text-muted-foreground transition-colors cursor-pointer hover:bg-muted/50 hover:text-foreground disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-muted-foreground"
417+ @click =" splitSelected"
418+ >
419+ <Scissors class="h-3.5 w-3.5 " />
420+ {{ $t("clips.editor.split") }}
421+ </button >
422+ <span class =" h-4 w-px bg-border/50" />
423+ <button
424+ type =" button"
425+ :disabled =" !editor.selectedId.value"
426+ class =" inline-flex h-6 items-center gap-1 rounded-[3px] px-2 font-mono text-[0.62rem] uppercase tracking-[0.14em] text-muted-foreground transition-colors cursor-pointer hover:bg-destructive/10 hover:text-destructive disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-muted-foreground"
427+ @click =" deleteSelected"
428+ >
429+ <Trash2 class="h-3.5 w-3.5 " />
430+ {{ $t("clips.editor.delete") }}
431+ </button >
432+ </div >
433+
434+ <span class =" h-5 w-px bg-border/60" />
435+
436+ <!-- Preview / Stop — set apart as the playback control. -->
437+ <button
394438 type =" button"
395- size="sm"
396- variant="outline"
397- class="h-7 text-xs"
398439 :disabled =" !editor.isValid.value"
440+ class =" inline-flex h-7 items-center gap-1.5 rounded-md border px-2.5 font-mono text-[0.62rem] uppercase tracking-[0.14em] transition-colors cursor-pointer disabled:opacity-40 disabled:cursor-not-allowed"
399441 :class ="
400442 editor.previewing.value
401- ? ' border-[hsl(var(--tac-amber))] text-[hsl(var(--tac-amber))]'
402- : ' '
443+ ? 'border-[hsl(var(--tac-amber))] bg-[hsl(var(--tac-amber)/0.12)] text-[hsl(var(--tac-amber))]'
444+ : 'border-border/60 text-foreground/90 hover:border-[hsl(var(--tac-amber)/0.6)] hover:text-[hsl(var(--tac-amber))] '
403445 "
404446 @click =" togglePreview"
405447 >
406- <Square v-if =" editor .previewing .value " class="h-3.5 w-3.5 mr-1 " />
407- <Play v-else class="h-3.5 w-3.5 mr-1 " />
448+ <Square v-if =" editor .previewing .value " class="h-3.5 w-3.5 " />
449+ <Play v-else class="h-3.5 w-3.5 " />
408450 {{ editor.previewing.value ? "Stop" : "Preview" }}
409- </Button >
410- <Button
451+ </button >
452+
453+ <button
411454 type =" button"
412- size="sm"
413- variant="ghost"
414- class="h-7 text-xs"
455+ class =" inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground/70 transition-colors cursor-pointer hover:bg-muted/50 hover:text-foreground"
456+ :title =" $t('clips.editor.close')"
415457 @click =" close"
416458 >
417- <X class="h-3.5 w-3.5 mr-1" />
418- {{ $t("clips.editor.close") }}
419- </Button >
459+ <X class="h-4 w-4" />
460+ </button >
420461 </div >
421462 </div >
422463
@@ -590,7 +631,7 @@ function onRenderClose() {
590631 </div >
591632
592633 <div
593- class =" grid grid-cols-1 sm:grid-cols-[1fr_auto_auto_auto ] gap-2 items-end"
634+ class =" grid grid-cols-1 sm:grid-cols-[1fr_auto_auto ] gap-2 items-end"
594635 >
595636 <div class =" space-y-1" >
596637 <Label
@@ -623,26 +664,6 @@ function onRenderClose() {
623664 </SelectContent >
624665 </Select >
625666 </div >
626- <div class =" space-y-1" >
627- <Label
628- class="text-[0.6rem ] font-mono uppercase tracking-[0.16em ] text-muted-foreground"
629- >
630- {{ $t("clips.editor.destination") }}
631- </Label >
632- <Select v-model =" destination " >
633- <SelectTrigger class="h-8 w-[8rem] text-xs">
634- <SelectValue />
635- </SelectTrigger >
636- <SelectContent >
637- <SelectItem value="library">{{
638- $t("clip_editor_dest.library")
639- }}</SelectItem >
640- <SelectItem value="download">{{
641- $t("clip_editor_dest.download")
642- }}</SelectItem >
643- </SelectContent >
644- </Select >
645- </div >
646667 <Button
647668 type="button"
648669 class="h-8 self-end"
0 commit comments