Add output navigation preserving viewer visibility
This commit is contained in:
+49
-5
@@ -1261,6 +1261,11 @@
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div class="flex items-center gap-3">
|
||||
<h2 class="font-display text-2xl font-bold">Output</h2>
|
||||
<div v-if="outputNavigationIndex >= 0 && outputNavigationItems.length > 1" class="flex items-center gap-2" aria-label="Browse outputs">
|
||||
<button type="button" aria-label="Previous output" title="Previous output" class="h-9 w-9 rounded-full border border-white/20 hover:border-amber-300/60" @click="stepOutput(-1)">←</button>
|
||||
<span class="text-xs tabular-nums text-zinc-400">{{ outputNavigationIndex + 1 }} / {{ outputNavigationItems.length }}</span>
|
||||
<button type="button" aria-label="Next output" title="Next output" class="h-9 w-9 rounded-full border border-white/20 hover:border-amber-300/60" @click="stepOutput(1)">→</button>
|
||||
</div>
|
||||
<button
|
||||
v-if="canRestoreOutput"
|
||||
type="button"
|
||||
@@ -1593,9 +1598,11 @@
|
||||
Edited still appears here
|
||||
</div>
|
||||
<FamilyNav
|
||||
:count="outputFamilyStills.length"
|
||||
:index="outputFamilyIndex"
|
||||
@step="stepOutputFamily"
|
||||
:count="outputNavigationIndex >= 0 ? outputNavigationItems.length : 0"
|
||||
:index="outputNavigationIndex"
|
||||
prev-label="Previous output"
|
||||
next-label="Next output"
|
||||
@step="stepOutput"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="editResultUrl && !editLockedSave && !editAwaitingReveal" class="mt-4 flex flex-wrap gap-3">
|
||||
@@ -3536,6 +3543,15 @@ const reviewingStillId = computed(() => {
|
||||
if (outputPreviewKind.value !== 'edit' || editLockedSave.value) return ''
|
||||
return stillIdFromLibraryUrl(editResultUrl.value)
|
||||
})
|
||||
type OutputNavigationItem = { kind: 'still'; item: LibraryStill } | { kind: 'clip'; item: LibraryClip }
|
||||
const outputNavigationItems = computed<OutputNavigationItem[]>(() => libraryEntries.value.flatMap((entry): OutputNavigationItem[] =>
|
||||
entry.kind === 'still'
|
||||
? chronologicalStills(entry.stillGroup.parts).map(item => ({ kind: 'still' as const, item }))
|
||||
: chronologicalParts(entry.group.parts).map(item => ({ kind: 'clip' as const, item }))
|
||||
))
|
||||
const outputNavigationIndex = computed(() => outputNavigationItems.value.findIndex(entry =>
|
||||
entry.kind === 'still' ? entry.item.id === reviewingStillId.value : entry.item.id === reviewingClipId.value
|
||||
))
|
||||
const STUDIO_LIBRARY_CAP = 36
|
||||
const visibleLibraryEntries = computed(() => libraryEntries.value.slice(0, STUDIO_LIBRARY_CAP))
|
||||
const libraryCapped = computed(() => libraryEntries.value.length > STUDIO_LIBRARY_CAP)
|
||||
@@ -5872,9 +5888,37 @@ function onStudioKey(event: KeyboardEvent) {
|
||||
}
|
||||
if (typingInField(event)) return
|
||||
if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return
|
||||
if (outputFamilyStills.value.length < 2) return
|
||||
if (editLightboxUrl.value) {
|
||||
if (outputFamilyStills.value.length < 2) return
|
||||
event.preventDefault()
|
||||
stepOutputFamily(event.key === 'ArrowLeft' ? -1 : 1)
|
||||
return
|
||||
}
|
||||
if (outputNavigationIndex.value < 0 || outputNavigationItems.value.length < 2) return
|
||||
event.preventDefault()
|
||||
stepOutputFamily(event.key === 'ArrowLeft' ? -1 : 1)
|
||||
stepOutput(event.key === 'ArrowLeft' ? -1 : 1)
|
||||
}
|
||||
|
||||
function stepOutput(delta: number) {
|
||||
const items = outputNavigationItems.value
|
||||
const index = outputNavigationIndex.value
|
||||
if (index < 0 || items.length < 2) return
|
||||
const next = items[(index + delta + items.length) % items.length]
|
||||
if (!next) return
|
||||
const covered = outputPreviewKind.value === 'edit' ? editAwaitingReveal.value : awaitingReveal.value
|
||||
if (next.kind === 'still') {
|
||||
openStill(next.item)
|
||||
lastV2StillId.value = next.item.id
|
||||
editAwaitingReveal.value = covered
|
||||
concealEditOutput.value = covered || next.item.hideInput === true
|
||||
if (!editBusy.value) editStatusMessage.value = covered ? 'Hidden still ready' : 'Loaded from library'
|
||||
} else {
|
||||
player.value?.pause()
|
||||
openClip(next.item)
|
||||
awaitingReveal.value = covered
|
||||
concealOutput.value = covered || next.item.hideThumbnail === true
|
||||
if (!videoBusy.value) statusMessage.value = covered ? 'Hidden clip ready' : 'Loaded from library'
|
||||
}
|
||||
}
|
||||
|
||||
function showOutputStill(still: LibraryStill) {
|
||||
|
||||
Reference in New Issue
Block a user