@rslsp1/fa-app-tools 2.0.30 → 2.0.46
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 +635 -431
- package/dist/index.mjs +558 -357
- 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,33 @@ 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");
|
|
1033
|
+
|
|
1034
|
+
// src/lib/grouping.ts
|
|
1035
|
+
function groupByPrompt(items) {
|
|
1036
|
+
const map = /* @__PURE__ */ new Map();
|
|
1037
|
+
for (const item of items) {
|
|
1038
|
+
const key = item.prompt ?? "";
|
|
1039
|
+
if (!map.has(key)) map.set(key, []);
|
|
1040
|
+
map.get(key).push(item);
|
|
1041
|
+
}
|
|
1042
|
+
const groups = [];
|
|
1043
|
+
for (const [prompt, groupItems] of map) {
|
|
1044
|
+
const titled = groupItems.filter((i) => i.titleTs);
|
|
1045
|
+
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);
|
|
1046
|
+
groups.push({ prompt, items: groupItems, representative });
|
|
1047
|
+
}
|
|
1048
|
+
return groups.sort((a, b) => {
|
|
1049
|
+
const aMax = Math.max(...a.items.map((i) => i.timestamp));
|
|
1050
|
+
const bMax = Math.max(...b.items.map((i) => i.timestamp));
|
|
1051
|
+
return bMax - aMax;
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
// src/components/HistoryPanel.tsx
|
|
1027
1056
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1057
|
+
var PAGE_SIZE = 20;
|
|
1028
1058
|
var formatFriendlyTimestamp = (timestamp) => {
|
|
1029
1059
|
const date = new Date(timestamp);
|
|
1030
1060
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1037,46 +1067,83 @@ var formatFriendlyTimestamp = (timestamp) => {
|
|
|
1037
1067
|
return `${date.toLocaleDateString([], { day: "2-digit", month: "2-digit" })}, ${timeStr}`;
|
|
1038
1068
|
};
|
|
1039
1069
|
var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
|
|
1070
|
+
const [visibleCount, setVisibleCount] = (0, import_react4.useState)(PAGE_SIZE);
|
|
1071
|
+
const doneItems = history.filter((g) => g.status === "done");
|
|
1072
|
+
const processingItems = history.filter((g) => g.status !== "done");
|
|
1073
|
+
const groups = groupByPrompt(doneItems);
|
|
1074
|
+
const visibleGroups = groups.slice(0, visibleCount);
|
|
1040
1075
|
if (history.length === 0) {
|
|
1041
1076
|
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
1077
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "history" }),
|
|
1043
1078
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[10px] font-bold uppercase tracking-widest", children: "Keine Historie" })
|
|
1044
1079
|
] });
|
|
1045
1080
|
}
|
|
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.jsx)("span", { className: "text-[7px] font-bold text-white/20 uppercase
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
'"'
|
|
1081
|
+
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: [
|
|
1082
|
+
processingItems.map((gen) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1083
|
+
"div",
|
|
1084
|
+
{
|
|
1085
|
+
className: "flex gap-3 p-2 bg-white/5 border border-white/5 rounded-2xl cursor-pointer group transition-all relative",
|
|
1086
|
+
onClick: () => onSelect(gen),
|
|
1087
|
+
children: [
|
|
1088
|
+
/* @__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: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "w-5 h-5 border-t-2 border-white rounded-full animate-spin" }) }),
|
|
1089
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex-1 py-0.5 overflow-hidden", children: [
|
|
1090
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[7px] font-bold text-white/20 uppercase", children: "Generiere..." }),
|
|
1091
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "text-[9px] text-white/40 line-clamp-2 leading-tight mt-1", children: [
|
|
1092
|
+
'"',
|
|
1093
|
+
gen.prompt,
|
|
1094
|
+
'"'
|
|
1095
|
+
] })
|
|
1062
1096
|
] })
|
|
1063
|
-
]
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1097
|
+
]
|
|
1098
|
+
},
|
|
1099
|
+
gen.id
|
|
1100
|
+
)),
|
|
1101
|
+
visibleGroups.map((group) => {
|
|
1102
|
+
const rep = group.representative;
|
|
1103
|
+
const isActive = group.items.some((i) => i.id === currentResultId);
|
|
1104
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1105
|
+
"div",
|
|
1106
|
+
{
|
|
1107
|
+
className: `flex gap-3 p-2 bg-white/5 border rounded-2xl cursor-pointer group transition-all relative ${isActive ? "border-white/40 bg-white/10 shadow-lg" : "border-white/5 hover:border-white/20"}`,
|
|
1108
|
+
onClick: () => onSelect(rep),
|
|
1109
|
+
children: [
|
|
1110
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w-14 h-14 rounded-xl overflow-hidden bg-black shrink-0 border border-white/5 relative", children: [
|
|
1111
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: rep.base64 ? rep.base64.startsWith("data:") ? rep.base64 : `data:image/png;base64,${rep.base64}` : "", className: "w-full h-full object-cover", alt: "Thumbnail" }),
|
|
1112
|
+
group.items.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "absolute bottom-0.5 right-0.5 px-1 bg-black/80 rounded text-[7px] font-bold text-white/70", children: group.items.length })
|
|
1113
|
+
] }),
|
|
1114
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex-1 py-0.5 overflow-hidden", children: [
|
|
1115
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [
|
|
1116
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-[7px] font-bold text-white/20 uppercase whitespace-nowrap", children: formatFriendlyTimestamp(rep.timestamp) }),
|
|
1117
|
+
rep.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: rep.model })
|
|
1118
|
+
] }),
|
|
1119
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "text-[9px] text-white/60 line-clamp-2 leading-tight", children: [
|
|
1120
|
+
'"',
|
|
1121
|
+
rep.prompt,
|
|
1122
|
+
'"'
|
|
1123
|
+
] })
|
|
1124
|
+
] }),
|
|
1125
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: (e) => {
|
|
1126
|
+
e.stopPropagation();
|
|
1127
|
+
onDelete(rep.id);
|
|
1128
|
+
}, 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", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "delete" }) })
|
|
1129
|
+
]
|
|
1130
|
+
},
|
|
1131
|
+
rep.id
|
|
1132
|
+
);
|
|
1133
|
+
}),
|
|
1134
|
+
visibleCount < groups.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: [
|
|
1135
|
+
groups.length - visibleCount,
|
|
1136
|
+
" weitere laden"
|
|
1137
|
+
] })
|
|
1138
|
+
] });
|
|
1072
1139
|
};
|
|
1073
1140
|
|
|
1074
1141
|
// src/components/InspectPanel.tsx
|
|
1075
|
-
var
|
|
1076
|
-
var
|
|
1142
|
+
var import_react6 = require("react");
|
|
1143
|
+
var import_react7 = require("motion/react");
|
|
1077
1144
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1078
1145
|
var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagToggle }) => {
|
|
1079
|
-
const currentIndex = (0,
|
|
1146
|
+
const currentIndex = (0, import_react6.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
|
|
1080
1147
|
if (!currentResult) {
|
|
1081
1148
|
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
1149
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "info" }),
|
|
@@ -1084,7 +1151,7 @@ var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagTogg
|
|
|
1084
1151
|
] });
|
|
1085
1152
|
}
|
|
1086
1153
|
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)(
|
|
1154
|
+
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
1155
|
/* @__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
1156
|
/* @__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
1157
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SectionLabel, { children: "Vorschau" }),
|
|
@@ -1137,8 +1204,8 @@ var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagTogg
|
|
|
1137
1204
|
};
|
|
1138
1205
|
|
|
1139
1206
|
// src/components/SetupPanel.tsx
|
|
1140
|
-
var
|
|
1141
|
-
var
|
|
1207
|
+
var import_react8 = require("react");
|
|
1208
|
+
var import_react9 = require("motion/react");
|
|
1142
1209
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1143
1210
|
var PRESET_URLS = [
|
|
1144
1211
|
"https://jsonplaceholder.typicode.com/todos/1",
|
|
@@ -1146,12 +1213,12 @@ var PRESET_URLS = [
|
|
|
1146
1213
|
"https://esm.sh/@rslsp1/fa-app-tools@latest"
|
|
1147
1214
|
];
|
|
1148
1215
|
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,
|
|
1216
|
+
const workspaceInputRef = (0, import_react8.useRef)(null);
|
|
1217
|
+
const [urlInput, setUrlInput] = (0, import_react8.useState)("");
|
|
1218
|
+
const [tokenInput, setTokenInput] = (0, import_react8.useState)("");
|
|
1219
|
+
const [testStatus, setTestStatus] = (0, import_react8.useState)("idle");
|
|
1220
|
+
const [result, setResult] = (0, import_react8.useState)(null);
|
|
1221
|
+
const [fetchError, setFetchError] = (0, import_react8.useState)(null);
|
|
1155
1222
|
const runTest = async (url) => {
|
|
1156
1223
|
if (!url.trim()) return;
|
|
1157
1224
|
setTestStatus("loading");
|
|
@@ -1191,7 +1258,7 @@ var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
|
1191
1258
|
setTestStatus("error");
|
|
1192
1259
|
}
|
|
1193
1260
|
};
|
|
1194
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1261
|
+
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
1262
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-4", children: [
|
|
1196
1263
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
1197
1264
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionLabel, { children: "Workspace Management" }),
|
|
@@ -1314,18 +1381,25 @@ var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
|
1314
1381
|
};
|
|
1315
1382
|
|
|
1316
1383
|
// src/components/MediaLibrary.tsx
|
|
1317
|
-
var
|
|
1384
|
+
var import_react10 = require("react");
|
|
1385
|
+
var import_react11 = require("motion/react");
|
|
1318
1386
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1387
|
+
var PAGE_SIZE2 = 20;
|
|
1319
1388
|
var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, onBatchDownload, onGenerateReference }) => {
|
|
1389
|
+
const [visibleCount, setVisibleCount] = (0, import_react10.useState)(PAGE_SIZE2);
|
|
1320
1390
|
const selectedCount = items.filter((i) => i.selectedForExport).length;
|
|
1391
|
+
const groups = groupByPrompt(items);
|
|
1392
|
+
const visibleGroups = groups.slice(0, visibleCount);
|
|
1321
1393
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
1322
1394
|
/* @__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
1395
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between", children: [
|
|
1324
1396
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col", children: [
|
|
1325
1397
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-[10px] font-bold text-white uppercase tracking-widest", children: "Projekt Galerie" }),
|
|
1326
1398
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "text-[9px] text-white/30 uppercase tracking-tighter", children: [
|
|
1399
|
+
visibleCount < groups.length ? `${visibleCount} / ${groups.length}` : groups.length,
|
|
1400
|
+
" Gruppen \xB7 ",
|
|
1327
1401
|
items.length,
|
|
1328
|
-
" Assets
|
|
1402
|
+
" Assets"
|
|
1329
1403
|
] })
|
|
1330
1404
|
] }),
|
|
1331
1405
|
/* @__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 +1407,7 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
|
|
|
1333
1407
|
"Laden"
|
|
1334
1408
|
] })
|
|
1335
1409
|
] }),
|
|
1336
|
-
selectedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1410
|
+
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
1411
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "text-[9px] font-bold uppercase text-blue-400 ml-1", children: [
|
|
1338
1412
|
selectedCount,
|
|
1339
1413
|
" ausgew\xE4hlt"
|
|
@@ -1344,44 +1418,60 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
|
|
|
1344
1418
|
] })
|
|
1345
1419
|
] })
|
|
1346
1420
|
] }),
|
|
1347
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex-1 overflow-y-auto p-4 dark-scrollbar", children:
|
|
1421
|
+
/* @__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
1422
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "photo_library" }),
|
|
1349
1423
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
1350
1424
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-[12px] font-bold uppercase tracking-widest", children: "Keine Medien" }),
|
|
1351
1425
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-[10px] italic", children: "Importiere Assets aus deinem Projekt." })
|
|
1352
1426
|
] })
|
|
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
|
-
|
|
1427
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "grid grid-cols-2 gap-3 pb-10", children: [
|
|
1428
|
+
visibleGroups.map((group) => {
|
|
1429
|
+
const rep = group.representative;
|
|
1430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1431
|
+
import_react11.motion.div,
|
|
1432
|
+
{
|
|
1433
|
+
initial: { opacity: 0, scale: 0.9 },
|
|
1434
|
+
animate: { opacity: 1, scale: 1 },
|
|
1435
|
+
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",
|
|
1436
|
+
onClick: () => onSelect(rep),
|
|
1437
|
+
children: [
|
|
1438
|
+
/* @__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 }),
|
|
1439
|
+
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: [
|
|
1440
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "material-symbols-outlined text-[10px]", children: "photo_library" }),
|
|
1441
|
+
group.items.length
|
|
1442
|
+
] }),
|
|
1443
|
+
/* @__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: [
|
|
1444
|
+
/* @__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" }),
|
|
1445
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
1446
|
+
onGenerateReference && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", onClick: (e) => {
|
|
1447
|
+
e.stopPropagation();
|
|
1448
|
+
onGenerateReference(rep);
|
|
1449
|
+
}, 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" }) }),
|
|
1450
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", onClick: (e) => {
|
|
1451
|
+
e.stopPropagation();
|
|
1452
|
+
onDelete(rep.id);
|
|
1453
|
+
}, 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" }) })
|
|
1454
|
+
] })
|
|
1455
|
+
] }) }),
|
|
1456
|
+
/* @__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" })
|
|
1457
|
+
]
|
|
1458
|
+
},
|
|
1459
|
+
rep.id
|
|
1460
|
+
);
|
|
1461
|
+
}),
|
|
1462
|
+
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: [
|
|
1463
|
+
groups.length - visibleCount,
|
|
1464
|
+
" weitere laden"
|
|
1465
|
+
] }) })
|
|
1466
|
+
] }) })
|
|
1377
1467
|
] });
|
|
1378
1468
|
};
|
|
1379
1469
|
|
|
1380
1470
|
// src/components/ListView.tsx
|
|
1381
|
-
var
|
|
1471
|
+
var import_react12 = require("react");
|
|
1382
1472
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1383
1473
|
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,
|
|
1474
|
+
const inputRef = (0, import_react12.useRef)(null);
|
|
1385
1475
|
const hasChildren = children && children.length > 0;
|
|
1386
1476
|
const handleKeyDown = (e) => {
|
|
1387
1477
|
if (e.key === "Tab") {
|
|
@@ -1409,7 +1499,7 @@ var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNod
|
|
|
1409
1499
|
onMoveNode(node.id, "down");
|
|
1410
1500
|
}
|
|
1411
1501
|
};
|
|
1412
|
-
(0,
|
|
1502
|
+
(0, import_react12.useEffect)(() => {
|
|
1413
1503
|
if (isActive && inputRef.current) inputRef.current.focus();
|
|
1414
1504
|
}, [isActive]);
|
|
1415
1505
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col w-full", children: [
|
|
@@ -1443,7 +1533,7 @@ var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNod
|
|
|
1443
1533
|
] });
|
|
1444
1534
|
};
|
|
1445
1535
|
function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, focusedNodeId, onFocus, activePath, onGenerate, onGenerateBranch, onGenerateSubtree, isGeneratingNodeId }) {
|
|
1446
|
-
const [collapsed, setCollapsed] = (0,
|
|
1536
|
+
const [collapsed, setCollapsed] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
|
|
1447
1537
|
const toggleCollapse = (id) => {
|
|
1448
1538
|
setCollapsed((prev) => {
|
|
1449
1539
|
const next = new Set(prev);
|
|
@@ -1471,13 +1561,13 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
|
|
|
1471
1561
|
}
|
|
1472
1562
|
|
|
1473
1563
|
// src/components/AvatarArchitectApp.tsx
|
|
1474
|
-
var
|
|
1564
|
+
var import_react27 = require("react");
|
|
1475
1565
|
|
|
1476
1566
|
// src/components/PromptTab.tsx
|
|
1477
|
-
var
|
|
1567
|
+
var import_react14 = require("react");
|
|
1478
1568
|
|
|
1479
1569
|
// src/components/CollapsibleCard.tsx
|
|
1480
|
-
var
|
|
1570
|
+
var import_react13 = require("react");
|
|
1481
1571
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1482
1572
|
var CollapsibleCard = ({
|
|
1483
1573
|
title,
|
|
@@ -1488,7 +1578,7 @@ var CollapsibleCard = ({
|
|
|
1488
1578
|
collapsible = true,
|
|
1489
1579
|
className = ""
|
|
1490
1580
|
}) => {
|
|
1491
|
-
const [isOpen, setIsOpen] = (0,
|
|
1581
|
+
const [isOpen, setIsOpen] = (0, import_react13.useState)(defaultOpen);
|
|
1492
1582
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `border border-neutral-800 rounded-lg ${className}`, children: [
|
|
1493
1583
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1494
1584
|
"div",
|
|
@@ -1535,20 +1625,20 @@ var PromptTab = ({
|
|
|
1535
1625
|
onTagUpdate,
|
|
1536
1626
|
onTagDelete
|
|
1537
1627
|
}) => {
|
|
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,
|
|
1628
|
+
const [selectedLabels, setSelectedLabels] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
1629
|
+
const [instructions, setInstructions] = (0, import_react14.useState)("");
|
|
1630
|
+
const [rules, setRules] = (0, import_react14.useState)("");
|
|
1631
|
+
const [activeCategory, setActiveCategory] = (0, import_react14.useState)(null);
|
|
1632
|
+
const [copied, setCopied] = (0, import_react14.useState)(false);
|
|
1633
|
+
const imgInputRef = (0, import_react14.useRef)(null);
|
|
1634
|
+
const [addingInCat, setAddingInCat] = (0, import_react14.useState)(null);
|
|
1635
|
+
const [newLabel, setNewLabel] = (0, import_react14.useState)("");
|
|
1636
|
+
const [newValue, setNewValue] = (0, import_react14.useState)("");
|
|
1637
|
+
const [editingTag, setEditingTag] = (0, import_react14.useState)(null);
|
|
1638
|
+
const [editLabel, setEditLabel] = (0, import_react14.useState)("");
|
|
1639
|
+
const [editValue, setEditValue] = (0, import_react14.useState)("");
|
|
1640
|
+
const longPressTimer = (0, import_react14.useRef)(null);
|
|
1641
|
+
const longPressActivated = (0, import_react14.useRef)(false);
|
|
1552
1642
|
const toggleTag = (label) => {
|
|
1553
1643
|
setSelectedLabels((prev) => {
|
|
1554
1644
|
const next = new Set(prev);
|
|
@@ -1995,7 +2085,7 @@ var PromptTab = ({
|
|
|
1995
2085
|
};
|
|
1996
2086
|
|
|
1997
2087
|
// src/components/ProjectSyncTab.tsx
|
|
1998
|
-
var
|
|
2088
|
+
var import_react15 = require("react");
|
|
1999
2089
|
init_hfStateService();
|
|
2000
2090
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2001
2091
|
var ProjectSyncTab = ({
|
|
@@ -2016,14 +2106,14 @@ var ProjectSyncTab = ({
|
|
|
2016
2106
|
onProjectExportBase64,
|
|
2017
2107
|
onHfInitialSync
|
|
2018
2108
|
}) => {
|
|
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,
|
|
2109
|
+
const projectInputRef = (0, import_react15.useRef)(null);
|
|
2110
|
+
const workspaceInputRef = (0, import_react15.useRef)(null);
|
|
2111
|
+
const [saveName, setSaveName] = (0, import_react15.useState)("");
|
|
2112
|
+
const [isSaving, setIsSaving] = (0, import_react15.useState)(false);
|
|
2113
|
+
const [isExporting, setIsExporting] = (0, import_react15.useState)(false);
|
|
2114
|
+
const [syncState, setSyncState] = (0, import_react15.useState)("idle");
|
|
2115
|
+
const [syncDiff, setSyncDiff] = (0, import_react15.useState)(null);
|
|
2116
|
+
const [selectedLocalIds, setSelectedLocalIds] = (0, import_react15.useState)(/* @__PURE__ */ new Set());
|
|
2027
2117
|
const handleExport = async () => {
|
|
2028
2118
|
if (!onProjectExport) return;
|
|
2029
2119
|
setIsExporting(true);
|
|
@@ -2069,13 +2159,13 @@ var ProjectSyncTab = ({
|
|
|
2069
2159
|
});
|
|
2070
2160
|
};
|
|
2071
2161
|
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,
|
|
2162
|
+
const [hfProjects, setHfProjects] = (0, import_react15.useState)([]);
|
|
2163
|
+
const [hfLoading, setHfLoading] = (0, import_react15.useState)(false);
|
|
2164
|
+
const [hfSaving, setHfSaving] = (0, import_react15.useState)(false);
|
|
2165
|
+
const [hfError, setHfError] = (0, import_react15.useState)(null);
|
|
2166
|
+
const [hfSaveName, setHfSaveName] = (0, import_react15.useState)("");
|
|
2167
|
+
const [hfSyncProgress, setHfSyncProgress] = (0, import_react15.useState)(null);
|
|
2168
|
+
const [hfSyncing, setHfSyncing] = (0, import_react15.useState)(false);
|
|
2079
2169
|
const loadHfProjects = async (token) => {
|
|
2080
2170
|
setHfLoading(true);
|
|
2081
2171
|
setHfError(null);
|
|
@@ -2087,7 +2177,7 @@ var ProjectSyncTab = ({
|
|
|
2087
2177
|
setHfLoading(false);
|
|
2088
2178
|
}
|
|
2089
2179
|
};
|
|
2090
|
-
(0,
|
|
2180
|
+
(0, import_react15.useEffect)(() => {
|
|
2091
2181
|
if (hfToken) loadHfProjects(hfToken);
|
|
2092
2182
|
}, [hfToken]);
|
|
2093
2183
|
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 +2591,7 @@ function toPromptImages(images) {
|
|
|
2501
2591
|
init_hfStateService();
|
|
2502
2592
|
|
|
2503
2593
|
// src/hooks/useHFState.ts
|
|
2504
|
-
var
|
|
2594
|
+
var import_react16 = require("react");
|
|
2505
2595
|
init_hfStateService();
|
|
2506
2596
|
|
|
2507
2597
|
// src/lib/hfReducer.ts
|
|
@@ -2523,6 +2613,13 @@ function applyEvent(state, event) {
|
|
|
2523
2613
|
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
2614
|
return { ...state, tags: { by_category: { ...tags.by_category, [p.category]: newCat }, all: newAll } };
|
|
2525
2615
|
}
|
|
2616
|
+
case "thumb_added": {
|
|
2617
|
+
const p = event.payload;
|
|
2618
|
+
return {
|
|
2619
|
+
...state,
|
|
2620
|
+
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, hasThumb: true } : m)
|
|
2621
|
+
};
|
|
2622
|
+
}
|
|
2526
2623
|
case "metadata_updated": {
|
|
2527
2624
|
const p = event.payload;
|
|
2528
2625
|
return {
|
|
@@ -2530,6 +2627,13 @@ function applyEvent(state, event) {
|
|
|
2530
2627
|
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, ...p.delta } : m)
|
|
2531
2628
|
};
|
|
2532
2629
|
}
|
|
2630
|
+
case "title_set": {
|
|
2631
|
+
const p = event.payload;
|
|
2632
|
+
return {
|
|
2633
|
+
...state,
|
|
2634
|
+
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, titleTs: event.ts } : m)
|
|
2635
|
+
};
|
|
2636
|
+
}
|
|
2533
2637
|
default:
|
|
2534
2638
|
return state;
|
|
2535
2639
|
}
|
|
@@ -2620,18 +2724,18 @@ function writeOfflineBuffer(events) {
|
|
|
2620
2724
|
}
|
|
2621
2725
|
}
|
|
2622
2726
|
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,
|
|
2727
|
+
const [state, setState] = (0, import_react16.useState)(null);
|
|
2728
|
+
const [isLoading, setIsLoading] = (0, import_react16.useState)(false);
|
|
2729
|
+
const [error, setError] = (0, import_react16.useState)(null);
|
|
2730
|
+
const [eventCount, setEventCount] = (0, import_react16.useState)(0);
|
|
2731
|
+
const [localOnlyCount, setLocalOnlyCount] = (0, import_react16.useState)(0);
|
|
2732
|
+
const [forks, setForks] = (0, import_react16.useState)([]);
|
|
2733
|
+
const [pendingBufferCount, setPendingBufferCount] = (0, import_react16.useState)(readOfflineBuffer().length);
|
|
2734
|
+
const [lastEventTs, setLastEventTs] = (0, import_react16.useState)(0);
|
|
2735
|
+
const [hasStateZip, setHasStateZip] = (0, import_react16.useState)(false);
|
|
2736
|
+
const knownEventPaths = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
|
|
2737
|
+
const allEventsRef = (0, import_react16.useRef)([]);
|
|
2738
|
+
const applyNewEvents = (0, import_react16.useCallback)((snapshot, newEvents) => {
|
|
2635
2739
|
if (!newEvents.length && allEventsRef.current.length === 0) {
|
|
2636
2740
|
setEventCount(0);
|
|
2637
2741
|
return snapshot;
|
|
@@ -2645,7 +2749,7 @@ function useHFState(token, namespace) {
|
|
|
2645
2749
|
if (afterConsolidation.length) setLastEventTs(Math.max(...afterConsolidation.map((e) => e.ts)));
|
|
2646
2750
|
return applyEvents(snapshot, afterConsolidation);
|
|
2647
2751
|
}, []);
|
|
2648
|
-
const loadFull = (0,
|
|
2752
|
+
const loadFull = (0, import_react16.useCallback)(async () => {
|
|
2649
2753
|
if (!token || !namespace) return;
|
|
2650
2754
|
setIsLoading(true);
|
|
2651
2755
|
setError(null);
|
|
@@ -2692,7 +2796,7 @@ function useHFState(token, namespace) {
|
|
|
2692
2796
|
setIsLoading(false);
|
|
2693
2797
|
}
|
|
2694
2798
|
}, [token, namespace, applyNewEvents]);
|
|
2695
|
-
const pollNew = (0,
|
|
2799
|
+
const pollNew = (0, import_react16.useCallback)(async () => {
|
|
2696
2800
|
if (!token || !namespace || !state) return;
|
|
2697
2801
|
try {
|
|
2698
2802
|
const events = await loadPendingEvents(namespace, token, state.meta.consolidatedAt);
|
|
@@ -2706,15 +2810,15 @@ function useHFState(token, namespace) {
|
|
|
2706
2810
|
} catch {
|
|
2707
2811
|
}
|
|
2708
2812
|
}, [token, namespace, state, applyNewEvents]);
|
|
2709
|
-
(0,
|
|
2813
|
+
(0, import_react16.useEffect)(() => {
|
|
2710
2814
|
if (token && namespace) loadFull();
|
|
2711
2815
|
}, [token, namespace]);
|
|
2712
|
-
(0,
|
|
2816
|
+
(0, import_react16.useEffect)(() => {
|
|
2713
2817
|
if (!token || !namespace) return;
|
|
2714
2818
|
const id = setInterval(pollNew, POLL_INTERVAL_MS);
|
|
2715
2819
|
return () => clearInterval(id);
|
|
2716
2820
|
}, [token, namespace, pollNew]);
|
|
2717
|
-
const writeEvent = (0,
|
|
2821
|
+
const writeEvent = (0, import_react16.useCallback)(async (type, payload) => {
|
|
2718
2822
|
const prevTs = lastEventTs ? [lastEventTs] : [state?.meta.consolidatedAt ?? 0];
|
|
2719
2823
|
console.log("[HF] writeEvent called:", { type, namespace, tokenOk: !!token, prevTs });
|
|
2720
2824
|
await pollNew();
|
|
@@ -2764,13 +2868,13 @@ function useHFState(token, namespace) {
|
|
|
2764
2868
|
}
|
|
2765
2869
|
|
|
2766
2870
|
// src/components/labs/LabsTab.tsx
|
|
2767
|
-
var
|
|
2871
|
+
var import_react23 = require("react");
|
|
2768
2872
|
|
|
2769
2873
|
// src/components/labs/LabRemix.tsx
|
|
2770
|
-
var
|
|
2874
|
+
var import_react18 = require("react");
|
|
2771
2875
|
|
|
2772
2876
|
// src/components/labs/LabImagePicker.tsx
|
|
2773
|
-
var
|
|
2877
|
+
var import_react17 = require("react");
|
|
2774
2878
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2775
2879
|
var LabImagePicker = ({
|
|
2776
2880
|
availableItems,
|
|
@@ -2779,8 +2883,8 @@ var LabImagePicker = ({
|
|
|
2779
2883
|
onClose,
|
|
2780
2884
|
title = "Bild w\xE4hlen"
|
|
2781
2885
|
}) => {
|
|
2782
|
-
const [search, setSearch] = (0,
|
|
2783
|
-
const [drillItem, setDrillItem] = (0,
|
|
2886
|
+
const [search, setSearch] = (0, import_react17.useState)("");
|
|
2887
|
+
const [drillItem, setDrillItem] = (0, import_react17.useState)(null);
|
|
2784
2888
|
const filtered = availableItems.filter(
|
|
2785
2889
|
(item) => !search || item.prompt.toLowerCase().includes(search.toLowerCase())
|
|
2786
2890
|
);
|
|
@@ -2882,13 +2986,13 @@ var LabImagePicker = ({
|
|
|
2882
2986
|
// src/components/labs/LabRemix.tsx
|
|
2883
2987
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2884
2988
|
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,
|
|
2989
|
+
const [showPicker, setShowPicker] = (0, import_react18.useState)(false);
|
|
2990
|
+
const [selected, setSelected] = (0, import_react18.useState)(null);
|
|
2991
|
+
const [instruction, setInstruction] = (0, import_react18.useState)("");
|
|
2992
|
+
const [generatedPrompt, setGeneratedPrompt] = (0, import_react18.useState)("");
|
|
2993
|
+
const [resultImage, setResultImage] = (0, import_react18.useState)(null);
|
|
2994
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react18.useState)(false);
|
|
2995
|
+
const [isGeneratingImage, setIsGeneratingImage] = (0, import_react18.useState)(false);
|
|
2892
2996
|
const handleSelectImage = (item, frame) => {
|
|
2893
2997
|
services.onItemUsed(item);
|
|
2894
2998
|
setSelected({
|
|
@@ -3071,16 +3175,16 @@ var LabRemix = ({ services, onResult }) => {
|
|
|
3071
3175
|
};
|
|
3072
3176
|
|
|
3073
3177
|
// src/components/labs/LabBlend.tsx
|
|
3074
|
-
var
|
|
3178
|
+
var import_react19 = require("react");
|
|
3075
3179
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3076
3180
|
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,
|
|
3181
|
+
const [showPickerFor, setShowPickerFor] = (0, import_react19.useState)(null);
|
|
3182
|
+
const [selectedImages, setSelectedImages] = (0, import_react19.useState)([]);
|
|
3183
|
+
const [instruction, setInstruction] = (0, import_react19.useState)("");
|
|
3184
|
+
const [generatedPrompt, setGeneratedPrompt] = (0, import_react19.useState)("");
|
|
3185
|
+
const [resultImage, setResultImage] = (0, import_react19.useState)(null);
|
|
3186
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react19.useState)(false);
|
|
3187
|
+
const [isGeneratingImage, setIsGeneratingImage] = (0, import_react19.useState)(false);
|
|
3084
3188
|
const handleSelectImage = (index, item, frame) => {
|
|
3085
3189
|
services.onItemUsed(item);
|
|
3086
3190
|
const newImg = {
|
|
@@ -3267,17 +3371,17 @@ var LabBlend = ({ services, onResult }) => {
|
|
|
3267
3371
|
};
|
|
3268
3372
|
|
|
3269
3373
|
// src/components/labs/LabCompare.tsx
|
|
3270
|
-
var
|
|
3374
|
+
var import_react20 = require("react");
|
|
3271
3375
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3272
3376
|
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,
|
|
3377
|
+
const [showPickerFor, setShowPickerFor] = (0, import_react20.useState)(null);
|
|
3378
|
+
const [selectedImages, setSelectedImages] = (0, import_react20.useState)([]);
|
|
3379
|
+
const [instruction, setInstruction] = (0, import_react20.useState)("");
|
|
3380
|
+
const [analysis, setAnalysis] = (0, import_react20.useState)("");
|
|
3381
|
+
const [generatedPrompt, setGeneratedPrompt] = (0, import_react20.useState)("");
|
|
3382
|
+
const [resultImage, setResultImage] = (0, import_react20.useState)(null);
|
|
3383
|
+
const [isAnalyzing, setIsAnalyzing] = (0, import_react20.useState)(false);
|
|
3384
|
+
const [isGeneratingImage, setIsGeneratingImage] = (0, import_react20.useState)(false);
|
|
3281
3385
|
const handleSelectImage = (index, item, frame) => {
|
|
3282
3386
|
services.onItemUsed(item);
|
|
3283
3387
|
const newImg = {
|
|
@@ -3440,14 +3544,14 @@ var LabCompare = ({ services, onResult }) => {
|
|
|
3440
3544
|
};
|
|
3441
3545
|
|
|
3442
3546
|
// src/components/labs/LabLoop.tsx
|
|
3443
|
-
var
|
|
3547
|
+
var import_react21 = require("react");
|
|
3444
3548
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3445
3549
|
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,
|
|
3550
|
+
const [rounds, setRounds] = (0, import_react21.useState)([]);
|
|
3551
|
+
const [currentInstruction, setCurrentInstruction] = (0, import_react21.useState)("");
|
|
3552
|
+
const [showPickerForRound, setShowPickerForRound] = (0, import_react21.useState)(null);
|
|
3553
|
+
const [pendingImages, setPendingImages] = (0, import_react21.useState)([]);
|
|
3554
|
+
const [isGenerating, setIsGenerating] = (0, import_react21.useState)(false);
|
|
3451
3555
|
const currentPrompt = rounds.length > 0 ? rounds[rounds.length - 1].prompt : "";
|
|
3452
3556
|
const handleAddImage = (item, frame) => {
|
|
3453
3557
|
services.onItemUsed(item);
|
|
@@ -3603,7 +3707,7 @@ var LabLoop = ({ services, onResult }) => {
|
|
|
3603
3707
|
};
|
|
3604
3708
|
|
|
3605
3709
|
// src/components/labs/LabFrameExtractor.tsx
|
|
3606
|
-
var
|
|
3710
|
+
var import_react22 = require("react");
|
|
3607
3711
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3608
3712
|
var formatTime = (s) => {
|
|
3609
3713
|
const m = Math.floor(s / 60);
|
|
@@ -3617,15 +3721,15 @@ var LabFrameExtractor = ({
|
|
|
3617
3721
|
onResult,
|
|
3618
3722
|
resolveVideoUrl
|
|
3619
3723
|
}) => {
|
|
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,
|
|
3724
|
+
const videoRef = (0, import_react22.useRef)(null);
|
|
3725
|
+
const canvasRef = (0, import_react22.useRef)(null);
|
|
3726
|
+
const cancelledRef = (0, import_react22.useRef)(false);
|
|
3727
|
+
const [selectedItem, setSelectedItem] = (0, import_react22.useState)(null);
|
|
3728
|
+
const [videoSrc, setVideoSrc] = (0, import_react22.useState)(null);
|
|
3729
|
+
const [videoReady, setVideoReady] = (0, import_react22.useState)(false);
|
|
3730
|
+
const [frames, setFrames] = (0, import_react22.useState)([]);
|
|
3731
|
+
const [isExtracting, setIsExtracting] = (0, import_react22.useState)(false);
|
|
3732
|
+
const [intervalSec, setIntervalSec] = (0, import_react22.useState)("1");
|
|
3629
3733
|
const handleVideoSelect = (item) => {
|
|
3630
3734
|
const mediaId = item.frames[0]?.mediaId;
|
|
3631
3735
|
if (!mediaId) return;
|
|
@@ -3635,7 +3739,7 @@ var LabFrameExtractor = ({
|
|
|
3635
3739
|
setVideoReady(false);
|
|
3636
3740
|
cancelledRef.current = false;
|
|
3637
3741
|
};
|
|
3638
|
-
const captureAt = (0,
|
|
3742
|
+
const captureAt = (0, import_react22.useCallback)(
|
|
3639
3743
|
(t, label) => new Promise((resolve) => {
|
|
3640
3744
|
const video = videoRef.current;
|
|
3641
3745
|
const canvas = canvasRef.current;
|
|
@@ -3862,7 +3966,7 @@ var BASE_TABS = [
|
|
|
3862
3966
|
];
|
|
3863
3967
|
var FRAMES_TAB = { key: "frames", label: "Frames", icon: "crop_original" };
|
|
3864
3968
|
var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
|
|
3865
|
-
const [activeTab, setActiveTab] = (0,
|
|
3969
|
+
const [activeTab, setActiveTab] = (0, import_react23.useState)("remix");
|
|
3866
3970
|
const showFrames = !!(videoItems && resolveVideoUrl);
|
|
3867
3971
|
const tabs = showFrames ? [...BASE_TABS, FRAMES_TAB] : BASE_TABS;
|
|
3868
3972
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
@@ -3896,19 +4000,19 @@ var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
|
|
|
3896
4000
|
};
|
|
3897
4001
|
|
|
3898
4002
|
// src/components/TagManagerPanel.tsx
|
|
3899
|
-
var
|
|
4003
|
+
var import_react24 = require("react");
|
|
3900
4004
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3901
4005
|
function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete, onTagReorder, onTagMove }) {
|
|
3902
4006
|
const categories = Object.keys(workspaceTags.by_category).filter(
|
|
3903
4007
|
(cat) => (workspaceTags.by_category[cat] || []).some((t) => !t.is_deleted)
|
|
3904
4008
|
);
|
|
3905
|
-
const [selectedCategory, setSelectedCategory] = (0,
|
|
4009
|
+
const [selectedCategory, setSelectedCategory] = (0, import_react24.useState)(categories[0] || "");
|
|
3906
4010
|
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,
|
|
4011
|
+
const [editingLabel, setEditingLabel] = (0, import_react24.useState)(null);
|
|
4012
|
+
const [editState, setEditState] = (0, import_react24.useState)({ label: "", value: "" });
|
|
4013
|
+
const [newTag, setNewTag] = (0, import_react24.useState)({ label: "", value: "" });
|
|
4014
|
+
const [movingLabel, setMovingLabel] = (0, import_react24.useState)(null);
|
|
4015
|
+
const [moveTarget, setMoveTarget] = (0, import_react24.useState)("");
|
|
3912
4016
|
const tags = (workspaceTags.by_category[effectiveCategory] || []).filter((t) => !t.is_deleted);
|
|
3913
4017
|
const otherCategories = categories.filter((c) => c !== effectiveCategory);
|
|
3914
4018
|
const startEdit = (tag) => {
|
|
@@ -4104,7 +4208,7 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
|
|
|
4104
4208
|
}
|
|
4105
4209
|
|
|
4106
4210
|
// src/components/HFTestTab.tsx
|
|
4107
|
-
var
|
|
4211
|
+
var import_react25 = require("react");
|
|
4108
4212
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4109
4213
|
var HF_BASE2 = "https://huggingface.co";
|
|
4110
4214
|
var HF_REPO2 = "RolandSch/fa-app-state";
|
|
@@ -4297,7 +4401,7 @@ function tryFmt(s) {
|
|
|
4297
4401
|
}
|
|
4298
4402
|
}
|
|
4299
4403
|
function CopyBtn({ text }) {
|
|
4300
|
-
const [done, setDone] = (0,
|
|
4404
|
+
const [done, setDone] = (0, import_react25.useState)(false);
|
|
4301
4405
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4302
4406
|
"button",
|
|
4303
4407
|
{
|
|
@@ -4468,10 +4572,10 @@ function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadSta
|
|
|
4468
4572
|
] })
|
|
4469
4573
|
] });
|
|
4470
4574
|
}
|
|
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,
|
|
4575
|
+
function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEventKeys = /* @__PURE__ */ new Set(), imageUploadStatus = /* @__PURE__ */ new Map(), missingImages = [] }) {
|
|
4576
|
+
const [selected, setSelected] = (0, import_react25.useState)(null);
|
|
4577
|
+
const [results, setResults] = (0, import_react25.useState)({});
|
|
4578
|
+
const [expanded, setExpanded] = (0, import_react25.useState)({});
|
|
4475
4579
|
const withResults = galleryItems.filter((g) => g.base64 && g.status === "done");
|
|
4476
4580
|
const setRunning = (id) => setResults((r) => ({ ...r, [id]: { status: "running", steps: [], totalMs: 0 } }));
|
|
4477
4581
|
const setDone = (id, steps, t0) => {
|
|
@@ -4538,6 +4642,33 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
|
|
|
4538
4642
|
)
|
|
4539
4643
|
}
|
|
4540
4644
|
) }),
|
|
4645
|
+
missingImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4646
|
+
CollapsibleCard,
|
|
4647
|
+
{
|
|
4648
|
+
title: `Fehlende Bilder auf HF (${missingImages.length})`,
|
|
4649
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "broken_image" }),
|
|
4650
|
+
defaultOpen: false,
|
|
4651
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { padding: "8px 10px 4px" }, children: [
|
|
4652
|
+
/* @__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." }),
|
|
4653
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { display: "flex", gap: 8, marginBottom: 8, fontSize: 11, color: "rgba(255,255,255,0.5)" }, children: [
|
|
4654
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { children: [
|
|
4655
|
+
"UUID (Flow-App): ",
|
|
4656
|
+
missingImages.filter((e) => !e.filename).length
|
|
4657
|
+
] }),
|
|
4658
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "\xB7" }),
|
|
4659
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { children: [
|
|
4660
|
+
"Filename (Server-Upload): ",
|
|
4661
|
+
missingImages.filter((e) => !!e.filename).length
|
|
4662
|
+
] })
|
|
4663
|
+
] }),
|
|
4664
|
+
/* @__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: [
|
|
4665
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { color: e.filename ? "#fb923c" : "#60a5fa", minWidth: 60 }, children: e.filename ? "filename" : "uuid" }),
|
|
4666
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: e.filename ?? e.id }),
|
|
4667
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { color: "rgba(255,255,255,0.3)" }, children: new Date(e.timestamp).toLocaleDateString("de") })
|
|
4668
|
+
] }, e.id)) })
|
|
4669
|
+
] })
|
|
4670
|
+
}
|
|
4671
|
+
) }),
|
|
4541
4672
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4542
4673
|
CollapsibleCard,
|
|
4543
4674
|
{
|
|
@@ -4642,77 +4773,44 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
|
|
|
4642
4773
|
}
|
|
4643
4774
|
|
|
4644
4775
|
// 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();
|
|
4776
|
+
var import_react26 = require("react");
|
|
4683
4777
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4684
4778
|
function StarRating({ rating = 0 }) {
|
|
4685
4779
|
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
4780
|
}
|
|
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
|
-
|
|
4781
|
+
async function serverGet(baseUrl, path) {
|
|
4782
|
+
const url = `${baseUrl.replace(/\/$/, "")}${path}`;
|
|
4783
|
+
const res = await fetch(url, { credentials: "include" });
|
|
4784
|
+
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
|
|
4785
|
+
const json = await res.json();
|
|
4786
|
+
return json && typeof json === "object" && "data" in json ? json.data : json;
|
|
4787
|
+
}
|
|
4788
|
+
function ServerTab({ serverBaseUrl }) {
|
|
4789
|
+
const [step, setStep] = (0, import_react26.useState)("user");
|
|
4790
|
+
const [users, setUsers] = (0, import_react26.useState)([]);
|
|
4791
|
+
const [usersLoading, setUsersLoading] = (0, import_react26.useState)(false);
|
|
4792
|
+
const [usersError, setUsersError] = (0, import_react26.useState)(null);
|
|
4793
|
+
const [selectedUser, setSelectedUser] = (0, import_react26.useState)(null);
|
|
4794
|
+
const [contexts, setContexts] = (0, import_react26.useState)([]);
|
|
4795
|
+
const [contextsLoading, setContextsLoading] = (0, import_react26.useState)(false);
|
|
4796
|
+
const [selectedContext, setSelectedContext] = (0, import_react26.useState)(null);
|
|
4797
|
+
const [tags, setTags] = (0, import_react26.useState)([]);
|
|
4798
|
+
const [items, setItems] = (0, import_react26.useState)([]);
|
|
4799
|
+
const [libLoading, setLibLoading] = (0, import_react26.useState)(false);
|
|
4800
|
+
const [libError, setLibError] = (0, import_react26.useState)(null);
|
|
4801
|
+
const [activeTag, setActiveTag] = (0, import_react26.useState)(null);
|
|
4802
|
+
const [preview, setPreview] = (0, import_react26.useState)(null);
|
|
4803
|
+
(0, import_react26.useEffect)(() => {
|
|
4804
|
+
if (!serverBaseUrl) return;
|
|
4707
4805
|
setUsersLoading(true);
|
|
4708
4806
|
setUsersError(null);
|
|
4709
|
-
|
|
4710
|
-
}, [
|
|
4807
|
+
serverGet(serverBaseUrl, "/api/v2/users").then(setUsers).catch((e) => setUsersError(String(e))).finally(() => setUsersLoading(false));
|
|
4808
|
+
}, [serverBaseUrl]);
|
|
4711
4809
|
const selectUser = async (user) => {
|
|
4712
4810
|
setSelectedUser(user);
|
|
4713
4811
|
setContextsLoading(true);
|
|
4714
4812
|
try {
|
|
4715
|
-
const data = await
|
|
4813
|
+
const data = await serverGet(serverBaseUrl, `/api2/contexts?user_id=${user.id}`);
|
|
4716
4814
|
if (data.length === 1) {
|
|
4717
4815
|
await loadLibrary(user, data[0]);
|
|
4718
4816
|
} else {
|
|
@@ -4732,12 +4830,11 @@ function ServerTab({ hfToken }) {
|
|
|
4732
4830
|
setLibError(null);
|
|
4733
4831
|
try {
|
|
4734
4832
|
const [tagsRes, libRes] = await Promise.all([
|
|
4735
|
-
|
|
4736
|
-
|
|
4833
|
+
serverGet(serverBaseUrl, `/api2/tags?user_id=${user.id}`),
|
|
4834
|
+
serverGet(serverBaseUrl, `/api/storage/${user.id}/library`)
|
|
4737
4835
|
]);
|
|
4738
4836
|
setTags(Array.isArray(tagsRes) ? tagsRes : []);
|
|
4739
|
-
|
|
4740
|
-
setItems(raw);
|
|
4837
|
+
setItems(Array.isArray(libRes) ? libRes : []);
|
|
4741
4838
|
} catch (e) {
|
|
4742
4839
|
setLibError(String(e));
|
|
4743
4840
|
} finally {
|
|
@@ -4756,13 +4853,7 @@ function ServerTab({ hfToken }) {
|
|
|
4756
4853
|
setLibError(null);
|
|
4757
4854
|
};
|
|
4758
4855
|
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
|
-
}
|
|
4856
|
+
if (!serverBaseUrl) return null;
|
|
4766
4857
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col h-full min-h-0", children: [
|
|
4767
4858
|
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-white/8", children: [
|
|
4768
4859
|
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 +4861,7 @@ function ServerTab({ hfToken }) {
|
|
|
4770
4861
|
step === "user" && "Server Browser",
|
|
4771
4862
|
step === "context" && `${selectedUser?.username} \u2014 Kontext w\xE4hlen`,
|
|
4772
4863
|
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
|
-
)) })
|
|
4864
|
+
] })
|
|
4783
4865
|
] }),
|
|
4784
4866
|
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
4867
|
usersLoading && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-white/30 text-[11px] text-center py-4", children: "Lade User\u2026" }),
|
|
@@ -4870,8 +4952,8 @@ function ServerTab({ hfToken }) {
|
|
|
4870
4952
|
|
|
4871
4953
|
// src/components/AvatarArchitectApp.tsx
|
|
4872
4954
|
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,
|
|
4955
|
+
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, serverBaseUrl, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
4956
|
+
(0, import_react27.useEffect)(() => {
|
|
4875
4957
|
const id = "flow-styles";
|
|
4876
4958
|
if (!document.getElementById(id)) {
|
|
4877
4959
|
const style = document.createElement("style");
|
|
@@ -4880,19 +4962,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4880
4962
|
document.head.appendChild(style);
|
|
4881
4963
|
}
|
|
4882
4964
|
}, []);
|
|
4883
|
-
const [showStart, setShowStart] = (0,
|
|
4884
|
-
const [layoutChoice, setLayoutChoice] = (0,
|
|
4965
|
+
const [showStart, setShowStart] = (0, import_react27.useState)(true);
|
|
4966
|
+
const [layoutChoice, setLayoutChoice] = (0, import_react27.useState)(() => {
|
|
4885
4967
|
try {
|
|
4886
4968
|
return localStorage.getItem("aa-layout") || null;
|
|
4887
4969
|
} catch {
|
|
4888
4970
|
return null;
|
|
4889
4971
|
}
|
|
4890
4972
|
});
|
|
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,
|
|
4973
|
+
const [projectLoaded, setProjectLoaded] = (0, import_react27.useState)(false);
|
|
4974
|
+
const [hfToken, setHfToken] = (0, import_react27.useState)(initialHfToken || "");
|
|
4975
|
+
const [hfTokenInput, setHfTokenInput] = (0, import_react27.useState)(initialHfToken || "");
|
|
4976
|
+
const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react27.useState)(false);
|
|
4977
|
+
const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react27.useState)(() => {
|
|
4896
4978
|
try {
|
|
4897
4979
|
const stored = localStorage.getItem("aa-hf-namespace");
|
|
4898
4980
|
if (stored !== null) return stored;
|
|
@@ -4901,8 +4983,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4901
4983
|
return "";
|
|
4902
4984
|
}
|
|
4903
4985
|
});
|
|
4904
|
-
const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0,
|
|
4905
|
-
(0,
|
|
4986
|
+
const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react27.useState)(null);
|
|
4987
|
+
(0, import_react27.useEffect)(() => {
|
|
4906
4988
|
if (hfNamespace !== void 0) return;
|
|
4907
4989
|
const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
|
|
4908
4990
|
if (!backendUrl) return;
|
|
@@ -4924,9 +5006,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4924
5006
|
refresh: refreshHF,
|
|
4925
5007
|
hasStateZip
|
|
4926
5008
|
} = useHFState(hfToken, effectiveNamespace);
|
|
4927
|
-
const [imageUploadStatus, setImageUploadStatus] = (0,
|
|
4928
|
-
const [bootstrapLog, setBootstrapLog] = (0,
|
|
4929
|
-
const [isBootstrapping, setIsBootstrapping] = (0,
|
|
5009
|
+
const [imageUploadStatus, setImageUploadStatus] = (0, import_react27.useState)(/* @__PURE__ */ new Map());
|
|
5010
|
+
const [bootstrapLog, setBootstrapLog] = (0, import_react27.useState)([]);
|
|
5011
|
+
const [isBootstrapping, setIsBootstrapping] = (0, import_react27.useState)(false);
|
|
5012
|
+
const [hfMissingImages, setHfMissingImages] = (0, import_react27.useState)([]);
|
|
4930
5013
|
const syncTopSlot = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4931
5014
|
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
5015
|
"\u26A0 ",
|
|
@@ -4976,7 +5059,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4976
5059
|
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
5060
|
] })
|
|
4978
5061
|
] });
|
|
4979
|
-
const wsInputRef = (0,
|
|
5062
|
+
const wsInputRef = (0, import_react27.useRef)(null);
|
|
4980
5063
|
const startApp = (choice) => {
|
|
4981
5064
|
try {
|
|
4982
5065
|
localStorage.setItem("aa-layout", choice);
|
|
@@ -4985,16 +5068,16 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4985
5068
|
setLayoutChoice(choice);
|
|
4986
5069
|
setShowStart(false);
|
|
4987
5070
|
};
|
|
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,
|
|
5071
|
+
const [nodes, setNodes] = (0, import_react27.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
|
|
5072
|
+
const [edges, setEdges] = (0, import_react27.useState)([]);
|
|
5073
|
+
const [history, setHistory] = (0, import_react27.useState)([]);
|
|
5074
|
+
const [galleryItems, setGalleryItems] = (0, import_react27.useState)([]);
|
|
5075
|
+
const galleryItemsRef = (0, import_react27.useRef)([]);
|
|
5076
|
+
(0, import_react27.useEffect)(() => {
|
|
4994
5077
|
galleryItemsRef.current = galleryItems;
|
|
4995
5078
|
}, [galleryItems]);
|
|
4996
|
-
const hfImageNotFoundRef = (0,
|
|
4997
|
-
(0,
|
|
5079
|
+
const hfImageNotFoundRef = (0, import_react27.useRef)(/* @__PURE__ */ new Map());
|
|
5080
|
+
(0, import_react27.useEffect)(() => {
|
|
4998
5081
|
if (!hfState) return;
|
|
4999
5082
|
if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
|
|
5000
5083
|
const hfIds = new Set(hfState.metadata.map((m) => m.id));
|
|
@@ -5006,7 +5089,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5006
5089
|
model: m.model,
|
|
5007
5090
|
tags: m.tags || [],
|
|
5008
5091
|
timestamp: m.timestamp,
|
|
5009
|
-
status: "done"
|
|
5092
|
+
status: "done",
|
|
5093
|
+
filename: m.filename,
|
|
5094
|
+
hasThumb: m.hasThumb
|
|
5010
5095
|
}));
|
|
5011
5096
|
setGalleryItems((prev) => {
|
|
5012
5097
|
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
@@ -5018,80 +5103,86 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5018
5103
|
const merged = skeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
5019
5104
|
return [...localOnly, ...merged].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5020
5105
|
});
|
|
5021
|
-
const
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5106
|
+
const sortedEntries = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5107
|
+
(async () => {
|
|
5108
|
+
for (const entry of sortedEntries) {
|
|
5109
|
+
if (galleryItemsRef.current.find((g) => g.id === entry.id)?.base64) continue;
|
|
5110
|
+
if (hfImageNotFoundRef.current.has(entry.id)) continue;
|
|
5111
|
+
try {
|
|
5112
|
+
const b64 = await hfLoadImageAsBase64(entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb);
|
|
5113
|
+
if (!b64) {
|
|
5114
|
+
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
5115
|
+
setHfMissingImages((prev) => {
|
|
5116
|
+
if (prev.find((e) => e.id === entry.id)) return prev;
|
|
5117
|
+
return [...prev, { id: entry.id, filename: entry.filename, mimeType: entry.mimeType, timestamp: entry.timestamp }];
|
|
5118
|
+
});
|
|
5119
|
+
continue;
|
|
5120
|
+
}
|
|
5121
|
+
const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
|
|
5122
|
+
setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
5123
|
+
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
5124
|
+
} catch {
|
|
5028
5125
|
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
5029
|
-
return;
|
|
5030
5126
|
}
|
|
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
|
-
}
|
|
5127
|
+
}
|
|
5128
|
+
})();
|
|
5038
5129
|
}, [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,
|
|
5130
|
+
const [activePrompt, setActivePrompt] = (0, import_react27.useState)("");
|
|
5131
|
+
const [isSynthesizing, setIsSynthesizing] = (0, import_react27.useState)(false);
|
|
5132
|
+
const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react27.useState)(0);
|
|
5133
|
+
const [currentResult, setCurrentResult] = (0, import_react27.useState)(null);
|
|
5134
|
+
const [focusedNodeId, setFocusedNodeId] = (0, import_react27.useState)(null);
|
|
5135
|
+
const [leftTab, setLeftTab] = (0, import_react27.useState)("prompt");
|
|
5136
|
+
const [promptFeedback, setPromptFeedback] = (0, import_react27.useState)(null);
|
|
5137
|
+
const [lastPromptPayload, setLastPromptPayload] = (0, import_react27.useState)(null);
|
|
5138
|
+
const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react27.useState)(false);
|
|
5139
|
+
const [activeTab, setActiveTab] = (0, import_react27.useState)("history");
|
|
5140
|
+
const [mobileTab, setMobileTab] = (0, import_react27.useState)("stage");
|
|
5141
|
+
const [middlePanel, setMiddlePanel] = (0, import_react27.useState)("stage");
|
|
5142
|
+
const [recentLabItems, setRecentLabItems] = (0, import_react27.useState)([]);
|
|
5143
|
+
const [aspectRatio, setAspectRatio] = (0, import_react27.useState)("1:1");
|
|
5144
|
+
const [selectedModel, setSelectedModel] = (0, import_react27.useState)("\u{1F34C} Nano Banana Pro");
|
|
5145
|
+
const [seed, setSeed] = (0, import_react27.useState)(Math.floor(Math.random() * 1e6));
|
|
5146
|
+
const [seedMode, setSeedMode] = (0, import_react27.useState)("random");
|
|
5147
|
+
const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react27.useState)(false);
|
|
5148
|
+
const [isRightCollapsed, setIsRightCollapsed] = (0, import_react27.useState)(false);
|
|
5149
|
+
const [leftPanelWidth, setLeftPanelWidth] = (0, import_react27.useState)(() => {
|
|
5059
5150
|
try {
|
|
5060
5151
|
return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
|
|
5061
5152
|
} catch {
|
|
5062
5153
|
return 260;
|
|
5063
5154
|
}
|
|
5064
5155
|
});
|
|
5065
|
-
const [rightPanelWidth, setRightPanelWidth] = (0,
|
|
5156
|
+
const [rightPanelWidth, setRightPanelWidth] = (0, import_react27.useState)(() => {
|
|
5066
5157
|
try {
|
|
5067
5158
|
return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
|
|
5068
5159
|
} catch {
|
|
5069
5160
|
return 320;
|
|
5070
5161
|
}
|
|
5071
5162
|
});
|
|
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,
|
|
5163
|
+
const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react27.useState)(false);
|
|
5164
|
+
const [projectActionState, setProjectActionState] = (0, import_react27.useState)("idle");
|
|
5165
|
+
const syncServerDataRef = (0, import_react27.useRef)(null);
|
|
5166
|
+
const [workspaceTags, setWorkspaceTags] = (0, import_react27.useState)(null);
|
|
5167
|
+
const [serverProjects, setServerProjects] = (0, import_react27.useState)([]);
|
|
5168
|
+
const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react27.useState)(false);
|
|
5169
|
+
const [highContrast, setHighContrast] = (0, import_react27.useState)(() => {
|
|
5079
5170
|
try {
|
|
5080
5171
|
return localStorage.getItem("aa-contrast") === "high";
|
|
5081
5172
|
} catch {
|
|
5082
5173
|
return false;
|
|
5083
5174
|
}
|
|
5084
5175
|
});
|
|
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,
|
|
5176
|
+
const [activeReferenceId, setActiveReferenceId] = (0, import_react27.useState)(null);
|
|
5177
|
+
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react27.useState)(null);
|
|
5178
|
+
const [isScanningImage, setIsScanningImage] = (0, import_react27.useState)(false);
|
|
5179
|
+
const [touchStartX, setTouchStartX] = (0, import_react27.useState)(null);
|
|
5180
|
+
const [isFullscreen, setIsFullscreen] = (0, import_react27.useState)(false);
|
|
5181
|
+
const [zoomScale, setZoomScale] = (0, import_react27.useState)(1);
|
|
5182
|
+
const [zoomOffset, setZoomOffset] = (0, import_react27.useState)({ x: 0, y: 0 });
|
|
5183
|
+
const lastPinchDist = (0, import_react27.useRef)(null);
|
|
5184
|
+
const lastTapTime = (0, import_react27.useRef)(0);
|
|
5185
|
+
const dragStart = (0, import_react27.useRef)(null);
|
|
5095
5186
|
const openFullscreen = () => {
|
|
5096
5187
|
setIsFullscreen(true);
|
|
5097
5188
|
setZoomScale(1);
|
|
@@ -5154,7 +5245,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5154
5245
|
setActiveReferenceId(null);
|
|
5155
5246
|
setActiveReferenceThumbnail(null);
|
|
5156
5247
|
};
|
|
5157
|
-
const labServices = (0,
|
|
5248
|
+
const labServices = (0, import_react27.useMemo)(() => {
|
|
5158
5249
|
const available = groupGenerationsToLabItems([...galleryItems, ...history]);
|
|
5159
5250
|
return {
|
|
5160
5251
|
availableItems: available,
|
|
@@ -5234,17 +5325,45 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5234
5325
|
setIsScanningImage(false);
|
|
5235
5326
|
}
|
|
5236
5327
|
};
|
|
5237
|
-
const currentIndex = (0,
|
|
5238
|
-
const goToPrev = (0,
|
|
5328
|
+
const currentIndex = (0, import_react27.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
|
|
5329
|
+
const goToPrev = (0, import_react27.useCallback)(() => {
|
|
5239
5330
|
if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
|
|
5240
5331
|
}, [currentIndex, history]);
|
|
5241
|
-
const goToNext = (0,
|
|
5332
|
+
const goToNext = (0, import_react27.useCallback)(() => {
|
|
5242
5333
|
if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
|
|
5243
5334
|
}, [currentIndex, history]);
|
|
5335
|
+
const handleGallerySelect = (0, import_react27.useCallback)((g) => {
|
|
5336
|
+
setCurrentResult(g);
|
|
5337
|
+
setMobileTab("stage");
|
|
5338
|
+
if (g.filename && hfToken && !g.fullBase64) {
|
|
5339
|
+
hfLoadImageAsBase64(g.id, hfToken, effectiveNamespace, g.filename, void 0, g.mimeType, false).then((b64) => {
|
|
5340
|
+
if (!b64) return;
|
|
5341
|
+
const full = `data:${g.mimeType || "image/jpeg"};base64,${b64}`;
|
|
5342
|
+
setCurrentResult((prev) => prev?.id === g.id ? { ...prev, fullBase64: full } : prev);
|
|
5343
|
+
setGalleryItems((prev) => prev.map((item) => item.id === g.id ? { ...item, fullBase64: full } : item));
|
|
5344
|
+
}).catch(() => {
|
|
5345
|
+
});
|
|
5346
|
+
}
|
|
5347
|
+
}, [hfToken, effectiveNamespace]);
|
|
5348
|
+
const handleTitleSet = (0, import_react27.useCallback)((id) => {
|
|
5349
|
+
const ts = Date.now();
|
|
5350
|
+
setGalleryItems((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
|
|
5351
|
+
setHistory((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
|
|
5352
|
+
if (hfToken && effectiveNamespace) {
|
|
5353
|
+
hfWriteEvent("title_set", { id }).catch(() => {
|
|
5354
|
+
});
|
|
5355
|
+
}
|
|
5356
|
+
}, [hfToken, effectiveNamespace, hfWriteEvent]);
|
|
5357
|
+
const currentGroup = (0, import_react27.useMemo)(() => {
|
|
5358
|
+
if (!currentResult?.prompt) return [];
|
|
5359
|
+
const groups = groupByPrompt(galleryItems.filter((g) => g.status === "done" && !!g.base64));
|
|
5360
|
+
const group = groups.find((gr) => gr.prompt === currentResult.prompt);
|
|
5361
|
+
return group ? group.items : [];
|
|
5362
|
+
}, [galleryItems, currentResult?.prompt]);
|
|
5244
5363
|
const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
|
|
5245
5364
|
const isGenerating = activeGenerationsCount > 0;
|
|
5246
5365
|
useKeyboardNavigation(history, currentResult, setCurrentResult);
|
|
5247
|
-
const getSubtreeFormat = (0,
|
|
5366
|
+
const getSubtreeFormat = (0, import_react27.useCallback)((nodeId, depth = 0) => {
|
|
5248
5367
|
const node = nodes.find((n) => n.id === nodeId);
|
|
5249
5368
|
if (!node) return "";
|
|
5250
5369
|
const childrenIds = edges.filter((e) => e.source === nodeId).map((e) => e.target);
|
|
@@ -5252,7 +5371,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5252
5371
|
return `${indent}- ${node.data.label || "(unbenannt)"}
|
|
5253
5372
|
` + childrenIds.map((id) => getSubtreeFormat(id, depth + 1)).join("");
|
|
5254
5373
|
}, [nodes, edges]);
|
|
5255
|
-
const activePath = (0,
|
|
5374
|
+
const activePath = (0, import_react27.useMemo)(() => {
|
|
5256
5375
|
if (!focusedNodeId) return /* @__PURE__ */ new Set();
|
|
5257
5376
|
const path = /* @__PURE__ */ new Set([focusedNodeId]);
|
|
5258
5377
|
let currId = focusedNodeId;
|
|
@@ -5422,8 +5541,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5422
5541
|
const handleDownloadSingle = async () => {
|
|
5423
5542
|
if (!currentResult?.base64) return;
|
|
5424
5543
|
try {
|
|
5425
|
-
const
|
|
5426
|
-
const
|
|
5544
|
+
const downloadSrc = currentResult.fullBase64 || currentResult.base64;
|
|
5545
|
+
const base64Data = downloadSrc.split(",")[1];
|
|
5546
|
+
const mimeType = downloadSrc.split(";")[0].split(":")[1] || "image/png";
|
|
5427
5547
|
let finalBase64 = base64Data;
|
|
5428
5548
|
if (mimeType === "image/png") finalBase64 = injectXMPMetadata(base64Data, currentResult.prompt || "", currentResult.seed, currentResult.model, currentResult.id, currentResult.tags || [], getSubtreeFormat(currentResult.nodeId));
|
|
5429
5549
|
await onDownload(finalBase64, mimeType, `avatar_${currentResult.id.slice(0, 5)}.${mimeType.split("/")[1]}`);
|
|
@@ -5600,7 +5720,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5600
5720
|
setTimeout(() => setProjectActionState("idle"), 4e3);
|
|
5601
5721
|
}
|
|
5602
5722
|
};
|
|
5603
|
-
(0,
|
|
5723
|
+
(0, import_react27.useEffect)(() => {
|
|
5604
5724
|
if (activeTab === "setup" || activeTab === "sync") fetchServerProjects();
|
|
5605
5725
|
}, [activeTab]);
|
|
5606
5726
|
const mergeWorkspaceTags = (local, remote) => {
|
|
@@ -5623,7 +5743,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5623
5743
|
return { by_category: merged, all };
|
|
5624
5744
|
};
|
|
5625
5745
|
if (isFullscreen && currentResult?.base64) {
|
|
5626
|
-
const
|
|
5746
|
+
const fsRaw = currentResult.fullBase64 || currentResult.base64;
|
|
5747
|
+
const fsBase64 = fsRaw.startsWith("data:") ? fsRaw : `data:image/png;base64,${fsRaw}`;
|
|
5627
5748
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
5628
5749
|
"div",
|
|
5629
5750
|
{
|
|
@@ -5870,7 +5991,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5870
5991
|
setMobileTab("stage");
|
|
5871
5992
|
}
|
|
5872
5993
|
} }) }),
|
|
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, {
|
|
5994
|
+
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
5995
|
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
5996
|
TagManagerPanel,
|
|
5876
5997
|
{
|
|
@@ -5948,7 +6069,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5948
6069
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
|
|
5949
6070
|
/* @__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
6071
|
] }),
|
|
5951
|
-
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.base64, className: "w-full h-full object-contain" }),
|
|
6072
|
+
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
6073
|
!currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
5953
6074
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
|
|
5954
6075
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
@@ -5966,6 +6087,49 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5966
6087
|
]
|
|
5967
6088
|
}
|
|
5968
6089
|
),
|
|
6090
|
+
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: [
|
|
6091
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6092
|
+
"div",
|
|
6093
|
+
{
|
|
6094
|
+
onClick: () => handleGallerySelect(item),
|
|
6095
|
+
style: {
|
|
6096
|
+
width: 44,
|
|
6097
|
+
height: 44,
|
|
6098
|
+
borderRadius: 8,
|
|
6099
|
+
overflow: "hidden",
|
|
6100
|
+
cursor: "pointer",
|
|
6101
|
+
border: item.id === currentResult.id ? "2px solid rgba(255,255,255,0.8)" : "2px solid rgba(255,255,255,0.15)",
|
|
6102
|
+
opacity: item.id === currentResult.id ? 1 : 0.55
|
|
6103
|
+
},
|
|
6104
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
|
|
6105
|
+
}
|
|
6106
|
+
),
|
|
6107
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6108
|
+
"button",
|
|
6109
|
+
{
|
|
6110
|
+
onClick: (e) => {
|
|
6111
|
+
e.stopPropagation();
|
|
6112
|
+
handleTitleSet(item.id);
|
|
6113
|
+
},
|
|
6114
|
+
style: {
|
|
6115
|
+
position: "absolute",
|
|
6116
|
+
bottom: 2,
|
|
6117
|
+
right: 2,
|
|
6118
|
+
width: 14,
|
|
6119
|
+
height: 14,
|
|
6120
|
+
background: item.titleTs ? "#f59e0b" : "rgba(0,0,0,0.75)",
|
|
6121
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
6122
|
+
borderRadius: 3,
|
|
6123
|
+
cursor: "pointer",
|
|
6124
|
+
padding: 0,
|
|
6125
|
+
display: "flex",
|
|
6126
|
+
alignItems: "center",
|
|
6127
|
+
justifyContent: "center"
|
|
6128
|
+
},
|
|
6129
|
+
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" })
|
|
6130
|
+
}
|
|
6131
|
+
)
|
|
6132
|
+
] }, item.id)) }),
|
|
5969
6133
|
currentResult?.status === "done" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex gap-2 mt-3", children: [
|
|
5970
6134
|
/* @__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
6135
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
|
|
@@ -5988,10 +6152,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5988
6152
|
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
6153
|
] }),
|
|
5990
6154
|
/* @__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)) }),
|
|
6155
|
+
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
6156
|
activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
5996
6157
|
MediaLibrary,
|
|
5997
6158
|
{
|
|
@@ -6002,10 +6163,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6002
6163
|
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
6164
|
},
|
|
6004
6165
|
onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
|
|
6005
|
-
onSelect:
|
|
6006
|
-
setCurrentResult(g);
|
|
6007
|
-
setMobileTab("stage");
|
|
6008
|
-
},
|
|
6166
|
+
onSelect: handleGallerySelect,
|
|
6009
6167
|
onGenerateReference: (item) => {
|
|
6010
6168
|
handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true });
|
|
6011
6169
|
setMobileTab("stage");
|
|
@@ -6045,7 +6203,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6045
6203
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
|
|
6046
6204
|
"HF"
|
|
6047
6205
|
] }),
|
|
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" }) }),
|
|
6206
|
+
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
6207
|
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
6208
|
] }),
|
|
6051
6209
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
@@ -6128,10 +6286,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6128
6286
|
galleryItems,
|
|
6129
6287
|
allEvents: hfAllEvents,
|
|
6130
6288
|
confirmedEventKeys: hfConfirmedKeys,
|
|
6131
|
-
imageUploadStatus
|
|
6289
|
+
imageUploadStatus,
|
|
6290
|
+
missingImages: hfMissingImages
|
|
6132
6291
|
}
|
|
6133
6292
|
) }),
|
|
6134
|
-
activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, {
|
|
6293
|
+
activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "absolute inset-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, { serverBaseUrl }) })
|
|
6135
6294
|
] })
|
|
6136
6295
|
] }),
|
|
6137
6296
|
/* @__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 +6299,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6140
6299
|
{ id: "labs", icon: "science", label: "Labs" },
|
|
6141
6300
|
...workspaceTags ? [{ id: "tags", icon: "label", label: "Tags" }] : [],
|
|
6142
6301
|
{ id: "browse", icon: "photo_library", label: "Galerie" },
|
|
6143
|
-
{ id: "server", icon: "storage", label: "Server" }
|
|
6302
|
+
...serverBaseUrl ? [{ id: "server", icon: "storage", label: "Server" }] : []
|
|
6144
6303
|
].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
6304
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
|
|
6146
6305
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
|
|
@@ -6191,7 +6350,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6191
6350
|
] })
|
|
6192
6351
|
}
|
|
6193
6352
|
) }),
|
|
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:
|
|
6353
|
+
/* @__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
6354
|
] }),
|
|
6196
6355
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
|
|
6197
6356
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
@@ -6216,7 +6375,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6216
6375
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
|
|
6217
6376
|
/* @__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
6377
|
] }),
|
|
6219
|
-
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
|
|
6378
|
+
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
6379
|
!currentResult && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
|
|
6221
6380
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
|
|
6222
6381
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
|
|
@@ -6358,33 +6517,81 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6358
6517
|
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
6518
|
const frame = item.frames[0];
|
|
6360
6519
|
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 })
|
|
6520
|
+
} }) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
|
|
6521
|
+
/* @__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: [
|
|
6522
|
+
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: [
|
|
6523
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-3 h-3 border-t-2 border-white rounded-full animate-spin" }),
|
|
6524
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/60 uppercase font-bold tracking-widest", children: "Neue Referenz..." })
|
|
6374
6525
|
] }),
|
|
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
|
-
|
|
6526
|
+
currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
|
|
6527
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
|
|
6528
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
|
|
6529
|
+
] }) : 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: [
|
|
6530
|
+
/* @__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" }) }),
|
|
6531
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
6532
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
|
|
6533
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
|
|
6534
|
+
] }),
|
|
6535
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
|
|
6536
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
|
|
6537
|
+
/* @__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" }),
|
|
6538
|
+
/* @__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: [
|
|
6539
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
|
|
6540
|
+
/* @__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" }),
|
|
6541
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
|
|
6542
|
+
] })
|
|
6543
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
6544
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
|
|
6545
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
6382
6546
|
] })
|
|
6383
|
-
] })
|
|
6384
|
-
|
|
6385
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6386
|
-
|
|
6387
|
-
|
|
6547
|
+
] }) }),
|
|
6548
|
+
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: [
|
|
6549
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6550
|
+
"div",
|
|
6551
|
+
{
|
|
6552
|
+
onClick: () => handleGallerySelect(item),
|
|
6553
|
+
style: {
|
|
6554
|
+
width: 52,
|
|
6555
|
+
height: 52,
|
|
6556
|
+
borderRadius: 10,
|
|
6557
|
+
overflow: "hidden",
|
|
6558
|
+
cursor: "pointer",
|
|
6559
|
+
border: item.id === currentResult.id ? "2px solid rgba(255,255,255,0.8)" : "2px solid rgba(255,255,255,0.12)",
|
|
6560
|
+
opacity: item.id === currentResult.id ? 1 : 0.5,
|
|
6561
|
+
transition: "opacity 0.15s, border-color 0.15s"
|
|
6562
|
+
},
|
|
6563
|
+
className: "hover:opacity-80",
|
|
6564
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
|
|
6565
|
+
}
|
|
6566
|
+
),
|
|
6567
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6568
|
+
"button",
|
|
6569
|
+
{
|
|
6570
|
+
onClick: (e) => {
|
|
6571
|
+
e.stopPropagation();
|
|
6572
|
+
handleTitleSet(item.id);
|
|
6573
|
+
},
|
|
6574
|
+
title: "Als Titel markieren",
|
|
6575
|
+
style: {
|
|
6576
|
+
position: "absolute",
|
|
6577
|
+
bottom: 3,
|
|
6578
|
+
right: 3,
|
|
6579
|
+
width: 16,
|
|
6580
|
+
height: 16,
|
|
6581
|
+
background: item.titleTs ? "#f59e0b" : "rgba(0,0,0,0.75)",
|
|
6582
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
6583
|
+
borderRadius: 4,
|
|
6584
|
+
cursor: "pointer",
|
|
6585
|
+
padding: 0,
|
|
6586
|
+
display: "flex",
|
|
6587
|
+
alignItems: "center",
|
|
6588
|
+
justifyContent: "center"
|
|
6589
|
+
},
|
|
6590
|
+
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" })
|
|
6591
|
+
}
|
|
6592
|
+
)
|
|
6593
|
+
] }, item.id)) })
|
|
6594
|
+
] })
|
|
6388
6595
|
] })
|
|
6389
6596
|
] }),
|
|
6390
6597
|
!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 +6602,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6395
6602
|
setActiveTab(tab);
|
|
6396
6603
|
setIsRightCollapsed(false);
|
|
6397
6604
|
}, 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: () => {
|
|
6605
|
+
serverBaseUrl && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => {
|
|
6399
6606
|
setActiveTab("server");
|
|
6400
6607
|
setIsRightCollapsed(false);
|
|
6401
6608
|
}, 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 +6626,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6419
6626
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
|
|
6420
6627
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
|
|
6421
6628
|
] }) }),
|
|
6422
|
-
activeTab === "history" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect:
|
|
6629
|
+
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
6630
|
activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6424
6631
|
MediaLibrary,
|
|
6425
6632
|
{
|
|
@@ -6430,7 +6637,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6430
6637
|
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
6638
|
},
|
|
6432
6639
|
onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
|
|
6433
|
-
onSelect:
|
|
6640
|
+
onSelect: handleGallerySelect,
|
|
6434
6641
|
onGenerateReference: (item) => handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true })
|
|
6435
6642
|
}
|
|
6436
6643
|
),
|
|
@@ -6460,14 +6667,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6460
6667
|
onHfInitialSync: hfToken ? handleHfInitialSync : void 0
|
|
6461
6668
|
}
|
|
6462
6669
|
),
|
|
6463
|
-
activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, {
|
|
6670
|
+
activeTab === "server" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ServerTab, { serverBaseUrl })
|
|
6464
6671
|
] })
|
|
6465
6672
|
] })
|
|
6466
6673
|
] });
|
|
6467
6674
|
}
|
|
6468
6675
|
|
|
6469
6676
|
// src/components/FaApp.tsx
|
|
6470
|
-
var
|
|
6677
|
+
var import_react28 = require("react");
|
|
6471
6678
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
6472
6679
|
function FaApp({
|
|
6473
6680
|
onGenerateImage,
|
|
@@ -6487,8 +6694,8 @@ function FaApp({
|
|
|
6487
6694
|
onServerDelete,
|
|
6488
6695
|
buildInfo
|
|
6489
6696
|
}) {
|
|
6490
|
-
const [hfNamespace, setHfNamespace] = (0,
|
|
6491
|
-
(0,
|
|
6697
|
+
const [hfNamespace, setHfNamespace] = (0, import_react28.useState)(void 0);
|
|
6698
|
+
(0, import_react28.useEffect)(() => {
|
|
6492
6699
|
if (!serverBaseUrl) return;
|
|
6493
6700
|
fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
6494
6701
|
if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
|
|
@@ -6509,6 +6716,7 @@ function FaApp({
|
|
|
6509
6716
|
initialHfToken: libToken ? libToken.startsWith("hf_") ? libToken : `hf_${libToken}` : void 0,
|
|
6510
6717
|
hfNamespace,
|
|
6511
6718
|
allowDevNamespace: !hfNamespace && allowDevNamespace,
|
|
6719
|
+
serverBaseUrl,
|
|
6512
6720
|
onFetchServerProjects,
|
|
6513
6721
|
onServerSave,
|
|
6514
6722
|
onServerLoad,
|
|
@@ -6521,7 +6729,7 @@ function FaApp({
|
|
|
6521
6729
|
// src/index.ts
|
|
6522
6730
|
init_hfStateService();
|
|
6523
6731
|
init_hfStateService();
|
|
6524
|
-
var LIB_VERSION = "2.0.
|
|
6732
|
+
var LIB_VERSION = "2.0.46";
|
|
6525
6733
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6526
6734
|
0 && (module.exports = {
|
|
6527
6735
|
AvatarArchitectApp,
|
|
@@ -6566,10 +6774,6 @@ var LIB_VERSION = "2.0.30";
|
|
|
6566
6774
|
cleanAiResponse,
|
|
6567
6775
|
createFlowServices,
|
|
6568
6776
|
exportProjectToZip,
|
|
6569
|
-
faServerDelete,
|
|
6570
|
-
faServerGet,
|
|
6571
|
-
faServerPost,
|
|
6572
|
-
faServerPut,
|
|
6573
6777
|
findForks,
|
|
6574
6778
|
findTips,
|
|
6575
6779
|
formatTreeToMarkdown,
|