mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-21 21:07:33 +00:00
Compare commits
5 Commits
fix/load-a
...
queue_text
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33dc74fa2a | ||
|
|
bd37da7161 | ||
|
|
0b8d98e1e7 | ||
|
|
25a6b9f393 | ||
|
|
bdf32790c9 |
@@ -36,6 +36,7 @@
|
|||||||
/>
|
/>
|
||||||
<ResultVideo v-else-if="item.isVideo" :result="item" />
|
<ResultVideo v-else-if="item.isVideo" :result="item" />
|
||||||
<ResultAudio v-else-if="item.isAudio" :result="item" />
|
<ResultAudio v-else-if="item.isAudio" :result="item" />
|
||||||
|
<ResultText v-else-if="item.isText" :result="item" />
|
||||||
</template>
|
</template>
|
||||||
</Galleria>
|
</Galleria>
|
||||||
</template>
|
</template>
|
||||||
@@ -48,12 +49,13 @@ import ComfyImage from '@/components/common/ComfyImage.vue'
|
|||||||
import { ResultItemImpl } from '@/stores/queueStore'
|
import { ResultItemImpl } from '@/stores/queueStore'
|
||||||
|
|
||||||
import ResultAudio from './ResultAudio.vue'
|
import ResultAudio from './ResultAudio.vue'
|
||||||
|
import ResultText from './ResultText.vue'
|
||||||
import ResultVideo from './ResultVideo.vue'
|
import ResultVideo from './ResultVideo.vue'
|
||||||
|
|
||||||
const galleryVisible = ref(false)
|
const galleryVisible = ref(false)
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: 'update:activeIndex', value: number): void
|
'update:activeIndex': [number]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
/>
|
/>
|
||||||
<ResultVideo v-else-if="result.isVideo" :result="result" />
|
<ResultVideo v-else-if="result.isVideo" :result="result" />
|
||||||
<ResultAudio v-else-if="result.isAudio" :result="result" />
|
<ResultAudio v-else-if="result.isAudio" :result="result" />
|
||||||
|
<ResultText v-else-if="result.isText" :result="result" />
|
||||||
<div v-else class="task-result-preview">
|
<div v-else class="task-result-preview">
|
||||||
<i class="pi pi-file" />
|
<i class="pi pi-file" />
|
||||||
<span>{{ result.mediaType }}</span>
|
<span>{{ result.mediaType }}</span>
|
||||||
@@ -28,6 +29,7 @@ import { ResultItemImpl } from '@/stores/queueStore'
|
|||||||
import { useSettingStore } from '@/stores/settingStore'
|
import { useSettingStore } from '@/stores/settingStore'
|
||||||
|
|
||||||
import ResultAudio from './ResultAudio.vue'
|
import ResultAudio from './ResultAudio.vue'
|
||||||
|
import ResultText from './ResultText.vue'
|
||||||
import ResultVideo from './ResultVideo.vue'
|
import ResultVideo from './ResultVideo.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
81
src/components/sidebar/tabs/queue/ResultText.vue
Normal file
81
src/components/sidebar/tabs/queue/ResultText.vue
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<template>
|
||||||
|
<div class="result-text-container">
|
||||||
|
<div class="text-content">
|
||||||
|
{{ result.text }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
class="copy-button"
|
||||||
|
icon="pi pi-copy"
|
||||||
|
text
|
||||||
|
@click.stop="copyToClipboard(result.text ?? '')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Button from 'primevue/button'
|
||||||
|
|
||||||
|
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
||||||
|
import { ResultItemImpl } from '@/stores/queueStore'
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
result: ResultItemImpl
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const { copyToClipboard } = useCopyToClipboard()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.result-text-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 1rem;
|
||||||
|
text-align: center;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-content {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--text-color);
|
||||||
|
width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
max-width: 80vw;
|
||||||
|
overflow-y: auto;
|
||||||
|
line-height: 1.5;
|
||||||
|
padding-right: 0.5rem;
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hide scrollbar but keep functionality */
|
||||||
|
.text-content::-webkit-scrollbar {
|
||||||
|
width: 0;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.5rem;
|
||||||
|
right: 0.5rem;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
color: var(--text-color-secondary);
|
||||||
|
padding: 0.25rem;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
background-color: var(--surface-ground);
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-text-container:hover .copy-button {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-button:hover {
|
||||||
|
background-color: var(--surface-hover);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -22,7 +22,8 @@ const zOutputs = z
|
|||||||
audio: z.array(zResultItem).optional(),
|
audio: z.array(zResultItem).optional(),
|
||||||
images: z.array(zResultItem).optional(),
|
images: z.array(zResultItem).optional(),
|
||||||
video: z.array(zResultItem).optional(),
|
video: z.array(zResultItem).optional(),
|
||||||
animated: z.array(z.boolean()).optional()
|
animated: z.array(z.boolean()).optional(),
|
||||||
|
text: z.string().optional()
|
||||||
})
|
})
|
||||||
.passthrough()
|
.passthrough()
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export class ResultItemImpl {
|
|||||||
filename: string
|
filename: string
|
||||||
subfolder: string
|
subfolder: string
|
||||||
type: string
|
type: string
|
||||||
|
text?: string
|
||||||
|
|
||||||
nodeId: NodeId
|
nodeId: NodeId
|
||||||
// 'audio' | 'images' | ...
|
// 'audio' | 'images' | ...
|
||||||
@@ -43,6 +44,7 @@ export class ResultItemImpl {
|
|||||||
this.filename = obj.filename ?? ''
|
this.filename = obj.filename ?? ''
|
||||||
this.subfolder = obj.subfolder ?? ''
|
this.subfolder = obj.subfolder ?? ''
|
||||||
this.type = obj.type ?? ''
|
this.type = obj.type ?? ''
|
||||||
|
this.text = obj.text
|
||||||
|
|
||||||
this.nodeId = obj.nodeId
|
this.nodeId = obj.nodeId
|
||||||
this.mediaType = obj.mediaType
|
this.mediaType = obj.mediaType
|
||||||
@@ -193,8 +195,12 @@ export class ResultItemImpl {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isText(): boolean {
|
||||||
|
return ['text', 'json', 'display_text'].includes(this.mediaType)
|
||||||
|
}
|
||||||
|
|
||||||
get supportsPreview(): boolean {
|
get supportsPreview(): boolean {
|
||||||
return this.isImage || this.isVideo || this.isAudio
|
return this.isImage || this.isVideo || this.isAudio || this.isText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,14 +239,21 @@ export class TaskItemImpl {
|
|||||||
}
|
}
|
||||||
return Object.entries(this.outputs).flatMap(([nodeId, nodeOutputs]) =>
|
return Object.entries(this.outputs).flatMap(([nodeId, nodeOutputs]) =>
|
||||||
Object.entries(nodeOutputs).flatMap(([mediaType, items]) =>
|
Object.entries(nodeOutputs).flatMap(([mediaType, items]) =>
|
||||||
(items as ResultItem[]).map(
|
(items as (ResultItem | string)[]).map((item: ResultItem | string) => {
|
||||||
(item: ResultItem) =>
|
if (typeof item === 'string') {
|
||||||
new ResultItemImpl({
|
return new ResultItemImpl({
|
||||||
|
text: item,
|
||||||
|
nodeId,
|
||||||
|
mediaType
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return new ResultItemImpl({
|
||||||
...item,
|
...item,
|
||||||
nodeId,
|
nodeId,
|
||||||
mediaType
|
mediaType
|
||||||
})
|
})
|
||||||
)
|
}
|
||||||
|
})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user