Skip to content

Commit 96b9dff

Browse files
authored
bug: fix clip visibility controls (menu hidden in modal, chip stale until refresh) (#419)
Co-authored-by: Flegma <Flegma@users.noreply.github.com>
1 parent 79062ba commit 96b9dff

2 files changed

Lines changed: 33 additions & 14 deletions

File tree

components/clips/ClipDetailModal.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ async function setVisibility(v: Visibility) {
163163
],
164164
} as any),
165165
});
166+
// The match_clips subscription does not always echo this change back
167+
// promptly, so reflect it locally to keep the chip in sync.
168+
if (clip.value) {
169+
clip.value = { ...clip.value, visibility: v };
170+
}
166171
visPopoverOpen.value = false;
167172
} catch (e) {
168173
console.error("[clip-modal] visibility toggle failed:", e);
@@ -531,7 +536,7 @@ onMounted(() => {
531536
</span>
532537
{{ clip.visibility }}
533538
</PopoverTrigger>
534-
<PopoverContent class="w-64 p-1" align="end">
539+
<PopoverContent class="z-[70] w-64 p-1" align="end">
535540
<div
536541
class="px-2 py-1.5 font-mono text-[0.6rem] uppercase tracking-[0.18em] text-muted-foreground"
537542
>

components/clips/HighlightCard.vue

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { computed, ref } from "vue";
2+
import { computed, ref, watch } from "vue";
33
import { useI18n } from "vue-i18n";
44
import {
55
Film,
@@ -104,15 +104,28 @@ const VISIBILITY_OPTIONS = computed<
104104
const saving = ref(false);
105105
const visPopoverOpen = ref(false);
106106
107+
// The highlights/match lists load clips with a network-only query, so the
108+
// updateClip mutation (which returns only { success }) never refreshes this
109+
// card's prop. Track the displayed visibility locally, sync it when the prop
110+
// changes, and set it on a successful toggle so the chip reflects the new
111+
// state immediately instead of only after a page refresh.
112+
const visibility = ref<Visibility>(props.clip.visibility as Visibility);
113+
watch(
114+
() => props.clip.visibility,
115+
(v) => {
116+
visibility.value = v as Visibility;
117+
},
118+
);
119+
107120
const currentVisibilityMeta = computed(() => {
108121
return (
109-
VISIBILITY_OPTIONS.value.find((o) => o.value === props.clip.visibility) ??
122+
VISIBILITY_OPTIONS.value.find((o) => o.value === visibility.value) ??
110123
VISIBILITY_OPTIONS.value[2]
111124
);
112125
});
113126
114127
async function setVisibility(v: Visibility) {
115-
if (saving.value || props.clip.visibility === v) {
128+
if (saving.value || visibility.value === v) {
116129
visPopoverOpen.value = false;
117130
return;
118131
}
@@ -126,6 +139,7 @@ async function setVisibility(v: Visibility) {
126139
],
127140
} as any),
128141
});
142+
visibility.value = v;
129143
visPopoverOpen.value = false;
130144
} catch (e) {
131145
console.error("[highlight-card] visibility toggle failed:", e);
@@ -199,20 +213,20 @@ async function setVisibility(v: Visibility) {
199213
class="inline-flex h-7 items-center gap-1 rounded-full bg-black/75 pl-1.5 pr-2 text-white/90 backdrop-blur-sm transition-colors hover:bg-black/90 hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring cursor-pointer"
200214
:aria-label="
201215
$t('ui_extras.visibility_change_hint', {
202-
value: clip.visibility,
216+
value: visibility,
203217
})
204218
"
205219
:title="
206-
$t('ui_extras.visibility_label', { value: clip.visibility })
220+
$t('ui_extras.visibility_label', { value: visibility })
207221
"
208222
@click.stop
209223
>
210224
<span
211225
class="inline-flex h-4 w-4 items-center justify-center rounded-full"
212226
:class="
213-
clip.visibility === 'public'
227+
visibility === 'public'
214228
? 'bg-emerald-400/20 text-emerald-300'
215-
: clip.visibility === 'unlisted'
229+
: visibility === 'unlisted'
216230
? 'bg-amber-400/20 text-amber-300'
217231
: 'bg-white/10 text-white/80'
218232
"
@@ -241,7 +255,7 @@ async function setVisibility(v: Visibility) {
241255
:key="opt.value"
242256
type="button"
243257
class="w-full text-left flex items-start gap-2 rounded px-2 py-1.5 text-xs hover:bg-muted/60 transition-colors disabled:cursor-not-allowed disabled:opacity-60"
244-
:class="clip.visibility === opt.value ? 'bg-muted/40' : ''"
258+
:class="visibility === opt.value ? 'bg-muted/40' : ''"
245259
:disabled="saving"
246260
@click="setVisibility(opt.value)"
247261
>
@@ -261,7 +275,7 @@ async function setVisibility(v: Visibility) {
261275
<span class="flex items-center gap-1.5 font-medium">
262276
{{ opt.label }}
263277
<Check
264-
v-if="clip.visibility === opt.value"
278+
v-if="visibility === opt.value"
265279
class="h-3 w-3 text-[hsl(var(--tac-amber))]"
266280
/>
267281
</span>
@@ -278,18 +292,18 @@ async function setVisibility(v: Visibility) {
278292
v-else
279293
class="inline-flex h-7 items-center gap-1 rounded-full bg-black/75 pl-1.5 pr-2 text-white/90 backdrop-blur-sm pointer-events-none"
280294
:title="
281-
$t('ui_extras.visibility_label', { value: clip.visibility })
295+
$t('ui_extras.visibility_label', { value: visibility })
282296
"
283297
:aria-label="
284-
$t('ui_extras.visibility_label', { value: clip.visibility })
298+
$t('ui_extras.visibility_label', { value: visibility })
285299
"
286300
>
287301
<span
288302
class="inline-flex h-4 w-4 items-center justify-center rounded-full"
289303
:class="
290-
clip.visibility === 'public'
304+
visibility === 'public'
291305
? 'bg-emerald-400/20 text-emerald-300'
292-
: clip.visibility === 'unlisted'
306+
: visibility === 'unlisted'
293307
? 'bg-amber-400/20 text-amber-300'
294308
: 'bg-white/10 text-white/80'
295309
"

0 commit comments

Comments
 (0)