Initial main panel video support

This commit is contained in:
Austin Mroz
2025-12-22 17:52:18 -08:00
parent 75cc8b8b59
commit d5d995de80

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { useEventListener, useInfiniteScroll } from '@vueuse/core' import { useEventListener, useInfiniteScroll, useScroll } from '@vueuse/core'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import Divider from 'primevue/divider' import Divider from 'primevue/divider'
import Splitter from 'primevue/splitter' import Splitter from 'primevue/splitter'
@@ -102,6 +102,7 @@ function resetOutputsScroll() {
outputsRef.value?.scrollTo(0, 0) outputsRef.value?.scrollTo(0, 0)
activeLoad.value = [-1, -1] activeLoad.value = [-1, -1]
} }
const { y: outputScrollState } = useScroll(outputsRef)
watch(activeLoad, () => { watch(activeLoad, () => {
const [index, key] = activeLoad.value const [index, key] = activeLoad.value
@@ -123,12 +124,10 @@ function loadWorkflow(item: AssetItem, index: [number, number]) {
changeTracker.updateState([workflow], changeTracker.undoQueue) changeTracker.updateState([workflow], changeTracker.undoQueue)
} }
function allOutputs(item: AssetItem): [string, number][] { function allOutputs(item?: AssetItem) {
if (item?.user_metadata?.allOutputs) const user_metadata = getOutputAssetMetadata(item?.user_metadata)
return (item.user_metadata.allOutputs as { url: string }[]).map( if (!user_metadata?.allOutputs) return []
(output, index) => [output.url, index] return user_metadata.allOutputs
)
return []
} }
const activeItem = computed(() => { const activeItem = computed(() => {
@@ -136,13 +135,13 @@ const activeItem = computed(() => {
return outputs.media.value[index] return outputs.media.value[index]
}) })
const previewUrl = computed(() => { const preview = computed(() => {
const [index, key] = activeLoad.value const [index, key] = activeLoad.value
if (index >= 0 && key >= 0) { if (index >= 0 && key >= 0) {
const output = allOutputs(outputs.media.value[index])[key][0] const output = allOutputs(outputs.media.value[index])[key]
if (output) return output if (output) return output
} }
return allOutputs(outputs.media.value[0])[0]?.[0] return allOutputs(outputs.media.value[0])[0]
}) })
//TODO: reconsider reactivity of locale. //TODO: reconsider reactivity of locale.
@@ -270,9 +269,11 @@ function handleCenterWheel(e: WheelEvent) {
</Button> </Button>
<div class="flex-1" /> <div class="flex-1" />
<div class="p-1 bg-secondary-background rounded-lg w-10"> <div class="p-1 bg-secondary-background rounded-lg w-10">
<!--FIXME: pointer-events-none means no tooltips-->
<Button <Button
class="rounded-b-none pointer-events-none" class="rounded-b-none pointer-events-none"
size="icon" size="icon"
:title="t('Simple Mode')"
variant="inverted" variant="inverted"
> >
<i class="icon-[lucide--panels-top-left]" /> <i class="icon-[lucide--panels-top-left]" />
@@ -280,6 +281,7 @@ function handleCenterWheel(e: WheelEvent) {
<Button <Button
class="rounded-t-none" class="rounded-t-none"
size="icon" size="icon"
:title="t('Graph Mode')"
@click="useCanvasStore().linearMode = false" @click="useCanvasStore().linearMode = false"
> >
<i class="icon-[comfy--workflow]" /> <i class="icon-[comfy--workflow]" />
@@ -301,21 +303,22 @@ function handleCenterWheel(e: WheelEvent) {
" "
> >
<img <img
v-for="[output, key] in allOutputs(item)" v-for="(output, key) in allOutputs(item)"
:key :key
:class=" :class="
cn( cn(
'p-1 rounded-lg', 'p-1 rounded-lg aspect-square object-cover',
index === activeLoad[0] && key === activeLoad[1] && 'border-2' index === activeLoad[0] && key === activeLoad[1] && 'border-2'
) )
" "
:src="output" :src="output.url"
@click="loadWorkflow(item, [index, key])" @click="loadWorkflow(item, [index, key])"
/> />
</div> </div>
</div> </div>
<!--FIXME: Z-index of this button is wrong, and stacking contexts are funky. Need -right-22 once fixed--> <!--FIXME: Z-index of this button is wrong, and stacking contexts are funky. Need -right-22 once fixed-->
<Button <Button
v-if="outputScrollState"
class="absolute bottom-6 -right-5 p-3 size-10 bg-base-foreground" class="absolute bottom-6 -right-5 p-3 size-10 bg-base-foreground"
@click="resetOutputsScroll" @click="resetOutputsScroll"
> >
@@ -324,7 +327,7 @@ function handleCenterWheel(e: WheelEvent) {
</SplitterPanel> </SplitterPanel>
<SplitterPanel <SplitterPanel
:size="98" :size="98"
class="flex flex-col overflow-y-auto flex-wrap min-w-min gap-4 mx-12 my-8" class="flex flex-col min-w-min gap-4 mx-12 my-8"
@wheel="handleCenterWheel" @wheel="handleCenterWheel"
> >
<div class="flex gap-4 text-muted-foreground h-14 w-full items-center"> <div class="flex gap-4 text-muted-foreground h-14 w-full items-center">
@@ -353,9 +356,17 @@ function handleCenterWheel(e: WheelEvent) {
</Button> </Button>
</div> </div>
<img <img
v-if="previewUrl" v-if="preview?.mediaType === 'images'"
class="pointer-events-none object-contain flex-1 max-h-full" class="object-contain flex-1 max-h-full"
:src="previewUrl" :src="preview.url"
/>
<!--FIXME: core videos are type 'images', VHS still wrapped as 'gifs'-->
<video
v-else-if="preview?.mediaType === 'gifs'"
class="object-contain flex-1 min-h-0"
controls
:src="preview.url"
@wheel.prevent
/> />
<img <img
v-else v-else