-
-
{t('attach.addedTo')} {attached.title}
-
{t('attach.viewInProject')}
+
+
{t('attach.addedTo')} {attached.title}
+
{t('attach.viewInProject')}
@@ -703,6 +704,8 @@
color: var(--text-2);
}
.media-tag {
+ white-space: nowrap;
+ flex-shrink: 0;
display: inline-flex;
align-items: center;
height: 18px;
@@ -713,6 +716,8 @@
color: var(--on-media);
}
.result-title small {
+ min-width: 0;
+ flex-shrink: 1;
color: var(--on-media);
font-size: 11px;
white-space: nowrap;
diff --git a/calliope-web/src/lib/components/desk/StudioDesk.svelte b/calliope-web/src/lib/components/desk/StudioDesk.svelte
index 61bbc637..e3d14e2d 100644
--- a/calliope-web/src/lib/components/desk/StudioDesk.svelte
+++ b/calliope-web/src/lib/components/desk/StudioDesk.svelte
@@ -291,7 +291,9 @@
}
let actionRevision = 0;
+ let promptContextEpoch = $state(0);
function pickWorkflow(id: number) {
+ ++promptContextEpoch;
bayOpen = false;
if (slotBusy || submitting) return;
actionRevision++;
@@ -1279,6 +1281,8 @@
>
+ import { page } from '$app/state';
+ import { promptTool } from '$lib/components/prompt-tools/state.svelte';
+ import ToolButtons from '$lib/components/prompt-tools/ToolButtons.svelte';
+ import ResultBand from '$lib/components/prompt-tools/ResultBand.svelte';
import { resolve } from '$app/paths';
import Modal from '$lib/components/ui/Modal.svelte';
import { tick } from 'svelte';
@@ -19,6 +23,8 @@
/** Scrollable creative inputs with a separate, always visible submission footer. */
interface Props {
header?: Snippet;
+ contextEpoch?: number;
+ contextIdentity?: string;
dock?: boolean;
ds: DeskSchema;
values: FormValues;
@@ -47,6 +53,8 @@
let {
header,
+ contextEpoch = 0,
+ contextIdentity = '',
dock = false,
ds,
values,
@@ -108,6 +116,27 @@
const promptVal = $derived(
ds.prompt ? String(values[ds.prompt.nodeId] ?? '') : '',
);
+ const positiveTool = promptTool(
+ () => promptVal,
+ () =>
+ `${page.url.href}|${contextIdentity}|${contextEpoch}|${current?.id}|${current?.kind}|${ds.prompt?.nodeId}|positive`,
+ (v) => {
+ if (ds.prompt) onSet(ds.prompt.nodeId, v);
+ },
+ '正向提示词',
+ () => negativeTool.close(),
+ );
+ const negativeTool = promptTool(
+ () => (ds.negative ? String(values[ds.negative.nodeId] ?? '') : ''),
+ () =>
+ `${page.url.href}|${contextIdentity}|${contextEpoch}|${current?.id}|${current?.kind}|${ds.negative?.nodeId}|negative`,
+ (v) => {
+ if (ds.negative) onSet(ds.negative.nodeId, v);
+ },
+ '反向提示词',
+ () => positiveTool.close(),
+ );
+
const promptErr = $derived(
showErrors && ds.prompt ? errors[ds.prompt.nodeId] : undefined,
);
@@ -210,6 +239,7 @@
>{ds.negative ? '正向提示词' : '提示词'}
{#if ds.prompt.required}必填{/if}
+
- onSet(ds.prompt!.nodeId, e.currentTarget.value)}
+ oninput={(e) => (
+ positiveTool.edit(),
+ onSet(ds.prompt!.nodeId, e.currentTarget.value)
+ )}
>
Enter 换行 · Ctrl + Enter 生成{/if}
{#if dock && ds.negative}
-
+
避免的内容
{/if}
+