mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-15 09:57:33 +00:00
Compare commits
5 Commits
cloud/1.32
...
queue_text
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33dc74fa2a | ||
|
|
bd37da7161 | ||
|
|
0b8d98e1e7 | ||
|
|
25a6b9f393 | ||
|
|
bdf32790c9 |
@@ -36,6 +36,7 @@
|
||||
/>
|
||||
<ResultVideo v-else-if="item.isVideo" :result="item" />
|
||||
<ResultAudio v-else-if="item.isAudio" :result="item" />
|
||||
<ResultText v-else-if="item.isText" :result="item" />
|
||||
</template>
|
||||
</Galleria>
|
||||
</template>
|
||||
@@ -48,12 +49,13 @@ import ComfyImage from '@/components/common/ComfyImage.vue'
|
||||
import { ResultItemImpl } from '@/stores/queueStore'
|
||||
|
||||
import ResultAudio from './ResultAudio.vue'
|
||||
import ResultText from './ResultText.vue'
|
||||
import ResultVideo from './ResultVideo.vue'
|
||||
|
||||
const galleryVisible = ref(false)
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'update:activeIndex', value: number): void
|
||||
'update:activeIndex': [number]
|
||||
}>()
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
/>
|
||||
<ResultVideo v-else-if="result.isVideo" :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">
|
||||
<i class="pi pi-file" />
|
||||
<span>{{ result.mediaType }}</span>
|
||||
@@ -28,6 +29,7 @@ import { ResultItemImpl } from '@/stores/queueStore'
|
||||
import { useSettingStore } from '@/stores/settingStore'
|
||||
|
||||
import ResultAudio from './ResultAudio.vue'
|
||||
import ResultText from './ResultText.vue'
|
||||
import ResultVideo from './ResultVideo.vue'
|
||||
|
||||
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(),
|
||||
images: 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()
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ export class ResultItemImpl {
|
||||
filename: string
|
||||
subfolder: string
|
||||
type: string
|
||||
text?: string
|
||||
|
||||
nodeId: NodeId
|
||||
// 'audio' | 'images' | ...
|
||||
@@ -43,6 +44,7 @@ export class ResultItemImpl {
|
||||
this.filename = obj.filename ?? ''
|
||||
this.subfolder = obj.subfolder ?? ''
|
||||
this.type = obj.type ?? ''
|
||||
this.text = obj.text
|
||||
|
||||
this.nodeId = obj.nodeId
|
||||
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 {
|
||||
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]) =>
|
||||
Object.entries(nodeOutputs).flatMap(([mediaType, items]) =>
|
||||
(items as ResultItem[]).map(
|
||||
(item: ResultItem) =>
|
||||
new ResultItemImpl({
|
||||
(items as (ResultItem | string)[]).map((item: ResultItem | string) => {
|
||||
if (typeof item === 'string') {
|
||||
return new ResultItemImpl({
|
||||
text: item,
|
||||
nodeId,
|
||||
mediaType
|
||||
})
|
||||
} else {
|
||||
return new ResultItemImpl({
|
||||
...item,
|
||||
nodeId,
|
||||
mediaType
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user