Your Name 1912bcd25b
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
chore: sync all remaining local workspace changes
2026-05-08 11:26:57 +08:00

1910 lines
76 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Extracted from browser-delivered Turbopack chunk: fd0220e4d10052af.701bdafa2d.js
* Module id: 142838
* 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(111558),
r = e.i(549116);
e.i(606823);
var a = e.i(471454),
o = e.i(844567),
s = e.i(476293),
c = e.i(284309),
l = e.i(532354),
u = e.i(41671),
h = e.i(777784),
f = e.i(646554),
d = e.i(944733),
p = e.i(458390),
g = e.i(68058),
b = e.i(637591),
m = e.i(373518),
w = e.i(216257),
v = e.i(253237),
x = e.i(791997),
y = e.i(704030),
_ = e.i(33725),
S = e.i(529833),
E = e.i(501716),
M = e.i(630379),
T = e.i(771705),
k = e.i(733077),
C = e.i(41114),
A = e.i(749967),
N = e.i(734911),
I = e.i(610582),
P = e.i(247232),
R = e.i(145239),
L = e.i(732030),
D = e.i(194940),
j = e.i(384916),
O = e.i(763910),
F = e.i(687517);
e.i(370357);
var U = e.i(492394),
B = e.i(524961),
H = e.i(211478),
z = e.i(677588),
G = e.i(416501);
let $ = [
{ value: "phone", label: "手机" },
{ value: "wechat", label: "微信" },
],
V = {
input:
"h-8 min-h-8 rounded-lg border-hair border-input-border bg-input text-[13px] text-fg-default placeholder:text-(--input-placeholder)",
},
W = {
input:
"h-8 min-h-8 cursor-not-allowed rounded-lg border-hair border-input-border bg-bg-surface-secondary text-[13px] text-fg-muted",
},
K = {
input:
"h-8 min-h-8 rounded-lg border-hair border-input-border bg-input text-[13px] text-fg-default",
option:
"text-fg-default mb-1 transition-colors last:mb-0 rounded-lg hover:bg-btn-ghost-hover data-[combobox-active]:bg-btn-ghost-hover data-[combobox-active]:text-fg-default data-[combobox-selected]:bg-btn-ghost-active data-[combobox-selected]:text-fg-default",
},
q = {
input:
"min-h-[80px] rounded-lg border-hair border-input-border bg-input text-[13px] text-fg-default placeholder:text-(--input-placeholder)",
};
function X({
trigger: e,
campaignData: i,
onSuccess: r,
onClose: a,
opened: o,
onOpenedChange: s,
onCloseResult: c,
}) {
let { activityName: l, activityId: f, tagId: d } = i,
{ isLogin: p } = (0, F.useLoginHook)(),
{ currentLoginUserInfo: g } = (0, U.usePersonalInfo)(),
{ openLogin: b } = (0, H.useLogin)(),
[m, w] = (0, n.useState)(!1),
v = void 0 !== o,
x = v ? o : m,
[y, _] = (0, n.useState)(!1),
[S, E] = (0, n.useState)("phone"),
[M, T] = (0, n.useState)(""),
[k, C] = (0, n.useState)(""),
[A, I] = (0, n.useState)(""),
[D, j] = (0, n.useState)(""),
[O, X] = (0, n.useState)(!1),
Y = (0, n.useRef)(p);
(0, n.useEffect)(() => {
p && !Y.current && y && (_(!1), v ? s?.(!0) : w(!0)), (Y.current = p);
}, [p, y, v, s]);
let J = (0, n.useCallback)(() => {
if (!p) {
_(!0), b({ closeOnClickOutside: !1 });
return;
}
v ? s?.(!0) : w(!0);
}, [p, b, v, s]),
Z = (0, n.useCallback)(
(e = !1) => {
v ? s?.(!1) : w(!1), a?.(), c?.(e);
},
[a, s, c, v],
),
Q = (0, n.useCallback)(async () => {
let e = g?.nickname ?? g?.nickName ?? "";
if (!e) return void h.Notify.error("请先登录");
let t = M.trim();
if (!t) return void h.Notify.error("请填写联系方式");
if (!k.trim()) return void h.Notify.error("请填写社媒主页链接");
let n = "wechat" === S ? `wechat:${t}` : `phone:${t}`,
i = D.split(/[\n,,]/)
.map((e) => e.trim())
.filter(Boolean),
a = i.length > 0 ? i.join(",") : void 0;
X(!0);
try {
let t = {
activityId: Number(f),
tagId: d,
name: e,
contactInfo: n,
personalHomepageUrl: k.trim() || "",
inviteCode: A.trim() || "",
workUrl: a,
description: "",
};
(0, z.reportLog)({
e: "libtv.challenge.register_submit.click",
var: { register_params: JSON.stringify(t) },
}),
await (0, G.submitRegistration)(t),
h.Notify.success("报名成功"),
Z(!0),
r?.();
} catch (e) {
h.Notify.error(e instanceof Error ? e.message : "报名失败,请重试");
} finally {
X(!1);
}
}, [g, S, M, k, A, D, Z, r]),
ee = g?.nickname ?? g?.nickName ?? "";
return (0, t.jsxs)(t.Fragment, {
children: [
!v &&
(e
? (0, t.jsx)("div", {
onClick: J,
onKeyDown: (e) => "Enter" === e.key && J(),
role: "button",
tabIndex: 0,
children: e,
})
: (0, t.jsx)(B.Button, {
variant: "filled",
color: "blue",
size: "sm",
onClick: J,
leftSection: (0, t.jsx)(u.Icons.Editt, {
className: "size-4",
}),
children: "报名",
})),
(0, t.jsxs)(N.Modal, {
opened: x,
onClose: () => Z(!1),
title: "挑战赛报名",
centered: !0,
size: 480,
classNames: {
header:
"flex items-center justify-between border-b border-border-default px-4 pb-3",
body: "px-4 pb-4 pt-4",
content:
"w-[480px] max-w-[min(90vw,480px)] rounded-xl border-hair border-border-default bg-bg-surface text-fg-default",
title: "text-sm font-medium text-fg-default",
close: "text-fg-muted hover:text-fg-default",
},
children: [
(0, t.jsxs)("div", {
className: "flex max-h-[520px] flex-col gap-4 overflow-y-auto",
children: [
(0, t.jsxs)("div", {
className: "flex flex-col gap-2",
children: [
(0, t.jsx)("label", {
className: "text-fg-default text-sm",
children: "活动名称",
}),
(0, t.jsx)("p", {
className: "text-fg-muted text-sm",
children: l,
}),
],
}),
(0, t.jsxs)("div", {
className: "flex flex-col gap-2",
children: [
(0, t.jsx)("label", {
className: "text-fg-default text-sm",
children: "昵称",
}),
(0, t.jsx)(L.TextInput, {
value: ee,
readOnly: !0,
classNames: W,
className: "w-full cursor-not-allowed",
}),
],
}),
(0, t.jsxs)("div", {
className: "flex flex-col gap-2",
children: [
(0, t.jsxs)("label", {
className: "text-fg-default text-sm",
children: [
"联系方式 ",
(0, t.jsx)("span", {
className: "text-status-error",
children: "*",
}),
],
}),
(0, t.jsxs)("div", {
className: "flex gap-2",
children: [
(0, t.jsx)(P.Select, {
placeholder: "手机/微信",
value: S,
onChange: E,
data: $,
classNames: K,
className: "w-[160px] shrink-0",
rightSectionPointerEvents: "none",
withCheckIcon: !1,
styles: {
dropdown: {
backgroundColor: "var(--popover-bg)",
backdropFilter: "blur(16px)",
WebkitBackdropFilter: "blur(16px)",
border: "1px solid var(--popover-border)",
borderRadius: "12px",
padding: "6px",
boxShadow: "var(--canvas-shadow-menu)",
},
},
}),
(0, t.jsx)(L.TextInput, {
placeholder: "请输入手机号或微信号",
value: M,
onChange: (e) => T(e.target.value),
classNames: V,
className: "flex-1",
}),
],
}),
],
}),
(0, t.jsxs)("div", {
className: "flex flex-col gap-2",
children: [
(0, t.jsxs)("label", {
className: "text-fg-default text-sm",
children: [
"邀请码",
(0, t.jsx)("span", {
className: "text-fg-subtle",
children: "(可选)",
}),
],
}),
(0, t.jsx)(L.TextInput, {
placeholder: "请输入邀请码",
value: A,
onChange: (e) => I(e.target.value),
classNames: V,
}),
],
}),
(0, t.jsxs)("div", {
className: "flex flex-col gap-2",
children: [
(0, t.jsxs)("label", {
className: "text-fg-default text-sm",
children: [
"社媒主页链接",
(0, t.jsx)("span", {
className: "text-status-error",
children: "*",
}),
],
}),
(0, t.jsx)(L.TextInput, {
placeholder:
"填写您的社媒主页链接,如,小红书、B站、抖音等",
value: k,
onChange: (e) => C(e.target.value),
classNames: V,
}),
(0, t.jsx)("p", {
className: "text-fg-muted text-xs",
children:
"提交您具有相关AI作品的社媒主页,报名后获得启动积分的机会将大大提升!",
}),
],
}),
(0, t.jsxs)("div", {
className: "flex flex-col gap-2",
children: [
(0, t.jsxs)("label", {
className: "text-fg-default text-sm",
children: [
"添加AI创作的视频作品",
(0, t.jsx)("span", {
className: "text-fg-subtle",
children: "(可选)",
}),
],
}),
(0, t.jsx)(R.Textarea, {
placeholder: "请添加1-3条您使用AI创作的视频作品链接",
value: D,
onChange: (e) => j(e.target.value),
classNames: q,
minRows: 3,
autosize: !0,
}),
],
}),
],
}),
(0, t.jsxs)("div", {
className: "mt-4 flex justify-end gap-3",
children: [
(0, t.jsx)(B.Button, {
unstyled: !0,
className:
"text-fg-default bg-btn-ghost-hover hover:bg-btn-ghost-active flex h-8 min-h-8 items-center justify-center rounded-lg px-3 text-[13px] dark:bg-white/10 dark:text-white dark:hover:bg-white/20",
onClick: () => Z(!1),
children: "取消",
}),
(0, t.jsx)(B.Button, {
unstyled: !0,
className:
"bg-btn-primary text-btn-primary-text hover:bg-btn-primary-hover active:bg-btn-primary-active flex h-8 min-h-8 items-center justify-center rounded-lg px-3 text-[13px] disabled:cursor-not-allowed disabled:opacity-60",
loading: O,
loaderProps: { size: 16, color: "var(--btn-primary-text)" },
onClick: () => void Q(),
children: "提交报名",
}),
],
}),
],
}),
],
});
}
e.s(["default", () => X], 142838);
var Y = e.i(505e3),
J = e.i(635287),
Z = e.i(396805);
let Q = {
name: "",
description: "",
finalOutputUrl: null,
coverUrl: null,
isPublic: !0,
tagId: 0,
trackId: null,
socialMediaUrl: "",
},
ee = (0, Z.createWithEqualityFn)(
(e) => ({
...Q,
updateDraft: (t) => e((e) => ({ ...e, ...t })),
resetDraft: () => e(Q),
}),
Object.is,
);
e.i(135623);
var et = e.i(168823);
e.i(954175);
var en = e.i(616803),
ei = e.i(301710);
let er = (e) => ({
backgroundColor: "transparent",
border: `1px solid ${e.error ? "rgba(239, 68, 68, 0.6)" : "var(--canvas-controls-border)"}`,
color: "var(--canvas-controls-text)",
borderRadius: "8px",
"&:focus": {
borderColor: e.error
? "rgba(239, 68, 68, 0.85)"
: "var(--color-brand-400)",
},
"&::placeholder": {
color: "var(--canvas-controls-text)",
opacity: 0.35,
},
}),
ea = {
dropdown: {
backgroundColor: "var(--canvas-controls-bg)",
color: "var(--canvas-controls-text)",
backdropFilter: "blur(16px)",
WebkitBackdropFilter: "blur(16px)",
border: "0.5px solid var(--canvas-controls-border)",
borderRadius: "12px",
padding: "6px",
boxShadow: "var(--canvas-shadow-dropdown)",
},
input: {
backgroundColor: "transparent",
border: "1px solid var(--canvas-controls-border)",
color: "var(--canvas-controls-text)",
borderRadius: "8px",
height: 32,
minHeight: 32,
fontSize: 13,
"&:focus": { borderColor: "var(--color-brand-400)" },
"&::placeholder": {
color: "var(--canvas-controls-text)",
opacity: 0.35,
},
},
},
eo = {
option:
"mb-1 last:mb-0 rounded-lg text-canvas-controls-text/85 transition-colors hover:bg-canvas-controls-hover hover:text-canvas-controls-text data-[combobox-active]:bg-canvas-controls-hover data-[combobox-active]:text-canvas-controls-text data-[combobox-selected]:bg-canvas-controls-active data-[combobox-selected]:text-canvas-controls-text data-[combobox-selected]:ring-1 data-[combobox-selected]:ring-canvas-controls-border",
};
function es({
label: e,
accept: i,
previewUrl: r,
onUpload: a,
uploading: o,
setUploading: s,
previewType: c = "image",
galleryMediaType: l,
showError: f = !1,
needMediaAudit: d = !1,
hint: p,
}) {
let g = (0, x.useCanvasThemeStore)((e) => "light" === e.theme),
b = (0, n.useRef)(null),
m = (0, n.useRef)(null),
w = (0, n.useRef)(null),
[v, y] = (0, n.useState)(""),
[_, S] = (0, n.useState)(null),
[E, M] = (0, n.useState)(!1),
T = (0, n.useRef)(0);
(0, n.useEffect)(
() => () => {
T.current += 1;
},
[],
),
(0, n.useEffect)(() => {
if (!_) return;
let e = (e) => {
let t = e.target;
m.current?.contains(t) || w.current?.contains(t) || S(null);
};
return (
document.addEventListener("mousedown", e),
() => document.removeEventListener("mousedown", e)
);
}, [_]);
let k = (0, n.useCallback)(
async (e) => {
let t = e.target.files?.[0];
if (!t) return;
e.target.value = "";
let n = (0, et.getCookie)(Y.USER_TOKEN_COOKIE_KEY),
i = (0, et.getCookie)(Y.USER_UUID_COOKIE_KEY);
if (!n || "string" != typeof n || !i || "string" != typeof i)
return void h.Notify.error("请先登录");
T.current += 1;
let r = T.current,
o = () => T.current !== r;
a("", t), s(!0), y("上传中(0%)...");
try {
let e =
t.type.startsWith("video/") || t.type.startsWith("audio/"),
r = await (0, ei.uploadViaPreSign)(t, {
token: n,
uuid: i,
onCalcHashEnd: () => void 0,
onProgress: (e) => {
if (o()) return;
let t = Math.min(100, Math.max(0, Math.round(100 * e)));
y(`上传中(${t}%)...`);
},
verify: !e,
});
if (o()) return;
let s = (0, ei.resolveUploadUrl)(r);
if (!s) return void h.Notify.error("上传失败");
if (d && e) {
let e = t.type.startsWith("video/")
? en.AuditContentType.VIDEO
: en.AuditContentType.AUDIO;
try {
await (0, en.pollMediaAudit)(s, e, o);
} catch (e) {
o() ||
h.Notify.error(
e instanceof en.MediaAuditError
? e.message
: "审核失败,请重试",
);
return;
}
}
o() || a(s, t);
} catch (e) {
o() ||
h.Notify.error(
e instanceof en.FileReviewError
? "封面审核未通过"
: "上传失败,请重试",
);
} finally {
s(!1), y("");
}
},
[a, s, d],
),
A = (0, n.useCallback)(
(e, t) => {
o ||
S((n) =>
n
? null
: {
position: "fixed",
top: t + 6,
left: e,
width: 100,
zIndex: 9999,
},
);
},
[o],
),
N = (0, n.useCallback)(() => {
o || (S(null), b.current?.click());
}, [o]),
P = (0, n.useCallback)(
(e) => {
let t,
n = e[0];
if (!n) return;
if (n.mediaType !== l)
return void h.Notify.error(
"video" === l ? "请选择视频素材" : "请选择图片素材",
);
let i =
((t = n.raw),
"video" === n.mediaType
? t.videoUrl ||
t.originalVideoUrl ||
t.previewPath ||
n.thumbnailUrl ||
""
: "audio" === n.mediaType
? t.audioUrl || t.previewPath || n.thumbnailUrl || ""
: n.thumbnailUrl || t.imageUrl || t.url || "");
i ? (a(i), M(!1)) : h.Notify.error("未获取到可用素材链接");
},
[l, a],
),
R = f && !r && !o;
return (0, t.jsxs)("div", {
className: "relative flex-1",
children: [
(0, t.jsx)("input", {
ref: b,
type: "file",
accept: i,
onChange: (e) => void k(e),
className: "hidden",
}),
(0, t.jsx)("div", {
ref: m,
role: "button",
tabIndex: 0,
onClick: (e) => A(e.clientX, e.clientY),
onKeyDown: (e) => {
if ("Enter" !== e.key) return;
e.preventDefault();
let t = e.currentTarget.getBoundingClientRect();
A(t.left, t.bottom);
},
className: `border-canvas-controls-border bg-canvas-controls-hover hover:bg-canvas-controls-active canvas-light:bg-white canvas-light:hover:bg-[#F7F7F7] relative flex h-[120px] cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border transition-colors ${R ? "border-red-500/60" : ""}`,
children: o
? (0, t.jsxs)("div", {
className: "flex flex-col items-center gap-2",
children: [
(0, t.jsxs)("svg", {
className:
"text-canvas-controls-text/40 size-6 animate-spin",
viewBox: "0 0 24 24",
fill: "none",
children: [
(0, t.jsx)("circle", {
cx: "12",
cy: "12",
r: "10",
stroke: "currentColor",
strokeWidth: "2",
opacity: "0.3",
}),
(0, t.jsx)("path", {
d: "M12 2a10 10 0 0 1 10 10",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
}),
],
}),
(0, t.jsx)("span", {
className: "text-canvas-controls-text/50 text-xs",
children: v || "上传中...",
}),
],
})
: r
? (0, t.jsxs)("div", {
className: "group/preview relative h-full w-full",
children: [
"video" === c
? (0, t.jsx)("video", {
src: r,
loop: !0,
muted: !0,
playsInline: !0,
autoPlay: !0,
className: "h-full w-full rounded-lg object-cover",
})
: (0, t.jsx)("img", {
src: r,
alt: e,
className: "h-full w-full rounded-lg object-cover",
}),
(0, t.jsx)("span", {
className:
"bg-canvas-controls-bg/90 text-canvas-controls-text absolute left-2 top-2 rounded-lg px-2 py-1 text-[13px] backdrop-blur-sm",
children: "video" === c ? "作品" : "封面",
}),
(0, t.jsxs)("span", {
className:
"bg-canvas-controls-bg/90 text-canvas-controls-text absolute right-2 top-2 flex items-center gap-1 rounded-lg px-2 py-1 text-[13px] opacity-0 backdrop-blur-sm transition-opacity group-hover/preview:opacity-100",
children: [
(0, t.jsx)(u.Icons.plus, { className: "size-3" }),
"替换",
],
}),
],
})
: (0, t.jsxs)(t.Fragment, {
children: [
(0, t.jsx)(u.Icons.plus, {
className: "text-canvas-controls-icon mb-1 size-3",
}),
(0, t.jsx)("span", {
className: "text-canvas-controls-text/70 text-sm",
children: e,
}),
(0, t.jsx)("span", {
className: `absolute bottom-4 left-1/2 -translate-x-1/2 text-xs ${p ? "text-canvas-controls-text/45" : "invisible"}`,
children: p || e,
}),
],
}),
}),
_ &&
(0, t.jsx)(I.Portal, {
children: (0, t.jsxs)("div", {
ref: w,
style: _,
className: (0, C.cn)(
"border-canvas-controls-border bg-canvas-controls shadow-canvas-dropdown rounded-lg border p-1",
g && "canvas-light",
),
children: [
(0, t.jsx)("button", {
type: "button",
onClick: N,
className:
"text-canvas-controls-text hover:bg-canvas-controls-hover w-full cursor-pointer rounded-md px-3 py-2 text-left text-xs transition-colors",
children: "本地上传",
}),
(0, t.jsx)("button", {
type: "button",
onClick: () => {
S(null), M(!0);
},
className:
"text-canvas-controls-text hover:bg-canvas-controls-hover w-full cursor-pointer rounded-md px-3 py-2 text-left text-xs transition-colors",
children: "历史图库",
}),
],
}),
}),
R &&
(0, t.jsxs)("p", {
className: "mt-1 text-xs text-red-500/80",
children: ["请", e],
}),
(0, t.jsx)(O.GalleryModal, {
opened: E,
onClose: () => M(!1),
onConfirm: P,
maxSelect: 1,
allowedMediaType: l,
}),
],
});
}
let ec = n.default.memo(function ({ opened: e, onClose: i }) {
let r = "light" === (0, x.useCanvasThemeStore)((e) => e.theme),
a = n.default.useMemo(
() => ({ ...eo, dropdown: (0, C.cn)(r && "canvas-light") }),
[r],
),
o = (0, w.useCanvasStore)((e) => e.projectId),
s = (0, w.useCanvasStore)((e) => e.projectName),
c = (0, w.useCanvasStore)((e) => e.projectTemplateUuid),
l = ee((e) => e.name),
f = ee((e) => e.description),
d = ee((e) => e.finalOutputUrl),
p = ee((e) => e.coverUrl),
g = ee((e) => e.isPublic),
b = ee((e) => e.tagId),
m = ee((e) => e.trackId),
v = ee((e) => e.socialMediaUrl),
y = ee((e) => e.updateDraft),
S = ee((e) => e.resetDraft),
[E, M] = (0, n.useState)(!1),
[T, I] = (0, n.useState)([]),
O = n.default.useMemo(
() => T.find((e) => e.id === b)?.children ?? [],
[T, b],
),
[F, U] = (0, n.useState)(null),
[B, H] = (0, n.useState)(!1),
[$, V] = (0, n.useState)(!1),
[W, K] = (0, n.useState)(!1),
[q, Y] = (0, n.useState)(!0),
[Z, Q] = (0, n.useState)(!1),
et = !!c;
(0, n.useEffect)(() => {
if (!e) return;
let t = (e) => {
"Escape" !== e.key || E || (e.preventDefault(), i());
};
return (
document.addEventListener("keydown", t),
() => document.removeEventListener("keydown", t)
);
}, [e, E, i]);
let en = (0, n.useRef)(!1);
(0, n.useEffect)(() => {
if (!e || en.current) {
en.current = e;
return;
}
(en.current = e),
et && c
? (0, k.getProjectTemplateDetail)({ projectTemplateUuid: c })
.then((e) => {
let t = e?.data?.detail ?? e?.detail;
if (t) {
let {
name: e,
description: n,
coverUrl: i,
finalOutput: r,
} = t,
a = (e) => ("string" == typeof e ? e : ""),
o = (e) =>
"string" == typeof e && e.trim() ? e : null,
{ tagId: s, trackId: c } = (function (e) {
if (!e?.length) return { tagId: 0, trackId: null };
let t = e.find((e) => 0 === Number(e.parentTag));
if (null != t) {
let n = Number(t.id),
i = e.find((e) => Number(e.parentTag) === n);
return {
tagId: n,
trackId: null != i ? Number(i.id) : null,
};
}
let n = e[0],
i = Number(n.parentTag);
return i > 0
? { tagId: i, trackId: Number(n.id) }
: { tagId: Number(n.id), trackId: null };
})(
(function (e) {
if (!Array.isArray(e) || 0 === e.length) return;
let t = [];
for (let n of e) {
if (null === n || "object" != typeof n) continue;
let e = Number(n.id),
i = Number(n.parentTag);
Number.isFinite(e) &&
Number.isFinite(i) &&
t.push({
id: e,
parentTag: i,
tagLabel:
"string" == typeof n.tagLabel
? n.tagLabel
: void 0,
code:
"string" == typeof n.code ? n.code : void 0,
path:
"string" == typeof n.path ? n.path : void 0,
});
}
return t.length > 0 ? t : void 0;
})(t.tags),
);
y({
name: a(e),
description: a(n),
coverUrl: o(i),
finalOutputUrl: o(r),
isPublic: !!t.snapshotData,
socialMediaUrl: a(t.socialMediaUrl),
tagId: s,
trackId: c,
});
} else l || y({ name: s || "" });
})
.catch(() => {
h.Notify.error("获取作品详情失败,请重试"),
l || y({ name: s || "" });
})
: l || y({ name: s || "" });
}, [e, et, c, l, s, y]),
(0, n.useEffect)(() => {
null != b && b > 0 && !g && y({ isPublic: !0 });
}, [b, g, y]),
(0, n.useEffect)(() => {
e &&
(0, J.getTagTreeByCategory)({ categoryId: 0, tagType: 5 }).then(
(e) => {
I(
(e?.data?.items ?? []).filter(
(e) =>
Number(e.activityStatus) === G.ActivityEnum.IN_PROGRESS,
),
);
},
);
}, [e]);
let ei = (0, n.useCallback)(async () => {
if (!o) return void h.Notify.error("项目未加载");
K(!0);
let e = [];
if (
(d || e.push("上传视频"),
p || e.push("上传封面"),
l.trim() || e.push("输入作品名称"),
q || e.push("勾选同意作者协议"),
e.length > 0)
)
return void h.Notify.error(`请${e.join("、")}`);
if (null != b && b > 0 && O.length > 0 && (null == m || 0 === m))
return void h.Notify.error("请选择参赛单元");
if (null != b && b > 0 && !v.trim())
return void h.Notify.error("请填写社媒链接");
if (null != b && b > 0) {
let e = T.find((e) => e.id === b),
t = e?.activityId;
if (null != t) {
let { data: e } = await (0, G.checkActivityRegister)({
activityId: t,
});
if (!e?.hasRegistered) {
let { data: e } = await (0, G.getCampaignDetail)({
activityId: t,
});
U({
activityId: t,
tagId: b,
activityName: e?.activity?.name ?? "",
});
return;
}
}
}
let t = g ? (w.stores.canvas?.getState().nodes ?? []) : [],
n = g ? (w.stores.canvas?.getState().edges ?? []) : [];
if (g && 0 === t.length)
return void h.Notify.error("画布节点为空,无法公开发布");
M(!0);
try {
let e = g
? JSON.stringify({ nodes: t, edges: n, savedAt: Date.now() })
: "",
r = [];
if (null != b && b > 0) {
let e = T.find((e) => e.id === b);
e && r.push(e.id);
}
if (null != m && m > 0) {
let e = O.find((e) => e.id === m);
e && r.push(e.id);
}
if (c) {
let t = {
projectTemplateUuid: c,
name: l.trim(),
description: f.trim(),
coverUrl: p || "",
finalOutput: d || "",
snapshotData: e || "",
...(r.length > 0 ? { tagIds: r } : {}),
...(v.trim() ? { socialMediaUrl: v.trim() } : {}),
};
try {
let e = (0, D.default)(t);
delete e.snapshotData,
(e.activityId =
T.find((e) => e.id === b)?.activityId ?? ""),
(0, z.reportLog)({
e: "libtv.canvas.publish.click",
var: { publish_data: JSON.stringify(e) },
});
} catch {
console.error("libtv.canvas.publish.click 上报失败", o);
}
let n = await (0, k.republishProject)(t),
a = n?.data ?? n;
if (a?.templateUuid || n?.code === 0)
h.Notify.success("发布更新成功!"),
K(!1),
Y(!1),
S(),
Q(!1),
i();
else {
let e = "string" == typeof n?.msg ? String(n.msg) : "";
h.Notify.error(e || "更新失败,请重试");
}
} else {
let t = {
projectUuid: o,
name: l.trim(),
description: f.trim(),
coverUrl: p || "",
finalOutput: d || "",
snapshotData: e,
...(r.length > 0 ? { tagIds: r } : {}),
...(v.trim() ? { socialMediaUrl: v.trim() } : {}),
},
n = await (0, k.publishProject)(t),
a = n?.data ?? n;
if (a?.templateUuid)
w.stores.canvas?.setProjectTemplateUuid(a.templateUuid),
h.Notify.success("发布成功!"),
K(!1),
Y(!1),
S(),
i();
else {
let e = "string" == typeof n?.msg ? String(n.msg) : "";
h.Notify.error(e || "发布失败,请重试");
}
}
} catch {
h.Notify.error(et ? "更新失败,请重试" : "发布失败,请重试");
} finally {
M(!1);
}
}, [o, c, l, f, p, d, g, q, b, m, v, T, O, i, S, et]),
ec = (0, n.useCallback)(() => {
et ? Q(!0) : ei();
}, [et, ei]),
el = (0, n.useCallback)(() => {
Q(!1), ei();
}, [ei]),
eu = (0, n.useCallback)((e) => {
U(null), e || h.Notify.error("未报名无法参与活动,请先进行报名");
}, []);
return (0, t.jsxs)(N.Modal, {
opened: e,
onClose: i,
closeOnEscape: !1,
centered: !0,
radius: "lg",
size: 480,
padding: 0,
withCloseButton: !1,
overlayProps: { backgroundOpacity: 0.6, blur: 4 },
classNames: { content: (0, C.cn)(r && "canvas-light") },
styles: {
content: {
backgroundColor: "var(--canvas-controls-bg)",
border: "0.5px solid var(--canvas-controls-border)",
overflow: "hidden",
padding: "16px",
maxHeight: "min(90dvh, 880px)",
overflowX: "hidden",
overflowY: "auto",
overscrollBehaviorY: "contain",
WebkitOverflowScrolling: "touch",
color: "var(--canvas-controls-text)",
boxShadow: "var(--canvas-shadow-dropdown)",
},
},
children: [
(0, t.jsx)("div", {
className:
"-top-15 absolute left-0 -z-10 h-[214px] w-[503px] bg-cover bg-center bg-no-repeat object-cover",
style: {
backgroundImage:
"linear-gradient(to bottom, rgba(0, 0, 0, 0.25) 70%, var(--canvas-controls-bg) 100%), url('https://libtv-res.liblib.art/upload-images/4e7115e6ee6947b78d73e0203a85fc56/771d92a21c6dce69a97513d21ee3253fe0eedec9.png')",
},
}),
(0, t.jsx)("button", {
type: "button",
onClick: i,
className:
"absolute right-4 top-4 z-[2] flex size-8 cursor-pointer items-center justify-center rounded-full text-white/80 transition-colors hover:bg-black/35 hover:text-white",
children: (0, t.jsx)("svg", {
width: "16",
height: "16",
viewBox: "0 0 16 16",
fill: "none",
children: (0, t.jsx)("path", {
d: "M4 4l8 8M12 4l-8 8",
stroke: "currentColor",
strokeWidth: "1.5",
strokeLinecap: "round",
}),
}),
}),
(0, t.jsxs)("div", {
className: "z-10 flex flex-col gap-4",
children: [
(0, t.jsxs)("div", {
className:
"relative z-[1] mt-3 flex max-w-[min(100%,420px)] flex-col gap-2",
children: [
(0, t.jsx)("p", {
className:
"text-[16px] font-medium text-white drop-shadow-[0_1px_3px_rgba(0,0,0,0.85)]",
children: et ? "更新线上作品" : "发布作品到LibTV",
}),
(0, t.jsx)("p", {
className:
"text-[14px] font-normal not-italic leading-normal text-white/85 drop-shadow-[0_1px_2px_rgba(0,0,0,0.75)]",
children: et
? "将当前画布发布为新版本并上线,上线后会覆盖原有版本"
: "您的作品将展示到LibTV Show,方便大家交流使用",
}),
],
}),
(0, t.jsxs)("div", {
className: "mt-6 flex gap-3",
children: [
(0, t.jsx)(es, {
label: "选择视频",
accept: "video/*",
previewUrl: d,
onUpload: (e) => y({ finalOutputUrl: e }),
uploading: B,
setUploading: H,
previewType: "video",
galleryMediaType: "video",
showError: W,
}),
(0, t.jsx)(es, {
label: "选择封面",
hint: "建议上传横版图片",
accept: "image/*",
previewUrl: p,
onUpload: (e) => y({ coverUrl: e }),
uploading: $,
setUploading: V,
galleryMediaType: "image",
showError: W,
}),
],
}),
(0, t.jsxs)("div", {
children: [
(0, t.jsxs)("label", {
className:
"text-canvas-controls-text mb-1.5 block text-sm font-medium",
children: [
"作品名称 ",
(0, t.jsx)("span", {
className: "text-red-500",
children: "*",
}),
],
}),
(0, t.jsx)(L.TextInput, {
value: l,
onChange: (e) => y({ name: e.currentTarget.value }),
placeholder: "请输入作品名称",
maxLength: 120,
error: W && !l.trim() ? "请输入作品名称" : void 0,
styles: { input: er({ error: W && !l.trim() }) },
}),
],
}),
(0, t.jsxs)("div", {
children: [
(0, t.jsx)("label", {
className:
"text-canvas-controls-text mb-1.5 block text-sm font-medium",
children: "作品描述",
}),
(0, t.jsx)(R.Textarea, {
value: f,
onChange: (e) =>
y({ description: e.currentTarget.value }),
placeholder: "请输入作品描述",
minRows: 3,
maxRows: 5,
autosize: !0,
maxLength: 500,
styles: { input: er({}) },
}),
],
}),
(0, t.jsxs)("div", {
className: "flex gap-3",
children: [
(0, t.jsxs)("div", {
className: "flex flex-1 flex-col gap-2",
children: [
(0, t.jsx)("label", {
className:
"text-canvas-controls-text text-sm font-medium",
children: "活动标签",
}),
(0, t.jsx)(P.Select, {
value: String(b ?? 0),
onChange: (e) => {
let t = null != e ? Number(e) : 0;
y({
tagId: t,
trackId: null,
...(t > 0 && { isPublic: !0 }),
});
},
data: [
{ value: "0", label: "不参与" },
...T.map((e) => ({
value: String(e.id),
label: e.tagLabel,
})),
],
placeholder: "不参与",
withCheckIcon: !1,
classNames: a,
rightSectionPointerEvents: "none",
rightSection: (0, t.jsx)(u.Icons.chevronDown, {
width: 16,
height: 16,
color: "var(--canvas-controls-icon)",
}),
styles: { ...ea },
}),
],
}),
(0, t.jsxs)("div", {
className: "flex flex-1 flex-col gap-2",
children: [
(0, t.jsx)("label", {
className:
"text-canvas-controls-text text-sm font-medium",
children: "参赛赛道",
}),
(0, t.jsx)(P.Select, {
value: null != m ? String(m) : null,
onChange: (e) =>
y({ trackId: null != e ? Number(e) : null }),
data: O.map((e) => ({
value: String(e.id),
label: e.tagLabel,
})),
placeholder: "请选择参赛单元",
disabled: null == b || 0 === b,
withCheckIcon: !1,
classNames: a,
rightSectionPointerEvents: "none",
rightSection: (0, t.jsx)(u.Icons.chevronDown, {
width: 16,
height: 16,
color: "var(--canvas-controls-icon)",
}),
styles: {
...ea,
input: {
...ea.input,
opacity: null == b || 0 === b ? 0.5 : 1,
},
},
}),
],
}),
],
}),
(0, t.jsxs)("div", {
children: [
(0, t.jsxs)("label", {
className:
"text-canvas-controls-text mb-1.5 block flex items-center gap-1 text-sm font-medium",
children: [
"社媒链接",
(0, t.jsx)(_.CanvasTooltip, {
label: (0, t.jsxs)(t.Fragment, {
children: [
"投稿作品在社媒平台的影响力亦是参与最终评选的重要考虑因素",
(0, t.jsx)("br", {}),
"发布时需根据活动细则带上活动话题",
],
}),
w: 350,
withArrow: !0,
position: "top",
children: (0, t.jsx)("div", {
className:
"text-canvas-controls-icon inline-flex cursor-help",
children: (0, t.jsx)(u.Icons.InfoL, {
className: "size-3",
}),
}),
}),
null != b &&
b > 0 &&
(0, t.jsx)("span", {
className: "text-red-500",
children: "*",
}),
],
}),
(0, t.jsx)(L.TextInput, {
value: v,
onChange: (e) =>
y({ socialMediaUrl: e.currentTarget.value }),
placeholder: "请添加您在社媒发布该作品的链接",
error:
W && null != b && b > 0 && !v.trim()
? "请填写社媒链接"
: void 0,
styles: {
input: er({
error: !!(W && null != b && b > 0 && !v.trim()),
}),
},
}),
],
}),
(0, t.jsxs)("div", {
className: "flex items-center justify-between",
children: [
(0, t.jsxs)("div", {
className: "flex items-center gap-2",
children: [
(0, t.jsx)("span", {
className: "text-canvas-controls-text text-[13px]",
children: "公开画布",
}),
null != b && b > 0
? (0, t.jsx)(_.CanvasTooltip, {
label: "已选择参与活动,必须公开画布",
withArrow: !0,
position: "top",
children: (0, t.jsx)("div", {
className: "inline-flex",
children: (0, t.jsx)(j.Switch, {
checked: g,
disabled: !0,
size: "xs",
}),
}),
})
: (0, t.jsx)(j.Switch, {
checked: g,
onChange: (e) =>
y({ isPublic: e.currentTarget.checked }),
size: "xs",
}),
],
}),
(0, t.jsx)(_.CanvasTooltip, {
label: (0, t.jsxs)(t.Fragment, {
children: [
"发布作品会经过审核,审核通过后方可在 LibTV社区 展示。",
(0, t.jsx)("br", {}),
"您可在 LibLib 个人中心页面 管理已发布的TV作品。",
],
}),
withArrow: !0,
position: "top",
multiline: !0,
w: 200,
children: (0, t.jsx)("button", {
onClick: ec,
disabled: E,
className:
"cursor-pointer rounded-lg bg-[#478EFF] px-3 py-2 text-[13px] text-white transition-colors hover:bg-[#2563EB]",
children: E
? et
? "更新中..."
: "发布中..."
: et
? "更新线上版本"
: "发布并投稿",
}),
}),
],
}),
(0, t.jsxs)("label", {
className:
"mt-0 mt-[-4px] flex cursor-pointer items-center gap-1",
children: [
(0, t.jsx)(A.Checkbox, {
checked: q,
onChange: (e) => Y(e.currentTarget.checked),
size: "12px",
color: r ? "#478EFF" : "gray",
styles: {
input: {
...(!r && { backgroundColor: "transparent" }),
borderColor: r
? "var(--border-emphasis, #c4c4c4)"
: "var(--canvas-controls-border)",
},
},
}),
(0, t.jsxs)("span", {
className: "text-canvas-controls-text/60 text-[10px]",
children: [
"点击发布即代表同意",
(0, t.jsx)("a", {
href: "https://www.liblib.art/activities/4b7ea7f1dbbf41669d9e05cd25a3fa77",
target: "_blank",
rel: "noreferrer",
className: "text-[#478EFF] hover:underline",
children: "《LibTV创作许可服务协议》",
}),
],
}),
],
}),
],
}),
(0, t.jsxs)(N.Modal, {
opened: Z,
onClose: () => Q(!1),
centered: !0,
radius: "lg",
size: "sm",
title: "更新线上作品",
classNames: { content: (0, C.cn)(r && "canvas-light") },
styles: {
content: {
backgroundColor: "var(--canvas-controls-bg)",
border: "0.5px solid var(--canvas-controls-border)",
boxShadow: "var(--canvas-shadow-dropdown)",
color: "var(--canvas-controls-text)",
},
title: {
color: "var(--canvas-controls-text)",
fontWeight: 600,
},
},
children: [
(0, t.jsx)("p", {
className: "text-canvas-controls-text/65 my-4 text-[14px]",
children: "作品更新后将会覆盖线上版本",
}),
(0, t.jsxs)("div", {
className: "flex justify-end gap-2",
children: [
(0, t.jsx)("button", {
type: "button",
onClick: () => Q(!1),
className:
"text-canvas-controls-text hover:bg-canvas-controls-hover cursor-pointer rounded-lg px-3 py-2 text-[13px] transition-colors",
children: "取消",
}),
(0, t.jsx)("button", {
type: "button",
onClick: el,
disabled: E,
className:
"cursor-pointer rounded-lg bg-[#478EFF] px-3 py-2 text-[13px] text-white transition-colors hover:bg-[#2563EB] disabled:opacity-60",
children: E ? "更新中..." : "确认",
}),
],
}),
],
}),
F &&
(0, t.jsx)(X, {
opened: !0,
onOpenedChange: (e) => !e && U(null),
campaignData: F,
onCloseResult: eu,
onSuccess: () => void ei(),
}),
],
});
}),
el = n.default.memo(function () {
let e = (0, x.useCanvasThemeStore)((e) => e.theme),
i = (0, w.useCanvasStore)((e) => e.projectId),
r = (0, w.useCanvasStore)((e) => e.projectTemplateUuid),
[a, o] = (0, n.useState)(!1),
[s, c] = (0, n.useState)(!1),
[l, u] = (0, n.useState)(!1),
f = (0, n.useCallback)(async () => {
if (i && !l) {
u(!0);
try {
let e = await (0, k.setProjectShareEnabled)({
projectUuid: i,
open: !0,
}),
t = e?.data?.shareId ?? e?.shareId;
if (t) {
let e = `${window.location.origin}/canvas/share?shareId=${t}`;
try {
await navigator.clipboard.writeText(e);
} catch {
let t = document.createElement("textarea");
(t.value = e),
document.body.appendChild(t),
t.select(),
document.execCommand("copy"),
document.body.removeChild(t);
}
h.Notify.success("分享链接已复制至剪切板");
} else h.Notify.error("获取分享链接失败");
} catch {
h.Notify.error("获取分享链接失败");
} finally {
u(!1), o(!1);
}
}
}, [i, l]);
return i
? (0, t.jsxs)(t.Fragment, {
children: [
(0, t.jsxs)(S.Popover, {
opened: a,
onChange: o,
position: "bottom-end",
offset: 8,
shadow: "lg",
radius: "md",
width: 360,
children: [
(0, t.jsx)(S.Popover.Target, {
children: (0, t.jsx)("div", {
className:
"border-(--topnav-btn-border) bg-panel-background hover:bg-(--topnav-btn-hover-bg) relative flex size-10 cursor-pointer items-center justify-center rounded-xl border-[0.5px]",
onClick: () => o((e) => !e),
children: (0, t.jsx)(M.default, {}),
}),
}),
(0, t.jsx)(S.Popover.Dropdown, {
classNames: {
dropdown: (0, C.cn)("light" === e && "canvas-light"),
},
styles: {
dropdown: {
backgroundColor: "var(--canvas-controls-bg)",
border: "0.5px solid var(--canvas-controls-border)",
backdropFilter: "blur(16px)",
borderRadius: "16px",
padding: "8px",
boxShadow: "var(--canvas-shadow-dropdown)",
color: "var(--canvas-controls-text)",
},
},
children: (0, t.jsxs)("div", {
className: "flex flex-col gap-2",
children: [
(0, t.jsx)("span", {
className:
"text-canvas-controls-text/60 pl-2 text-sm font-medium",
children: "发布与分享",
}),
(0, t.jsxs)("button", {
type: "button",
className:
"hover:bg-canvas-controls-hover flex cursor-pointer items-center gap-3 rounded-xl p-2 text-left transition-colors",
onClick: () => {
o(!1), c(!0);
},
children: [
(0, t.jsx)("div", {
className:
"bg-canvas-controls-active flex size-10 shrink-0 items-center justify-center rounded-lg",
children: (0, t.jsx)(E.default, {}),
}),
(0, t.jsxs)("div", {
className: "flex flex-col gap-1",
children: [
(0, t.jsx)("span", {
className:
"text-canvas-controls-text text-sm font-medium",
children: r
? "更新线上版本"
: "在LibTV上发布",
}),
(0, t.jsx)("span", {
className:
"text-canvas-controls-text/70 text-xs leading-snug",
children: r
? "将当前画布发布为新版本并上线,上线后会覆盖原有版本"
: "发布你的作品和创作过程,让更多创作者看到。",
}),
],
}),
],
}),
(0, t.jsxs)("button", {
type: "button",
disabled: l,
className: (0, C.cn)(
"hover:bg-canvas-controls-hover flex cursor-pointer items-center gap-3 rounded-xl p-2 text-left transition-colors",
l && "pointer-events-none opacity-60",
),
onClick: () => void f(),
children: [
(0, t.jsx)("div", {
className:
"bg-canvas-controls-active flex size-10 shrink-0 items-center justify-center rounded-lg",
children: l
? (0, t.jsx)("span", {
className:
"border-canvas-controls-text/40 border-t-canvas-controls-text inline-block size-5 animate-spin rounded-full border-2",
})
: (0, t.jsx)(T.default, {}),
}),
(0, t.jsxs)("div", {
className: "flex flex-col gap-1",
children: [
(0, t.jsx)("span", {
className:
"text-canvas-controls-text text-sm font-medium",
children: l ? "获取链接中..." : "分享链接",
}),
(0, t.jsx)("span", {
className:
"text-canvas-controls-text/70 text-xs leading-snug",
children:
"拥有此链接的人可以查看并复制你的画布。",
}),
],
}),
],
}),
],
}),
}),
],
}),
(0, t.jsx)(ec, { opened: s, onClose: () => c(!1) }),
],
})
: null;
});
function eu() {
let e = (0, w.useCanvasStore)((e) => e.projectId),
i = (0, w.useCanvasStore)((e) => e.projectName),
r = (0, w.useCanvasStore)((e) => e.setProjectName),
a = (0, n.useRef)(null),
[o, c] = (0, n.useState)(i);
(0, n.useEffect)(() => {
c(i);
}, [i]);
let l = (0, n.useCallback)(
(0, s.default)((t) => {
e && t.trim() && (0, v.renameProject)(e, t.trim());
}, 800),
[e],
),
u = (0, n.useCallback)(() => {
setTimeout(() => {
a.current?.select();
}, 0);
}, []),
h = (0, n.useCallback)(() => {
let e = a.current?.value?.trim();
e ? e !== i && (r(e), l(e)) : c(i);
}, [i, r, l]),
f = (0, n.useCallback)(
(e) => {
e.nativeEvent.isComposing ||
("Enter" === e.key &&
(e.preventDefault(), h(), a.current?.blur()),
"Escape" === e.key && (c(i), a.current?.blur()));
},
[h, i],
);
return (0, t.jsx)("input", {
ref: a,
value: o,
onChange: (e) => c(e.target.value),
onFocus: u,
onBlur: h,
onKeyDown: f,
maxLength: 120,
className:
"min-w-[60px] max-w-[160px] cursor-text truncate border-b border-dashed border-transparent bg-transparent text-sm font-medium outline-none transition-colors",
style: { color: "var(--canvas-controls-text)", fieldSizing: "content" },
onClick: (e) => e.stopPropagation(),
});
}
function eh({ name: e }) {
return (0, t.jsx)("span", {
className: "max-w-[240px] truncate text-sm font-medium",
style: { color: "var(--canvas-controls-text)" },
children: e || "未命名项目",
});
}
function ef({ onClone: e, busy: n }) {
return (0, t.jsxs)("button", {
type: "button",
className:
"border-(--topnav-btn-border) bg-panel-background hover:bg-(--topnav-btn-hover-bg) flex h-10 cursor-pointer items-center gap-1.5 rounded-xl border px-3 text-[12px] transition-colors disabled:cursor-not-allowed disabled:opacity-60",
onClick: () => {
n || e();
},
disabled: n,
children: [
(0, t.jsx)(u.Icons.Clone, { className: "size-4" }),
n ? "复制中..." : "复制项目",
],
});
}
function ed({ readonly: e }) {
let i = (0, x.useCanvasThemeStore)((e) => e.theme),
r = (0, c.useRouter)(),
a = (0, w.useCanvasStore)((e) => e.projectId),
s = (0, n.useCallback)(() => {
r.push("/");
}, [r]),
u = (0, n.useCallback)(() => {
r.push("/project");
}, [r]),
h = (0, n.useCallback)(() => {
window.open("/canvas?newProject=true", "_blank");
}, []),
f = (0, n.useCallback)(() => {
a &&
(0, d.confirm)({
title: "删除项目",
message: "确定要删除当前项目吗?此操作不可恢复。",
onConfirm: async () => {
await (0, v.deleteCurrentProject)(a), r.replace("/");
},
});
}, [a, r]),
p =
"w-full h-11 cursor-pointer rounded-lg px-3 text-left text-[14px] font-medium transition-colors hover:bg-canvas-controls-hover";
return (0, t.jsx)(t.Fragment, {
children: (0, t.jsxs)(o.HoverCard, {
width: 200,
position: "bottom-start",
offset: 4,
shadow: "md",
openDelay: 0,
closeDelay: 120,
children: [
(0, t.jsx)(o.HoverCard.Target, {
children: (0, t.jsx)("div", {
className:
"hover:bg-canvas-controls-hover flex h-10 cursor-pointer items-center justify-center rounded-xl px-2 transition-colors",
children: (0, t.jsx)(l.default, { className: "h-6" }),
}),
}),
(0, t.jsxs)(o.HoverCard.Dropdown, {
className: `border-0 p-1 ${"light" === i ? "canvas-light" : ""}`,
style: {
color: "var(--canvas-controls-text)",
backgroundColor: "var(--canvas-controls-bg)",
border: "0.5px solid var(--canvas-controls-border)",
backdropFilter: "blur(20px)",
borderRadius: "16px",
boxShadow: "var(--canvas-shadow-menu)",
},
children: [
(0, t.jsx)("button", {
className: p,
onClick: s,
children: "回到主页",
}),
(0, t.jsx)("button", {
className: p,
onClick: u,
children: "全部项目",
}),
!e &&
(0, t.jsxs)(t.Fragment, {
children: [
(0, t.jsx)("div", {
className: "my-0.5 h-px",
style: {
backgroundColor: "var(--canvas-controls-border)",
},
}),
(0, t.jsx)("button", {
className: p,
onClick: h,
children: "创建新项目",
}),
(0, t.jsx)("button", {
className:
"w-full h-11 cursor-pointer rounded-lg px-3 text-left text-[14px] font-medium transition-colors hover:bg-canvas-controls-hover",
onClick: f,
disabled: !a,
children: "删除项目",
}),
],
}),
],
}),
],
}),
});
}
let ep = n.default.memo(function ({
readonly: e,
projectName: o,
onCloneProject: s,
cloneProjectBusy: c = !1,
}) {
let [l, d] = (0, n.useState)(!1),
[v, x] = (0, n.useState)(!1),
S = (0, n.useRef)(!1),
E = (0, w.useCanvasStore)((e) => e.projectId),
{ personalAccount: M } = (0, a.useAccountHooks)(),
T = M?.source === 2,
[k, C] = (0, n.useState)(!1),
[A, N] = (0, n.useState)(null),
I = (0, n.useRef)(!1);
(0, n.useEffect)(() => {
T &&
!I.current &&
((I.current = !0),
(0, b.getInviteCodeDetails)(m.TEAM_FISSION_BATCH_NO)
.then((e) => N(e?.data ?? null))
.catch(() => {}));
}, [T]),
(0, n.useCallback)((e) => {
e
? navigator.clipboard.writeText(e).then(
() => h.Notify.success("邀请链接已复制"),
() => h.Notify.error("复制失败,请手动复制"),
)
: h.Notify.warn("暂无邀请链接");
}, []),
(0, n.useCallback)(() => {
(0, r.openTeamPaywall)({ paywall: "group" });
}, []);
let P = (0, n.useCallback)(() => {
e ||
!E ||
S.current ||
((S.current = !0),
(0, i.flushSync)(() => {
x(!0);
}),
(async () => {
try {
let e = (await w.stores.canvas?.saveFullSnapshotAsUpdate()) ?? {
ok: !1,
};
e.ok
? (h.Notify.success("保存成功"),
(0, y.rumCustomReport)({
type: "canvas",
name: "libtv.canvas.manual_save.success",
properties: {},
}))
: (h.Notify.error(
e.msg?.trim() || "保存失败或超时,请检查网络后重试",
),
(0, y.rumCustomReport)({
type: "canvas",
name: "libtv.canvas.manual_save.fail",
properties: { code: e.code, msg: e.msg ?? "" },
}));
} catch (e) {
(0, y.rumCustomReport)({
type: "canvas",
name: "libtv.canvas.manual_save.fail",
properties: {
code: "EXCEPTION",
msg: e instanceof Error ? e.message : String(e),
},
}),
h.Notify.error(e instanceof Error ? e.message : "保存失败");
} finally {
(S.current = !1), x(!1);
}
})());
}, [E, e]);
return (0, t.jsxs)(t.Fragment, {
children: [
(0, t.jsxs)("nav", {
className:
"pointer-events-none absolute left-0 right-0 top-4 z-40 flex h-12 items-center justify-between pl-2 pr-4",
children: [
(0, t.jsxs)("div", {
className: "pointer-events-auto flex items-center gap-3",
children: [
(0, t.jsx)(ed, { readonly: e }),
(0, t.jsx)("div", {
className: "h-4 w-px",
style: { backgroundColor: "var(--canvas-controls-border)" },
}),
e ? (0, t.jsx)(eh, { name: o || "" }) : (0, t.jsx)(eu, {}),
],
}),
(0, t.jsxs)("div", {
className: "pointer-events-auto flex items-center gap-2",
children: [
(0, t.jsx)("button", {
type: "button",
className:
"border-(--topnav-btn-border) bg-panel-background border-hair hover:bg-(--topnav-btn-hover-bg) flex h-10 cursor-pointer items-center justify-center rounded-xl px-3 text-[13px] font-[400]",
"aria-label": "创建access key",
onClick: () => d(!0),
children: "LibTV Skills",
}),
(0, t.jsx)(g.default, {
renderTrigger: !1,
opened: l,
onOpenChange: d,
}),
!e && E
? (0, t.jsx)(_.CanvasTooltip, {
label: v
? "正在保存…"
: "画布内容会自动保存,您也可以点击这里手动保存",
position: "bottom",
withArrow: !0,
children: (0, t.jsx)("span", {
className: "inline-flex",
children: (0, t.jsx)("button", {
type: "button",
className:
"border-(--topnav-btn-border) bg-panel-background hover:bg-(--topnav-btn-hover-bg) relative flex size-10 cursor-pointer items-center justify-center rounded-xl border-[0.5px] transition-colors disabled:cursor-not-allowed disabled:opacity-60",
"aria-label": v ? "正在保存" : "保存画布",
"aria-busy": v,
disabled: v,
onClick: () => void P(),
children: v
? (0, t.jsx)("span", {
className:
"box-border inline-block size-4 shrink-0 animate-spin rounded-full border-[1.5px] border-solid border-t-transparent opacity-90",
style: {
borderColor: "var(--canvas-controls-text)",
borderTopColor: "transparent",
},
"aria-hidden": !0,
})
: (0, t.jsx)(u.Icons.canvasNavSave, {
width: 16,
height: 16,
color: "var(--canvas-controls-text)",
}),
}),
}),
})
: null,
e
? s && (0, t.jsx)(ef, { onClone: s, busy: c })
: (0, t.jsx)(el, {}),
(0, t.jsx)(p.default, {}),
],
}),
],
}),
(0, t.jsx)(f.default, { opened: k, onClose: () => C(!1) }),
],
});
});
e.s(["default", 0, ep], 21775);
};
export default moduleFactory;