@rslsp1/fa-app-tools 2.0.30 → 2.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-UCEQOGPT.mjs → chunk-TTJTQP43.mjs} +30 -21
- package/dist/{hfStateService-TC65WQXK.mjs → hfStateService-5BU5DVQ6.mjs} +1 -1
- package/dist/index.d.mts +42 -39
- package/dist/index.d.ts +42 -39
- package/dist/index.js +616 -432
- package/dist/index.mjs +539 -358
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -566,30 +566,39 @@ async function hfUploadImage(base64, id, token, mimeType = "image/jpeg") {
|
|
|
566
566
|
commitTitle: `Add image ${id}`
|
|
567
567
|
});
|
|
568
568
|
}
|
|
569
|
-
async function hfLoadImageAsBase64(id, token, namespace) {
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
if (!res.ok) continue;
|
|
580
|
-
const blob = await res.blob();
|
|
581
|
-
return new Promise((resolve, reject) => {
|
|
582
|
-
const reader = new FileReader();
|
|
583
|
-
reader.onload = () => resolve(reader.result.split(",")[1]);
|
|
584
|
-
reader.onerror = reject;
|
|
585
|
-
reader.readAsDataURL(blob);
|
|
586
|
-
});
|
|
587
|
-
} catch {
|
|
588
|
-
continue;
|
|
569
|
+
async function hfLoadImageAsBase64(id, token, namespace, filename, on404, mimeType, hasThumb) {
|
|
570
|
+
const fetchBase64 = async (repoPath) => {
|
|
571
|
+
try {
|
|
572
|
+
const res = await fetch(
|
|
573
|
+
`${HF_BASE}/datasets/${HF_REPO}/resolve/main/${repoPath}?download=true`,
|
|
574
|
+
{ headers: { Authorization: `Bearer ${token}` } }
|
|
575
|
+
);
|
|
576
|
+
if (!res.ok) {
|
|
577
|
+
if (on404 && on404()) return "ABORT";
|
|
578
|
+
return null;
|
|
589
579
|
}
|
|
580
|
+
const blob = await res.blob();
|
|
581
|
+
return new Promise((resolve, reject) => {
|
|
582
|
+
const reader = new FileReader();
|
|
583
|
+
reader.onload = () => resolve(reader.result.split(",")[1]);
|
|
584
|
+
reader.onerror = reject;
|
|
585
|
+
reader.readAsDataURL(blob);
|
|
586
|
+
});
|
|
587
|
+
} catch {
|
|
588
|
+
return null;
|
|
590
589
|
}
|
|
590
|
+
};
|
|
591
|
+
if (filename) {
|
|
592
|
+
if (hasThumb) {
|
|
593
|
+
const thumb = await fetchBase64(`thumbs/${filename}`);
|
|
594
|
+
if (thumb && thumb !== "ABORT") return thumb;
|
|
595
|
+
}
|
|
596
|
+
const result2 = await fetchBase64(`images/${filename}`);
|
|
597
|
+
return result2 === "ABORT" ? null : result2;
|
|
591
598
|
}
|
|
592
|
-
|
|
599
|
+
const ext = mimeType === "image/png" ? "png" : "jpg";
|
|
600
|
+
const result = await fetchBase64(`images/${id}.${ext}`);
|
|
601
|
+
return result === "ABORT" ? null : result;
|
|
593
602
|
}
|
|
594
603
|
var import_jszip2, import_hub, HF_BASE, HF_REPO, HF_TOKEN_KEY, SESSION_CLIENT_ID;
|
|
595
604
|
var init_hfStateService = __esm({
|
|
@@ -650,10 +659,6 @@ __export(index_exports, {
|
|
|
650
659
|
cleanAiResponse: () => cleanAiResponse,
|
|
651
660
|
createFlowServices: () => createFlowServices,
|
|
652
661
|
exportProjectToZip: () => exportProjectToZip,
|
|
653
|
-
faServerDelete: () => faServerDelete,
|
|
654
|
-
faServerGet: () => faServerGet,
|
|
655
|
-
faServerPost: () => faServerPost,
|
|
656
|
-
faServerPut: () => faServerPut,
|
|
657
662
|
findForks: () => findForks,
|
|
658
663
|
findTips: () => findTips,
|
|
659
664
|
formatTreeToMarkdown: () => formatTreeToMarkdown,
|
|
@@ -1023,8 +1028,10 @@ var CompactDropdown = ({
|
|
|
1023
1028
|
};
|
|
1024
1029
|
|
|
1025
1030
|
// src/components/HistoryPanel.tsx
|
|
1026
|
-
var import_react4 = require("
|
|
1031
|
+
var import_react4 = require("react");
|
|
1032
|
+
var import_react5 = require("motion/react");
|
|
1027
1033
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1034
|
+
var PAGE_SIZE = 20;
|
|
1028
1035
|
var formatFriendlyTimestamp = (timestamp) => {
|
|
1029
1036
|
const date = new Date(timestamp);
|
|
1030
1037
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1037,46 +1044,63 @@ var formatFriendlyTimestamp = (timestamp) => {
|
|
|
1037
1044
|
return `${date.toLocaleDateString([], { day: "2-digit", month: "2-digit" })}, ${timeStr}`;
|
|
1038
1045
|
};
|
|
1039
1046
|
var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
|
|
1047
|
+
const [visibleCount, setVisibleCount] = (0, import_react4.useState)(PAGE_SIZE);
|
|
1048
|
+
const visibleHistory = history.slice(0, visibleCount);
|
|
1040
1049
|
if (history.length === 0) {
|
|
1041
1050
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-col items-center justify-center py-20 text-center gap-4 opacity-10", children: [
|
|
1042
1051
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "history" }),
|
|
1043
1052
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[10px] font-bold uppercase tracking-widest", children: "Keine Historie" })
|
|
1044
1053
|
] });
|
|
1045
1054
|
}
|
|
1046
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex
|
|
1055
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1056
|
-
|
|
1055
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react5.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 p-4 flex flex-col gap-3 overflow-y-auto dark-scrollbar", children: [
|
|
1056
|
+
visibleHistory.map((gen) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1057
|
+
"div",
|
|
1058
|
+
{
|
|
1059
|
+
className: `flex gap-3 p-2 bg-white/5 border rounded-2xl cursor-pointer group transition-all relative ${currentResultId === gen.id ? "border-white/40 bg-white/10 shadow-lg" : "border-white/5 hover:border-white/20"}`,
|
|
1060
|
+
onClick: () => onSelect(gen),
|
|
1061
|
+
children: [
|
|
1062
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-14 h-14 rounded-xl overflow-hidden bg-black shrink-0 border border-white/5 flex items-center justify-center", children: gen.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-5 h-5 border-t-2 border-white/40 rounded-full animate-spin" }) : gen.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "material-symbols-outlined text-red-400 text-[20px]", children: "warning" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: gen.base64 ? gen.base64.startsWith("data:") ? gen.base64 : `data:image/png;base64,${gen.base64}` : "", className: "w-full h-full object-cover", alt: "Thumbnail" }) }),
|
|
1063
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex-1 py-0.5 overflow-hidden", children: [
|
|
1064
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [
|
|
1065
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[7px] font-bold text-white/20 uppercase whitespace-nowrap", children: formatFriendlyTimestamp(gen.timestamp) }),
|
|
1066
|
+
gen.model && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[7px] font-bold text-white/40 bg-white/5 px-1 rounded uppercase truncate max-w-[60px]", children: gen.model })
|
|
1067
|
+
] }),
|
|
1068
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "text-[9px] text-white/60 line-clamp-2 leading-tight", children: [
|
|
1069
|
+
'"',
|
|
1070
|
+
gen.prompt,
|
|
1071
|
+
'"'
|
|
1072
|
+
] }),
|
|
1073
|
+
gen.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[8px] text-white/30 mt-0.5", children: "Generiert\u2026" }),
|
|
1074
|
+
gen.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[8px] text-red-400/70 mt-0.5 truncate", children: gen.error?.message })
|
|
1057
1075
|
] }),
|
|
1058
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1076
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1077
|
+
"button",
|
|
1078
|
+
{
|
|
1079
|
+
onClick: (e) => {
|
|
1080
|
+
e.stopPropagation();
|
|
1081
|
+
onDelete(gen.id);
|
|
1082
|
+
},
|
|
1083
|
+
className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 w-6 h-6 flex items-center justify-center bg-red-500/20 text-red-400 hover:bg-red-500 hover:text-white rounded-md transition-all",
|
|
1084
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "delete" })
|
|
1085
|
+
}
|
|
1086
|
+
)
|
|
1087
|
+
]
|
|
1088
|
+
},
|
|
1089
|
+
gen.id
|
|
1090
|
+
)),
|
|
1091
|
+
visibleCount < history.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", onClick: () => setVisibleCount((c) => c + PAGE_SIZE), className: "w-full py-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-xl text-[10px] font-bold uppercase text-white/60 hover:text-white transition-all", children: [
|
|
1092
|
+
history.length - visibleCount,
|
|
1093
|
+
" weitere laden"
|
|
1094
|
+
] })
|
|
1095
|
+
] });
|
|
1072
1096
|
};
|
|
1073
1097
|
|
|
1074
1098
|
// src/components/InspectPanel.tsx
|
|
1075
|
-
var
|
|
1076
|
-
var
|
|
1099
|
+
var import_react6 = require("react");
|
|
1100
|
+
var import_react7 = require("motion/react");
|
|
1077
1101
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1078
1102
|
var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagToggle }) => {
|
|
1079
|
-
const currentIndex = (0,
|
|
1103
|
+
const currentIndex = (0, import_react6.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
|
|
1080
1104
|
if (!currentResult) {
|
|
1081
1105
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col items-center justify-center py-20 text-center gap-4 opacity-10", children: [
|
|
1082
1106
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "info" }),
|
|
@@ -1084,7 +1108,7 @@ var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagTogg
|
|
|
1084
1108
|
] });
|
|
1085
1109
|
}
|
|
1086
1110
|
const fullDateStr = new Date(currentResult.timestamp).toLocaleString([], { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
1087
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1111
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react7.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 flex flex-col overflow-hidden", children: [
|
|
1088
1112
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex-shrink-0 border-b border-white/5 bg-black/20 py-3 px-4", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex gap-2 overflow-x-auto no-scrollbar pb-1", children: history.map((gen) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: () => onSelect(gen), className: `w-10 h-10 rounded-lg overflow-hidden border shrink-0 transition-all ${currentResult.id === gen.id ? "border-white scale-105 shadow-lg" : "border-white/5 opacity-40 hover:opacity-100"}`, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src: gen.base64 ? gen.base64.startsWith("data:") ? gen.base64 : `data:image/png;base64,${gen.base64}` : "", className: "w-full h-full object-cover", alt: "Thumbnail" }) }, gen.id)) }) }),
|
|
1089
1113
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex-1 overflow-y-auto p-4 flex flex-col gap-6 dark-scrollbar pb-10", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex flex-col gap-4", children: [
|
|
1090
1114
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SectionLabel, { children: "Vorschau" }),
|
|
@@ -1137,8 +1161,8 @@ var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagTogg
|
|
|
1137
1161
|
};
|
|
1138
1162
|
|
|
1139
1163
|
// src/components/SetupPanel.tsx
|
|
1140
|
-
var
|
|
1141
|
-
var
|
|
1164
|
+
var import_react8 = require("react");
|
|
1165
|
+
var import_react9 = require("motion/react");
|
|
1142
1166
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1143
1167
|
var PRESET_URLS = [
|
|
1144
1168
|
"https://jsonplaceholder.typicode.com/todos/1",
|
|
@@ -1146,12 +1170,12 @@ var PRESET_URLS = [
|
|
|
1146
1170
|
"https://esm.sh/@rslsp1/fa-app-tools@latest"
|
|
1147
1171
|
];
|
|
1148
1172
|
var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
1149
|
-
const workspaceInputRef = (0,
|
|
1150
|
-
const [urlInput, setUrlInput] = (0,
|
|
1151
|
-
const [tokenInput, setTokenInput] = (0,
|
|
1152
|
-
const [testStatus, setTestStatus] = (0,
|
|
1153
|
-
const [result, setResult] = (0,
|
|
1154
|
-
const [fetchError, setFetchError] = (0,
|
|
1173
|
+
const workspaceInputRef = (0, import_react8.useRef)(null);
|
|
1174
|
+
const [urlInput, setUrlInput] = (0, import_react8.useState)("");
|
|
1175
|
+
const [tokenInput, setTokenInput] = (0, import_react8.useState)("");
|
|
1176
|
+
const [testStatus, setTestStatus] = (0, import_react8.useState)("idle");
|
|
1177
|
+
const [result, setResult] = (0, import_react8.useState)(null);
|
|
1178
|
+
const [fetchError, setFetchError] = (0, import_react8.useState)(null);
|
|
1155
1179
|
const runTest = async (url) => {
|
|
1156
1180
|
if (!url.trim()) return;
|
|
1157
1181
|
setTestStatus("loading");
|
|
@@ -1191,7 +1215,7 @@ var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
|
1191
1215
|
setTestStatus("error");
|
|
1192
1216
|
}
|
|
1193
1217
|
};
|
|
1194
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react9.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 p-6 flex flex-col gap-10 overflow-y-auto", children: [
|
|
1195
1219
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-4", children: [
|
|
1196
1220
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
1197
1221
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionLabel, { children: "Workspace Management" }),
|
|
@@ -1314,18 +1338,48 @@ var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
|
1314
1338
|
};
|
|
1315
1339
|
|
|
1316
1340
|
// src/components/MediaLibrary.tsx
|
|
1317
|
-
var
|
|
1341
|
+
var import_react10 = require("react");
|
|
1342
|
+
var import_react11 = require("motion/react");
|
|
1343
|
+
|
|
1344
|
+
// src/lib/grouping.ts
|
|
1345
|
+
function groupByPrompt(items) {
|
|
1346
|
+
const map = /* @__PURE__ */ new Map();
|
|
1347
|
+
for (const item of items) {
|
|
1348
|
+
const key = item.prompt ?? "";
|
|
1349
|
+
if (!map.has(key)) map.set(key, []);
|
|
1350
|
+
map.get(key).push(item);
|
|
1351
|
+
}
|
|
1352
|
+
const groups = [];
|
|
1353
|
+
for (const [prompt, groupItems] of map) {
|
|
1354
|
+
const titled = groupItems.filter((i) => i.titleTs);
|
|
1355
|
+
const representative = titled.length > 0 ? titled.reduce((a, b) => a.titleTs > b.titleTs ? a : b) : groupItems.reduce((a, b) => a.timestamp > b.timestamp ? a : b);
|
|
1356
|
+
groups.push({ prompt, items: groupItems, representative });
|
|
1357
|
+
}
|
|
1358
|
+
return groups.sort((a, b) => {
|
|
1359
|
+
const aMax = Math.max(...a.items.map((i) => i.timestamp));
|
|
1360
|
+
const bMax = Math.max(...b.items.map((i) => i.timestamp));
|
|
1361
|
+
return bMax - aMax;
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
// src/components/MediaLibrary.tsx
|
|
1318
1366
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1367
|
+
var PAGE_SIZE2 = 20;
|
|
1319
1368
|
var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, onBatchDownload, onGenerateReference }) => {
|
|
1369
|
+
const [visibleCount, setVisibleCount] = (0, import_react10.useState)(PAGE_SIZE2);
|
|
1320
1370
|
const selectedCount = items.filter((i) => i.selectedForExport).length;
|
|
1371
|
+
const groups = groupByPrompt(items);
|
|
1372
|
+
const visibleGroups = groups.slice(0, visibleCount);
|
|
1321
1373
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
1322
1374
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col p-4 border-b border-white/5 gap-3 bg-black/20", children: [
|
|
1323
1375
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
1324
1376
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col", children: [
|
|
1325
1377
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-[10px] font-bold text-white uppercase tracking-widest", children: "Projekt Galerie" }),
|
|
1326
1378
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "text-[9px] text-white/30 uppercase tracking-tighter", children: [
|
|
1379
|
+
visibleCount < groups.length ? `${visibleCount} / ${groups.length}` : groups.length,
|
|
1380
|
+
" Gruppen \xB7 ",
|
|
1327
1381
|
items.length,
|
|
1328
|
-
" Assets
|
|
1382
|
+
" Assets"
|
|
1329
1383
|
] })
|
|
1330
1384
|
] }),
|
|
1331
1385
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "button", onClick: () => onImport?.(), className: "flex items-center gap-1.5 px-3 py-1.5 bg-blue-500 hover:bg-blue-400 text-white rounded-lg text-[10px] font-bold uppercase transition-all shadow-[0_0_15px_rgba(59,130,246,0.3)]", children: [
|
|
@@ -1333,7 +1387,7 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
|
|
|
1333
1387
|
"Laden"
|
|
1334
1388
|
] })
|
|
1335
1389
|
] }),
|
|
1336
|
-
selectedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1390
|
+
selectedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react11.motion.div, { initial: { opacity: 0, y: -10 }, animate: { opacity: 1, y: 0 }, className: "flex items-center justify-between bg-blue-500/10 border border-blue-500/20 p-2 rounded-xl", children: [
|
|
1337
1391
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "text-[9px] font-bold uppercase text-blue-400 ml-1", children: [
|
|
1338
1392
|
selectedCount,
|
|
1339
1393
|
" ausgew\xE4hlt"
|
|
@@ -1344,44 +1398,60 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
|
|
|
1344
1398
|
] })
|
|
1345
1399
|
] })
|
|
1346
1400
|
] }),
|
|
1347
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex-1 overflow-y-auto p-4 dark-scrollbar", children:
|
|
1401
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex-1 overflow-y-auto p-4 dark-scrollbar", children: groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col items-center justify-center py-20 text-center gap-4 opacity-10", children: [
|
|
1348
1402
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "photo_library" }),
|
|
1349
1403
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
1350
1404
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-[12px] font-bold uppercase tracking-widest", children: "Keine Medien" }),
|
|
1351
1405
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-[10px] italic", children: "Importiere Assets aus deinem Projekt." })
|
|
1352
1406
|
] })
|
|
1353
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime8.
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1407
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "grid grid-cols-2 gap-3 pb-10", children: [
|
|
1408
|
+
visibleGroups.map((group) => {
|
|
1409
|
+
const rep = group.representative;
|
|
1410
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1411
|
+
import_react11.motion.div,
|
|
1412
|
+
{
|
|
1413
|
+
initial: { opacity: 0, scale: 0.9 },
|
|
1414
|
+
animate: { opacity: 1, scale: 1 },
|
|
1415
|
+
className: "relative aspect-square group/item rounded-xl overflow-hidden border border-white/10 opacity-70 hover:opacity-100 transition-all bg-white/5 cursor-pointer shadow-lg",
|
|
1416
|
+
onClick: () => onSelect(rep),
|
|
1417
|
+
children: [
|
|
1418
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: rep.base64 ? rep.base64.startsWith("data:") ? rep.base64 : `data:image/png;base64,${rep.base64}` : "", className: "w-full h-full object-cover transition-transform duration-500 group-hover/item:scale-110", alt: rep.prompt }),
|
|
1419
|
+
group.items.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "absolute top-1.5 left-1.5 px-1.5 py-0.5 bg-black/70 backdrop-blur-md rounded text-[8px] font-bold text-white/80 flex items-center gap-1", children: [
|
|
1420
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "material-symbols-outlined text-[10px]", children: "photo_library" }),
|
|
1421
|
+
group.items.length
|
|
1422
|
+
] }),
|
|
1423
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-transparent to-transparent opacity-0 group-hover/item:opacity-100 transition-opacity flex flex-col justify-end p-2 gap-2 pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
1424
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-[8px] font-bold text-white/80 truncate max-w-[80px] uppercase tracking-tighter", children: rep.prompt || "Importiert" }),
|
|
1425
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
1426
|
+
onGenerateReference && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", onClick: (e) => {
|
|
1427
|
+
e.stopPropagation();
|
|
1428
|
+
onGenerateReference(rep);
|
|
1429
|
+
}, className: "w-6 h-6 flex items-center justify-center bg-blue-500/20 text-blue-400 hover:bg-blue-500 rounded-md transition-all hover:text-white pointer-events-auto", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }) }),
|
|
1430
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", onClick: (e) => {
|
|
1431
|
+
e.stopPropagation();
|
|
1432
|
+
onDelete(rep.id);
|
|
1433
|
+
}, className: "w-6 h-6 flex items-center justify-center bg-red-500/20 text-red-400 hover:bg-red-500 rounded-md transition-all hover:text-white pointer-events-auto", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "delete" }) })
|
|
1434
|
+
] })
|
|
1435
|
+
] }) }),
|
|
1436
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "absolute top-1 right-1 px-1.5 py-0.5 bg-black/60 backdrop-blur-md rounded text-[7px] font-bold text-white/60 uppercase tracking-tight", children: rep.type === "import" ? "Library" : "Gen" })
|
|
1437
|
+
]
|
|
1438
|
+
},
|
|
1439
|
+
rep.id
|
|
1440
|
+
);
|
|
1441
|
+
}),
|
|
1442
|
+
visibleCount < groups.length && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "col-span-2 flex justify-center pt-2 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "button", onClick: () => setVisibleCount((c) => c + PAGE_SIZE2), className: "px-4 py-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-lg text-[10px] font-bold uppercase text-white/60 hover:text-white transition-all", children: [
|
|
1443
|
+
groups.length - visibleCount,
|
|
1444
|
+
" weitere laden"
|
|
1445
|
+
] }) })
|
|
1446
|
+
] }) })
|
|
1377
1447
|
] });
|
|
1378
1448
|
};
|
|
1379
1449
|
|
|
1380
1450
|
// src/components/ListView.tsx
|
|
1381
|
-
var
|
|
1451
|
+
var import_react12 = require("react");
|
|
1382
1452
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1383
1453
|
var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, isActive, isInPath, onFocus, onGenerate, onGenerateBranch, onGenerateSubtree, isGenerating, isCollapsed, toggleCollapse, renderNode, children }) => {
|
|
1384
|
-
const inputRef = (0,
|
|
1454
|
+
const inputRef = (0, import_react12.useRef)(null);
|
|
1385
1455
|
const hasChildren = children && children.length > 0;
|
|
1386
1456
|
const handleKeyDown = (e) => {
|
|
1387
1457
|
if (e.key === "Tab") {
|
|
@@ -1409,7 +1479,7 @@ var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNod
|
|
|
1409
1479
|
onMoveNode(node.id, "down");
|
|
1410
1480
|
}
|
|
1411
1481
|
};
|
|
1412
|
-
(0,
|
|
1482
|
+
(0, import_react12.useEffect)(() => {
|
|
1413
1483
|
if (isActive && inputRef.current) inputRef.current.focus();
|
|
1414
1484
|
}, [isActive]);
|
|
1415
1485
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col w-full", children: [
|
|
@@ -1443,7 +1513,7 @@ var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNod
|
|
|
1443
1513
|
] });
|
|
1444
1514
|
};
|
|
1445
1515
|
function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, focusedNodeId, onFocus, activePath, onGenerate, onGenerateBranch, onGenerateSubtree, isGeneratingNodeId }) {
|
|
1446
|
-
const [collapsed, setCollapsed] = (0,
|
|
1516
|
+
const [collapsed, setCollapsed] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
|
|
1447
1517
|
const toggleCollapse = (id) => {
|
|
1448
1518
|
setCollapsed((prev) => {
|
|
1449
1519
|
const next = new Set(prev);
|
|
@@ -1471,13 +1541,13 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
|
|
|
1471
1541
|
}
|
|
1472
1542
|
|
|
1473
1543
|
// src/components/AvatarArchitectApp.tsx
|
|
1474
|
-
var
|
|
1544
|
+
var import_react27 = require("react");
|
|
1475
1545
|
|
|
1476
1546
|
// src/components/PromptTab.tsx
|
|
1477
|
-
var
|
|
1547
|
+
var import_react14 = require("react");
|
|
1478
1548
|
|
|
1479
1549
|
// src/components/CollapsibleCard.tsx
|
|
1480
|
-
var
|
|
1550
|
+
var import_react13 = require("react");
|
|
1481
1551
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1482
1552
|
var CollapsibleCard = ({
|
|
1483
1553
|
title,
|
|
@@ -1488,7 +1558,7 @@ var CollapsibleCard = ({
|
|
|
1488
1558
|
collapsible = true,
|
|
1489
1559
|
className = ""
|
|
1490
1560
|
}) => {
|
|
1491
|
-
const [isOpen, setIsOpen] = (0,
|
|
1561
|
+
const [isOpen, setIsOpen] = (0, import_react13.useState)(defaultOpen);
|
|
1492
1562
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `border border-neutral-800 rounded-lg ${className}`, children: [
|
|
1493
1563
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1494
1564
|
"div",
|
|
@@ -1535,20 +1605,20 @@ var PromptTab = ({
|
|
|
1535
1605
|
onTagUpdate,
|
|
1536
1606
|
onTagDelete
|
|
1537
1607
|
}) => {
|
|
1538
|
-
const [selectedLabels, setSelectedLabels] = (0,
|
|
1539
|
-
const [instructions, setInstructions] = (0,
|
|
1540
|
-
const [rules, setRules] = (0,
|
|
1541
|
-
const [activeCategory, setActiveCategory] = (0,
|
|
1542
|
-
const [copied, setCopied] = (0,
|
|
1543
|
-
const imgInputRef = (0,
|
|
1544
|
-
const [addingInCat, setAddingInCat] = (0,
|
|
1545
|
-
const [newLabel, setNewLabel] = (0,
|
|
1546
|
-
const [newValue, setNewValue] = (0,
|
|
1547
|
-
const [editingTag, setEditingTag] = (0,
|
|
1548
|
-
const [editLabel, setEditLabel] = (0,
|
|
1549
|
-
const [editValue, setEditValue] = (0,
|
|
1550
|
-
const longPressTimer = (0,
|
|
1551
|
-
const longPressActivated = (0,
|
|
1608
|
+
const [selectedLabels, setSelectedLabels] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
1609
|
+
const [instructions, setInstructions] = (0, import_react14.useState)("");
|
|
1610
|
+
const [rules, setRules] = (0, import_react14.useState)("");
|
|
1611
|
+
const [activeCategory, setActiveCategory] = (0, import_react14.useState)(null);
|
|
1612
|
+
const [copied, setCopied] = (0, import_react14.useState)(false);
|
|
1613
|
+
const imgInputRef = (0, import_react14.useRef)(null);
|
|
1614
|
+
const [addingInCat, setAddingInCat] = (0, import_react14.useState)(null);
|
|
1615
|
+
const [newLabel, setNewLabel] = (0, import_react14.useState)("");
|
|
1616
|
+
const [newValue, setNewValue] = (0, import_react14.useState)("");
|
|
1617
|
+
const [editingTag, setEditingTag] = (0, import_react14.useState)(null);
|
|
1618
|
+
const [editLabel, setEditLabel] = (0, import_react14.useState)("");
|
|
1619
|
+
const [editValue, setEditValue] = (0, import_react14.useState)("");
|
|
1620
|
+
const longPressTimer = (0, import_react14.useRef)(null);
|
|
1621
|
+
const longPressActivated = (0, import_react14.useRef)(false);
|
|
1552
1622
|
const toggleTag = (label) => {
|
|
1553
1623
|
setSelectedLabels((prev) => {
|
|
1554
1624
|
const next = new Set(prev);
|
|
@@ -1995,7 +2065,7 @@ var PromptTab = ({
|
|
|
1995
2065
|
};
|
|
1996
2066
|
|
|
1997
2067
|
// src/components/ProjectSyncTab.tsx
|
|
1998
|
-
var
|
|
2068
|
+
var import_react15 = require("react");
|
|
1999
2069
|
init_hfStateService();
|
|
2000
2070
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2001
2071
|
var ProjectSyncTab = ({
|
|
@@ -2016,14 +2086,14 @@ var ProjectSyncTab = ({
|
|
|
2016
2086
|
onProjectExportBase64,
|
|
2017
2087
|
onHfInitialSync
|
|
2018
2088
|
}) => {
|
|
2019
|
-
const projectInputRef = (0,
|
|
2020
|
-
const workspaceInputRef = (0,
|
|
2021
|
-
const [saveName, setSaveName] = (0,
|
|
2022
|
-
const [isSaving, setIsSaving] = (0,
|
|
2023
|
-
const [isExporting, setIsExporting] = (0,
|
|
2024
|
-
const [syncState, setSyncState] = (0,
|
|
2025
|
-
const [syncDiff, setSyncDiff] = (0,
|
|
2026
|
-
const [selectedLocalIds, setSelectedLocalIds] = (0,
|
|
2089
|
+
const projectInputRef = (0, import_react15.useRef)(null);
|
|
2090
|
+
const workspaceInputRef = (0, import_react15.useRef)(null);
|
|
2091
|
+
const [saveName, setSaveName] = (0, import_react15.useState)("");
|
|
2092
|
+
const [isSaving, setIsSaving] = (0, import_react15.useState)(false);
|
|
2093
|
+
const [isExporting, setIsExporting] = (0, import_react15.useState)(false);
|
|
2094
|
+
const [syncState, setSyncState] = (0, import_react15.useState)("idle");
|
|
2095
|
+
const [syncDiff, setSyncDiff] = (0, import_react15.useState)(null);
|
|
2096
|
+
const [selectedLocalIds, setSelectedLocalIds] = (0, import_react15.useState)(/* @__PURE__ */ new Set());
|
|
2027
2097
|
const handleExport = async () => {
|
|
2028
2098
|
if (!onProjectExport) return;
|
|
2029
2099
|
setIsExporting(true);
|
|
@@ -2069,13 +2139,13 @@ var ProjectSyncTab = ({
|
|
|
2069
2139
|
});
|
|
2070
2140
|
};
|
|
2071
2141
|
const isWorking = projectActionState === "working" || projectActionState === "working-full";
|
|
2072
|
-
const [hfProjects, setHfProjects] = (0,
|
|
2073
|
-
const [hfLoading, setHfLoading] = (0,
|
|
2074
|
-
const [hfSaving, setHfSaving] = (0,
|
|
2075
|
-
const [hfError, setHfError] = (0,
|
|
2076
|
-
const [hfSaveName, setHfSaveName] = (0,
|
|
2077
|
-
const [hfSyncProgress, setHfSyncProgress] = (0,
|
|
2078
|
-
const [hfSyncing, setHfSyncing] = (0,
|
|
2142
|
+
const [hfProjects, setHfProjects] = (0, import_react15.useState)([]);
|
|
2143
|
+
const [hfLoading, setHfLoading] = (0, import_react15.useState)(false);
|
|
2144
|
+
const [hfSaving, setHfSaving] = (0, import_react15.useState)(false);
|
|
2145
|
+
const [hfError, setHfError] = (0, import_react15.useState)(null);
|
|
2146
|
+
const [hfSaveName, setHfSaveName] = (0, import_react15.useState)("");
|
|
2147
|
+
const [hfSyncProgress, setHfSyncProgress] = (0, import_react15.useState)(null);
|
|
2148
|
+
const [hfSyncing, setHfSyncing] = (0, import_react15.useState)(false);
|
|
2079
2149
|
const loadHfProjects = async (token) => {
|
|
2080
2150
|
setHfLoading(true);
|
|
2081
2151
|
setHfError(null);
|
|
@@ -2087,7 +2157,7 @@ var ProjectSyncTab = ({
|
|
|
2087
2157
|
setHfLoading(false);
|
|
2088
2158
|
}
|
|
2089
2159
|
};
|
|
2090
|
-
(0,
|
|
2160
|
+
(0, import_react15.useEffect)(() => {
|
|
2091
2161
|
if (hfToken) loadHfProjects(hfToken);
|
|
2092
2162
|
}, [hfToken]);
|
|
2093
2163
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "absolute inset-0 overflow-y-auto dark-scrollbar", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "p-6 flex flex-col gap-8", children: [
|
|
@@ -2501,7 +2571,7 @@ function toPromptImages(images) {
|
|
|
2501
2571
|
init_hfStateService();
|
|
2502
2572
|
|
|
2503
2573
|
// src/hooks/useHFState.ts
|
|
2504
|
-
var
|
|
2574
|
+
var import_react16 = require("react");
|
|
2505
2575
|
init_hfStateService();
|
|
2506
2576
|
|
|
2507
2577
|
// src/lib/hfReducer.ts
|
|
@@ -2523,6 +2593,13 @@ function applyEvent(state, event) {
|
|
|
2523
2593
|
const newAll = tags.all.some((t) => t.value === p.value && t.category === p.category) ? tags.all.map((t) => t.value === p.value && t.category === p.category ? { ...t, ...updated, category: p.category } : t) : [...tags.all, { ...updated, category: p.category }];
|
|
2524
2594
|
return { ...state, tags: { by_category: { ...tags.by_category, [p.category]: newCat }, all: newAll } };
|
|
2525
2595
|
}
|
|
2596
|
+
case "thumb_added": {
|
|
2597
|
+
const p = event.payload;
|
|
2598
|
+
return {
|
|
2599
|
+
...state,
|
|
2600
|
+
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, hasThumb: true } : m)
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
2526
2603
|
case "metadata_updated": {
|
|
2527
2604
|
const p = event.payload;
|
|
2528
2605
|
return {
|
|
@@ -2530,6 +2607,13 @@ function applyEvent(state, event) {
|
|
|
2530
2607
|
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, ...p.delta } : m)
|
|
2531
2608
|
};
|
|
2532
2609
|
}
|
|
2610
|
+
case "title_set": {
|
|
2611
|
+
const p = event.payload;
|
|
2612
|
+
return {
|
|
2613
|
+
...state,
|
|
2614
|
+
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, titleTs: event.ts } : m)
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2533
2617
|
default:
|
|
2534
2618
|
return state;
|
|
2535
2619
|
}
|
|
@@ -2620,18 +2704,18 @@ function writeOfflineBuffer(events) {
|
|
|
2620
2704
|
}
|
|
2621
2705
|
}
|
|
2622
2706
|
function useHFState(token, namespace) {
|
|
2623
|
-
const [state, setState] = (0,
|
|
2624
|
-
const [isLoading, setIsLoading] = (0,
|
|
2625
|
-
const [error, setError] = (0,
|
|
2626
|
-
const [eventCount, setEventCount] = (0,
|
|
2627
|
-
const [localOnlyCount, setLocalOnlyCount] = (0,
|
|
2628
|
-
const [forks, setForks] = (0,
|
|
2629
|
-
const [pendingBufferCount, setPendingBufferCount] = (0,
|
|
2630
|
-
const [lastEventTs, setLastEventTs] = (0,
|
|
2631
|
-
const [hasStateZip, setHasStateZip] = (0,
|
|
2632
|
-
const knownEventPaths = (0,
|
|
2633
|
-
const allEventsRef = (0,
|
|
2634
|
-
const applyNewEvents = (0,
|
|
2707
|
+
const [state, setState] = (0, import_react16.useState)(null);
|
|
2708
|
+
const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
|
|
2709
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
2710
|
+
const [eventCount, setEventCount] = (0, import_react16.useState)(0);
|
|
2711
|
+
const [localOnlyCount, setLocalOnlyCount] = (0, import_react16.useState)(0);
|
|
2712
|
+
const [forks, setForks] = (0, import_react16.useState)([]);
|
|
2713
|
+
const [pendingBufferCount, setPendingBufferCount] = (0, import_react16.useState)(readOfflineBuffer().length);
|
|
2714
|
+
const [lastEventTs, setLastEventTs] = (0, import_react16.useState)(0);
|
|
2715
|
+
const [hasStateZip, setHasStateZip] = (0, import_react16.useState)(false);
|
|
2716
|
+
const knownEventPaths = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
|
|
2717
|
+
const allEventsRef = (0, import_react16.useRef)([]);
|
|
2718
|
+
const applyNewEvents = (0, import_react16.useCallback)((snapshot, newEvents) => {
|
|
2635
2719
|
if (!newEvents.length && allEventsRef.current.length === 0) {
|
|
2636
2720
|
setEventCount(0);
|
|
2637
2721
|
return snapshot;
|
|
@@ -2645,7 +2729,7 @@ function useHFState(token, namespace) {
|
|
|
2645
2729
|
if (afterConsolidation.length) setLastEventTs(Math.max(...afterConsolidation.map((e) => e.ts)));
|
|
2646
2730
|
return applyEvents(snapshot, afterConsolidation);
|
|
2647
2731
|
}, []);
|
|
2648
|
-
const loadFull = (0,
|
|
2732
|
+
const loadFull = (0, import_react16.useCallback)(async () => {
|
|
2649
2733
|
if (!token || !namespace) return;
|
|
2650
2734
|
setIsLoading(true);
|
|
2651
2735
|
setError(null);
|
|
@@ -2692,7 +2776,7 @@ function useHFState(token, namespace) {
|
|
|
2692
2776
|
setIsLoading(false);
|
|
2693
2777
|
}
|
|
2694
2778
|
}, [token, namespace, applyNewEvents]);
|
|
2695
|
-
const pollNew = (0,
|
|
2779
|
+
const pollNew = (0, import_react16.useCallback)(async () => {
|
|
2696
2780
|
if (!token || !namespace || !state) return;
|
|
2697
2781
|
try {
|
|
2698
2782
|
const events = await loadPendingEvents(namespace, token, state.meta.consolidatedAt);
|
|
@@ -2706,15 +2790,15 @@ function useHFState(token, namespace) {
|
|
|
2706
2790
|
} catch {
|
|
2707
2791
|
}
|
|
2708
2792
|
}, [token, namespace, state, applyNewEvents]);
|
|
2709
|
-
(0,
|
|
2793
|
+
(0, import_react16.useEffect)(() => {
|
|
2710
2794
|
if (token && namespace) loadFull();
|
|
2711
2795
|
}, [token, namespace]);
|
|
2712
|
-
(0,
|
|
2796
|
+
(0, import_react16.useEffect)(() => {
|
|
2713
2797
|
if (!token || !namespace) return;
|
|
2714
2798
|
const id = setInterval(pollNew, POLL_INTERVAL_MS);
|
|
2715
2799
|
return () => clearInterval(id);
|
|
2716
2800
|
}, [token, namespace, pollNew]);
|
|
2717
|
-
const writeEvent = (0,
|
|
2801
|
+
const writeEvent = (0, import_react16.useCallback)(async (type, payload) => {
|
|
2718
2802
|
const prevTs = lastEventTs ? [lastEventTs] : [state?.meta.consolidatedAt ?? 0];
|
|
2719
2803
|
console.log("[HF] writeEvent called:", { type, namespace, tokenOk: !!token, prevTs });
|
|
2720
2804
|
await pollNew();
|
|
@@ -2764,13 +2848,13 @@ function useHFState(token, namespace) {
|
|
|
2764
2848
|
}
|
|
2765
2849
|
|
|
2766
2850
|
// src/components/labs/LabsTab.tsx
|
|
2767
|
-
var
|
|
2851
|
+
var import_react23 = require("react");
|
|
2768
2852
|
|
|
2769
2853
|
// src/components/labs/LabRemix.tsx
|
|
2770
|
-
var
|
|
2854
|
+
var import_react18 = require("react");
|
|
2771
2855
|
|
|
2772
2856
|
// src/components/labs/LabImagePicker.tsx
|
|
2773
|
-
var
|
|
2857
|
+
var import_react17 = require("react");
|
|
2774
2858
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2775
2859
|
var LabImagePicker = ({
|
|
2776
2860
|
availableItems,
|
|
@@ -2779,8 +2863,8 @@ var LabImagePicker = ({
|
|
|
2779
2863
|
onClose,
|
|
2780
2864
|
title = "Bild w\xE4hlen"
|
|
2781
2865
|
}) => {
|
|
2782
|
-
const [search, setSearch] = (0,
|
|
2783
|
-
const [drillItem, setDrillItem] = (0,
|
|
2866
|
+
const [search, setSearch] = (0, import_react17.useState)("");
|
|
2867
|
+
const [drillItem, setDrillItem] = (0, import_react17.useState)(null);
|
|
2784
2868
|
const filtered = availableItems.filter(
|
|
2785
2869
|
(item) => !search || item.prompt.toLowerCase().includes(search.toLowerCase())
|
|
2786
2870
|
);
|
|
@@ -2882,13 +2966,13 @@ var LabImagePicker = ({
|
|
|
2882
2966
|
// src/components/labs/LabRemix.tsx
|
|
2883
2967
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2884
2968
|
var LabRemix = ({ services, onResult }) => {
|
|
2885
|
-
const [showPicker, setShowPicker] = (0,
|
|
2886
|
-
const [selected, setSelected] = (0,
|
|
2887
|
-
const [instruction, setInstruction] = (0,
|
|
2888
|
-
const [generatedPrompt, setGeneratedPrompt] = (0,
|
|
2889
|
-
const [resultImage, setResultImage] = (0,
|
|
2890
|
-
const [isGeneratingPrompt, setIsGeneratingPrompt] = (0,
|
|
2891
|
-
const [isGeneratingImage, setIsGeneratingImage] = (0,
|
|
2969
|
+
const [showPicker, setShowPicker] = (0, import_react18.useState)(false);
|
|
2970
|
+
const [selected, setSelected] = (0, import_react18.useState)(null);
|
|
2971
|
+
const [instruction, setInstruction] = (0, import_react18.useState)("");
|
|
2972
|
+
const [generatedPrompt, setGeneratedPrompt] = (0, import_react18.useState)("");
|
|
2973
|
+
const [resultImage, setResultImage] = (0, import_react18.useState)(null);
|
|
2974
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react18.useState)(false);
|
|
2975
|
+
const [isGeneratingImage, setIsGeneratingImage] = (0, import_react18.useState)(false);
|
|
2892
2976
|
const handleSelectImage = (item, frame) => {
|
|
2893
2977
|
services.onItemUsed(item);
|
|
2894
2978
|
setSelected({
|
|
@@ -3071,16 +3155,16 @@ var LabRemix = ({ services, onResult }) => {
|
|
|
3071
3155
|
};
|
|
3072
3156
|
|
|
3073
3157
|
// src/components/labs/LabBlend.tsx
|
|
3074
|
-
var
|
|
3158
|
+
var import_react19 = require("react");
|
|
3075
3159
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3076
3160
|
var LabBlend = ({ services, onResult }) => {
|
|
3077
|
-
const [showPickerFor, setShowPickerFor] = (0,
|
|
3078
|
-
const [selectedImages, setSelectedImages] = (0,
|
|
3079
|
-
const [instruction, setInstruction] = (0,
|
|
3080
|
-
const [generatedPrompt, setGeneratedPrompt] = (0,
|
|
3081
|
-
const [resultImage, setResultImage] = (0,
|
|
3082
|
-
const [isGeneratingPrompt, setIsGeneratingPrompt] = (0,
|
|
3083
|
-
const [isGeneratingImage, setIsGeneratingImage] = (0,
|
|
3161
|
+
const [showPickerFor, setShowPickerFor] = (0, import_react19.useState)(null);
|
|
3162
|
+
const [selectedImages, setSelectedImages] = (0, import_react19.useState)([]);
|
|
3163
|
+
const [instruction, setInstruction] = (0, import_react19.useState)("");
|
|
3164
|
+
const [generatedPrompt, setGeneratedPrompt] = (0, import_react19.useState)("");
|
|
3165
|
+
const [resultImage, setResultImage] = (0, import_react19.useState)(null);
|
|
3166
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react19.useState)(false);
|
|
3167
|
+
const [isGeneratingImage, setIsGeneratingImage] = (0, import_react19.useState)(false);
|
|
3084
3168
|
const handleSelectImage = (index, item, frame) => {
|
|
3085
3169
|
services.onItemUsed(item);
|
|
3086
3170
|
const newImg = {
|
|
@@ -3267,17 +3351,17 @@ var LabBlend = ({ services, onResult }) => {
|
|
|
3267
3351
|
};
|
|
3268
3352
|
|
|
3269
3353
|
// src/components/labs/LabCompare.tsx
|
|
3270
|
-
var
|
|
3354
|
+
var import_react20 = require("react");
|
|
3271
3355
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3272
3356
|
var LabCompare = ({ services, onResult }) => {
|
|
3273
|
-
const [showPickerFor, setShowPickerFor] = (0,
|
|
3274
|
-
const [selectedImages, setSelectedImages] = (0,
|
|
3275
|
-
const [instruction, setInstruction] = (0,
|
|
3276
|
-
const [analysis, setAnalysis] = (0,
|
|
3277
|
-
const [generatedPrompt, setGeneratedPrompt] = (0,
|
|
3278
|
-
const [resultImage, setResultImage] = (0,
|
|
3279
|
-
const [isAnalyzing, setIsAnalyzing] = (0,
|
|
3280
|
-
const [isGeneratingImage, setIsGeneratingImage] = (0,
|
|
3357
|
+
const [showPickerFor, setShowPickerFor] = (0, import_react20.useState)(null);
|
|
3358
|
+
const [selectedImages, setSelectedImages] = (0, import_react20.useState)([]);
|
|
3359
|
+
const [instruction, setInstruction] = (0, import_react20.useState)("");
|
|
3360
|
+
const [analysis, setAnalysis] = (0, import_react20.useState)("");
|
|
3361
|
+
const [generatedPrompt, setGeneratedPrompt] = (0, import_react20.useState)("");
|
|
3362
|
+
const [resultImage, setResultImage] = (0, import_react20.useState)(null);
|
|
3363
|
+
const [isAnalyzing, setIsAnalyzing] = (0, import_react20.useState)(false);
|
|
3364
|
+
const [isGeneratingImage, setIsGeneratingImage] = (0, import_react20.useState)(false);
|
|
3281
3365
|
const handleSelectImage = (index, item, frame) => {
|
|
3282
3366
|
services.onItemUsed(item);
|
|
3283
3367
|
const newImg = {
|
|
@@ -3440,14 +3524,14 @@ var LabCompare = ({ services, onResult }) => {
|
|
|
3440
3524
|
};
|
|
3441
3525
|
|
|
3442
3526
|
// src/components/labs/LabLoop.tsx
|
|
3443
|
-
var
|
|
3527
|
+
var import_react21 = require("react");
|
|
3444
3528
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3445
3529
|
var LabLoop = ({ services, onResult }) => {
|
|
3446
|
-
const [rounds, setRounds] = (0,
|
|
3447
|
-
const [currentInstruction, setCurrentInstruction] = (0,
|
|
3448
|
-
const [showPickerForRound, setShowPickerForRound] = (0,
|
|
3449
|
-
const [pendingImages, setPendingImages] = (0,
|
|
3450
|
-
const [isGenerating, setIsGenerating] = (0,
|
|
3530
|
+
const [rounds, setRounds] = (0, import_react21.useState)([]);
|
|
3531
|
+
const [currentInstruction, setCurrentInstruction] = (0, import_react21.useState)("");
|
|
3532
|
+
const [showPickerForRound, setShowPickerForRound] = (0, import_react21.useState)(null);
|
|
3533
|
+
const [pendingImages, setPendingImages] = (0, import_react21.useState)([]);
|
|
3534
|
+
const [isGenerating, setIsGenerating] = (0, import_react21.useState)(false);
|
|
3451
3535
|
const currentPrompt = rounds.length > 0 ? rounds[rounds.length - 1].prompt : "";
|
|
3452
3536
|
const handleAddImage = (item, frame) => {
|
|
3453
3537
|
services.onItemUsed(item);
|
|
@@ -3603,7 +3687,7 @@ var LabLoop = ({ services, onResult }) => {
|
|
|
3603
3687
|
};
|
|
3604
3688
|
|
|
3605
3689
|
// src/components/labs/LabFrameExtractor.tsx
|
|
3606
|
-
var
|
|
3690
|
+
var import_react22 = require("react");
|
|
3607
3691
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3608
3692
|
var formatTime = (s) => {
|
|
3609
3693
|
const m = Math.floor(s / 60);
|
|
@@ -3617,15 +3701,15 @@ var LabFrameExtractor = ({
|
|
|
3617
3701
|
onResult,
|
|
3618
3702
|
resolveVideoUrl
|
|
3619
3703
|
}) => {
|
|
3620
|
-
const videoRef = (0,
|
|
3621
|
-
const canvasRef = (0,
|
|
3622
|
-
const cancelledRef = (0,
|
|
3623
|
-
const [selectedItem, setSelectedItem] = (0,
|
|
3624
|
-
const [videoSrc, setVideoSrc] = (0,
|
|
3625
|
-
const [videoReady, setVideoReady] = (0,
|
|
3626
|
-
const [frames, setFrames] = (0,
|
|
3627
|
-
const [isExtracting, setIsExtracting] = (0,
|
|
3628
|
-
const [intervalSec, setIntervalSec] = (0,
|
|
3704
|
+
const videoRef = (0, import_react22.useRef)(null);
|
|
3705
|
+
const canvasRef = (0, import_react22.useRef)(null);
|
|
3706
|
+
const cancelledRef = (0, import_react22.useRef)(false);
|
|
3707
|
+
const [selectedItem, setSelectedItem] = (0, import_react22.useState)(null);
|
|
3708
|
+
const [videoSrc, setVideoSrc] = (0, import_react22.useState)(null);
|
|
3709
|
+
const [videoReady, setVideoReady] = (0, import_react22.useState)(false);
|
|
3710
|
+
const [frames, setFrames] = (0, import_react22.useState)([]);
|
|
3711
|
+
const [isExtracting, setIsExtracting] = (0, import_react22.useState)(false);
|
|
3712
|
+
const [intervalSec, setIntervalSec] = (0, import_react22.useState)("1");
|
|
3629
3713
|
const handleVideoSelect = (item) => {
|
|
3630
3714
|
const mediaId = item.frames[0]?.mediaId;
|
|
3631
3715
|
if (!mediaId) return;
|
|
@@ -3635,7 +3719,7 @@ var LabFrameExtractor = ({
|
|
|
3635
3719
|
setVideoReady(false);
|
|
3636
3720
|
cancelledRef.current = false;
|
|
3637
3721
|
};
|
|
3638
|
-
const captureAt = (0,
|
|
3722
|
+
const captureAt = (0, import_react22.useCallback)(
|
|
3639
3723
|
(t, label) => new Promise((resolve) => {
|
|
3640
3724
|
const video = videoRef.current;
|
|
3641
3725
|
const canvas = canvasRef.current;
|
|
@@ -3862,7 +3946,7 @@ var BASE_TABS = [
|
|
|
3862
3946
|
];
|
|
3863
3947
|
var FRAMES_TAB = { key: "frames", label: "Frames", icon: "crop_original" };
|
|
3864
3948
|
var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
|
|
3865
|
-
const [activeTab, setActiveTab] = (0,
|
|
3949
|
+
const [activeTab, setActiveTab] = (0, import_react23.useState)("remix");
|
|
3866
3950
|
const showFrames = !!(videoItems && resolveVideoUrl);
|
|
3867
3951
|
const tabs = showFrames ? [...BASE_TABS, FRAMES_TAB] : BASE_TABS;
|
|
3868
3952
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
@@ -3896,19 +3980,19 @@ var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
|
|
|
3896
3980
|
};
|
|
3897
3981
|
|
|
3898
3982
|
// src/components/TagManagerPanel.tsx
|
|
3899
|
-
var
|
|
3983
|
+
var import_react24 = require("react");
|
|
3900
3984
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3901
3985
|
function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete, onTagReorder, onTagMove }) {
|
|
3902
3986
|
const categories = Object.keys(workspaceTags.by_category).filter(
|
|
3903
3987
|
(cat) => (workspaceTags.by_category[cat] || []).some((t) => !t.is_deleted)
|
|
3904
3988
|
);
|
|
3905
|
-
const [selectedCategory, setSelectedCategory] = (0,
|
|
3989
|
+
const [selectedCategory, setSelectedCategory] = (0, import_react24.useState)(categories[0] || "");
|
|
3906
3990
|
const effectiveCategory = categories.includes(selectedCategory) ? selectedCategory : categories[0] || "";
|
|
3907
|
-
const [editingLabel, setEditingLabel] = (0,
|
|
3908
|
-
const [editState, setEditState] = (0,
|
|
3909
|
-
const [newTag, setNewTag] = (0,
|
|
3910
|
-
const [movingLabel, setMovingLabel] = (0,
|
|
3911
|
-
const [moveTarget, setMoveTarget] = (0,
|
|
3991
|
+
const [editingLabel, setEditingLabel] = (0, import_react24.useState)(null);
|
|
3992
|
+
const [editState, setEditState] = (0, import_react24.useState)({ label: "", value: "" });
|
|
3993
|
+
const [newTag, setNewTag] = (0, import_react24.useState)({ label: "", value: "" });
|
|
3994
|
+
const [movingLabel, setMovingLabel] = (0, import_react24.useState)(null);
|
|
3995
|
+
const [moveTarget, setMoveTarget] = (0, import_react24.useState)("");
|
|
3912
3996
|
const tags = (workspaceTags.by_category[effectiveCategory] || []).filter((t) => !t.is_deleted);
|
|
3913
3997
|
const otherCategories = categories.filter((c) => c !== effectiveCategory);
|
|
3914
3998
|
const startEdit = (tag) => {
|
|
@@ -4104,7 +4188,7 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
|
|
|
4104
4188
|
}
|
|
4105
4189
|
|
|
4106
4190
|
// src/components/HFTestTab.tsx
|
|
4107
|
-
var
|
|
4191
|
+
var import_react25 = require("react");
|
|
4108
4192
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4109
4193
|
var HF_BASE2 = "https://huggingface.co";
|
|
4110
4194
|
var HF_REPO2 = "RolandSch/fa-app-state";
|
|
@@ -4297,7 +4381,7 @@ function tryFmt(s) {
|
|
|
4297
4381
|
}
|
|
4298
4382
|
}
|
|
4299
4383
|
function CopyBtn({ text }) {
|
|
4300
|
-
const [done, setDone] = (0,
|
|
4384
|
+
const [done, setDone] = (0, import_react25.useState)(false);
|
|
4301
4385
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4302
4386
|
"button",
|
|
4303
4387
|
{
|
|
@@ -4468,10 +4552,10 @@ function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadSta
|
|
|
4468
4552
|
] })
|
|
4469
4553
|
] });
|
|
4470
4554
|
}
|
|
4471
|
-
function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEventKeys = /* @__PURE__ */ new Set(), imageUploadStatus = /* @__PURE__ */ new Map() }) {
|
|
4472
|
-
const [selected, setSelected] = (0,
|
|
4473
|
-
const [results, setResults] = (0,
|
|
4474
|
-
const [expanded, setExpanded] = (0,
|
|
4555
|
+
function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEventKeys = /* @__PURE__ */ new Set(), imageUploadStatus = /* @__PURE__ */ new Map(), missingImages = [] }) {
|
|
4556
|
+
const [selected, setSelected] = (0, import_react25.useState)(null);
|
|
4557
|
+
const [results, setResults] = (0, import_react25.useState)({});
|
|
4558
|
+
const [expanded, setExpanded] = (0, import_react25.useState)({});
|
|
4475
4559
|
const withResults = galleryItems.filter((g) => g.base64 && g.status === "done");
|
|
4476
4560
|
const setRunning = (id) => setResults((r) => ({ ...r, [id]: { status: "running", steps: [], totalMs: 0 } }));
|
|
4477
4561
|
const setDone = (id, steps, t0) => {
|
|
@@ -4538,6 +4622,33 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
|
|
|
4538
4622
|
)
|
|
4539
4623
|
}
|
|
4540
4624
|
) }),
|
|
4625
|
+
missingImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4626
|
+
CollapsibleCard,
|
|
4627
|
+
{
|
|
4628
|
+
title: `Fehlende Bilder auf HF (${missingImages.length})`,
|
|
4629
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "broken_image" }),
|
|
4630
|
+
defaultOpen: false,
|
|
4631
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "8px 10px 4px" }, children: [
|
|
4632
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { fontSize: 11, color: "rgba(255,255,255,0.4)", marginBottom: 8 }, children: "Metadata-Eintr\xE4ge ohne Bild auf HuggingFace \u2014 Orphaned entries." }),
|
|
4633
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", gap: 8, marginBottom: 8, fontSize: 11, color: "rgba(255,255,255,0.5)" }, children: [
|
|
4634
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { children: [
|
|
4635
|
+
"UUID (Flow-App): ",
|
|
4636
|
+
missingImages.filter((e) => !e.filename).length
|
|
4637
|
+
] }),
|
|
4638
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "\xB7" }),
|
|
4639
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { children: [
|
|
4640
|
+
"Filename (Server-Upload): ",
|
|
4641
|
+
missingImages.filter((e) => !!e.filename).length
|
|
4642
|
+
] })
|
|
4643
|
+
] }),
|
|
4644
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { maxHeight: 300, overflowY: "auto", fontFamily: "monospace", fontSize: 10 }, children: missingImages.map((e) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "3px 0", borderBottom: "1px solid rgba(255,255,255,0.04)", color: "rgba(255,255,255,0.5)", display: "flex", gap: 8 }, children: [
|
|
4645
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { color: e.filename ? "#fb923c" : "#60a5fa", minWidth: 60 }, children: e.filename ? "filename" : "uuid" }),
|
|
4646
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: e.filename ?? e.id }),
|
|
4647
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { color: "rgba(255,255,255,0.3)" }, children: new Date(e.timestamp).toLocaleDateString("de") })
|
|
4648
|
+
] }, e.id)) })
|
|
4649
|
+
] })
|
|
4650
|
+
}
|
|
4651
|
+
) }),
|
|
4541
4652
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4542
4653
|
CollapsibleCard,
|
|
4543
4654
|
{
|
|
@@ -4642,77 +4753,44 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
|
|
|
4642
4753
|
}
|
|
4643
4754
|
|
|
4644
4755
|
// src/components/ServerTab.tsx
|
|
4645
|
-
var
|
|
4646
|
-
|
|
4647
|
-
// src/lib/faHfServerService.ts
|
|
4648
|
-
init_hfStateService();
|
|
4649
|
-
var FA_APP_SPACE = "https://rolandsch-fa-app.hf.space";
|
|
4650
|
-
async function request(method, path, env = "prod", body, tokenOverride) {
|
|
4651
|
-
const token = tokenOverride || getHFToken();
|
|
4652
|
-
if (!token) throw new Error("fa-app gateway: kein HF Token gesetzt");
|
|
4653
|
-
const res = await fetch(`${FA_APP_SPACE}/${path.replace(/^\//, "")}`, {
|
|
4654
|
-
method,
|
|
4655
|
-
headers: {
|
|
4656
|
-
"Authorization": `Bearer ${token}`,
|
|
4657
|
-
"X-Env": env,
|
|
4658
|
-
...body !== void 0 ? { "Content-Type": "application/json" } : {}
|
|
4659
|
-
},
|
|
4660
|
-
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
4661
|
-
});
|
|
4662
|
-
if (!res.ok) {
|
|
4663
|
-
const text = await res.text().catch(() => "");
|
|
4664
|
-
throw new Error(`fa-app gateway ${method} /${path} [${env}] \u2192 ${res.status}: ${text.slice(0, 200)}`);
|
|
4665
|
-
}
|
|
4666
|
-
return res.json();
|
|
4667
|
-
}
|
|
4668
|
-
function faServerGet(path, env = "prod", token) {
|
|
4669
|
-
return request("GET", path, env, void 0, token);
|
|
4670
|
-
}
|
|
4671
|
-
function faServerPost(path, body, env = "prod", token) {
|
|
4672
|
-
return request("POST", path, env, body, token);
|
|
4673
|
-
}
|
|
4674
|
-
function faServerPut(path, body, env = "prod", token) {
|
|
4675
|
-
return request("PUT", path, env, body, token);
|
|
4676
|
-
}
|
|
4677
|
-
function faServerDelete(path, env = "prod", token) {
|
|
4678
|
-
return request("DELETE", path, env, void 0, token);
|
|
4679
|
-
}
|
|
4680
|
-
|
|
4681
|
-
// src/components/ServerTab.tsx
|
|
4682
|
-
init_hfStateService();
|
|
4756
|
+
var import_react26 = require("react");
|
|
4683
4757
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4684
4758
|
function StarRating({ rating = 0 }) {
|
|
4685
4759
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex gap-[2px]", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: `material-symbols-outlined text-[12px] ${i <= rating ? "text-yellow-400" : "text-white/15"}`, children: "star" }, i)) });
|
|
4686
4760
|
}
|
|
4687
|
-
function
|
|
4688
|
-
const
|
|
4689
|
-
const
|
|
4690
|
-
|
|
4691
|
-
const
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
const [
|
|
4696
|
-
const [
|
|
4697
|
-
const [
|
|
4698
|
-
const [
|
|
4699
|
-
const [
|
|
4700
|
-
const [
|
|
4701
|
-
const [
|
|
4702
|
-
const [
|
|
4703
|
-
const [
|
|
4704
|
-
const [
|
|
4705
|
-
(0,
|
|
4706
|
-
|
|
4761
|
+
async function serverGet(baseUrl, path) {
|
|
4762
|
+
const url = `${baseUrl.replace(/\/$/, "")}${path}`;
|
|
4763
|
+
const res = await fetch(url, { credentials: "include" });
|
|
4764
|
+
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
|
|
4765
|
+
const json = await res.json();
|
|
4766
|
+
return json && typeof json === "object" && "data" in json ? json.data : json;
|
|
4767
|
+
}
|
|
4768
|
+
function ServerTab({ serverBaseUrl }) {
|
|
4769
|
+
const [step, setStep] = (0, import_react26.useState)("user");
|
|
4770
|
+
const [users, setUsers] = (0, import_react26.useState)([]);
|
|
4771
|
+
const [usersLoading, setUsersLoading] = (0, import_react26.useState)(false);
|
|
4772
|
+
const [usersError, setUsersError] = (0, import_react26.useState)(null);
|
|
4773
|
+
const [selectedUser, setSelectedUser] = (0, import_react26.useState)(null);
|
|
4774
|
+
const [contexts, setContexts] = (0, import_react26.useState)([]);
|
|
4775
|
+
const [contextsLoading, setContextsLoading] = (0, import_react26.useState)(false);
|
|
4776
|
+
const [selectedContext, setSelectedContext] = (0, import_react26.useState)(null);
|
|
4777
|
+
const [tags, setTags] = (0, import_react26.useState)([]);
|
|
4778
|
+
const [items, setItems] = (0, import_react26.useState)([]);
|
|
4779
|
+
const [libLoading, setLibLoading] = (0, import_react26.useState)(false);
|
|
4780
|
+
const [libError, setLibError] = (0, import_react26.useState)(null);
|
|
4781
|
+
const [activeTag, setActiveTag] = (0, import_react26.useState)(null);
|
|
4782
|
+
const [preview, setPreview] = (0, import_react26.useState)(null);
|
|
4783
|
+
(0, import_react26.useEffect)(() => {
|
|
4784
|
+
if (!serverBaseUrl) return;
|
|
4707
4785
|
setUsersLoading(true);
|
|
4708
4786
|
setUsersError(null);
|
|
4709
|
-
|
|
4710
|
-
}, [
|
|
4787
|
+
serverGet(serverBaseUrl, "/api/v2/users").then(setUsers).catch((e) => setUsersError(String(e))).finally(() => setUsersLoading(false));
|
|
4788
|
+
}, [serverBaseUrl]);
|
|
4711
4789
|
const selectUser = async (user) => {
|
|
4712
4790
|
setSelectedUser(user);
|
|
4713
4791
|
setContextsLoading(true);
|
|
4714
4792
|
try {
|
|
4715
|
-
const data = await
|
|
4793
|
+
const data = await serverGet(serverBaseUrl, `/api2/contexts?user_id=${user.id}`);
|
|
4716
4794
|
if (data.length === 1) {
|
|
4717
4795
|
await loadLibrary(user, data[0]);
|
|
4718
4796
|
} else {
|
|
@@ -4732,12 +4810,11 @@ function ServerTab({ hfToken }) {
|
|
|
4732
4810
|
setLibError(null);
|
|
4733
4811
|
try {
|
|
4734
4812
|
const [tagsRes, libRes] = await Promise.all([
|
|
4735
|
-
|
|
4736
|
-
|
|
4813
|
+
serverGet(serverBaseUrl, `/api2/tags?user_id=${user.id}`),
|
|
4814
|
+
serverGet(serverBaseUrl, `/api/storage/${user.id}/library`)
|
|
4737
4815
|
]);
|
|
4738
4816
|
setTags(Array.isArray(tagsRes) ? tagsRes : []);
|
|
4739
|
-
|
|
4740
|
-
setItems(raw);
|
|
4817
|
+
setItems(Array.isArray(libRes) ? libRes : []);
|
|
4741
4818
|
} catch (e) {
|
|
4742
4819
|
setLibError(String(e));
|
|
4743
4820
|
} finally {
|
|
@@ -4756,13 +4833,7 @@ function ServerTab({ hfToken }) {
|
|
|
4756
4833
|
setLibError(null);
|
|
4757
4834
|
};
|
|
4758
4835
|
const filteredItems = activeTag ? items.filter((item) => item.tags?.some((t) => t.l === activeTag)) : items;
|
|
4759
|
-
if (!
|
|
4760
|
-
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex items-center justify-center h-full p-6", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("p", { className: "text-white/30 text-[12px] text-center", children: [
|
|
4761
|
-
"Kein HF Token gesetzt.",
|
|
4762
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("br", {}),
|
|
4763
|
-
"Bitte zuerst im Setup-Tab einrichten."
|
|
4764
|
-
] }) });
|
|
4765
|
-
}
|
|
4836
|
+
if (!serverBaseUrl) return null;
|
|
4766
4837
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col h-full min-h-0", children: [
|
|
4767
4838
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-white/8", children: [
|
|
4768
4839
|
step !== "user" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { onClick: reset, className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "arrow_back" }) }),
|
|
@@ -4770,16 +4841,7 @@ function ServerTab({ hfToken }) {
|
|
|
4770
4841
|
step === "user" && "Server Browser",
|
|
4771
4842
|
step === "context" && `${selectedUser?.username} \u2014 Kontext w\xE4hlen`,
|
|
4772
4843
|
step === "library" && `${selectedUser?.username} / ${selectedContext?.label || selectedContext?.name || selectedContext?.id}`
|
|
4773
|
-
] })
|
|
4774
|
-
step === "user" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex gap-1", children: ["prod", "dev"].map((e) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4775
|
-
"button",
|
|
4776
|
-
{
|
|
4777
|
-
onClick: () => setEnv(e),
|
|
4778
|
-
className: `text-[10px] font-bold px-2 py-0.5 rounded-lg transition-colors ${env === e ? "bg-white/15 text-white" : "text-white/30 hover:text-white/60"}`,
|
|
4779
|
-
children: e
|
|
4780
|
-
},
|
|
4781
|
-
e
|
|
4782
|
-
)) })
|
|
4844
|
+
] })
|
|
4783
4845
|
] }),
|
|
4784
4846
|
step === "user" && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col flex-1 min-h-0 overflow-y-auto p-3 gap-2", children: [
|
|
4785
4847
|
usersLoading && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-white/30 text-[11px] text-center py-4", children: "Lade User\u2026" }),
|
|
@@ -4870,8 +4932,8 @@ function ServerTab({ hfToken }) {
|
|
|
4870
4932
|
|
|
4871
4933
|
// src/components/AvatarArchitectApp.tsx
|
|
4872
4934
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4873
|
-
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
4874
|
-
(0,
|
|
4935
|
+
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, serverBaseUrl, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
4936
|
+
(0, import_react27.useEffect)(() => {
|
|
4875
4937
|
const id = "flow-styles";
|
|
4876
4938
|
if (!document.getElementById(id)) {
|
|
4877
4939
|
const style = document.createElement("style");
|
|
@@ -4880,29 +4942,29 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4880
4942
|
document.head.appendChild(style);
|
|
4881
4943
|
}
|
|
4882
4944
|
}, []);
|
|
4883
|
-
const [showStart, setShowStart] = (0,
|
|
4884
|
-
const [layoutChoice, setLayoutChoice] = (0,
|
|
4945
|
+
const [showStart, setShowStart] = (0, import_react27.useState)(true);
|
|
4946
|
+
const [layoutChoice, setLayoutChoice] = (0, import_react27.useState)(() => {
|
|
4885
4947
|
try {
|
|
4886
4948
|
return localStorage.getItem("aa-layout") || null;
|
|
4887
4949
|
} catch {
|
|
4888
4950
|
return null;
|
|
4889
4951
|
}
|
|
4890
4952
|
});
|
|
4891
|
-
const [projectLoaded, setProjectLoaded] = (0,
|
|
4892
|
-
const [hfToken, setHfToken] = (0,
|
|
4893
|
-
const [hfTokenInput, setHfTokenInput] = (0,
|
|
4894
|
-
const [isLoadingFromHF, setIsLoadingFromHF] = (0,
|
|
4895
|
-
const [hfNamespaceLocal, setHfNamespaceLocal] = (0,
|
|
4953
|
+
const [projectLoaded, setProjectLoaded] = (0, import_react27.useState)(false);
|
|
4954
|
+
const [hfToken, setHfToken] = (0, import_react27.useState)(initialHfToken || "");
|
|
4955
|
+
const [hfTokenInput, setHfTokenInput] = (0, import_react27.useState)(initialHfToken || "");
|
|
4956
|
+
const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react27.useState)(false);
|
|
4957
|
+
const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react27.useState)(() => {
|
|
4896
4958
|
try {
|
|
4897
4959
|
const stored = localStorage.getItem("aa-hf-namespace");
|
|
4898
4960
|
if (stored !== null) return stored;
|
|
4899
|
-
return
|
|
4961
|
+
return "app.art-by-rolands.de/";
|
|
4900
4962
|
} catch {
|
|
4901
4963
|
return "";
|
|
4902
4964
|
}
|
|
4903
4965
|
});
|
|
4904
|
-
const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0,
|
|
4905
|
-
(0,
|
|
4966
|
+
const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react27.useState)(null);
|
|
4967
|
+
(0, import_react27.useEffect)(() => {
|
|
4906
4968
|
if (hfNamespace !== void 0) return;
|
|
4907
4969
|
const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
|
|
4908
4970
|
if (!backendUrl) return;
|
|
@@ -4924,9 +4986,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4924
4986
|
refresh: refreshHF,
|
|
4925
4987
|
hasStateZip
|
|
4926
4988
|
} = useHFState(hfToken, effectiveNamespace);
|
|
4927
|
-
const [imageUploadStatus, setImageUploadStatus] = (0,
|
|
4928
|
-
const [bootstrapLog, setBootstrapLog] = (0,
|
|
4929
|
-
const [isBootstrapping, setIsBootstrapping] = (0,
|
|
4989
|
+
const [imageUploadStatus, setImageUploadStatus] = (0, import_react27.useState)(/* @__PURE__ */ new Map());
|
|
4990
|
+
const [bootstrapLog, setBootstrapLog] = (0, import_react27.useState)([]);
|
|
4991
|
+
const [isBootstrapping, setIsBootstrapping] = (0, import_react27.useState)(false);
|
|
4992
|
+
const [hfMissingImages, setHfMissingImages] = (0, import_react27.useState)([]);
|
|
4930
4993
|
const syncTopSlot = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4931
4994
|
localOnlyCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { background: "rgba(234,179,8,0.15)", border: "1px solid rgba(234,179,8,0.3)", padding: "4px 10px", fontSize: 11, color: "#fbbf24", borderRadius: 4, marginBottom: 4 }, children: [
|
|
4932
4995
|
"\u26A0 ",
|
|
@@ -4976,7 +5039,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4976
5039
|
bootstrapLog.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { children: l }, i)) })
|
|
4977
5040
|
] })
|
|
4978
5041
|
] });
|
|
4979
|
-
const wsInputRef = (0,
|
|
5042
|
+
const wsInputRef = (0, import_react27.useRef)(null);
|
|
4980
5043
|
const startApp = (choice) => {
|
|
4981
5044
|
try {
|
|
4982
5045
|
localStorage.setItem("aa-layout", choice);
|
|
@@ -4985,16 +5048,16 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4985
5048
|
setLayoutChoice(choice);
|
|
4986
5049
|
setShowStart(false);
|
|
4987
5050
|
};
|
|
4988
|
-
const [nodes, setNodes] = (0,
|
|
4989
|
-
const [edges, setEdges] = (0,
|
|
4990
|
-
const [history, setHistory] = (0,
|
|
4991
|
-
const [galleryItems, setGalleryItems] = (0,
|
|
4992
|
-
const galleryItemsRef = (0,
|
|
4993
|
-
(0,
|
|
5051
|
+
const [nodes, setNodes] = (0, import_react27.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
|
|
5052
|
+
const [edges, setEdges] = (0, import_react27.useState)([]);
|
|
5053
|
+
const [history, setHistory] = (0, import_react27.useState)([]);
|
|
5054
|
+
const [galleryItems, setGalleryItems] = (0, import_react27.useState)([]);
|
|
5055
|
+
const galleryItemsRef = (0, import_react27.useRef)([]);
|
|
5056
|
+
(0, import_react27.useEffect)(() => {
|
|
4994
5057
|
galleryItemsRef.current = galleryItems;
|
|
4995
5058
|
}, [galleryItems]);
|
|
4996
|
-
const hfImageNotFoundRef = (0,
|
|
4997
|
-
(0,
|
|
5059
|
+
const hfImageNotFoundRef = (0, import_react27.useRef)(/* @__PURE__ */ new Map());
|
|
5060
|
+
(0, import_react27.useEffect)(() => {
|
|
4998
5061
|
if (!hfState) return;
|
|
4999
5062
|
if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
|
|
5000
5063
|
const hfIds = new Set(hfState.metadata.map((m) => m.id));
|
|
@@ -5006,7 +5069,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5006
5069
|
model: m.model,
|
|
5007
5070
|
tags: m.tags || [],
|
|
5008
5071
|
timestamp: m.timestamp,
|
|
5009
|
-
status: "done"
|
|
5072
|
+
status: "done",
|
|
5073
|
+
filename: m.filename,
|
|
5074
|
+
hasThumb: m.hasThumb
|
|
5010
5075
|
}));
|
|
5011
5076
|
setGalleryItems((prev) => {
|
|
5012
5077
|
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
@@ -5018,80 +5083,86 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5018
5083
|
const merged = skeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
5019
5084
|
return [...localOnly, ...merged].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5020
5085
|
});
|
|
5021
|
-
const
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5086
|
+
const sortedEntries = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5087
|
+
(async () => {
|
|
5088
|
+
for (const entry of sortedEntries) {
|
|
5089
|
+
if (galleryItemsRef.current.find((g) => g.id === entry.id)?.base64) continue;
|
|
5090
|
+
if (hfImageNotFoundRef.current.has(entry.id)) continue;
|
|
5091
|
+
try {
|
|
5092
|
+
const b64 = await hfLoadImageAsBase64(entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb);
|
|
5093
|
+
if (!b64) {
|
|
5094
|
+
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
5095
|
+
setHfMissingImages((prev) => {
|
|
5096
|
+
if (prev.find((e) => e.id === entry.id)) return prev;
|
|
5097
|
+
return [...prev, { id: entry.id, filename: entry.filename, mimeType: entry.mimeType, timestamp: entry.timestamp }];
|
|
5098
|
+
});
|
|
5099
|
+
continue;
|
|
5100
|
+
}
|
|
5101
|
+
const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
|
|
5102
|
+
setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
5103
|
+
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
5104
|
+
} catch {
|
|
5028
5105
|
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
5029
|
-
return;
|
|
5030
5106
|
}
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
5034
|
-
}).catch(() => {
|
|
5035
|
-
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
5036
|
-
});
|
|
5037
|
-
}
|
|
5107
|
+
}
|
|
5108
|
+
})();
|
|
5038
5109
|
}, [hfState]);
|
|
5039
|
-
const [activePrompt, setActivePrompt] = (0,
|
|
5040
|
-
const [isSynthesizing, setIsSynthesizing] = (0,
|
|
5041
|
-
const [activeGenerationsCount, setActiveGenerationsCount] = (0,
|
|
5042
|
-
const [currentResult, setCurrentResult] = (0,
|
|
5043
|
-
const [focusedNodeId, setFocusedNodeId] = (0,
|
|
5044
|
-
const [leftTab, setLeftTab] = (0,
|
|
5045
|
-
const [promptFeedback, setPromptFeedback] = (0,
|
|
5046
|
-
const [lastPromptPayload, setLastPromptPayload] = (0,
|
|
5047
|
-
const [isPromptTabGenerating, setIsPromptTabGenerating] = (0,
|
|
5048
|
-
const [activeTab, setActiveTab] = (0,
|
|
5049
|
-
const [mobileTab, setMobileTab] = (0,
|
|
5050
|
-
const [middlePanel, setMiddlePanel] = (0,
|
|
5051
|
-
const [recentLabItems, setRecentLabItems] = (0,
|
|
5052
|
-
const [aspectRatio, setAspectRatio] = (0,
|
|
5053
|
-
const [selectedModel, setSelectedModel] = (0,
|
|
5054
|
-
const [seed, setSeed] = (0,
|
|
5055
|
-
const [seedMode, setSeedMode] = (0,
|
|
5056
|
-
const [isLeftCollapsed, setIsLeftCollapsed] = (0,
|
|
5057
|
-
const [isRightCollapsed, setIsRightCollapsed] = (0,
|
|
5058
|
-
const [leftPanelWidth, setLeftPanelWidth] = (0,
|
|
5110
|
+
const [activePrompt, setActivePrompt] = (0, import_react27.useState)("");
|
|
5111
|
+
const [isSynthesizing, setIsSynthesizing] = (0, import_react27.useState)(false);
|
|
5112
|
+
const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react27.useState)(0);
|
|
5113
|
+
const [currentResult, setCurrentResult] = (0, import_react27.useState)(null);
|
|
5114
|
+
const [focusedNodeId, setFocusedNodeId] = (0, import_react27.useState)(null);
|
|
5115
|
+
const [leftTab, setLeftTab] = (0, import_react27.useState)("prompt");
|
|
5116
|
+
const [promptFeedback, setPromptFeedback] = (0, import_react27.useState)(null);
|
|
5117
|
+
const [lastPromptPayload, setLastPromptPayload] = (0, import_react27.useState)(null);
|
|
5118
|
+
const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react27.useState)(false);
|
|
5119
|
+
const [activeTab, setActiveTab] = (0, import_react27.useState)("history");
|
|
5120
|
+
const [mobileTab, setMobileTab] = (0, import_react27.useState)("stage");
|
|
5121
|
+
const [middlePanel, setMiddlePanel] = (0, import_react27.useState)("stage");
|
|
5122
|
+
const [recentLabItems, setRecentLabItems] = (0, import_react27.useState)([]);
|
|
5123
|
+
const [aspectRatio, setAspectRatio] = (0, import_react27.useState)("1:1");
|
|
5124
|
+
const [selectedModel, setSelectedModel] = (0, import_react27.useState)("\u{1F34C} Nano Banana Pro");
|
|
5125
|
+
const [seed, setSeed] = (0, import_react27.useState)(Math.floor(Math.random() * 1e6));
|
|
5126
|
+
const [seedMode, setSeedMode] = (0, import_react27.useState)("random");
|
|
5127
|
+
const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react27.useState)(false);
|
|
5128
|
+
const [isRightCollapsed, setIsRightCollapsed] = (0, import_react27.useState)(false);
|
|
5129
|
+
const [leftPanelWidth, setLeftPanelWidth] = (0, import_react27.useState)(() => {
|
|
5059
5130
|
try {
|
|
5060
5131
|
return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
|
|
5061
5132
|
} catch {
|
|
5062
5133
|
return 260;
|
|
5063
5134
|
}
|
|
5064
5135
|
});
|
|
5065
|
-
const [rightPanelWidth, setRightPanelWidth] = (0,
|
|
5136
|
+
const [rightPanelWidth, setRightPanelWidth] = (0, import_react27.useState)(() => {
|
|
5066
5137
|
try {
|
|
5067
5138
|
return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
|
|
5068
5139
|
} catch {
|
|
5069
5140
|
return 320;
|
|
5070
5141
|
}
|
|
5071
5142
|
});
|
|
5072
|
-
const [isPromptCollapsed, setIsPromptCollapsed] = (0,
|
|
5073
|
-
const [projectActionState, setProjectActionState] = (0,
|
|
5074
|
-
const syncServerDataRef = (0,
|
|
5075
|
-
const [workspaceTags, setWorkspaceTags] = (0,
|
|
5076
|
-
const [serverProjects, setServerProjects] = (0,
|
|
5077
|
-
const [isLoadingFromServer, setIsLoadingFromServer] = (0,
|
|
5078
|
-
const [highContrast, setHighContrast] = (0,
|
|
5143
|
+
const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react27.useState)(false);
|
|
5144
|
+
const [projectActionState, setProjectActionState] = (0, import_react27.useState)("idle");
|
|
5145
|
+
const syncServerDataRef = (0, import_react27.useRef)(null);
|
|
5146
|
+
const [workspaceTags, setWorkspaceTags] = (0, import_react27.useState)(null);
|
|
5147
|
+
const [serverProjects, setServerProjects] = (0, import_react27.useState)([]);
|
|
5148
|
+
const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react27.useState)(false);
|
|
5149
|
+
const [highContrast, setHighContrast] = (0, import_react27.useState)(() => {
|
|
5079
5150
|
try {
|
|
5080
5151
|
return localStorage.getItem("aa-contrast") === "high";
|
|
5081
5152
|
} catch {
|
|
5082
5153
|
return false;
|
|
5083
5154
|
}
|
|
5084
5155
|
});
|
|
5085
|
-
const [activeReferenceId, setActiveReferenceId] = (0,
|
|
5086
|
-
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0,
|
|
5087
|
-
const [isScanningImage, setIsScanningImage] = (0,
|
|
5088
|
-
const [touchStartX, setTouchStartX] = (0,
|
|
5089
|
-
const [isFullscreen, setIsFullscreen] = (0,
|
|
5090
|
-
const [zoomScale, setZoomScale] = (0,
|
|
5091
|
-
const [zoomOffset, setZoomOffset] = (0,
|
|
5092
|
-
const lastPinchDist = (0,
|
|
5093
|
-
const lastTapTime = (0,
|
|
5094
|
-
const dragStart = (0,
|
|
5156
|
+
const [activeReferenceId, setActiveReferenceId] = (0, import_react27.useState)(null);
|
|
5157
|
+
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react27.useState)(null);
|
|
5158
|
+
const [isScanningImage, setIsScanningImage] = (0, import_react27.useState)(false);
|
|
5159
|
+
const [touchStartX, setTouchStartX] = (0, import_react27.useState)(null);
|
|
5160
|
+
const [isFullscreen, setIsFullscreen] = (0, import_react27.useState)(false);
|
|
5161
|
+
const [zoomScale, setZoomScale] = (0, import_react27.useState)(1);
|
|
5162
|
+
const [zoomOffset, setZoomOffset] = (0, import_react27.useState)({ x: 0, y: 0 });
|
|
5163
|
+
const lastPinchDist = (0, import_react27.useRef)(null);
|
|
5164
|
+
const lastTapTime = (0, import_react27.useRef)(0);
|
|
5165
|
+
const dragStart = (0, import_react27.useRef)(null);
|
|
5095
5166
|
const openFullscreen = () => {
|
|
5096
5167
|
setIsFullscreen(true);
|
|
5097
5168
|
setZoomScale(1);
|
|
@@ -5154,7 +5225,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5154
5225
|
setActiveReferenceId(null);
|
|
5155
5226
|
setActiveReferenceThumbnail(null);
|
|
5156
5227
|
};
|
|
5157
|
-
const labServices = (0,
|
|
5228
|
+
const labServices = (0, import_react27.useMemo)(() => {
|
|
5158
5229
|
const available = groupGenerationsToLabItems([...galleryItems, ...history]);
|
|
5159
5230
|
return {
|
|
5160
5231
|
availableItems: available,
|
|
@@ -5234,17 +5305,45 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5234
5305
|
setIsScanningImage(false);
|
|
5235
5306
|
}
|
|
5236
5307
|
};
|
|
5237
|
-
const currentIndex = (0,
|
|
5238
|
-
const goToPrev = (0,
|
|
5308
|
+
const currentIndex = (0, import_react27.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
|
|
5309
|
+
const goToPrev = (0, import_react27.useCallback)(() => {
|
|
5239
5310
|
if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
|
|
5240
5311
|
}, [currentIndex, history]);
|
|
5241
|
-
const goToNext = (0,
|
|
5312
|
+
const goToNext = (0, import_react27.useCallback)(() => {
|
|
5242
5313
|
if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
|
|
5243
5314
|
}, [currentIndex, history]);
|
|
5315
|
+
const handleGallerySelect = (0, import_react27.useCallback)((g) => {
|
|
5316
|
+
setCurrentResult(g);
|
|
5317
|
+
setMobileTab("stage");
|
|
5318
|
+
if (g.filename && hfToken && !g.fullBase64) {
|
|
5319
|
+
hfLoadImageAsBase64(g.id, hfToken, effectiveNamespace, g.filename, void 0, g.mimeType, false).then((b64) => {
|
|
5320
|
+
if (!b64) return;
|
|
5321
|
+
const full = `data:${g.mimeType || "image/jpeg"};base64,${b64}`;
|
|
5322
|
+
setCurrentResult((prev) => prev?.id === g.id ? { ...prev, fullBase64: full } : prev);
|
|
5323
|
+
setGalleryItems((prev) => prev.map((item) => item.id === g.id ? { ...item, fullBase64: full } : item));
|
|
5324
|
+
}).catch(() => {
|
|
5325
|
+
});
|
|
5326
|
+
}
|
|
5327
|
+
}, [hfToken, effectiveNamespace]);
|
|
5328
|
+
const handleTitleSet = (0, import_react27.useCallback)((id) => {
|
|
5329
|
+
const ts = Date.now();
|
|
5330
|
+
setGalleryItems((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
|
|
5331
|
+
setHistory((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
|
|
5332
|
+
if (hfToken && effectiveNamespace) {
|
|
5333
|
+
hfWriteEvent("title_set", { id }).catch(() => {
|
|
5334
|
+
});
|
|
5335
|
+
}
|
|
5336
|
+
}, [hfToken, effectiveNamespace, hfWriteEvent]);
|
|
5337
|
+
const currentGroup = (0, import_react27.useMemo)(() => {
|
|
5338
|
+
if (!currentResult?.prompt) return [];
|
|
5339
|
+
const groups = groupByPrompt(galleryItems.filter((g) => g.status === "done" && !!g.base64));
|
|
5340
|
+
const group = groups.find((gr) => gr.prompt === currentResult.prompt);
|
|
5341
|
+
return group ? group.items : [];
|
|
5342
|
+
}, [galleryItems, currentResult?.prompt]);
|
|
5244
5343
|
const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
|
|
5245
5344
|
const isGenerating = activeGenerationsCount > 0;
|
|
5246
5345
|
useKeyboardNavigation(history, currentResult, setCurrentResult);
|
|
5247
|
-
const getSubtreeFormat = (0,
|
|
5346
|
+
const getSubtreeFormat = (0, import_react27.useCallback)((nodeId, depth = 0) => {
|
|
5248
5347
|
const node = nodes.find((n) => n.id === nodeId);
|
|
5249
5348
|
if (!node) return "";
|
|
5250
5349
|
const childrenIds = edges.filter((e) => e.source === nodeId).map((e) => e.target);
|
|
@@ -5252,7 +5351,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5252
5351
|
return `${indent}- ${node.data.label || "(unbenannt)"}
|
|
5253
5352
|
` + childrenIds.map((id) => getSubtreeFormat(id, depth + 1)).join("");
|
|
5254
5353
|
}, [nodes, edges]);
|
|
5255
|
-
const activePath = (0,
|
|
5354
|
+
const activePath = (0, import_react27.useMemo)(() => {
|
|
5256
5355
|
if (!focusedNodeId) return /* @__PURE__ */ new Set();
|
|
5257
5356
|
const path = /* @__PURE__ */ new Set([focusedNodeId]);
|
|
5258
5357
|
let currId = focusedNodeId;
|
|
@@ -5422,8 +5521,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5422
5521
|
const handleDownloadSingle = async () => {
|
|
5423
5522
|
if (!currentResult?.base64) return;
|
|
5424
5523
|
try {
|
|
5425
|
-
const
|
|
5426
|
-
const
|
|
5524
|
+
const downloadSrc = currentResult.fullBase64 || currentResult.base64;
|
|
5525
|
+
const base64Data = downloadSrc.split(",")[1];
|
|
5526
|
+
const mimeType = downloadSrc.split(";")[0].split(":")[1] || "image/png";
|
|
5427
5527
|
let finalBase64 = base64Data;
|
|
5428
5528
|
if (mimeType === "image/png") finalBase64 = injectXMPMetadata(base64Data, currentResult.prompt || "", currentResult.seed, currentResult.model, currentResult.id, currentResult.tags || [], getSubtreeFormat(currentResult.nodeId));
|
|
5429
5529
|
await onDownload(finalBase64, mimeType, `avatar_${currentResult.id.slice(0, 5)}.${mimeType.split("/")[1]}`);
|
|
@@ -5600,7 +5700,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5600
5700
|
setTimeout(() => setProjectActionState("idle"), 4e3);
|
|
5601
5701
|
}
|
|
5602
5702
|
};
|
|
5603
|
-
(0,
|
|
5703
|
+
(0, import_react27.useEffect)(() => {
|
|
5604
5704
|
if (activeTab === "setup" || activeTab === "sync") fetchServerProjects();
|
|
5605
5705
|
}, [activeTab]);
|
|
5606
5706
|
const mergeWorkspaceTags = (local, remote) => {
|
|
@@ -5623,7 +5723,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5623
5723
|
return { by_category: merged, all };
|
|
5624
5724
|
};
|
|
5625
5725
|
if (isFullscreen && currentResult?.base64) {
|
|
5626
|
-
const
|
|
5726
|
+
const fsRaw = currentResult.fullBase64 || currentResult.base64;
|
|
5727
|
+
const fsBase64 = fsRaw.startsWith("data:") ? fsRaw : `data:image/png;base64,${fsRaw}`;
|
|
5627
5728
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
5628
5729
|
"div",
|
|
5629
5730
|
{
|
|
@@ -5870,7 +5971,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5870
5971
|
setMobileTab("stage");
|
|
5871
5972
|
}
|
|
5872
5973
|
} }) }),
|
|
5873
|
-
mobileTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-col flex-1 min-h-0 relative", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, {
|
|
5974
|
+
mobileTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-col flex-1 min-h-0 relative", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, { serverBaseUrl }) }),
|
|
5874
5975
|
mobileTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5875
5976
|
TagManagerPanel,
|
|
5876
5977
|
{
|
|
@@ -5948,7 +6049,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5948
6049
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
|
|
5949
6050
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => handleGenerateImage(currentResult.prompt), className: "px-4 py-2 rounded-lg border border-white/20 text-[13px] text-white/70 active:bg-white/10", children: "Erneut versuchen" })
|
|
5950
6051
|
] }),
|
|
5951
|
-
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.base64, className: "w-full h-full object-contain" }),
|
|
6052
|
+
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
|
|
5952
6053
|
!currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
5953
6054
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
|
|
5954
6055
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
@@ -5966,6 +6067,49 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5966
6067
|
]
|
|
5967
6068
|
}
|
|
5968
6069
|
),
|
|
6070
|
+
currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "mt-2 flex gap-1.5 overflow-x-auto pb-1", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { position: "relative", flexShrink: 0 }, children: [
|
|
6071
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6072
|
+
"div",
|
|
6073
|
+
{
|
|
6074
|
+
onClick: () => handleGallerySelect(item),
|
|
6075
|
+
style: {
|
|
6076
|
+
width: 44,
|
|
6077
|
+
height: 44,
|
|
6078
|
+
borderRadius: 8,
|
|
6079
|
+
overflow: "hidden",
|
|
6080
|
+
cursor: "pointer",
|
|
6081
|
+
border: item.id === currentResult.id ? "2px solid rgba(255,255,255,0.8)" : "2px solid rgba(255,255,255,0.15)",
|
|
6082
|
+
opacity: item.id === currentResult.id ? 1 : 0.55
|
|
6083
|
+
},
|
|
6084
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
|
|
6085
|
+
}
|
|
6086
|
+
),
|
|
6087
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6088
|
+
"button",
|
|
6089
|
+
{
|
|
6090
|
+
onClick: (e) => {
|
|
6091
|
+
e.stopPropagation();
|
|
6092
|
+
handleTitleSet(item.id);
|
|
6093
|
+
},
|
|
6094
|
+
style: {
|
|
6095
|
+
position: "absolute",
|
|
6096
|
+
bottom: 2,
|
|
6097
|
+
right: 2,
|
|
6098
|
+
width: 14,
|
|
6099
|
+
height: 14,
|
|
6100
|
+
background: item.titleTs ? "#f59e0b" : "rgba(0,0,0,0.75)",
|
|
6101
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
6102
|
+
borderRadius: 3,
|
|
6103
|
+
cursor: "pointer",
|
|
6104
|
+
padding: 0,
|
|
6105
|
+
display: "flex",
|
|
6106
|
+
alignItems: "center",
|
|
6107
|
+
justifyContent: "center"
|
|
6108
|
+
},
|
|
6109
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 9, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
|
|
6110
|
+
}
|
|
6111
|
+
)
|
|
6112
|
+
] }, item.id)) }),
|
|
5969
6113
|
currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-2 mt-3", children: [
|
|
5970
6114
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => setActivePrompt(currentResult.prompt || ""), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl border border-white/10 bg-white/5 active:bg-white/10 transition-colors", style: { height: 44 }, children: [
|
|
5971
6115
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
|
|
@@ -5988,10 +6132,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5988
6132
|
hfToken && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => refreshHF(), disabled: isHfRefreshing, className: "w-12 flex items-center justify-center text-white/20 active:text-white transition-colors disabled:opacity-30", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
|
|
5989
6133
|
] }),
|
|
5990
6134
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
5991
|
-
activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: (
|
|
5992
|
-
setCurrentResult(g);
|
|
5993
|
-
setMobileTab("stage");
|
|
5994
|
-
}, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
|
|
6135
|
+
activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
|
|
5995
6136
|
activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5996
6137
|
MediaLibrary,
|
|
5997
6138
|
{
|
|
@@ -6002,10 +6143,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6002
6143
|
setGalleryItems((prev) => [...media.map((m) => ({ id: crypto.randomUUID(), nodeId: "1", base64: `data:${m.mimeType};base64,${m.base64}`, mediaId: m.mediaId, prompt: m.name || "Importiert", timestamp: Date.now(), status: "done", tags: [], type: "import" })), ...prev]);
|
|
6003
6144
|
},
|
|
6004
6145
|
onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
|
|
6005
|
-
onSelect:
|
|
6006
|
-
setCurrentResult(g);
|
|
6007
|
-
setMobileTab("stage");
|
|
6008
|
-
},
|
|
6146
|
+
onSelect: handleGallerySelect,
|
|
6009
6147
|
onGenerateReference: (item) => {
|
|
6010
6148
|
handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true });
|
|
6011
6149
|
setMobileTab("stage");
|
|
@@ -6045,7 +6183,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6045
6183
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
|
|
6046
6184
|
"HF"
|
|
6047
6185
|
] }),
|
|
6048
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActiveTab("server"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "server" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) }),
|
|
6186
|
+
serverBaseUrl && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActiveTab("server"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "server" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) }),
|
|
6049
6187
|
workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActiveTab("tags"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "tags" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
|
|
6050
6188
|
] }),
|
|
6051
6189
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
@@ -6128,10 +6266,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6128
6266
|
galleryItems,
|
|
6129
6267
|
allEvents: hfAllEvents,
|
|
6130
6268
|
confirmedEventKeys: hfConfirmedKeys,
|
|
6131
|
-
imageUploadStatus
|
|
6269
|
+
imageUploadStatus,
|
|
6270
|
+
missingImages: hfMissingImages
|
|
6132
6271
|
}
|
|
6133
6272
|
) }),
|
|
6134
|
-
activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, {
|
|
6273
|
+
activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, { serverBaseUrl }) })
|
|
6135
6274
|
] })
|
|
6136
6275
|
] }),
|
|
6137
6276
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex border-t border-white/10 bg-black shrink-0", style: { height: 56, paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
|
|
@@ -6140,7 +6279,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6140
6279
|
{ id: "labs", icon: "science", label: "Labs" },
|
|
6141
6280
|
...workspaceTags ? [{ id: "tags", icon: "label", label: "Tags" }] : [],
|
|
6142
6281
|
{ id: "browse", icon: "photo_library", label: "Galerie" },
|
|
6143
|
-
{ id: "server", icon: "storage", label: "Server" }
|
|
6282
|
+
...serverBaseUrl ? [{ id: "server", icon: "storage", label: "Server" }] : []
|
|
6144
6283
|
].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => setMobileTab(tab.id), className: `flex-1 flex flex-col items-center justify-center gap-0.5 transition-colors ${mobileTab === tab.id ? "text-white" : "text-white/30"}`, children: [
|
|
6145
6284
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
|
|
6146
6285
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
|
|
@@ -6191,7 +6330,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6191
6330
|
] })
|
|
6192
6331
|
}
|
|
6193
6332
|
) }),
|
|
6194
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect:
|
|
6333
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }) })
|
|
6195
6334
|
] }),
|
|
6196
6335
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
|
|
6197
6336
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
@@ -6216,7 +6355,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6216
6355
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
|
|
6217
6356
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => handleGenerateImage(currentResult.prompt), style: { padding: "8px 16px", borderRadius: 8, border: "1px solid rgba(255,255,255,0.2)", fontSize: 11, color: "rgba(255,255,255,0.7)", background: "none", cursor: "pointer", fontFamily: "inherit" }, children: "Erneut versuchen" })
|
|
6218
6357
|
] }),
|
|
6219
|
-
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
|
|
6358
|
+
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
|
|
6220
6359
|
!currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
|
|
6221
6360
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
|
|
6222
6361
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
|
|
@@ -6358,33 +6497,81 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6358
6497
|
middlePanel === "labs" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(LabsTab, { services: labServices, onResult: (item) => {
|
|
6359
6498
|
const frame = item.frames[0];
|
|
6360
6499
|
if (frame?.base64) setCurrentResult(frameToGeneration(frame, item));
|
|
6361
|
-
} }) }) : /* @__PURE__ */ (0, import_jsx_runtime23.
|
|
6362
|
-
|
|
6363
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
6367
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
|
|
6368
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
|
|
6369
|
-
] }) : currentResult.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
|
|
6370
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
|
|
6371
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
6372
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
|
|
6373
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
|
|
6500
|
+
} }) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
|
|
6501
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full max-w-4xl aspect-square rounded-3xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center group shadow-2xl", children: [
|
|
6502
|
+
isGenerating && currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "absolute top-6 right-6 z-30 bg-black/60 backdrop-blur-md px-4 py-2 rounded-full border border-white/10 flex items-center gap-3", children: [
|
|
6503
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-3 h-3 border-t-2 border-white rounded-full animate-spin" }),
|
|
6504
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/60 uppercase font-bold tracking-widest", children: "Neue Referenz..." })
|
|
6374
6505
|
] }),
|
|
6375
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "
|
|
6379
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6380
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.
|
|
6381
|
-
|
|
6506
|
+
currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
6507
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
|
|
6508
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
|
|
6509
|
+
] }) : currentResult.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
|
|
6510
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
|
|
6511
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
6512
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
|
|
6513
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
|
|
6514
|
+
] }),
|
|
6515
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
|
|
6516
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
|
|
6517
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.fullBase64 || currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
|
|
6518
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "absolute bottom-6 flex gap-2 opacity-0 group-hover:opacity-100 transition-all translate-y-4 group-hover:translate-y-0 z-20", children: [
|
|
6519
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
|
|
6520
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
|
|
6521
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
|
|
6522
|
+
] })
|
|
6523
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
6524
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
|
|
6525
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
6382
6526
|
] })
|
|
6383
|
-
] })
|
|
6384
|
-
|
|
6385
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6386
|
-
|
|
6387
|
-
|
|
6527
|
+
] }) }),
|
|
6528
|
+
currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { position: "relative", flexShrink: 0 }, children: [
|
|
6529
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6530
|
+
"div",
|
|
6531
|
+
{
|
|
6532
|
+
onClick: () => handleGallerySelect(item),
|
|
6533
|
+
style: {
|
|
6534
|
+
width: 52,
|
|
6535
|
+
height: 52,
|
|
6536
|
+
borderRadius: 10,
|
|
6537
|
+
overflow: "hidden",
|
|
6538
|
+
cursor: "pointer",
|
|
6539
|
+
border: item.id === currentResult.id ? "2px solid rgba(255,255,255,0.8)" : "2px solid rgba(255,255,255,0.12)",
|
|
6540
|
+
opacity: item.id === currentResult.id ? 1 : 0.5,
|
|
6541
|
+
transition: "opacity 0.15s, border-color 0.15s"
|
|
6542
|
+
},
|
|
6543
|
+
className: "hover:opacity-80",
|
|
6544
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
|
|
6545
|
+
}
|
|
6546
|
+
),
|
|
6547
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6548
|
+
"button",
|
|
6549
|
+
{
|
|
6550
|
+
onClick: (e) => {
|
|
6551
|
+
e.stopPropagation();
|
|
6552
|
+
handleTitleSet(item.id);
|
|
6553
|
+
},
|
|
6554
|
+
title: "Als Titel markieren",
|
|
6555
|
+
style: {
|
|
6556
|
+
position: "absolute",
|
|
6557
|
+
bottom: 3,
|
|
6558
|
+
right: 3,
|
|
6559
|
+
width: 16,
|
|
6560
|
+
height: 16,
|
|
6561
|
+
background: item.titleTs ? "#f59e0b" : "rgba(0,0,0,0.75)",
|
|
6562
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
6563
|
+
borderRadius: 4,
|
|
6564
|
+
cursor: "pointer",
|
|
6565
|
+
padding: 0,
|
|
6566
|
+
display: "flex",
|
|
6567
|
+
alignItems: "center",
|
|
6568
|
+
justifyContent: "center"
|
|
6569
|
+
},
|
|
6570
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 10, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
|
|
6571
|
+
}
|
|
6572
|
+
)
|
|
6573
|
+
] }, item.id)) })
|
|
6574
|
+
] })
|
|
6388
6575
|
] })
|
|
6389
6576
|
] }),
|
|
6390
6577
|
!isRightCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
|
|
@@ -6395,7 +6582,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6395
6582
|
setActiveTab(tab);
|
|
6396
6583
|
setIsRightCollapsed(false);
|
|
6397
6584
|
}, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : tab === "inspect" ? "info" : tab === "setup" ? "settings" : tab === "sync" ? "cloud_sync" : "label" }) }, tab)),
|
|
6398
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
|
|
6585
|
+
serverBaseUrl && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
|
|
6399
6586
|
setActiveTab("server");
|
|
6400
6587
|
setIsRightCollapsed(false);
|
|
6401
6588
|
}, className: `w-10 flex items-center justify-center relative transition-colors ${activeTab === "server" ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) })
|
|
@@ -6419,7 +6606,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6419
6606
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
|
|
6420
6607
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
|
|
6421
6608
|
] }) }),
|
|
6422
|
-
activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect:
|
|
6609
|
+
activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
|
|
6423
6610
|
activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6424
6611
|
MediaLibrary,
|
|
6425
6612
|
{
|
|
@@ -6430,7 +6617,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6430
6617
|
setGalleryItems((prev) => [...media.map((m) => ({ id: crypto.randomUUID(), nodeId: "1", base64: `data:${m.mimeType};base64,${m.base64}`, mediaId: m.mediaId, prompt: m.name || "Importiert", timestamp: Date.now(), status: "done", tags: [], type: "import" })), ...prev]);
|
|
6431
6618
|
},
|
|
6432
6619
|
onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
|
|
6433
|
-
onSelect:
|
|
6620
|
+
onSelect: handleGallerySelect,
|
|
6434
6621
|
onGenerateReference: (item) => handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true })
|
|
6435
6622
|
}
|
|
6436
6623
|
),
|
|
@@ -6460,14 +6647,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6460
6647
|
onHfInitialSync: hfToken ? handleHfInitialSync : void 0
|
|
6461
6648
|
}
|
|
6462
6649
|
),
|
|
6463
|
-
activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, {
|
|
6650
|
+
activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, { serverBaseUrl })
|
|
6464
6651
|
] })
|
|
6465
6652
|
] })
|
|
6466
6653
|
] });
|
|
6467
6654
|
}
|
|
6468
6655
|
|
|
6469
6656
|
// src/components/FaApp.tsx
|
|
6470
|
-
var
|
|
6657
|
+
var import_react28 = require("react");
|
|
6471
6658
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
6472
6659
|
function FaApp({
|
|
6473
6660
|
onGenerateImage,
|
|
@@ -6487,8 +6674,8 @@ function FaApp({
|
|
|
6487
6674
|
onServerDelete,
|
|
6488
6675
|
buildInfo
|
|
6489
6676
|
}) {
|
|
6490
|
-
const [hfNamespace, setHfNamespace] = (0,
|
|
6491
|
-
(0,
|
|
6677
|
+
const [hfNamespace, setHfNamespace] = (0, import_react28.useState)(void 0);
|
|
6678
|
+
(0, import_react28.useEffect)(() => {
|
|
6492
6679
|
if (!serverBaseUrl) return;
|
|
6493
6680
|
fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
6494
6681
|
if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
|
|
@@ -6509,6 +6696,7 @@ function FaApp({
|
|
|
6509
6696
|
initialHfToken: libToken ? libToken.startsWith("hf_") ? libToken : `hf_${libToken}` : void 0,
|
|
6510
6697
|
hfNamespace,
|
|
6511
6698
|
allowDevNamespace: !hfNamespace && allowDevNamespace,
|
|
6699
|
+
serverBaseUrl,
|
|
6512
6700
|
onFetchServerProjects,
|
|
6513
6701
|
onServerSave,
|
|
6514
6702
|
onServerLoad,
|
|
@@ -6521,7 +6709,7 @@ function FaApp({
|
|
|
6521
6709
|
// src/index.ts
|
|
6522
6710
|
init_hfStateService();
|
|
6523
6711
|
init_hfStateService();
|
|
6524
|
-
var LIB_VERSION = "2.0.
|
|
6712
|
+
var LIB_VERSION = "2.0.48";
|
|
6525
6713
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6526
6714
|
0 && (module.exports = {
|
|
6527
6715
|
AvatarArchitectApp,
|
|
@@ -6566,10 +6754,6 @@ var LIB_VERSION = "2.0.30";
|
|
|
6566
6754
|
cleanAiResponse,
|
|
6567
6755
|
createFlowServices,
|
|
6568
6756
|
exportProjectToZip,
|
|
6569
|
-
faServerDelete,
|
|
6570
|
-
faServerGet,
|
|
6571
|
-
faServerPost,
|
|
6572
|
-
faServerPut,
|
|
6573
6757
|
findForks,
|
|
6574
6758
|
findTips,
|
|
6575
6759
|
formatTreeToMarkdown,
|