1248 lines
45 KiB
JavaScript
1248 lines
45 KiB
JavaScript
/*
|
||
* Extracted from browser-delivered Turbopack chunk: fd0220e4d10052af.701bdafa2d.js
|
||
* Module id: 385951
|
||
* For reading/searching only; this factory depends on the original Turbopack runtime.
|
||
*/
|
||
|
||
const moduleFactory = (e) => {
|
||
"use strict";
|
||
var t = e.i(462214),
|
||
n = e.i(358379),
|
||
i = e.i(292002),
|
||
r = e.i(768924),
|
||
a = e.i(41671),
|
||
o = e.i(777784),
|
||
s = e.i(790748),
|
||
c = e.i(184656),
|
||
l = e.i(111134),
|
||
u = e.i(677418),
|
||
h = e.i(450439),
|
||
f = e.i(485615),
|
||
d = e.i(703962),
|
||
p = e.i(713118),
|
||
g = e.i(182004),
|
||
b = e.i(500724),
|
||
m = e.i(677588),
|
||
w = e.i(562530),
|
||
v = e.i(216257),
|
||
x = e.i(929286),
|
||
y = e.i(664115),
|
||
_ = e.i(10036),
|
||
S = e.i(306677),
|
||
E = e.i(464025),
|
||
M = e.i(463672),
|
||
T = e.i(316925),
|
||
k = e.i(959248),
|
||
C = e.i(117313),
|
||
A = e.i(589001),
|
||
N = e.i(386951),
|
||
I = e.i(210550),
|
||
P = e.i(244263),
|
||
R = e.i(420510),
|
||
L = e.i(565453),
|
||
D = e.i(244008),
|
||
j = e.i(539839),
|
||
O = e.i(679952);
|
||
function F({ tableConfig: e, onTableConfigChange: i, shotColumns: r }) {
|
||
let o = e?.columnVisibility ?? {},
|
||
s = (0, n.useCallback)(
|
||
(t) => {
|
||
let n = o[t] ?? !0;
|
||
i({ ...e, columnVisibility: { ...o, [t]: !n } });
|
||
},
|
||
[e, o, i],
|
||
),
|
||
c = (0, n.useCallback)(() => {
|
||
let t = {};
|
||
g.SCRIPT_FIELD_META.forEach((e) => {
|
||
t[e.key] = !0;
|
||
}),
|
||
i({ ...e, columnVisibility: t });
|
||
}, [e, i]),
|
||
l = (0, n.useCallback)(() => {
|
||
let t = {};
|
||
g.SCRIPT_FIELD_META.forEach((e) => {
|
||
t[e.key] = "shotNumber" === e.key;
|
||
}),
|
||
i({ ...e, columnVisibility: t });
|
||
}, [e, i]);
|
||
return (0, t.jsxs)("div", {
|
||
className: "flex flex-col gap-3",
|
||
children: [
|
||
(0, t.jsxs)("div", {
|
||
className: "flex items-center justify-between",
|
||
children: [
|
||
(0, t.jsx)("span", {
|
||
className: "text-sm font-medium text-white/80",
|
||
children: "字段可见性",
|
||
}),
|
||
(0, t.jsxs)("div", {
|
||
className: "flex gap-2",
|
||
children: [
|
||
(0, t.jsx)("button", {
|
||
type: "button",
|
||
onClick: c,
|
||
className: "text-xs text-white/40 hover:text-white/70",
|
||
children: "全部显示",
|
||
}),
|
||
(0, t.jsx)("button", {
|
||
type: "button",
|
||
onClick: l,
|
||
className: "text-xs text-white/40 hover:text-white/70",
|
||
children: "全部隐藏",
|
||
}),
|
||
],
|
||
}),
|
||
],
|
||
}),
|
||
(0, t.jsx)("div", {
|
||
className: "flex flex-col gap-0.5",
|
||
children: g.SCRIPT_FIELD_META.map((e) => {
|
||
let n = o[e.key] ?? !0;
|
||
return (0, t.jsxs)(
|
||
"button",
|
||
{
|
||
type: "button",
|
||
onClick: () => s(e.key),
|
||
className:
|
||
"flex items-center gap-2.5 rounded-md px-2 py-1.5 text-xs transition-colors hover:bg-white/[0.06]",
|
||
children: [
|
||
n
|
||
? (0, t.jsx)(a.Icons.eye, {
|
||
width: 14,
|
||
height: 14,
|
||
className: "text-white/60",
|
||
})
|
||
: (0, t.jsx)(a.Icons.eyeOff, {
|
||
width: 14,
|
||
height: 14,
|
||
className: "text-white/30",
|
||
}),
|
||
(0, t.jsx)("span", {
|
||
className: n ? "text-white/80" : "text-white/30",
|
||
children: (0, g.getFieldLabel)(e.key, r),
|
||
}),
|
||
],
|
||
},
|
||
e.key,
|
||
);
|
||
}),
|
||
}),
|
||
],
|
||
});
|
||
}
|
||
let U = [
|
||
{ value: "contains", label: "包含" },
|
||
{ value: "equals", label: "等于" },
|
||
{ value: "gt", label: "大于" },
|
||
{ value: "lt", label: "小于" },
|
||
];
|
||
function B({ tableConfig: e, onTableConfigChange: i, shotColumns: r }) {
|
||
let o = e?.columnFilters ?? [],
|
||
[s, c] = (0, n.useState)(g.SCRIPT_FIELD_META[2]?.key ?? "scene"),
|
||
[l, u] = (0, n.useState)("contains"),
|
||
[h, f] = (0, n.useState)(""),
|
||
d = (0, n.useCallback)(() => {
|
||
if (!h.trim()) return;
|
||
let t = { id: s, value: { operator: l, value: h.trim() } };
|
||
i({ ...e, columnFilters: [...o, t] }), f("");
|
||
}, [e, o, s, l, h, i]),
|
||
p = (0, n.useCallback)(
|
||
(t) => {
|
||
i({ ...e, columnFilters: o.filter((e, n) => n !== t) });
|
||
},
|
||
[e, o, i],
|
||
),
|
||
b = (0, n.useCallback)(() => {
|
||
i({ ...e, columnFilters: [] });
|
||
}, [e, i]);
|
||
return (0, t.jsxs)("div", {
|
||
className: "flex flex-col gap-3",
|
||
children: [
|
||
(0, t.jsxs)("div", {
|
||
className: "flex items-center justify-between",
|
||
children: [
|
||
(0, t.jsx)("span", {
|
||
className: "text-sm font-medium text-white/80",
|
||
children: "筛选条件",
|
||
}),
|
||
o.length > 0 &&
|
||
(0, t.jsx)("button", {
|
||
type: "button",
|
||
onClick: b,
|
||
className: "text-xs text-white/40 hover:text-white/70",
|
||
children: "清除全部",
|
||
}),
|
||
],
|
||
}),
|
||
o.length > 0 &&
|
||
(0, t.jsx)("div", {
|
||
className: "flex flex-col gap-1",
|
||
children: o.map((e, n) => {
|
||
let i = (0, g.getFieldLabel)(e.id, r),
|
||
o = e.value,
|
||
s =
|
||
U.find((e) => e.value === o?.operator)?.label ??
|
||
o?.operator,
|
||
c = `${e.id}-${o?.operator ?? ""}-${o?.value ?? ""}`;
|
||
return (0, t.jsxs)(
|
||
"div",
|
||
{
|
||
className:
|
||
"flex items-center gap-2 rounded-md bg-white/[0.04] px-2 py-1.5 text-xs text-white/60",
|
||
children: [
|
||
(0, t.jsx)("span", {
|
||
className: "text-white/80",
|
||
children: i,
|
||
}),
|
||
(0, t.jsx)("span", {
|
||
className: "text-white/40",
|
||
children: s,
|
||
}),
|
||
(0, t.jsx)("span", {
|
||
className: "flex-1 truncate text-white/60",
|
||
children: String(o?.value ?? ""),
|
||
}),
|
||
(0, t.jsx)("button", {
|
||
type: "button",
|
||
onClick: () => p(n),
|
||
className: "text-white/30 hover:text-red-400",
|
||
children: (0, t.jsx)(a.Icons.x, {
|
||
width: 12,
|
||
height: 12,
|
||
}),
|
||
}),
|
||
],
|
||
},
|
||
c,
|
||
);
|
||
}),
|
||
}),
|
||
(0, t.jsxs)("div", {
|
||
className:
|
||
"flex flex-col gap-2 rounded-lg border border-white/[0.06] p-2.5",
|
||
children: [
|
||
(0, t.jsxs)("div", {
|
||
className: "flex gap-2",
|
||
children: [
|
||
(0, t.jsx)("select", {
|
||
value: s,
|
||
onChange: (e) => c(e.target.value),
|
||
className:
|
||
"flex-1 rounded-md border border-white/10 bg-white/[0.04] px-2 py-1.5 text-xs text-white/80 outline-none",
|
||
children: g.SCRIPT_FIELD_META.map((e) =>
|
||
(0, t.jsx)(
|
||
"option",
|
||
{
|
||
value: e.key,
|
||
children: (0, g.getFieldLabel)(e.key, r),
|
||
},
|
||
e.key,
|
||
),
|
||
),
|
||
}),
|
||
(0, t.jsx)("select", {
|
||
value: l,
|
||
onChange: (e) => u(e.target.value),
|
||
className:
|
||
"rounded-md border border-white/10 bg-white/[0.04] px-2 py-1.5 text-xs text-white/80 outline-none",
|
||
children: U.map((e) =>
|
||
(0, t.jsx)(
|
||
"option",
|
||
{ value: e.value, children: e.label },
|
||
e.value,
|
||
),
|
||
),
|
||
}),
|
||
],
|
||
}),
|
||
(0, t.jsxs)("div", {
|
||
className: "flex gap-2",
|
||
children: [
|
||
(0, t.jsx)("input", {
|
||
value: h,
|
||
onChange: (e) => f(e.target.value),
|
||
onKeyDown: (e) => "Enter" === e.key && d(),
|
||
placeholder: "输入筛选值...",
|
||
className:
|
||
"flex-1 rounded-md border border-white/10 bg-white/[0.04] px-2 py-1.5 text-xs text-white/80 placeholder-white/30 outline-none",
|
||
}),
|
||
(0, t.jsx)("button", {
|
||
type: "button",
|
||
onClick: d,
|
||
disabled: !h.trim(),
|
||
className:
|
||
"rounded-md bg-white/10 px-3 py-1.5 text-xs text-white/70 transition-colors hover:bg-white/15 disabled:cursor-not-allowed disabled:opacity-40",
|
||
children: "添加",
|
||
}),
|
||
],
|
||
}),
|
||
],
|
||
}),
|
||
],
|
||
});
|
||
}
|
||
function H({ icon: e, label: n, active: i, onClick: r }) {
|
||
return (0, t.jsxs)("button", {
|
||
type: "button",
|
||
onClick: r,
|
||
className: `flex items-center gap-1.5 rounded-md px-2.5 py-1.5 text-xs transition-colors ${i ? "bg-canvas-controls-active text-fg-default" : "text-fg-muted hover:bg-canvas-controls-hover hover:text-fg-default"}`,
|
||
children: [e, (0, t.jsx)("span", { children: n })],
|
||
});
|
||
}
|
||
let z = (0, n.memo)(function ({
|
||
rows: e,
|
||
tableConfig: i,
|
||
onTableConfigChange: r,
|
||
shotColumns: o,
|
||
}) {
|
||
let [s, c] = (0, n.useState)(null),
|
||
l = (0, n.useCallback)((e) => {
|
||
c((t) => (t === e ? null : e));
|
||
}, []),
|
||
u = (0, n.useCallback)(() => c(null), []);
|
||
return (0, t.jsxs)("div", {
|
||
className: "relative shrink-0",
|
||
children: [
|
||
(0, t.jsxs)("div", {
|
||
className:
|
||
"flex items-center gap-1 border-b border-white/[0.06] px-6",
|
||
style: { height: "40px" },
|
||
children: [
|
||
(0, t.jsx)(H, {
|
||
icon: (0, t.jsx)(a.Icons.columns3, { width: 14, height: 14 }),
|
||
label: "字段",
|
||
active: "fields" === s,
|
||
onClick: () => l("fields"),
|
||
}),
|
||
(0, t.jsx)(H, {
|
||
icon: (0, t.jsx)(a.Icons.filter, { width: 14, height: 14 }),
|
||
label: "筛选",
|
||
active: "filter" === s,
|
||
onClick: () => l("filter"),
|
||
}),
|
||
(0, t.jsx)("div", { className: "flex-1" }),
|
||
],
|
||
}),
|
||
"fields" === s &&
|
||
(0, t.jsx)(G, {
|
||
onClose: u,
|
||
children: (0, t.jsx)(F, {
|
||
tableConfig: i,
|
||
onTableConfigChange: r,
|
||
shotColumns: o,
|
||
}),
|
||
}),
|
||
"filter" === s &&
|
||
(0, t.jsx)(G, {
|
||
onClose: u,
|
||
children: (0, t.jsx)(B, {
|
||
tableConfig: i,
|
||
onTableConfigChange: r,
|
||
shotColumns: o,
|
||
}),
|
||
}),
|
||
],
|
||
});
|
||
});
|
||
function G({ onClose: e, children: n }) {
|
||
return (0, t.jsxs)(t.Fragment, {
|
||
children: [
|
||
(0, t.jsx)("div", { className: "fixed inset-0 z-40", onClick: e }),
|
||
(0, t.jsx)("div", {
|
||
className:
|
||
"tiny-scrollbar bg-panel-background/95 absolute left-4 top-full z-50 mt-1 max-h-[400px] min-w-[320px] overflow-auto rounded-xl border border-white/10 p-4 shadow-2xl backdrop-blur-md",
|
||
onClick: (e) => e.stopPropagation(),
|
||
children: n,
|
||
}),
|
||
],
|
||
});
|
||
}
|
||
let $ = {
|
||
table: (0, t.jsx)(a.Icons.table2, { width: 14, height: 14 }),
|
||
creative: (0, t.jsx)(a.Icons.palette, { width: 14, height: 14 }),
|
||
},
|
||
V = (0, n.memo)(function ({ views: e, activeViewId: n, onActivate: i }) {
|
||
return (0, t.jsx)("div", {
|
||
className:
|
||
"flex shrink-0 items-center gap-1 border-b border-white/[0.06] px-6",
|
||
style: { height: "36px" },
|
||
children: e.map((e) =>
|
||
(0, t.jsxs)(
|
||
"button",
|
||
{
|
||
type: "button",
|
||
onClick: () => i(e.id),
|
||
className: `flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs transition-colors ${e.id === n ? "bg-white/10 text-white" : "text-white/50 hover:bg-white/[0.06] hover:text-white/70"}`,
|
||
children: [$[e.type], (0, t.jsx)("span", { children: e.name })],
|
||
},
|
||
e.id,
|
||
),
|
||
),
|
||
});
|
||
}),
|
||
W = {
|
||
position: "absolute",
|
||
inset: 0,
|
||
borderRadius: "inherit",
|
||
zIndex: 45,
|
||
pointerEvents: "all",
|
||
cursor: "grab",
|
||
};
|
||
function K() {
|
||
return (0, t.jsx)("div", { style: W });
|
||
}
|
||
function q({ viewMode: e, onViewModeChange: i, disabled: r = !1 }) {
|
||
let [o, s] = (0, n.useState)(!1),
|
||
c = (0, n.useRef)(null),
|
||
l = [
|
||
{ value: "table", label: "脚本视图" },
|
||
{ value: "creative", label: "创意视图" },
|
||
],
|
||
u = l.find((t) => t.value === e)?.label ?? "脚本视图",
|
||
h = (0, n.useCallback)(
|
||
(e) => {
|
||
e.stopPropagation(), r || s((e) => !e);
|
||
},
|
||
[r],
|
||
),
|
||
f = (0, n.useCallback)(
|
||
(e) => {
|
||
i(e), s(!1);
|
||
},
|
||
[i],
|
||
),
|
||
d = (0, n.useCallback)((e) => {
|
||
c.current?.contains(e.relatedTarget) || s(!1);
|
||
}, []);
|
||
return (0, t.jsxs)("div", {
|
||
ref: c,
|
||
className: "nodrag relative",
|
||
onBlur: d,
|
||
tabIndex: -1,
|
||
children: [
|
||
(0, t.jsxs)("button", {
|
||
type: "button",
|
||
onClick: h,
|
||
disabled: r,
|
||
className: `flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-sm transition-colors ${r ? "text-fg-disabled cursor-not-allowed" : "text-fg-default hover:bg-canvas-controls-hover"}`,
|
||
children: [
|
||
(0, t.jsx)("span", {
|
||
className: "whitespace-nowrap",
|
||
children: u,
|
||
}),
|
||
(0, t.jsx)(a.Icons.lucideChevronDown, {
|
||
width: 14,
|
||
height: 14,
|
||
className: `transition-transform ${o ? "rotate-180" : ""}`,
|
||
}),
|
||
],
|
||
}),
|
||
o &&
|
||
!r &&
|
||
(0, t.jsx)("div", {
|
||
className:
|
||
"bg-panel-background absolute left-0 top-full z-50 mt-1 min-w-[120px] rounded-lg border border-white/10 py-1 shadow-xl",
|
||
children: l.map((n) =>
|
||
(0, t.jsxs)(
|
||
"button",
|
||
{
|
||
type: "button",
|
||
onClick: (e) => {
|
||
e.stopPropagation(), f(n.value);
|
||
},
|
||
className: `flex w-full items-center gap-2 px-3 py-1.5 text-left text-sm transition-colors hover:bg-white/10 ${e === n.value ? "text-fg-default" : "text-fg-muted"}`,
|
||
children: [
|
||
e === n.value &&
|
||
(0, t.jsx)(a.Icons.lucideCheck, {
|
||
width: 12,
|
||
height: 12,
|
||
}),
|
||
(0, t.jsx)("span", {
|
||
className: e === n.value ? "" : "ml-5",
|
||
children: n.label,
|
||
}),
|
||
],
|
||
},
|
||
n.value,
|
||
),
|
||
),
|
||
}),
|
||
],
|
||
});
|
||
}
|
||
function X(e) {
|
||
return {
|
||
shotNumber: e,
|
||
durationSeconds: 0,
|
||
plotDescription: "",
|
||
characters: [],
|
||
shotSize: "",
|
||
characterAction: "",
|
||
emotion: "",
|
||
sceneTags: "",
|
||
lightingAndAtmosphere: "",
|
||
audioEffects: "",
|
||
dialogue: "",
|
||
imageGenerationPrompt: "",
|
||
videoMotionPrompt: "",
|
||
hiddenUuid: crypto.randomUUID(),
|
||
};
|
||
}
|
||
let Y = (0, n.memo)(function ({ id: e, selected: F }) {
|
||
let U = (0, n.useMemo)(() => (0, x.selectNodeData)(e), [e]),
|
||
B = (0, n.useMemo)(() => (0, x.selectHasIncomingEdge)(e), [e]),
|
||
H = (0, n.useMemo)(() => (0, x.selectHasOutgoingEdge)(e), [e]),
|
||
G = (0, v.useCanvasStore)(U),
|
||
$ = (0, v.useCanvasStore)((e) => e.updateNodeData),
|
||
W = (0, v.useCanvasStore)((e) => e.addNode),
|
||
Y = (0, v.useCanvasStore)((e) => e.addNodes),
|
||
J = (0, v.useCanvasStore)((e) => e.addEdge),
|
||
Z = (0, v.useCanvasStore)((e) => e.isReadonly),
|
||
Q = (0, v.useCanvasStore)((e) => e.applyNodeChanges),
|
||
ee = (0, v.useCanvasStore)(B),
|
||
et = (0, v.useCanvasStore)(H),
|
||
en = (0, v.useCanvasStore)((e) => e.projectId),
|
||
ei = (0, v.useGlobalStore)((e) => e.getModel),
|
||
er = (0, v.useGlobalStore)((e) => e.defaultModel.text),
|
||
ea = (0, v.useGlobalStore)((e) => e.schema.text),
|
||
eo = (0, r.useReactFlow)(),
|
||
{ getNode: es } = (0, r.useReactFlow)(),
|
||
ec = (0, E.useShouldShowGenerator)(F, e),
|
||
el = (0, c.useIncomingNodeData)(e),
|
||
{ updateTaskInfo: eu } = (0, l.useCreateTaskInfo)(e),
|
||
eh = (0, C.useNodeWheelCapture)(!Z && !!F),
|
||
[ef, ed] = (0, n.useState)(!1),
|
||
ep = (0, n.useRef)(null),
|
||
[eg, eb] = (0, n.useState)(new Set());
|
||
(0, n.useEffect)(() => {
|
||
ec || ed(!1);
|
||
}, [ec]),
|
||
(0, n.useEffect)(() => {
|
||
if (ef) {
|
||
ep.current || (ep.current = eo.getViewport());
|
||
let t = v.stores.canvas?.nodes?.find((t) => t.id === e);
|
||
if (t) {
|
||
let e = t.position.x,
|
||
n = t.position.y;
|
||
if (t.parentId) {
|
||
let i = v.stores.canvas?.nodes?.find(
|
||
(e) => e.id === t.parentId,
|
||
);
|
||
i && ((e += i.position.x), (n += i.position.y));
|
||
}
|
||
let i = G?.nodeWidth ?? 800,
|
||
r = G?.nodeHeight ?? 400,
|
||
a = document.querySelector(".react-flow"),
|
||
o = a?.clientWidth ?? window.innerWidth,
|
||
s = (a?.clientHeight ?? window.innerHeight) - 100 - 120 - 32,
|
||
c = Math.min((o - 160) / i, s / r, 1.2),
|
||
l = o / 2 - (e + i / 2) * c,
|
||
u = 116 + s / 2 - (n + r / 2) * c;
|
||
eo.setViewport({ x: l, y: u, zoom: c }, { duration: 300 });
|
||
}
|
||
} else
|
||
ep.current &&
|
||
(eo.setViewport(ep.current, { duration: 300 }),
|
||
(ep.current = null));
|
||
}, [ef]),
|
||
(0, n.useEffect)(() => {
|
||
if (!ef) return;
|
||
let e = (e) => {
|
||
"Escape" === e.key && (e.stopPropagation(), ed(!1));
|
||
};
|
||
return (
|
||
window.addEventListener("keydown", e),
|
||
() => window.removeEventListener("keydown", e)
|
||
);
|
||
}, [ef]);
|
||
let em = (0, n.useCallback)(() => {
|
||
(0, m.reportLog)({
|
||
e: "libtv.canvas.script_generator.generate_storyboard.click",
|
||
}),
|
||
eb(
|
||
new Set((G?.rows ?? []).map((e) => e.hiddenUuid).filter(Boolean)),
|
||
),
|
||
ed(!0);
|
||
}, [G?.rows]),
|
||
ew = (0, n.useCallback)(() => ed(!1), []),
|
||
ev = (0, n.useCallback)(
|
||
(e) => {
|
||
ed(!1);
|
||
let t = eo
|
||
.getNodes()
|
||
.map((t) => ({ type: "select", id: t.id, selected: t.id === e }));
|
||
t.push({ type: "select", id: e, selected: !0 }),
|
||
Q(t),
|
||
setTimeout(() => {
|
||
let t = eo.getNode(e);
|
||
if (t) {
|
||
let e = t.measured?.width ?? t.width ?? 500,
|
||
n = t.measured?.height ?? t.height ?? 500;
|
||
eo.fitBounds(
|
||
{ x: t.position.x, y: t.position.y, width: e, height: n },
|
||
{ duration: 400, padding: 0.15 },
|
||
);
|
||
}
|
||
}, 150);
|
||
},
|
||
[eo, Q],
|
||
),
|
||
ex = (0, n.useCallback)((e) => {
|
||
eb(e);
|
||
}, []),
|
||
ey = G?.title,
|
||
e_ = ey || G?.name || G?.label || "脚本",
|
||
eS = (0, n.useCallback)((t) => $(e, { name: t }), [e, $]),
|
||
{
|
||
isConnectionTarget: eE,
|
||
isConnectionBlocked: eM,
|
||
isConnectionInvalid: eT,
|
||
nodeHovered: ek,
|
||
onNodeMouseEnter: eC,
|
||
onNodeMouseLeave: eA,
|
||
tiltStyle: eN,
|
||
handleTiltMove: eI,
|
||
} = (0, N.useConnection3DTilt)(e),
|
||
eP = !!F || ek,
|
||
eR = (0, k.isTaskGenerating)(G?.taskInfo),
|
||
eL = (0, k.isTaskFailed)(G?.taskInfo),
|
||
eD = G?.rows ?? [],
|
||
ej = G?.viewMode ?? "table",
|
||
eO = (0, n.useCallback)(() => {
|
||
if (0 === eD.length) return;
|
||
(0, m.reportLog)({
|
||
e: "libtv.canvas.script_generator.download.click",
|
||
});
|
||
let e = (e) =>
|
||
e.includes(",") ||
|
||
e.includes('"') ||
|
||
e.includes("\n") ||
|
||
e.includes("\r")
|
||
? `"${e.replace(/"/g, '""')}"`
|
||
: e,
|
||
t = eD.reduce((e, t) => Math.max(e, t.characters?.length ?? 0), 0),
|
||
n = g.SCRIPT_FIELD_META.findIndex(
|
||
(e) => "plotDescription" === e.key,
|
||
),
|
||
i = n >= 0 ? n + 1 : g.SCRIPT_FIELD_META.length,
|
||
r = g.SCRIPT_FIELD_META.slice(0, i),
|
||
a = g.SCRIPT_FIELD_META.slice(i),
|
||
o = [];
|
||
for (let e = 1; e <= t; e++)
|
||
o.push(`角色${e}`, `角色描述${e}`, `角色图${e}`);
|
||
let s = G?.shotColumns,
|
||
c = [
|
||
...r.map((e) => (0, g.getFieldLabel)(e.key, s)),
|
||
...o,
|
||
...a.map((e) => (0, g.getFieldLabel)(e.key, s)),
|
||
],
|
||
l = (e, t) => {
|
||
if ("videoReference" === t.key)
|
||
return e.videoReference?.referenceFrameImage ?? "";
|
||
let n = e[t.key];
|
||
return "string" == typeof n
|
||
? n
|
||
: "number" == typeof n
|
||
? String(n)
|
||
: "";
|
||
},
|
||
u = eD.map((n) => {
|
||
let i = r.map((e) => l(n, e)),
|
||
o = [];
|
||
for (let e = 0; e < t; e++) {
|
||
let t = n.characters?.[e];
|
||
o.push(
|
||
t?.characterName ?? "",
|
||
t?.characterDescription ?? "",
|
||
t?.characterImageUrl ?? "",
|
||
);
|
||
}
|
||
return [...i, ...o, ...a.map((e) => l(n, e))].map(e).join(",");
|
||
}),
|
||
h = new Blob(["\uFEFF" + [c.map(e).join(","), ...u].join("\n")], {
|
||
type: "text/csv;charset=utf-8;",
|
||
}),
|
||
f = URL.createObjectURL(h),
|
||
d = document.createElement("a");
|
||
(d.href = f),
|
||
(d.download = (0, y.formatDownloadFileName)(e_ || "脚本", "csv")),
|
||
d.click(),
|
||
URL.revokeObjectURL(f);
|
||
}, [eD, e_, G?.shotColumns]),
|
||
eF =
|
||
eR || eL
|
||
? eR
|
||
? "generating"
|
||
: "failed"
|
||
: eD.length > 0
|
||
? "resource"
|
||
: ee || et
|
||
? "pending"
|
||
: "empty_generate",
|
||
eU = "empty_generate" === eF,
|
||
eB = "pending" === eF,
|
||
eH = ec && !ef && !Z && (eD.length > 0 || eL),
|
||
ez = ec && !ef && (eU || eB || "resource" === eF || "failed" === eF),
|
||
eG = (0, n.useMemo)(
|
||
() =>
|
||
"resource" !== eF
|
||
? eD
|
||
: (eD.length > 0 ? eD : [X(1)]).map((e, t) => ({
|
||
...e,
|
||
shotNumber: t + 1,
|
||
})),
|
||
[eD, eF],
|
||
),
|
||
e$ = G?.nodeWidth ?? 800,
|
||
eV = G?.nodeHeight ?? 400,
|
||
eW = (0, n.useMemo)(
|
||
() => G?.views ?? g.DEFAULT_SCRIPT_VIEWS,
|
||
[G?.views],
|
||
),
|
||
eK = G?.activeViewId ?? "default",
|
||
eq = (0, n.useMemo)(
|
||
() => eW.find((e) => e.id === eK) ?? eW[0],
|
||
[eW, eK],
|
||
),
|
||
{
|
||
isFullScreen: eX,
|
||
openFullScreen: eY,
|
||
closeFullScreen: eJ,
|
||
} = (0, A.useNodeFullScreen)(),
|
||
eZ = (0, n.useCallback)(
|
||
(e) => {
|
||
let t = e.target;
|
||
t?.closest('[data-script-text-cell="true"]') ||
|
||
(e.stopPropagation(), eR || eY());
|
||
},
|
||
[eY, eR],
|
||
),
|
||
eQ = (0, n.useCallback)(
|
||
(t) => {
|
||
$(e, { viewMode: t });
|
||
},
|
||
[e, $],
|
||
),
|
||
e1 = (0, n.useCallback)(
|
||
(t) => {
|
||
let n = eW.find((e) => e.type === t);
|
||
n
|
||
? $(e, { activeViewId: n.id, viewMode: t })
|
||
: $(e, { viewMode: t });
|
||
},
|
||
[e, eW, $],
|
||
),
|
||
e0 = (0, n.useCallback)(
|
||
(t) => {
|
||
$(e, {
|
||
rows: (t.length > 0 ? t : [X(1)]).map((e, t) => ({
|
||
...e,
|
||
shotNumber: t + 1,
|
||
})),
|
||
});
|
||
},
|
||
[e, $],
|
||
),
|
||
e2 = (0, n.useCallback)(
|
||
(t) => {
|
||
if (!t) return;
|
||
let n = v.stores.canvas?.getNode(e);
|
||
$(e, {
|
||
resourceMeta: (0, S.mergeResourceMetaBundle)(n?.resourceMeta, t),
|
||
});
|
||
},
|
||
[e, $],
|
||
),
|
||
e3 = (0, n.useCallback)(
|
||
(t) => {
|
||
$(e, { activeViewId: t });
|
||
},
|
||
[e, $],
|
||
),
|
||
e4 = (0, n.useCallback)(
|
||
(t) => {
|
||
$(e, {
|
||
views: eW.map((e) =>
|
||
e.id === eK ? { ...e, tableConfig: t } : e,
|
||
),
|
||
});
|
||
},
|
||
[e, eW, eK, $],
|
||
),
|
||
e5 = (0, n.useCallback)(() => {
|
||
let t = es(e);
|
||
if (!t) return;
|
||
let n = crypto.randomUUID();
|
||
W({
|
||
id: n,
|
||
type: g.NodeType.TEXT,
|
||
data: {
|
||
type: g.NodeType.TEXT,
|
||
name: "文本",
|
||
content: [b.SCRIPT_PRESETS.textToScript.textPrompt],
|
||
action: g.NodeAction.TEXT_RESOURCE,
|
||
},
|
||
position: {
|
||
x: t.position.x - p.NODE_WIDTH - p.NODE_GAP,
|
||
y: t.position.y,
|
||
},
|
||
sourcePosition: i.Position.Right,
|
||
targetPosition: i.Position.Left,
|
||
}),
|
||
J({
|
||
id: crypto.randomUUID(),
|
||
source: n,
|
||
sourceHandle: "source",
|
||
target: e,
|
||
targetHandle: "target",
|
||
});
|
||
}, [e, es, W, J]),
|
||
e6 = (0, n.useCallback)(() => {
|
||
let t = es(e);
|
||
if (!t) return;
|
||
let n = crypto.randomUUID();
|
||
W({
|
||
id: n,
|
||
type: g.NodeType.VIDEO,
|
||
data: {
|
||
type: g.NodeType.VIDEO,
|
||
name: "视频",
|
||
url: [b.SCRIPT_PRESETS.videoToScript.videoUrl],
|
||
poster: "",
|
||
action: g.NodeAction.VIDEO_RESOURCE,
|
||
params: { prompt: b.SCRIPT_PRESETS.videoToScript.videoPrompt },
|
||
},
|
||
position: {
|
||
x: t.position.x - p.NODE_WIDTH - p.NODE_GAP,
|
||
y: t.position.y,
|
||
},
|
||
sourcePosition: i.Position.Right,
|
||
targetPosition: i.Position.Left,
|
||
}),
|
||
J({
|
||
id: crypto.randomUUID(),
|
||
source: n,
|
||
sourceHandle: "source",
|
||
target: e,
|
||
targetHandle: "target",
|
||
});
|
||
}, [e, es, W, J]),
|
||
e8 = (0, n.useCallback)(() => {
|
||
let t = es(e);
|
||
if (!t) return;
|
||
let n = t.position.x - p.NODE_WIDTH - p.NODE_GAP,
|
||
r = t.position.y + p.NODE_HEIGHT_EMPTY / 2,
|
||
a = Math.round(0.75 * p.NODE_WIDTH),
|
||
o = crypto.randomUUID(),
|
||
s = crypto.randomUUID();
|
||
Y([
|
||
{
|
||
id: o,
|
||
type: g.NodeType.IMAGE,
|
||
data: {
|
||
type: g.NodeType.IMAGE,
|
||
name: "角色 1",
|
||
url: [b.SCRIPT_PRESETS.characterToScript.characterImages[0]],
|
||
alt: "角色参考图 1",
|
||
action: g.NodeAction.IMAGE_RESOURCE,
|
||
},
|
||
position: { x: n, y: r - 20 - a },
|
||
sourcePosition: i.Position.Right,
|
||
targetPosition: i.Position.Left,
|
||
},
|
||
{
|
||
id: s,
|
||
type: g.NodeType.IMAGE,
|
||
data: {
|
||
type: g.NodeType.IMAGE,
|
||
name: "角色 2",
|
||
url: [b.SCRIPT_PRESETS.characterToScript.characterImages[1]],
|
||
alt: "角色参考图 2",
|
||
action: g.NodeAction.IMAGE_RESOURCE,
|
||
},
|
||
position: { x: n, y: r + 20 },
|
||
sourcePosition: i.Position.Right,
|
||
targetPosition: i.Position.Left,
|
||
},
|
||
]),
|
||
J({
|
||
id: crypto.randomUUID(),
|
||
source: o,
|
||
sourceHandle: "source",
|
||
target: e,
|
||
targetHandle: "target",
|
||
}),
|
||
J({
|
||
id: crypto.randomUUID(),
|
||
source: s,
|
||
sourceHandle: "source",
|
||
target: e,
|
||
targetHandle: "target",
|
||
}),
|
||
$(e, {
|
||
params: { prompt: b.SCRIPT_PRESETS.characterToScript.prompt },
|
||
action: g.NodeAction.SCRIPT_GENERATE,
|
||
});
|
||
}, [e, es, Y, J, $]),
|
||
e9 = (0, n.useCallback)(async () => {
|
||
(0, m.reportLog)({
|
||
e: "libtv.canvas.script_generator.regenerate.click",
|
||
});
|
||
let t = G?.params?.model || er,
|
||
n = ea ? (ea[t] ?? null) : null,
|
||
i = (0, h.initScriptGeneratorParams)(G?.params, n, t),
|
||
r = {
|
||
...i,
|
||
scene: "script-generate",
|
||
textList: el.textList,
|
||
imageList: (0, u.applyMediaListOrder)(
|
||
el.imageList,
|
||
i.imageListOrder,
|
||
),
|
||
videoList: (0, u.applyMediaListOrder)(
|
||
el.videoList,
|
||
i.videoListOrder,
|
||
),
|
||
audioList: (0, u.applyMediaListOrder)(
|
||
el.audioList,
|
||
i.audioListOrder,
|
||
),
|
||
};
|
||
eu({ loading: !0, taskId: "" });
|
||
try {
|
||
let t = (0, _.buildRequestData)(r, "text", e, en, ei);
|
||
(0, m.reportLog)({
|
||
e: "libtv.canvas.generator.submit",
|
||
var: { generator_type: "脚本生成器", use_slash: !1, use_at: !1 },
|
||
});
|
||
let n = await (0, w.submitGenerationTask)(t);
|
||
if (n.success) {
|
||
if (!n.taskId) {
|
||
o.Notify.error("任务创建成功但缺少 taskId,请重试"),
|
||
eu({ loading: !1 });
|
||
return;
|
||
}
|
||
eu({ taskId: n.taskId, loading: !0 });
|
||
} else
|
||
n.handledByCommercial || o.Notify.error(n.errorMsg ?? "生成失败"),
|
||
eu({
|
||
loading: !1,
|
||
status: 3,
|
||
failedReason: n.errorMsg ?? "网络异常,请重试",
|
||
});
|
||
} catch {
|
||
o.Notify.error("网络异常,请重试"),
|
||
eu({ loading: !1, status: 3, failedReason: "网络异常,请重试" });
|
||
}
|
||
}, [G?.params, er, ea, el, eu, e, en, ei]),
|
||
e7 = (0, n.useCallback)(() => {
|
||
if (!eq) return null;
|
||
switch (eq.type) {
|
||
case "table":
|
||
return (0, t.jsx)(O.default, {
|
||
rows: eG,
|
||
onRowsChange: e0,
|
||
onResourceMetaChange: e2,
|
||
tableConfig: eq.tableConfig,
|
||
onTableConfigChange: e4,
|
||
shotColumns: G?.shotColumns,
|
||
});
|
||
case "creative":
|
||
return (0, t.jsx)(L.default, { rows: eG });
|
||
default:
|
||
return null;
|
||
}
|
||
}, [eq, eG, e0, e2, e4]);
|
||
return eU
|
||
? (0, t.jsxs)("div", {
|
||
className: "relative",
|
||
style: { overflow: "visible", width: "fit-content" },
|
||
children: [
|
||
(0, t.jsx)(M.default, {
|
||
nodeId: e,
|
||
label: "脚本生成器",
|
||
icon: (0, t.jsx)(P.TextIcon, { size: 14 }),
|
||
onLabelChange: eS,
|
||
readOnly: !0,
|
||
maxWidth: p.NODE_WIDTH,
|
||
}),
|
||
(0, t.jsxs)("div", {
|
||
ref: eh,
|
||
className:
|
||
"node-shell relative flex flex-col overflow-hidden rounded-xl",
|
||
"data-nodeid": e,
|
||
style: {
|
||
width: `${p.NODE_WIDTH}px`,
|
||
height: `${p.NODE_HEIGHT_EMPTY}px`,
|
||
background: "var(--Surface-secondary-background, #262626)",
|
||
border: "1px solid var(--canvas-node-border)",
|
||
outline: F
|
||
? "2px solid var(--canvas-node-border-selected)"
|
||
: "none",
|
||
outlineOffset: "-1px",
|
||
...eN,
|
||
},
|
||
onMouseEnter: eC,
|
||
onMouseLeave: eA,
|
||
onMouseMove: eI,
|
||
children: [
|
||
(0, t.jsx)(I.TargetHandle, { visible: eP }),
|
||
(0, t.jsx)(N.default, { active: eE, invalid: eT }),
|
||
(0, t.jsx)(N.NodeFrostedOverlay, { active: eM || eT }),
|
||
Z && (0, t.jsx)(K, {}),
|
||
(0, t.jsx)(T.default, {
|
||
icon: (0, t.jsx)(P.Text2Icon, {
|
||
size: 90,
|
||
className: "text-fg-disabled",
|
||
}),
|
||
isReadonly: Z,
|
||
actions: [
|
||
{
|
||
icon: (0, t.jsx)(a.Icons.alignJustify, {
|
||
width: 14,
|
||
height: 14,
|
||
}),
|
||
label: "剧本生成分镜脚本",
|
||
onClick: e5,
|
||
},
|
||
{
|
||
icon: (0, t.jsx)(a.Icons.video, {
|
||
width: 14,
|
||
height: 14,
|
||
}),
|
||
label: "视频参考生成分镜脚本",
|
||
onClick: e6,
|
||
},
|
||
{
|
||
icon: (0, t.jsx)(a.Icons.user, {
|
||
width: 14,
|
||
height: 14,
|
||
}),
|
||
label: "角色生成分镜脚本",
|
||
onClick: e8,
|
||
},
|
||
],
|
||
}),
|
||
(0, t.jsx)(I.SourceHandle, { visible: eP }),
|
||
],
|
||
}),
|
||
ez &&
|
||
(0, t.jsx)(s.GeneratorFactory, {
|
||
nodeType: g.NodeType.SCRIPT,
|
||
nodeId: e,
|
||
incomingData: el,
|
||
}),
|
||
],
|
||
})
|
||
: eB
|
||
? (0, t.jsxs)("div", {
|
||
className: "relative",
|
||
style: { overflow: "visible", width: "fit-content" },
|
||
children: [
|
||
(0, t.jsxs)("div", {
|
||
className:
|
||
"node-shell relative flex flex-col overflow-hidden rounded-xl",
|
||
"data-nodeid": e,
|
||
style: {
|
||
width: `${p.NODE_WIDTH}px`,
|
||
height: `${p.NODE_HEIGHT_EMPTY}px`,
|
||
background: "var(--Surface-Panel-background, #171717)",
|
||
border: "1px solid var(--canvas-node-border)",
|
||
outline: F
|
||
? "2px solid var(--canvas-node-border-selected)"
|
||
: "none",
|
||
outlineOffset: "-1px",
|
||
...eN,
|
||
},
|
||
onMouseEnter: eC,
|
||
onMouseLeave: eA,
|
||
onMouseMove: eI,
|
||
children: [
|
||
(0, t.jsx)(I.TargetHandle, { visible: eP }),
|
||
(0, t.jsx)(N.default, { active: eE, invalid: eT }),
|
||
(0, t.jsx)(N.NodeFrostedOverlay, { active: eM || eT }),
|
||
Z && (0, t.jsx)(K, {}),
|
||
(0, t.jsx)("div", {
|
||
className: "flex h-full items-center justify-center",
|
||
children: (0, t.jsx)(P.Text2Icon, {
|
||
size: 90,
|
||
className: "text-fg-disabled",
|
||
}),
|
||
}),
|
||
(0, t.jsx)(I.SourceHandle, { visible: eP }),
|
||
],
|
||
}),
|
||
ez &&
|
||
(0, t.jsx)(s.GeneratorFactory, {
|
||
nodeType: g.NodeType.SCRIPT,
|
||
nodeId: e,
|
||
incomingData: el,
|
||
}),
|
||
],
|
||
})
|
||
: (0, t.jsxs)("div", {
|
||
className: "relative",
|
||
style: { overflow: "visible", width: "fit-content" },
|
||
children: [
|
||
eH &&
|
||
(0, t.jsx)(d.default, {
|
||
nodeId: e,
|
||
baseOffset: 12,
|
||
children: (0, t.jsx)(D.ScriptFloatingToolbar, {
|
||
onRegenerate: () => {
|
||
e9();
|
||
},
|
||
onGenerateStoryboard: em,
|
||
onExport: eO,
|
||
disableRegenerate: eR,
|
||
disableStoryboard: eR,
|
||
disableExport: eR,
|
||
}),
|
||
}),
|
||
(0, t.jsxs)("div", {
|
||
ref: eh,
|
||
className:
|
||
"node-shell relative flex flex-col overflow-hidden rounded-xl",
|
||
"data-nodeid": e,
|
||
style: {
|
||
width: `${e$}px`,
|
||
height: `${eV}px`,
|
||
background: "var(--Surface-Panel-background, #171717)",
|
||
border: "1px solid var(--canvas-node-border)",
|
||
outline: F
|
||
? "2px solid var(--canvas-node-border-selected)"
|
||
: "none",
|
||
outlineOffset: "-1px",
|
||
...eN,
|
||
},
|
||
onMouseEnter: eC,
|
||
onMouseLeave: eA,
|
||
onMouseMove: eI,
|
||
children: [
|
||
(0, t.jsx)(I.TargetHandle, { visible: eP }),
|
||
(0, t.jsx)(N.default, { active: eE, invalid: eT }),
|
||
(0, t.jsx)(N.NodeFrostedOverlay, { active: eM || eT }),
|
||
Z && (0, t.jsx)(K, {}),
|
||
(0, t.jsxs)("div", {
|
||
className:
|
||
"flex shrink-0 cursor-grab items-center justify-between border-b border-white/10 px-3 active:cursor-grabbing",
|
||
style: { height: "40px" },
|
||
onDoubleClick: eZ,
|
||
children: [
|
||
(0, t.jsx)(M.default, {
|
||
nodeId: e,
|
||
label: e_,
|
||
onLabelChange: eS,
|
||
readOnly: Z || !!ey,
|
||
variant: "inline",
|
||
}),
|
||
(0, t.jsxs)("div", {
|
||
className: "flex shrink-0 items-center gap-1",
|
||
children: [
|
||
(0, t.jsx)(q, {
|
||
viewMode: ej,
|
||
onViewModeChange: eQ,
|
||
disabled: eR,
|
||
}),
|
||
(0, t.jsx)("button", {
|
||
type: "button",
|
||
onClick: eR ? void 0 : eY,
|
||
disabled: eR,
|
||
className: `nodrag flex items-center justify-center rounded-md p-1.5 transition-colors ${eR ? "text-fg-disabled cursor-not-allowed" : "text-fg-muted hover:bg-canvas-controls-hover hover:text-fg-default"}`,
|
||
title: "全屏展开",
|
||
children: (0, t.jsx)(a.Icons.BroadPicture, {
|
||
width: 16,
|
||
height: 16,
|
||
}),
|
||
}),
|
||
],
|
||
}),
|
||
],
|
||
}),
|
||
(0, t.jsx)("div", {
|
||
className: `min-h-0 flex-1${F ? " nodrag cursor-default" : ""}`,
|
||
onDoubleClick: eZ,
|
||
children: eR
|
||
? (0, t.jsx)(j.default, { taskInfo: G?.taskInfo })
|
||
: eL
|
||
? (0, t.jsx)(k.default, {
|
||
taskInfo: G?.taskInfo,
|
||
nodeId: e,
|
||
})
|
||
: "table" === ej
|
||
? (0, t.jsx)(O.default, {
|
||
rows: eG,
|
||
onRowsChange: e0,
|
||
onResourceMetaChange: e2,
|
||
shotColumns: G?.shotColumns,
|
||
readonly: !0,
|
||
showSelection: ef,
|
||
selectedRowIds: eg,
|
||
onSelectionChange: ex,
|
||
})
|
||
: (0, t.jsx)(L.default, {
|
||
rows: eG,
|
||
showSelection: ef,
|
||
selectedRowIds: eg,
|
||
onSelectionChange: ex,
|
||
}),
|
||
}),
|
||
(0, t.jsx)(I.SourceHandle, { visible: eP }),
|
||
],
|
||
}),
|
||
ez &&
|
||
(0, t.jsx)(s.GeneratorFactory, {
|
||
nodeType: g.NodeType.SCRIPT,
|
||
nodeId: e,
|
||
incomingData: el,
|
||
}),
|
||
ef &&
|
||
(0, t.jsx)(f.default, {
|
||
className: "absolute left-1/2 origin-top -translate-x-1/2",
|
||
style: { top: "calc(100% + 8px)" },
|
||
children: (0, t.jsx)(R.ScriptAggregatedGenerator, {
|
||
nodeId: e,
|
||
onClose: ew,
|
||
selectedCount: eg.size,
|
||
totalCount: eG.length,
|
||
selectedRowIds: eg,
|
||
onGenerated: ev,
|
||
}),
|
||
}),
|
||
(0, t.jsxs)(A.NodeFullScreenOverlay, {
|
||
open: eX,
|
||
onClose: eJ,
|
||
title: e_,
|
||
headerExtra: (0, t.jsx)(q, {
|
||
viewMode: eq?.type ?? ej,
|
||
onViewModeChange: e1,
|
||
}),
|
||
children: [
|
||
(0, t.jsx)(V, {
|
||
views: eW,
|
||
activeViewId: eK,
|
||
onActivate: e3,
|
||
}),
|
||
eq?.type === "table" &&
|
||
(0, t.jsx)(z, {
|
||
rows: eG,
|
||
tableConfig: eq.tableConfig,
|
||
onTableConfigChange: e4,
|
||
shotColumns: G?.shotColumns,
|
||
}),
|
||
(0, t.jsx)("div", {
|
||
className:
|
||
"tiny-scrollbar min-h-0 flex-1 overflow-auto px-6 pb-4 pt-2",
|
||
children: e7(),
|
||
}),
|
||
],
|
||
}),
|
||
],
|
||
});
|
||
});
|
||
(Y.displayName = "ScriptNode"), e.s(["default", 0, Y], 385951);
|
||
};
|
||
|
||
export default moduleFactory;
|