@rslsp1/fa-app-tools 2.0.56 → 2.0.61
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/index.js
CHANGED
|
@@ -404,11 +404,16 @@ async function loadHFState(namespace, token) {
|
|
|
404
404
|
meta: JSON.parse(metaStr)
|
|
405
405
|
};
|
|
406
406
|
}
|
|
407
|
-
async function loadPendingEvents(namespace, token, sinceTs) {
|
|
407
|
+
async function loadPendingEvents(namespace, token, sinceTs, knownPaths) {
|
|
408
408
|
const files = await hfListDir(namespace, "events", token);
|
|
409
|
-
const pending = files.filter((f) => f.type === "file" && tsFromEventPath(f.path) > sinceTs).sort((a, b) => a.path.localeCompare(b.path));
|
|
409
|
+
const pending = files.filter((f) => f.type === "file" && tsFromEventPath(f.path) > sinceTs && !knownPaths?.has(f.path)).sort((a, b) => a.path.localeCompare(b.path));
|
|
410
|
+
if (!pending.length) return [];
|
|
410
411
|
const raw = await Promise.all(
|
|
411
|
-
pending.map((f) =>
|
|
412
|
+
pending.map(async (f) => {
|
|
413
|
+
const result = await hfDownloadJsonByPath(f.path, token);
|
|
414
|
+
knownPaths?.add(f.path);
|
|
415
|
+
return result;
|
|
416
|
+
})
|
|
412
417
|
);
|
|
413
418
|
return raw.flatMap((e) => Array.isArray(e) ? e : [e]);
|
|
414
419
|
}
|
|
@@ -1028,10 +1033,8 @@ var CompactDropdown = ({
|
|
|
1028
1033
|
};
|
|
1029
1034
|
|
|
1030
1035
|
// src/components/HistoryPanel.tsx
|
|
1031
|
-
var import_react4 = require("react");
|
|
1032
|
-
var import_react5 = require("motion/react");
|
|
1036
|
+
var import_react4 = require("motion/react");
|
|
1033
1037
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1034
|
-
var PAGE_SIZE = 20;
|
|
1035
1038
|
var formatFriendlyTimestamp = (timestamp) => {
|
|
1036
1039
|
const date = new Date(timestamp);
|
|
1037
1040
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1043,8 +1046,7 @@ var formatFriendlyTimestamp = (timestamp) => {
|
|
|
1043
1046
|
if (date.toDateString() === yesterday.toDateString()) return `Gestern, ${timeStr}`;
|
|
1044
1047
|
return `${date.toLocaleDateString([], { day: "2-digit", month: "2-digit" })}, ${timeStr}`;
|
|
1045
1048
|
};
|
|
1046
|
-
var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
|
|
1047
|
-
const [visibleCount, setVisibleCount] = (0, import_react4.useState)(PAGE_SIZE);
|
|
1049
|
+
var HistoryPanel = ({ history, currentResultId, onSelect, onDelete, visibleCount, onLoadMore }) => {
|
|
1048
1050
|
const visibleHistory = history.slice(0, visibleCount);
|
|
1049
1051
|
if (history.length === 0) {
|
|
1050
1052
|
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: [
|
|
@@ -1052,7 +1054,7 @@ var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
|
|
|
1052
1054
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-[10px] font-bold uppercase tracking-widest", children: "Keine Historie" })
|
|
1053
1055
|
] });
|
|
1054
1056
|
}
|
|
1055
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1057
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react4.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 p-4 flex flex-col gap-3 overflow-y-auto dark-scrollbar", children: [
|
|
1056
1058
|
visibleHistory.map((gen) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1057
1059
|
"div",
|
|
1058
1060
|
{
|
|
@@ -1088,7 +1090,7 @@ var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
|
|
|
1088
1090
|
},
|
|
1089
1091
|
gen.id
|
|
1090
1092
|
)),
|
|
1091
|
-
visibleCount < history.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", onClick:
|
|
1093
|
+
visibleCount < history.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", onClick: onLoadMore, className: "w-full py-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-xl text-[10px] font-bold uppercase text-white/60 hover:text-white transition-all", children: [
|
|
1092
1094
|
history.length - visibleCount,
|
|
1093
1095
|
" weitere laden"
|
|
1094
1096
|
] })
|
|
@@ -1096,11 +1098,11 @@ var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
|
|
|
1096
1098
|
};
|
|
1097
1099
|
|
|
1098
1100
|
// src/components/InspectPanel.tsx
|
|
1099
|
-
var
|
|
1100
|
-
var
|
|
1101
|
+
var import_react5 = require("react");
|
|
1102
|
+
var import_react6 = require("motion/react");
|
|
1101
1103
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1102
1104
|
var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagToggle }) => {
|
|
1103
|
-
const currentIndex = (0,
|
|
1105
|
+
const currentIndex = (0, import_react5.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
|
|
1104
1106
|
if (!currentResult) {
|
|
1105
1107
|
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: [
|
|
1106
1108
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "material-symbols-outlined text-[64px]", children: "info" }),
|
|
@@ -1108,7 +1110,7 @@ var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagTogg
|
|
|
1108
1110
|
] });
|
|
1109
1111
|
}
|
|
1110
1112
|
const fullDateStr = new Date(currentResult.timestamp).toLocaleString([], { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
1111
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react6.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 flex flex-col overflow-hidden", children: [
|
|
1112
1114
|
/* @__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)) }) }),
|
|
1113
1115
|
/* @__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: [
|
|
1114
1116
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SectionLabel, { children: "Vorschau" }),
|
|
@@ -1161,8 +1163,8 @@ var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagTogg
|
|
|
1161
1163
|
};
|
|
1162
1164
|
|
|
1163
1165
|
// src/components/SetupPanel.tsx
|
|
1164
|
-
var
|
|
1165
|
-
var
|
|
1166
|
+
var import_react7 = require("react");
|
|
1167
|
+
var import_react8 = require("motion/react");
|
|
1166
1168
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1167
1169
|
var PRESET_URLS = [
|
|
1168
1170
|
"https://jsonplaceholder.typicode.com/todos/1",
|
|
@@ -1170,12 +1172,12 @@ var PRESET_URLS = [
|
|
|
1170
1172
|
"https://esm.sh/@rslsp1/fa-app-tools@latest"
|
|
1171
1173
|
];
|
|
1172
1174
|
var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
1173
|
-
const workspaceInputRef = (0,
|
|
1174
|
-
const [urlInput, setUrlInput] = (0,
|
|
1175
|
-
const [tokenInput, setTokenInput] = (0,
|
|
1176
|
-
const [testStatus, setTestStatus] = (0,
|
|
1177
|
-
const [result, setResult] = (0,
|
|
1178
|
-
const [fetchError, setFetchError] = (0,
|
|
1175
|
+
const workspaceInputRef = (0, import_react7.useRef)(null);
|
|
1176
|
+
const [urlInput, setUrlInput] = (0, import_react7.useState)("");
|
|
1177
|
+
const [tokenInput, setTokenInput] = (0, import_react7.useState)("");
|
|
1178
|
+
const [testStatus, setTestStatus] = (0, import_react7.useState)("idle");
|
|
1179
|
+
const [result, setResult] = (0, import_react7.useState)(null);
|
|
1180
|
+
const [fetchError, setFetchError] = (0, import_react7.useState)(null);
|
|
1179
1181
|
const runTest = async (url) => {
|
|
1180
1182
|
if (!url.trim()) return;
|
|
1181
1183
|
setTestStatus("loading");
|
|
@@ -1215,7 +1217,7 @@ var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
|
1215
1217
|
setTestStatus("error");
|
|
1216
1218
|
}
|
|
1217
1219
|
};
|
|
1218
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react8.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 p-6 flex flex-col gap-10 overflow-y-auto", children: [
|
|
1219
1221
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-4", children: [
|
|
1220
1222
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
1221
1223
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SectionLabel, { children: "Workspace Management" }),
|
|
@@ -1338,8 +1340,7 @@ var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
|
1338
1340
|
};
|
|
1339
1341
|
|
|
1340
1342
|
// src/components/MediaLibrary.tsx
|
|
1341
|
-
var
|
|
1342
|
-
var import_react11 = require("motion/react");
|
|
1343
|
+
var import_react9 = require("motion/react");
|
|
1343
1344
|
|
|
1344
1345
|
// src/lib/grouping.ts
|
|
1345
1346
|
function groupByPrompt(items) {
|
|
@@ -1364,9 +1365,7 @@ function groupByPrompt(items) {
|
|
|
1364
1365
|
|
|
1365
1366
|
// src/components/MediaLibrary.tsx
|
|
1366
1367
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1367
|
-
var
|
|
1368
|
-
var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, onBatchDownload, onGenerateReference }) => {
|
|
1369
|
-
const [visibleCount, setVisibleCount] = (0, import_react10.useState)(PAGE_SIZE2);
|
|
1368
|
+
var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, onBatchDownload, onGenerateReference, visibleCount, onLoadMore }) => {
|
|
1370
1369
|
const selectedCount = items.filter((i) => i.selectedForExport).length;
|
|
1371
1370
|
const groups = groupByPrompt(items);
|
|
1372
1371
|
const visibleGroups = groups.slice(0, visibleCount);
|
|
@@ -1387,7 +1386,7 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
|
|
|
1387
1386
|
"Laden"
|
|
1388
1387
|
] })
|
|
1389
1388
|
] }),
|
|
1390
|
-
selectedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1389
|
+
selectedCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react9.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: [
|
|
1391
1390
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "text-[9px] font-bold uppercase text-blue-400 ml-1", children: [
|
|
1392
1391
|
selectedCount,
|
|
1393
1392
|
" ausgew\xE4hlt"
|
|
@@ -1408,7 +1407,7 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
|
|
|
1408
1407
|
visibleGroups.map((group) => {
|
|
1409
1408
|
const rep = group.representative;
|
|
1410
1409
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1411
|
-
|
|
1410
|
+
import_react9.motion.div,
|
|
1412
1411
|
{
|
|
1413
1412
|
initial: { opacity: 0, scale: 0.9 },
|
|
1414
1413
|
animate: { opacity: 1, scale: 1 },
|
|
@@ -1439,7 +1438,7 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
|
|
|
1439
1438
|
rep.id
|
|
1440
1439
|
);
|
|
1441
1440
|
}),
|
|
1442
|
-
visibleCount < groups.length && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "col-span-2 flex justify-center pt-2 pb-4", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("button", { type: "button", onClick:
|
|
1441
|
+
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: onLoadMore, className: "px-4 py-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-lg text-[10px] font-bold uppercase text-white/60 hover:text-white transition-all", children: [
|
|
1443
1442
|
groups.length - visibleCount,
|
|
1444
1443
|
" weitere laden"
|
|
1445
1444
|
] }) })
|
|
@@ -1448,10 +1447,10 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
|
|
|
1448
1447
|
};
|
|
1449
1448
|
|
|
1450
1449
|
// src/components/ListView.tsx
|
|
1451
|
-
var
|
|
1450
|
+
var import_react10 = require("react");
|
|
1452
1451
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1453
1452
|
var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, isActive, isInPath, onFocus, onGenerate, onGenerateBranch, onGenerateSubtree, isGenerating, isCollapsed, toggleCollapse, renderNode, children }) => {
|
|
1454
|
-
const inputRef = (0,
|
|
1453
|
+
const inputRef = (0, import_react10.useRef)(null);
|
|
1455
1454
|
const hasChildren = children && children.length > 0;
|
|
1456
1455
|
const handleKeyDown = (e) => {
|
|
1457
1456
|
if (e.key === "Tab") {
|
|
@@ -1479,7 +1478,7 @@ var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNod
|
|
|
1479
1478
|
onMoveNode(node.id, "down");
|
|
1480
1479
|
}
|
|
1481
1480
|
};
|
|
1482
|
-
(0,
|
|
1481
|
+
(0, import_react10.useEffect)(() => {
|
|
1483
1482
|
if (isActive && inputRef.current) inputRef.current.focus();
|
|
1484
1483
|
}, [isActive]);
|
|
1485
1484
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col w-full", children: [
|
|
@@ -1513,7 +1512,7 @@ var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNod
|
|
|
1513
1512
|
] });
|
|
1514
1513
|
};
|
|
1515
1514
|
function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, focusedNodeId, onFocus, activePath, onGenerate, onGenerateBranch, onGenerateSubtree, isGeneratingNodeId }) {
|
|
1516
|
-
const [collapsed, setCollapsed] = (0,
|
|
1515
|
+
const [collapsed, setCollapsed] = (0, import_react10.useState)(/* @__PURE__ */ new Set());
|
|
1517
1516
|
const toggleCollapse = (id) => {
|
|
1518
1517
|
setCollapsed((prev) => {
|
|
1519
1518
|
const next = new Set(prev);
|
|
@@ -1541,13 +1540,13 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
|
|
|
1541
1540
|
}
|
|
1542
1541
|
|
|
1543
1542
|
// src/components/AvatarArchitectApp.tsx
|
|
1544
|
-
var
|
|
1543
|
+
var import_react25 = require("react");
|
|
1545
1544
|
|
|
1546
1545
|
// src/components/PromptTab.tsx
|
|
1547
|
-
var
|
|
1546
|
+
var import_react12 = require("react");
|
|
1548
1547
|
|
|
1549
1548
|
// src/components/CollapsibleCard.tsx
|
|
1550
|
-
var
|
|
1549
|
+
var import_react11 = require("react");
|
|
1551
1550
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1552
1551
|
var CollapsibleCard = ({
|
|
1553
1552
|
title,
|
|
@@ -1558,7 +1557,7 @@ var CollapsibleCard = ({
|
|
|
1558
1557
|
collapsible = true,
|
|
1559
1558
|
className = ""
|
|
1560
1559
|
}) => {
|
|
1561
|
-
const [isOpen, setIsOpen] = (0,
|
|
1560
|
+
const [isOpen, setIsOpen] = (0, import_react11.useState)(defaultOpen);
|
|
1562
1561
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: `border border-neutral-800 rounded-lg ${className}`, children: [
|
|
1563
1562
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1564
1563
|
"div",
|
|
@@ -1605,20 +1604,20 @@ var PromptTab = ({
|
|
|
1605
1604
|
onTagUpdate,
|
|
1606
1605
|
onTagDelete
|
|
1607
1606
|
}) => {
|
|
1608
|
-
const [selectedLabels, setSelectedLabels] = (0,
|
|
1609
|
-
const [instructions, setInstructions] = (0,
|
|
1610
|
-
const [rules, setRules] = (0,
|
|
1611
|
-
const [activeCategory, setActiveCategory] = (0,
|
|
1612
|
-
const [copied, setCopied] = (0,
|
|
1613
|
-
const imgInputRef = (0,
|
|
1614
|
-
const [addingInCat, setAddingInCat] = (0,
|
|
1615
|
-
const [newLabel, setNewLabel] = (0,
|
|
1616
|
-
const [newValue, setNewValue] = (0,
|
|
1617
|
-
const [editingTag, setEditingTag] = (0,
|
|
1618
|
-
const [editLabel, setEditLabel] = (0,
|
|
1619
|
-
const [editValue, setEditValue] = (0,
|
|
1620
|
-
const longPressTimer = (0,
|
|
1621
|
-
const longPressActivated = (0,
|
|
1607
|
+
const [selectedLabels, setSelectedLabels] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
|
|
1608
|
+
const [instructions, setInstructions] = (0, import_react12.useState)("");
|
|
1609
|
+
const [rules, setRules] = (0, import_react12.useState)("");
|
|
1610
|
+
const [activeCategory, setActiveCategory] = (0, import_react12.useState)(null);
|
|
1611
|
+
const [copied, setCopied] = (0, import_react12.useState)(false);
|
|
1612
|
+
const imgInputRef = (0, import_react12.useRef)(null);
|
|
1613
|
+
const [addingInCat, setAddingInCat] = (0, import_react12.useState)(null);
|
|
1614
|
+
const [newLabel, setNewLabel] = (0, import_react12.useState)("");
|
|
1615
|
+
const [newValue, setNewValue] = (0, import_react12.useState)("");
|
|
1616
|
+
const [editingTag, setEditingTag] = (0, import_react12.useState)(null);
|
|
1617
|
+
const [editLabel, setEditLabel] = (0, import_react12.useState)("");
|
|
1618
|
+
const [editValue, setEditValue] = (0, import_react12.useState)("");
|
|
1619
|
+
const longPressTimer = (0, import_react12.useRef)(null);
|
|
1620
|
+
const longPressActivated = (0, import_react12.useRef)(false);
|
|
1622
1621
|
const toggleTag = (label) => {
|
|
1623
1622
|
setSelectedLabels((prev) => {
|
|
1624
1623
|
const next = new Set(prev);
|
|
@@ -2065,7 +2064,7 @@ var PromptTab = ({
|
|
|
2065
2064
|
};
|
|
2066
2065
|
|
|
2067
2066
|
// src/components/ProjectSyncTab.tsx
|
|
2068
|
-
var
|
|
2067
|
+
var import_react13 = require("react");
|
|
2069
2068
|
init_hfStateService();
|
|
2070
2069
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2071
2070
|
var ProjectSyncTab = ({
|
|
@@ -2086,14 +2085,14 @@ var ProjectSyncTab = ({
|
|
|
2086
2085
|
onProjectExportBase64,
|
|
2087
2086
|
onHfInitialSync
|
|
2088
2087
|
}) => {
|
|
2089
|
-
const projectInputRef = (0,
|
|
2090
|
-
const workspaceInputRef = (0,
|
|
2091
|
-
const [saveName, setSaveName] = (0,
|
|
2092
|
-
const [isSaving, setIsSaving] = (0,
|
|
2093
|
-
const [isExporting, setIsExporting] = (0,
|
|
2094
|
-
const [syncState, setSyncState] = (0,
|
|
2095
|
-
const [syncDiff, setSyncDiff] = (0,
|
|
2096
|
-
const [selectedLocalIds, setSelectedLocalIds] = (0,
|
|
2088
|
+
const projectInputRef = (0, import_react13.useRef)(null);
|
|
2089
|
+
const workspaceInputRef = (0, import_react13.useRef)(null);
|
|
2090
|
+
const [saveName, setSaveName] = (0, import_react13.useState)("");
|
|
2091
|
+
const [isSaving, setIsSaving] = (0, import_react13.useState)(false);
|
|
2092
|
+
const [isExporting, setIsExporting] = (0, import_react13.useState)(false);
|
|
2093
|
+
const [syncState, setSyncState] = (0, import_react13.useState)("idle");
|
|
2094
|
+
const [syncDiff, setSyncDiff] = (0, import_react13.useState)(null);
|
|
2095
|
+
const [selectedLocalIds, setSelectedLocalIds] = (0, import_react13.useState)(/* @__PURE__ */ new Set());
|
|
2097
2096
|
const handleExport = async () => {
|
|
2098
2097
|
if (!onProjectExport) return;
|
|
2099
2098
|
setIsExporting(true);
|
|
@@ -2139,13 +2138,13 @@ var ProjectSyncTab = ({
|
|
|
2139
2138
|
});
|
|
2140
2139
|
};
|
|
2141
2140
|
const isWorking = projectActionState === "working" || projectActionState === "working-full";
|
|
2142
|
-
const [hfProjects, setHfProjects] = (0,
|
|
2143
|
-
const [hfLoading, setHfLoading] = (0,
|
|
2144
|
-
const [hfSaving, setHfSaving] = (0,
|
|
2145
|
-
const [hfError, setHfError] = (0,
|
|
2146
|
-
const [hfSaveName, setHfSaveName] = (0,
|
|
2147
|
-
const [hfSyncProgress, setHfSyncProgress] = (0,
|
|
2148
|
-
const [hfSyncing, setHfSyncing] = (0,
|
|
2141
|
+
const [hfProjects, setHfProjects] = (0, import_react13.useState)([]);
|
|
2142
|
+
const [hfLoading, setHfLoading] = (0, import_react13.useState)(false);
|
|
2143
|
+
const [hfSaving, setHfSaving] = (0, import_react13.useState)(false);
|
|
2144
|
+
const [hfError, setHfError] = (0, import_react13.useState)(null);
|
|
2145
|
+
const [hfSaveName, setHfSaveName] = (0, import_react13.useState)("");
|
|
2146
|
+
const [hfSyncProgress, setHfSyncProgress] = (0, import_react13.useState)(null);
|
|
2147
|
+
const [hfSyncing, setHfSyncing] = (0, import_react13.useState)(false);
|
|
2149
2148
|
const loadHfProjects = async (token) => {
|
|
2150
2149
|
setHfLoading(true);
|
|
2151
2150
|
setHfError(null);
|
|
@@ -2157,7 +2156,7 @@ var ProjectSyncTab = ({
|
|
|
2157
2156
|
setHfLoading(false);
|
|
2158
2157
|
}
|
|
2159
2158
|
};
|
|
2160
|
-
(0,
|
|
2159
|
+
(0, import_react13.useEffect)(() => {
|
|
2161
2160
|
if (hfToken) loadHfProjects(hfToken);
|
|
2162
2161
|
}, [hfToken]);
|
|
2163
2162
|
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: [
|
|
@@ -2571,7 +2570,7 @@ function toPromptImages(images) {
|
|
|
2571
2570
|
init_hfStateService();
|
|
2572
2571
|
|
|
2573
2572
|
// src/hooks/useHFState.ts
|
|
2574
|
-
var
|
|
2573
|
+
var import_react14 = require("react");
|
|
2575
2574
|
init_hfStateService();
|
|
2576
2575
|
|
|
2577
2576
|
// src/lib/hfReducer.ts
|
|
@@ -2704,18 +2703,19 @@ function writeOfflineBuffer(events) {
|
|
|
2704
2703
|
}
|
|
2705
2704
|
}
|
|
2706
2705
|
function useHFState(token, namespace) {
|
|
2707
|
-
const [state, setState] = (0,
|
|
2708
|
-
const [isLoading, setIsLoading] = (0,
|
|
2709
|
-
const [error, setError] = (0,
|
|
2710
|
-
const [eventCount, setEventCount] = (0,
|
|
2711
|
-
const [localOnlyCount, setLocalOnlyCount] = (0,
|
|
2712
|
-
const [forks, setForks] = (0,
|
|
2713
|
-
const [pendingBufferCount, setPendingBufferCount] = (0,
|
|
2714
|
-
const [lastEventTs, setLastEventTs] = (0,
|
|
2715
|
-
const [hasStateZip, setHasStateZip] = (0,
|
|
2716
|
-
const knownEventPaths = (0,
|
|
2717
|
-
const
|
|
2718
|
-
const
|
|
2706
|
+
const [state, setState] = (0, import_react14.useState)(null);
|
|
2707
|
+
const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
|
|
2708
|
+
const [error, setError] = (0, import_react14.useState)(null);
|
|
2709
|
+
const [eventCount, setEventCount] = (0, import_react14.useState)(0);
|
|
2710
|
+
const [localOnlyCount, setLocalOnlyCount] = (0, import_react14.useState)(0);
|
|
2711
|
+
const [forks, setForks] = (0, import_react14.useState)([]);
|
|
2712
|
+
const [pendingBufferCount, setPendingBufferCount] = (0, import_react14.useState)(readOfflineBuffer().length);
|
|
2713
|
+
const [lastEventTs, setLastEventTs] = (0, import_react14.useState)(0);
|
|
2714
|
+
const [hasStateZip, setHasStateZip] = (0, import_react14.useState)(false);
|
|
2715
|
+
const knownEventPaths = (0, import_react14.useRef)(/* @__PURE__ */ new Set());
|
|
2716
|
+
const knownFilePaths = (0, import_react14.useRef)(/* @__PURE__ */ new Set());
|
|
2717
|
+
const allEventsRef = (0, import_react14.useRef)([]);
|
|
2718
|
+
const applyNewEvents = (0, import_react14.useCallback)((snapshot, newEvents) => {
|
|
2719
2719
|
if (!newEvents.length && allEventsRef.current.length === 0) {
|
|
2720
2720
|
setEventCount(0);
|
|
2721
2721
|
return snapshot;
|
|
@@ -2729,10 +2729,11 @@ function useHFState(token, namespace) {
|
|
|
2729
2729
|
if (afterConsolidation.length) setLastEventTs(Math.max(...afterConsolidation.map((e) => e.ts)));
|
|
2730
2730
|
return applyEvents(snapshot, afterConsolidation);
|
|
2731
2731
|
}, []);
|
|
2732
|
-
const loadFull = (0,
|
|
2732
|
+
const loadFull = (0, import_react14.useCallback)(async () => {
|
|
2733
2733
|
if (!token || !namespace) return;
|
|
2734
2734
|
setIsLoading(true);
|
|
2735
2735
|
setError(null);
|
|
2736
|
+
knownFilePaths.current = /* @__PURE__ */ new Set();
|
|
2736
2737
|
try {
|
|
2737
2738
|
const snapshot = await loadHFState(namespace, token);
|
|
2738
2739
|
setHasStateZip(snapshot !== null);
|
|
@@ -2741,7 +2742,7 @@ function useHFState(token, namespace) {
|
|
|
2741
2742
|
tags: { by_category: {}, all: [] },
|
|
2742
2743
|
meta: { consolidatedAt: 0, version: 1 }
|
|
2743
2744
|
};
|
|
2744
|
-
const hfEvents = await loadPendingEvents(namespace, token, base.meta.consolidatedAt);
|
|
2745
|
+
const hfEvents = await loadPendingEvents(namespace, token, base.meta.consolidatedAt, knownFilePaths.current);
|
|
2745
2746
|
const hfEventKeys = new Set(hfEvents.map((e) => `${e.ts}_${e.clientId}`));
|
|
2746
2747
|
const localOnlyEvents = allEventsRef.current.filter(
|
|
2747
2748
|
(e) => !hfEventKeys.has(`${e.ts}_${e.clientId}`)
|
|
@@ -2766,7 +2767,7 @@ function useHFState(token, namespace) {
|
|
|
2766
2767
|
}
|
|
2767
2768
|
writeOfflineBuffer(failed);
|
|
2768
2769
|
setPendingBufferCount(failed.length);
|
|
2769
|
-
const freshEvents = await loadPendingEvents(namespace, token, base.meta.consolidatedAt);
|
|
2770
|
+
const freshEvents = await loadPendingEvents(namespace, token, base.meta.consolidatedAt, knownFilePaths.current);
|
|
2770
2771
|
freshEvents.forEach((e) => knownEventPaths.current.add(`${e.ts}_${e.clientId}`));
|
|
2771
2772
|
setState((prev) => prev ? applyNewEvents(base, freshEvents) : prev);
|
|
2772
2773
|
}
|
|
@@ -2776,10 +2777,10 @@ function useHFState(token, namespace) {
|
|
|
2776
2777
|
setIsLoading(false);
|
|
2777
2778
|
}
|
|
2778
2779
|
}, [token, namespace, applyNewEvents]);
|
|
2779
|
-
const pollNew = (0,
|
|
2780
|
+
const pollNew = (0, import_react14.useCallback)(async () => {
|
|
2780
2781
|
if (!token || !namespace || !state) return;
|
|
2781
2782
|
try {
|
|
2782
|
-
const events = await loadPendingEvents(namespace, token, state.meta.consolidatedAt);
|
|
2783
|
+
const events = await loadPendingEvents(namespace, token, state.meta.consolidatedAt, knownFilePaths.current);
|
|
2783
2784
|
const newEvents = events.filter((e) => !knownEventPaths.current.has(`${e.ts}_${e.clientId}`));
|
|
2784
2785
|
if (!newEvents.length) return;
|
|
2785
2786
|
newEvents.forEach((e) => knownEventPaths.current.add(`${e.ts}_${e.clientId}`));
|
|
@@ -2790,15 +2791,15 @@ function useHFState(token, namespace) {
|
|
|
2790
2791
|
} catch {
|
|
2791
2792
|
}
|
|
2792
2793
|
}, [token, namespace, state, applyNewEvents]);
|
|
2793
|
-
(0,
|
|
2794
|
+
(0, import_react14.useEffect)(() => {
|
|
2794
2795
|
if (token && namespace) loadFull();
|
|
2795
2796
|
}, [token, namespace]);
|
|
2796
|
-
(0,
|
|
2797
|
+
(0, import_react14.useEffect)(() => {
|
|
2797
2798
|
if (!token || !namespace) return;
|
|
2798
2799
|
const id = setInterval(pollNew, POLL_INTERVAL_MS);
|
|
2799
2800
|
return () => clearInterval(id);
|
|
2800
2801
|
}, [token, namespace, pollNew]);
|
|
2801
|
-
const writeEvent = (0,
|
|
2802
|
+
const writeEvent = (0, import_react14.useCallback)(async (type, payload) => {
|
|
2802
2803
|
const prevTs = lastEventTs ? [lastEventTs] : [state?.meta.consolidatedAt ?? 0];
|
|
2803
2804
|
console.log("[HF] writeEvent called:", { type, namespace, tokenOk: !!token, prevTs });
|
|
2804
2805
|
await pollNew();
|
|
@@ -2848,13 +2849,13 @@ function useHFState(token, namespace) {
|
|
|
2848
2849
|
}
|
|
2849
2850
|
|
|
2850
2851
|
// src/components/labs/LabsTab.tsx
|
|
2851
|
-
var
|
|
2852
|
+
var import_react21 = require("react");
|
|
2852
2853
|
|
|
2853
2854
|
// src/components/labs/LabRemix.tsx
|
|
2854
|
-
var
|
|
2855
|
+
var import_react16 = require("react");
|
|
2855
2856
|
|
|
2856
2857
|
// src/components/labs/LabImagePicker.tsx
|
|
2857
|
-
var
|
|
2858
|
+
var import_react15 = require("react");
|
|
2858
2859
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2859
2860
|
var LabImagePicker = ({
|
|
2860
2861
|
availableItems,
|
|
@@ -2863,8 +2864,8 @@ var LabImagePicker = ({
|
|
|
2863
2864
|
onClose,
|
|
2864
2865
|
title = "Bild w\xE4hlen"
|
|
2865
2866
|
}) => {
|
|
2866
|
-
const [search, setSearch] = (0,
|
|
2867
|
-
const [drillItem, setDrillItem] = (0,
|
|
2867
|
+
const [search, setSearch] = (0, import_react15.useState)("");
|
|
2868
|
+
const [drillItem, setDrillItem] = (0, import_react15.useState)(null);
|
|
2868
2869
|
const filtered = availableItems.filter(
|
|
2869
2870
|
(item) => !search || item.prompt.toLowerCase().includes(search.toLowerCase())
|
|
2870
2871
|
);
|
|
@@ -2966,13 +2967,13 @@ var LabImagePicker = ({
|
|
|
2966
2967
|
// src/components/labs/LabRemix.tsx
|
|
2967
2968
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2968
2969
|
var LabRemix = ({ services, onResult }) => {
|
|
2969
|
-
const [showPicker, setShowPicker] = (0,
|
|
2970
|
-
const [selected, setSelected] = (0,
|
|
2971
|
-
const [instruction, setInstruction] = (0,
|
|
2972
|
-
const [generatedPrompt, setGeneratedPrompt] = (0,
|
|
2973
|
-
const [resultImage, setResultImage] = (0,
|
|
2974
|
-
const [isGeneratingPrompt, setIsGeneratingPrompt] = (0,
|
|
2975
|
-
const [isGeneratingImage, setIsGeneratingImage] = (0,
|
|
2970
|
+
const [showPicker, setShowPicker] = (0, import_react16.useState)(false);
|
|
2971
|
+
const [selected, setSelected] = (0, import_react16.useState)(null);
|
|
2972
|
+
const [instruction, setInstruction] = (0, import_react16.useState)("");
|
|
2973
|
+
const [generatedPrompt, setGeneratedPrompt] = (0, import_react16.useState)("");
|
|
2974
|
+
const [resultImage, setResultImage] = (0, import_react16.useState)(null);
|
|
2975
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react16.useState)(false);
|
|
2976
|
+
const [isGeneratingImage, setIsGeneratingImage] = (0, import_react16.useState)(false);
|
|
2976
2977
|
const handleSelectImage = (item, frame) => {
|
|
2977
2978
|
services.onItemUsed(item);
|
|
2978
2979
|
setSelected({
|
|
@@ -3155,16 +3156,16 @@ var LabRemix = ({ services, onResult }) => {
|
|
|
3155
3156
|
};
|
|
3156
3157
|
|
|
3157
3158
|
// src/components/labs/LabBlend.tsx
|
|
3158
|
-
var
|
|
3159
|
+
var import_react17 = require("react");
|
|
3159
3160
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3160
3161
|
var LabBlend = ({ services, onResult }) => {
|
|
3161
|
-
const [showPickerFor, setShowPickerFor] = (0,
|
|
3162
|
-
const [selectedImages, setSelectedImages] = (0,
|
|
3163
|
-
const [instruction, setInstruction] = (0,
|
|
3164
|
-
const [generatedPrompt, setGeneratedPrompt] = (0,
|
|
3165
|
-
const [resultImage, setResultImage] = (0,
|
|
3166
|
-
const [isGeneratingPrompt, setIsGeneratingPrompt] = (0,
|
|
3167
|
-
const [isGeneratingImage, setIsGeneratingImage] = (0,
|
|
3162
|
+
const [showPickerFor, setShowPickerFor] = (0, import_react17.useState)(null);
|
|
3163
|
+
const [selectedImages, setSelectedImages] = (0, import_react17.useState)([]);
|
|
3164
|
+
const [instruction, setInstruction] = (0, import_react17.useState)("");
|
|
3165
|
+
const [generatedPrompt, setGeneratedPrompt] = (0, import_react17.useState)("");
|
|
3166
|
+
const [resultImage, setResultImage] = (0, import_react17.useState)(null);
|
|
3167
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = (0, import_react17.useState)(false);
|
|
3168
|
+
const [isGeneratingImage, setIsGeneratingImage] = (0, import_react17.useState)(false);
|
|
3168
3169
|
const handleSelectImage = (index, item, frame) => {
|
|
3169
3170
|
services.onItemUsed(item);
|
|
3170
3171
|
const newImg = {
|
|
@@ -3351,17 +3352,17 @@ var LabBlend = ({ services, onResult }) => {
|
|
|
3351
3352
|
};
|
|
3352
3353
|
|
|
3353
3354
|
// src/components/labs/LabCompare.tsx
|
|
3354
|
-
var
|
|
3355
|
+
var import_react18 = require("react");
|
|
3355
3356
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3356
3357
|
var LabCompare = ({ services, onResult }) => {
|
|
3357
|
-
const [showPickerFor, setShowPickerFor] = (0,
|
|
3358
|
-
const [selectedImages, setSelectedImages] = (0,
|
|
3359
|
-
const [instruction, setInstruction] = (0,
|
|
3360
|
-
const [analysis, setAnalysis] = (0,
|
|
3361
|
-
const [generatedPrompt, setGeneratedPrompt] = (0,
|
|
3362
|
-
const [resultImage, setResultImage] = (0,
|
|
3363
|
-
const [isAnalyzing, setIsAnalyzing] = (0,
|
|
3364
|
-
const [isGeneratingImage, setIsGeneratingImage] = (0,
|
|
3358
|
+
const [showPickerFor, setShowPickerFor] = (0, import_react18.useState)(null);
|
|
3359
|
+
const [selectedImages, setSelectedImages] = (0, import_react18.useState)([]);
|
|
3360
|
+
const [instruction, setInstruction] = (0, import_react18.useState)("");
|
|
3361
|
+
const [analysis, setAnalysis] = (0, import_react18.useState)("");
|
|
3362
|
+
const [generatedPrompt, setGeneratedPrompt] = (0, import_react18.useState)("");
|
|
3363
|
+
const [resultImage, setResultImage] = (0, import_react18.useState)(null);
|
|
3364
|
+
const [isAnalyzing, setIsAnalyzing] = (0, import_react18.useState)(false);
|
|
3365
|
+
const [isGeneratingImage, setIsGeneratingImage] = (0, import_react18.useState)(false);
|
|
3365
3366
|
const handleSelectImage = (index, item, frame) => {
|
|
3366
3367
|
services.onItemUsed(item);
|
|
3367
3368
|
const newImg = {
|
|
@@ -3524,14 +3525,14 @@ var LabCompare = ({ services, onResult }) => {
|
|
|
3524
3525
|
};
|
|
3525
3526
|
|
|
3526
3527
|
// src/components/labs/LabLoop.tsx
|
|
3527
|
-
var
|
|
3528
|
+
var import_react19 = require("react");
|
|
3528
3529
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3529
3530
|
var LabLoop = ({ services, onResult }) => {
|
|
3530
|
-
const [rounds, setRounds] = (0,
|
|
3531
|
-
const [currentInstruction, setCurrentInstruction] = (0,
|
|
3532
|
-
const [showPickerForRound, setShowPickerForRound] = (0,
|
|
3533
|
-
const [pendingImages, setPendingImages] = (0,
|
|
3534
|
-
const [isGenerating, setIsGenerating] = (0,
|
|
3531
|
+
const [rounds, setRounds] = (0, import_react19.useState)([]);
|
|
3532
|
+
const [currentInstruction, setCurrentInstruction] = (0, import_react19.useState)("");
|
|
3533
|
+
const [showPickerForRound, setShowPickerForRound] = (0, import_react19.useState)(null);
|
|
3534
|
+
const [pendingImages, setPendingImages] = (0, import_react19.useState)([]);
|
|
3535
|
+
const [isGenerating, setIsGenerating] = (0, import_react19.useState)(false);
|
|
3535
3536
|
const currentPrompt = rounds.length > 0 ? rounds[rounds.length - 1].prompt : "";
|
|
3536
3537
|
const handleAddImage = (item, frame) => {
|
|
3537
3538
|
services.onItemUsed(item);
|
|
@@ -3687,7 +3688,7 @@ var LabLoop = ({ services, onResult }) => {
|
|
|
3687
3688
|
};
|
|
3688
3689
|
|
|
3689
3690
|
// src/components/labs/LabFrameExtractor.tsx
|
|
3690
|
-
var
|
|
3691
|
+
var import_react20 = require("react");
|
|
3691
3692
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3692
3693
|
var formatTime = (s) => {
|
|
3693
3694
|
const m = Math.floor(s / 60);
|
|
@@ -3701,15 +3702,15 @@ var LabFrameExtractor = ({
|
|
|
3701
3702
|
onResult,
|
|
3702
3703
|
resolveVideoUrl
|
|
3703
3704
|
}) => {
|
|
3704
|
-
const videoRef = (0,
|
|
3705
|
-
const canvasRef = (0,
|
|
3706
|
-
const cancelledRef = (0,
|
|
3707
|
-
const [selectedItem, setSelectedItem] = (0,
|
|
3708
|
-
const [videoSrc, setVideoSrc] = (0,
|
|
3709
|
-
const [videoReady, setVideoReady] = (0,
|
|
3710
|
-
const [frames, setFrames] = (0,
|
|
3711
|
-
const [isExtracting, setIsExtracting] = (0,
|
|
3712
|
-
const [intervalSec, setIntervalSec] = (0,
|
|
3705
|
+
const videoRef = (0, import_react20.useRef)(null);
|
|
3706
|
+
const canvasRef = (0, import_react20.useRef)(null);
|
|
3707
|
+
const cancelledRef = (0, import_react20.useRef)(false);
|
|
3708
|
+
const [selectedItem, setSelectedItem] = (0, import_react20.useState)(null);
|
|
3709
|
+
const [videoSrc, setVideoSrc] = (0, import_react20.useState)(null);
|
|
3710
|
+
const [videoReady, setVideoReady] = (0, import_react20.useState)(false);
|
|
3711
|
+
const [frames, setFrames] = (0, import_react20.useState)([]);
|
|
3712
|
+
const [isExtracting, setIsExtracting] = (0, import_react20.useState)(false);
|
|
3713
|
+
const [intervalSec, setIntervalSec] = (0, import_react20.useState)("1");
|
|
3713
3714
|
const handleVideoSelect = (item) => {
|
|
3714
3715
|
const mediaId = item.frames[0]?.mediaId;
|
|
3715
3716
|
if (!mediaId) return;
|
|
@@ -3719,7 +3720,7 @@ var LabFrameExtractor = ({
|
|
|
3719
3720
|
setVideoReady(false);
|
|
3720
3721
|
cancelledRef.current = false;
|
|
3721
3722
|
};
|
|
3722
|
-
const captureAt = (0,
|
|
3723
|
+
const captureAt = (0, import_react20.useCallback)(
|
|
3723
3724
|
(t, label) => new Promise((resolve) => {
|
|
3724
3725
|
const video = videoRef.current;
|
|
3725
3726
|
const canvas = canvasRef.current;
|
|
@@ -3946,7 +3947,7 @@ var BASE_TABS = [
|
|
|
3946
3947
|
];
|
|
3947
3948
|
var FRAMES_TAB = { key: "frames", label: "Frames", icon: "crop_original" };
|
|
3948
3949
|
var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
|
|
3949
|
-
const [activeTab, setActiveTab] = (0,
|
|
3950
|
+
const [activeTab, setActiveTab] = (0, import_react21.useState)("remix");
|
|
3950
3951
|
const showFrames = !!(videoItems && resolveVideoUrl);
|
|
3951
3952
|
const tabs = showFrames ? [...BASE_TABS, FRAMES_TAB] : BASE_TABS;
|
|
3952
3953
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
@@ -3980,19 +3981,19 @@ var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
|
|
|
3980
3981
|
};
|
|
3981
3982
|
|
|
3982
3983
|
// src/components/TagManagerPanel.tsx
|
|
3983
|
-
var
|
|
3984
|
+
var import_react22 = require("react");
|
|
3984
3985
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3985
3986
|
function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete, onTagReorder, onTagMove }) {
|
|
3986
3987
|
const categories = Object.keys(workspaceTags.by_category).filter(
|
|
3987
3988
|
(cat) => (workspaceTags.by_category[cat] || []).some((t) => !t.is_deleted)
|
|
3988
3989
|
);
|
|
3989
|
-
const [selectedCategory, setSelectedCategory] = (0,
|
|
3990
|
+
const [selectedCategory, setSelectedCategory] = (0, import_react22.useState)(categories[0] || "");
|
|
3990
3991
|
const effectiveCategory = categories.includes(selectedCategory) ? selectedCategory : categories[0] || "";
|
|
3991
|
-
const [editingLabel, setEditingLabel] = (0,
|
|
3992
|
-
const [editState, setEditState] = (0,
|
|
3993
|
-
const [newTag, setNewTag] = (0,
|
|
3994
|
-
const [movingLabel, setMovingLabel] = (0,
|
|
3995
|
-
const [moveTarget, setMoveTarget] = (0,
|
|
3992
|
+
const [editingLabel, setEditingLabel] = (0, import_react22.useState)(null);
|
|
3993
|
+
const [editState, setEditState] = (0, import_react22.useState)({ label: "", value: "" });
|
|
3994
|
+
const [newTag, setNewTag] = (0, import_react22.useState)({ label: "", value: "" });
|
|
3995
|
+
const [movingLabel, setMovingLabel] = (0, import_react22.useState)(null);
|
|
3996
|
+
const [moveTarget, setMoveTarget] = (0, import_react22.useState)("");
|
|
3996
3997
|
const tags = (workspaceTags.by_category[effectiveCategory] || []).filter((t) => !t.is_deleted);
|
|
3997
3998
|
const otherCategories = categories.filter((c) => c !== effectiveCategory);
|
|
3998
3999
|
const startEdit = (tag) => {
|
|
@@ -4188,7 +4189,7 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
|
|
|
4188
4189
|
}
|
|
4189
4190
|
|
|
4190
4191
|
// src/components/HFTestTab.tsx
|
|
4191
|
-
var
|
|
4192
|
+
var import_react23 = require("react");
|
|
4192
4193
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4193
4194
|
var HF_BASE2 = "https://huggingface.co";
|
|
4194
4195
|
var HF_REPO2 = "RolandSch/fa-app-state";
|
|
@@ -4381,7 +4382,7 @@ function tryFmt(s) {
|
|
|
4381
4382
|
}
|
|
4382
4383
|
}
|
|
4383
4384
|
function CopyBtn({ text }) {
|
|
4384
|
-
const [done, setDone] = (0,
|
|
4385
|
+
const [done, setDone] = (0, import_react23.useState)(false);
|
|
4385
4386
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4386
4387
|
"button",
|
|
4387
4388
|
{
|
|
@@ -4553,9 +4554,9 @@ function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadSta
|
|
|
4553
4554
|
] });
|
|
4554
4555
|
}
|
|
4555
4556
|
function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEventKeys = /* @__PURE__ */ new Set(), imageUploadStatus = /* @__PURE__ */ new Map(), missingImages = [] }) {
|
|
4556
|
-
const [selected, setSelected] = (0,
|
|
4557
|
-
const [results, setResults] = (0,
|
|
4558
|
-
const [expanded, setExpanded] = (0,
|
|
4557
|
+
const [selected, setSelected] = (0, import_react23.useState)(null);
|
|
4558
|
+
const [results, setResults] = (0, import_react23.useState)({});
|
|
4559
|
+
const [expanded, setExpanded] = (0, import_react23.useState)({});
|
|
4559
4560
|
const withResults = galleryItems.filter((g) => g.base64 && g.status === "done");
|
|
4560
4561
|
const setRunning = (id) => setResults((r) => ({ ...r, [id]: { status: "running", steps: [], totalMs: 0 } }));
|
|
4561
4562
|
const setDone = (id, steps, t0) => {
|
|
@@ -4753,7 +4754,7 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
|
|
|
4753
4754
|
}
|
|
4754
4755
|
|
|
4755
4756
|
// src/components/ServerTab.tsx
|
|
4756
|
-
var
|
|
4757
|
+
var import_react24 = require("react");
|
|
4757
4758
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4758
4759
|
function StarRating({ rating = 0 }) {
|
|
4759
4760
|
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)) });
|
|
@@ -4766,21 +4767,21 @@ async function serverGet(baseUrl, path) {
|
|
|
4766
4767
|
return json && typeof json === "object" && "data" in json ? json.data : json;
|
|
4767
4768
|
}
|
|
4768
4769
|
function ServerTab({ serverBaseUrl }) {
|
|
4769
|
-
const [step, setStep] = (0,
|
|
4770
|
-
const [users, setUsers] = (0,
|
|
4771
|
-
const [usersLoading, setUsersLoading] = (0,
|
|
4772
|
-
const [usersError, setUsersError] = (0,
|
|
4773
|
-
const [selectedUser, setSelectedUser] = (0,
|
|
4774
|
-
const [contexts, setContexts] = (0,
|
|
4775
|
-
const [contextsLoading, setContextsLoading] = (0,
|
|
4776
|
-
const [selectedContext, setSelectedContext] = (0,
|
|
4777
|
-
const [tags, setTags] = (0,
|
|
4778
|
-
const [items, setItems] = (0,
|
|
4779
|
-
const [libLoading, setLibLoading] = (0,
|
|
4780
|
-
const [libError, setLibError] = (0,
|
|
4781
|
-
const [activeTag, setActiveTag] = (0,
|
|
4782
|
-
const [preview, setPreview] = (0,
|
|
4783
|
-
(0,
|
|
4770
|
+
const [step, setStep] = (0, import_react24.useState)("user");
|
|
4771
|
+
const [users, setUsers] = (0, import_react24.useState)([]);
|
|
4772
|
+
const [usersLoading, setUsersLoading] = (0, import_react24.useState)(false);
|
|
4773
|
+
const [usersError, setUsersError] = (0, import_react24.useState)(null);
|
|
4774
|
+
const [selectedUser, setSelectedUser] = (0, import_react24.useState)(null);
|
|
4775
|
+
const [contexts, setContexts] = (0, import_react24.useState)([]);
|
|
4776
|
+
const [contextsLoading, setContextsLoading] = (0, import_react24.useState)(false);
|
|
4777
|
+
const [selectedContext, setSelectedContext] = (0, import_react24.useState)(null);
|
|
4778
|
+
const [tags, setTags] = (0, import_react24.useState)([]);
|
|
4779
|
+
const [items, setItems] = (0, import_react24.useState)([]);
|
|
4780
|
+
const [libLoading, setLibLoading] = (0, import_react24.useState)(false);
|
|
4781
|
+
const [libError, setLibError] = (0, import_react24.useState)(null);
|
|
4782
|
+
const [activeTag, setActiveTag] = (0, import_react24.useState)(null);
|
|
4783
|
+
const [preview, setPreview] = (0, import_react24.useState)(null);
|
|
4784
|
+
(0, import_react24.useEffect)(() => {
|
|
4784
4785
|
if (!serverBaseUrl) return;
|
|
4785
4786
|
setUsersLoading(true);
|
|
4786
4787
|
setUsersError(null);
|
|
@@ -4933,7 +4934,7 @@ function ServerTab({ serverBaseUrl }) {
|
|
|
4933
4934
|
// src/components/AvatarArchitectApp.tsx
|
|
4934
4935
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4935
4936
|
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, serverBaseUrl, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
4936
|
-
(0,
|
|
4937
|
+
(0, import_react25.useEffect)(() => {
|
|
4937
4938
|
const id = "flow-styles";
|
|
4938
4939
|
if (!document.getElementById(id)) {
|
|
4939
4940
|
const style = document.createElement("style");
|
|
@@ -4942,19 +4943,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4942
4943
|
document.head.appendChild(style);
|
|
4943
4944
|
}
|
|
4944
4945
|
}, []);
|
|
4945
|
-
const [showStart, setShowStart] = (0,
|
|
4946
|
-
const [layoutChoice, setLayoutChoice] = (0,
|
|
4946
|
+
const [showStart, setShowStart] = (0, import_react25.useState)(true);
|
|
4947
|
+
const [layoutChoice, setLayoutChoice] = (0, import_react25.useState)(() => {
|
|
4947
4948
|
try {
|
|
4948
4949
|
return localStorage.getItem("aa-layout") || null;
|
|
4949
4950
|
} catch {
|
|
4950
4951
|
return null;
|
|
4951
4952
|
}
|
|
4952
4953
|
});
|
|
4953
|
-
const [projectLoaded, setProjectLoaded] = (0,
|
|
4954
|
-
const [hfToken, setHfToken] = (0,
|
|
4955
|
-
const [hfTokenInput, setHfTokenInput] = (0,
|
|
4956
|
-
const [isLoadingFromHF, setIsLoadingFromHF] = (0,
|
|
4957
|
-
const [hfNamespaceLocal, setHfNamespaceLocal] = (0,
|
|
4954
|
+
const [projectLoaded, setProjectLoaded] = (0, import_react25.useState)(false);
|
|
4955
|
+
const [hfToken, setHfToken] = (0, import_react25.useState)(initialHfToken || "");
|
|
4956
|
+
const [hfTokenInput, setHfTokenInput] = (0, import_react25.useState)(initialHfToken || "");
|
|
4957
|
+
const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react25.useState)(false);
|
|
4958
|
+
const [hfNamespaceLocal, setHfNamespaceLocal] = (0, import_react25.useState)(() => {
|
|
4958
4959
|
const KNOWN = ["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"];
|
|
4959
4960
|
const DEFAULT = "app.art-by-rolands.de/";
|
|
4960
4961
|
try {
|
|
@@ -4966,8 +4967,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4966
4967
|
return DEFAULT;
|
|
4967
4968
|
}
|
|
4968
4969
|
});
|
|
4969
|
-
const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0,
|
|
4970
|
-
(0,
|
|
4970
|
+
const [hfNamespaceFromServer, setHfNamespaceFromServer] = (0, import_react25.useState)(null);
|
|
4971
|
+
(0, import_react25.useEffect)(() => {
|
|
4971
4972
|
if (hfNamespace !== void 0) return;
|
|
4972
4973
|
const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
|
|
4973
4974
|
if (!backendUrl) return;
|
|
@@ -4989,10 +4990,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4989
4990
|
refresh: refreshHF,
|
|
4990
4991
|
hasStateZip
|
|
4991
4992
|
} = useHFState(hfToken, effectiveNamespace);
|
|
4992
|
-
const [imageUploadStatus, setImageUploadStatus] = (0,
|
|
4993
|
-
const [bootstrapLog, setBootstrapLog] = (0,
|
|
4994
|
-
const [isBootstrapping, setIsBootstrapping] = (0,
|
|
4995
|
-
const [hfMissingImages, setHfMissingImages] = (0,
|
|
4993
|
+
const [imageUploadStatus, setImageUploadStatus] = (0, import_react25.useState)(/* @__PURE__ */ new Map());
|
|
4994
|
+
const [bootstrapLog, setBootstrapLog] = (0, import_react25.useState)([]);
|
|
4995
|
+
const [isBootstrapping, setIsBootstrapping] = (0, import_react25.useState)(false);
|
|
4996
|
+
const [hfMissingImages, setHfMissingImages] = (0, import_react25.useState)([]);
|
|
4996
4997
|
const syncTopSlot = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4997
4998
|
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: [
|
|
4998
4999
|
"\u26A0 ",
|
|
@@ -5042,7 +5043,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5042
5043
|
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)) })
|
|
5043
5044
|
] })
|
|
5044
5045
|
] });
|
|
5045
|
-
const wsInputRef = (0,
|
|
5046
|
+
const wsInputRef = (0, import_react25.useRef)(null);
|
|
5046
5047
|
const startApp = (choice) => {
|
|
5047
5048
|
try {
|
|
5048
5049
|
localStorage.setItem("aa-layout", choice);
|
|
@@ -5051,16 +5052,37 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5051
5052
|
setLayoutChoice(choice);
|
|
5052
5053
|
setShowStart(false);
|
|
5053
5054
|
};
|
|
5054
|
-
const [nodes, setNodes] = (0,
|
|
5055
|
-
const [edges, setEdges] = (0,
|
|
5056
|
-
const [history, setHistory] = (0,
|
|
5057
|
-
const [galleryItems, setGalleryItems] = (0,
|
|
5058
|
-
const galleryItemsRef = (0,
|
|
5059
|
-
(0,
|
|
5055
|
+
const [nodes, setNodes] = (0, import_react25.useState)([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
|
|
5056
|
+
const [edges, setEdges] = (0, import_react25.useState)([]);
|
|
5057
|
+
const [history, setHistory] = (0, import_react25.useState)([]);
|
|
5058
|
+
const [galleryItems, setGalleryItems] = (0, import_react25.useState)([]);
|
|
5059
|
+
const galleryItemsRef = (0, import_react25.useRef)([]);
|
|
5060
|
+
(0, import_react25.useEffect)(() => {
|
|
5060
5061
|
galleryItemsRef.current = galleryItems;
|
|
5061
5062
|
}, [galleryItems]);
|
|
5062
|
-
const hfImageNotFoundRef = (0,
|
|
5063
|
-
(0,
|
|
5063
|
+
const hfImageNotFoundRef = (0, import_react25.useRef)(/* @__PURE__ */ new Map());
|
|
5064
|
+
const [galleryVisibleCount, setGalleryVisibleCount] = (0, import_react25.useState)(20);
|
|
5065
|
+
const [historyVisibleCount, setHistoryVisibleCount] = (0, import_react25.useState)(20);
|
|
5066
|
+
const loadThumbnailsForEntries = (0, import_react25.useCallback)(async (entries) => {
|
|
5067
|
+
for (const entry of entries) {
|
|
5068
|
+
if (galleryItemsRef.current.find((g) => g.id === entry.id)?.base64) continue;
|
|
5069
|
+
if (hfImageNotFoundRef.current.has(entry.id)) continue;
|
|
5070
|
+
try {
|
|
5071
|
+
const b64 = await hfLoadImageAsBase64(entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb);
|
|
5072
|
+
if (!b64) {
|
|
5073
|
+
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
5074
|
+
setHfMissingImages((prev) => prev.find((e) => e.id === entry.id) ? prev : [...prev, { id: entry.id, filename: entry.filename, mimeType: entry.mimeType ?? "image/jpeg", timestamp: entry.timestamp ?? 0 }]);
|
|
5075
|
+
continue;
|
|
5076
|
+
}
|
|
5077
|
+
const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
|
|
5078
|
+
setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
5079
|
+
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
5080
|
+
} catch {
|
|
5081
|
+
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
5082
|
+
}
|
|
5083
|
+
}
|
|
5084
|
+
}, [hfToken, effectiveNamespace]);
|
|
5085
|
+
(0, import_react25.useEffect)(() => {
|
|
5064
5086
|
if (!hfState) return;
|
|
5065
5087
|
if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
|
|
5066
5088
|
const hfIds = new Set(hfState.metadata.map((m) => m.id));
|
|
@@ -5086,90 +5108,97 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5086
5108
|
const merged = skeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
5087
5109
|
return [...localOnly, ...merged].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5088
5110
|
});
|
|
5089
|
-
const sortedEntries = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5090
|
-
const galleryRepIds = new Set(groupByPrompt(skeletons).slice(0, 20).map((g) => g.representative.id));
|
|
5091
|
-
const historyIds = new Set(sortedEntries.slice(0, 20).map((e) => e.id));
|
|
5092
|
-
const initialIds = /* @__PURE__ */ new Set([...galleryRepIds, ...historyIds]);
|
|
5093
|
-
const toLoad = sortedEntries.filter((e) => initialIds.has(e.id));
|
|
5094
|
-
(async () => {
|
|
5095
|
-
for (const entry of toLoad) {
|
|
5096
|
-
if (galleryItemsRef.current.find((g) => g.id === entry.id)?.base64) continue;
|
|
5097
|
-
if (hfImageNotFoundRef.current.has(entry.id)) continue;
|
|
5098
|
-
try {
|
|
5099
|
-
const b64 = await hfLoadImageAsBase64(entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb);
|
|
5100
|
-
if (!b64) {
|
|
5101
|
-
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
5102
|
-
setHfMissingImages((prev) => {
|
|
5103
|
-
if (prev.find((e) => e.id === entry.id)) return prev;
|
|
5104
|
-
return [...prev, { id: entry.id, filename: entry.filename, mimeType: entry.mimeType, timestamp: entry.timestamp }];
|
|
5105
|
-
});
|
|
5106
|
-
continue;
|
|
5107
|
-
}
|
|
5108
|
-
const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
|
|
5109
|
-
setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
5110
|
-
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
5111
|
-
} catch {
|
|
5112
|
-
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
5113
|
-
}
|
|
5114
|
-
}
|
|
5115
|
-
})();
|
|
5116
5111
|
}, [hfState]);
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
const [
|
|
5130
|
-
const [
|
|
5131
|
-
const [
|
|
5132
|
-
const [
|
|
5133
|
-
const [
|
|
5134
|
-
const [
|
|
5135
|
-
const [
|
|
5136
|
-
const [
|
|
5112
|
+
(0, import_react25.useEffect)(() => {
|
|
5113
|
+
if (!hfState) return;
|
|
5114
|
+
const sortedMeta = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5115
|
+
const skeletons = sortedMeta.map((m) => ({ id: m.id, prompt: m.prompt, timestamp: m.timestamp, status: "done", nodeId: m.id, tags: m.tags || [] }));
|
|
5116
|
+
const repIds = new Set(groupByPrompt(skeletons).slice(0, galleryVisibleCount).map((g) => g.representative.id));
|
|
5117
|
+
loadThumbnailsForEntries(sortedMeta.filter((e) => repIds.has(e.id)));
|
|
5118
|
+
}, [hfState, galleryVisibleCount, loadThumbnailsForEntries]);
|
|
5119
|
+
(0, import_react25.useEffect)(() => {
|
|
5120
|
+
if (!hfState) return;
|
|
5121
|
+
const sortedMeta = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5122
|
+
loadThumbnailsForEntries(sortedMeta.slice(0, historyVisibleCount));
|
|
5123
|
+
}, [hfState, historyVisibleCount, loadThumbnailsForEntries]);
|
|
5124
|
+
const [activePrompt, setActivePrompt] = (0, import_react25.useState)("");
|
|
5125
|
+
const [isSynthesizing, setIsSynthesizing] = (0, import_react25.useState)(false);
|
|
5126
|
+
const [activeGenerationsCount, setActiveGenerationsCount] = (0, import_react25.useState)(0);
|
|
5127
|
+
const [currentResult, setCurrentResult] = (0, import_react25.useState)(null);
|
|
5128
|
+
const [focusedNodeId, setFocusedNodeId] = (0, import_react25.useState)(null);
|
|
5129
|
+
const [leftTab, setLeftTab] = (0, import_react25.useState)("prompt");
|
|
5130
|
+
const [promptFeedback, setPromptFeedback] = (0, import_react25.useState)(null);
|
|
5131
|
+
const [lastPromptPayload, setLastPromptPayload] = (0, import_react25.useState)(null);
|
|
5132
|
+
const [isPromptTabGenerating, setIsPromptTabGenerating] = (0, import_react25.useState)(false);
|
|
5133
|
+
const [activeTab, setActiveTab] = (0, import_react25.useState)("history");
|
|
5134
|
+
const [mobileTab, setMobileTab] = (0, import_react25.useState)("stage");
|
|
5135
|
+
const [middlePanel, setMiddlePanel] = (0, import_react25.useState)("stage");
|
|
5136
|
+
const [recentLabItems, setRecentLabItems] = (0, import_react25.useState)([]);
|
|
5137
|
+
const [aspectRatio, setAspectRatio] = (0, import_react25.useState)("1:1");
|
|
5138
|
+
const [selectedModel, setSelectedModel] = (0, import_react25.useState)("\u{1F34C} Nano Banana Pro");
|
|
5139
|
+
const [seed, setSeed] = (0, import_react25.useState)(Math.floor(Math.random() * 1e6));
|
|
5140
|
+
const [seedMode, setSeedMode] = (0, import_react25.useState)("random");
|
|
5141
|
+
const [imageCount, setImageCount] = (0, import_react25.useState)(() => {
|
|
5142
|
+
try {
|
|
5143
|
+
const v = parseInt(localStorage.getItem("aa-image-count") || "", 10);
|
|
5144
|
+
return v >= 1 && v <= 8 ? v : 4;
|
|
5145
|
+
} catch {
|
|
5146
|
+
return 4;
|
|
5147
|
+
}
|
|
5148
|
+
});
|
|
5149
|
+
const updateImageCount = (val) => {
|
|
5150
|
+
const n = Math.max(1, Math.min(8, parseInt(val, 10) || 4));
|
|
5151
|
+
setImageCount(n);
|
|
5152
|
+
try {
|
|
5153
|
+
localStorage.setItem("aa-image-count", String(n));
|
|
5154
|
+
} catch {
|
|
5155
|
+
}
|
|
5156
|
+
};
|
|
5157
|
+
const imageCountOptions = [
|
|
5158
|
+
{ label: "1 Bild", value: "1" },
|
|
5159
|
+
{ label: "2 Bilder", value: "2" },
|
|
5160
|
+
{ label: "4 Bilder", value: "4" },
|
|
5161
|
+
{ label: "8 Bilder", value: "8" }
|
|
5162
|
+
];
|
|
5163
|
+
const [isLeftCollapsed, setIsLeftCollapsed] = (0, import_react25.useState)(false);
|
|
5164
|
+
const [isRightCollapsed, setIsRightCollapsed] = (0, import_react25.useState)(false);
|
|
5165
|
+
const [leftPanelWidth, setLeftPanelWidth] = (0, import_react25.useState)(() => {
|
|
5137
5166
|
try {
|
|
5138
5167
|
return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
|
|
5139
5168
|
} catch {
|
|
5140
5169
|
return 260;
|
|
5141
5170
|
}
|
|
5142
5171
|
});
|
|
5143
|
-
const [rightPanelWidth, setRightPanelWidth] = (0,
|
|
5172
|
+
const [rightPanelWidth, setRightPanelWidth] = (0, import_react25.useState)(() => {
|
|
5144
5173
|
try {
|
|
5145
5174
|
return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
|
|
5146
5175
|
} catch {
|
|
5147
5176
|
return 320;
|
|
5148
5177
|
}
|
|
5149
5178
|
});
|
|
5150
|
-
const [isPromptCollapsed, setIsPromptCollapsed] = (0,
|
|
5151
|
-
const [projectActionState, setProjectActionState] = (0,
|
|
5152
|
-
const syncServerDataRef = (0,
|
|
5153
|
-
const [workspaceTags, setWorkspaceTags] = (0,
|
|
5154
|
-
const [serverProjects, setServerProjects] = (0,
|
|
5155
|
-
const [isLoadingFromServer, setIsLoadingFromServer] = (0,
|
|
5156
|
-
const [highContrast, setHighContrast] = (0,
|
|
5179
|
+
const [isPromptCollapsed, setIsPromptCollapsed] = (0, import_react25.useState)(false);
|
|
5180
|
+
const [projectActionState, setProjectActionState] = (0, import_react25.useState)("idle");
|
|
5181
|
+
const syncServerDataRef = (0, import_react25.useRef)(null);
|
|
5182
|
+
const [workspaceTags, setWorkspaceTags] = (0, import_react25.useState)(null);
|
|
5183
|
+
const [serverProjects, setServerProjects] = (0, import_react25.useState)([]);
|
|
5184
|
+
const [isLoadingFromServer, setIsLoadingFromServer] = (0, import_react25.useState)(false);
|
|
5185
|
+
const [highContrast, setHighContrast] = (0, import_react25.useState)(() => {
|
|
5157
5186
|
try {
|
|
5158
5187
|
return localStorage.getItem("aa-contrast") === "high";
|
|
5159
5188
|
} catch {
|
|
5160
5189
|
return false;
|
|
5161
5190
|
}
|
|
5162
5191
|
});
|
|
5163
|
-
const [activeReferenceId, setActiveReferenceId] = (0,
|
|
5164
|
-
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0,
|
|
5165
|
-
const [isScanningImage, setIsScanningImage] = (0,
|
|
5166
|
-
const [touchStartX, setTouchStartX] = (0,
|
|
5167
|
-
const [isFullscreen, setIsFullscreen] = (0,
|
|
5168
|
-
const [zoomScale, setZoomScale] = (0,
|
|
5169
|
-
const [zoomOffset, setZoomOffset] = (0,
|
|
5170
|
-
const lastPinchDist = (0,
|
|
5171
|
-
const lastTapTime = (0,
|
|
5172
|
-
const dragStart = (0,
|
|
5192
|
+
const [activeReferenceId, setActiveReferenceId] = (0, import_react25.useState)(null);
|
|
5193
|
+
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react25.useState)(null);
|
|
5194
|
+
const [isScanningImage, setIsScanningImage] = (0, import_react25.useState)(false);
|
|
5195
|
+
const [touchStartX, setTouchStartX] = (0, import_react25.useState)(null);
|
|
5196
|
+
const [isFullscreen, setIsFullscreen] = (0, import_react25.useState)(false);
|
|
5197
|
+
const [zoomScale, setZoomScale] = (0, import_react25.useState)(1);
|
|
5198
|
+
const [zoomOffset, setZoomOffset] = (0, import_react25.useState)({ x: 0, y: 0 });
|
|
5199
|
+
const lastPinchDist = (0, import_react25.useRef)(null);
|
|
5200
|
+
const lastTapTime = (0, import_react25.useRef)(0);
|
|
5201
|
+
const dragStart = (0, import_react25.useRef)(null);
|
|
5173
5202
|
const openFullscreen = () => {
|
|
5174
5203
|
setIsFullscreen(true);
|
|
5175
5204
|
setZoomScale(1);
|
|
@@ -5232,7 +5261,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5232
5261
|
setActiveReferenceId(null);
|
|
5233
5262
|
setActiveReferenceThumbnail(null);
|
|
5234
5263
|
};
|
|
5235
|
-
const labServices = (0,
|
|
5264
|
+
const labServices = (0, import_react25.useMemo)(() => {
|
|
5236
5265
|
const available = groupGenerationsToLabItems([...galleryItems, ...history]);
|
|
5237
5266
|
return {
|
|
5238
5267
|
availableItems: available,
|
|
@@ -5312,17 +5341,17 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5312
5341
|
setIsScanningImage(false);
|
|
5313
5342
|
}
|
|
5314
5343
|
};
|
|
5315
|
-
const currentIndex = (0,
|
|
5316
|
-
const goToPrev = (0,
|
|
5344
|
+
const currentIndex = (0, import_react25.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
|
|
5345
|
+
const goToPrev = (0, import_react25.useCallback)(() => {
|
|
5317
5346
|
if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
|
|
5318
5347
|
}, [currentIndex, history]);
|
|
5319
|
-
const goToNext = (0,
|
|
5348
|
+
const goToNext = (0, import_react25.useCallback)(() => {
|
|
5320
5349
|
if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
|
|
5321
5350
|
}, [currentIndex, history]);
|
|
5322
|
-
const handleGallerySelect = (0,
|
|
5351
|
+
const handleGallerySelect = (0, import_react25.useCallback)((g) => {
|
|
5323
5352
|
setCurrentResult(g);
|
|
5324
5353
|
setMobileTab("stage");
|
|
5325
|
-
if (g.filename && hfToken && !g.fullBase64) {
|
|
5354
|
+
if (g.hasThumb && g.filename && hfToken && !g.fullBase64) {
|
|
5326
5355
|
hfLoadImageAsBase64(g.id, hfToken, effectiveNamespace, g.filename, void 0, g.mimeType, false).then((b64) => {
|
|
5327
5356
|
if (!b64) return;
|
|
5328
5357
|
const full = `data:${g.mimeType || "image/jpeg"};base64,${b64}`;
|
|
@@ -5332,7 +5361,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5332
5361
|
});
|
|
5333
5362
|
}
|
|
5334
5363
|
}, [hfToken, effectiveNamespace]);
|
|
5335
|
-
const handleTitleSet = (0,
|
|
5364
|
+
const handleTitleSet = (0, import_react25.useCallback)((id) => {
|
|
5336
5365
|
const ts = Date.now();
|
|
5337
5366
|
setGalleryItems((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
|
|
5338
5367
|
setHistory((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
|
|
@@ -5341,13 +5370,13 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5341
5370
|
});
|
|
5342
5371
|
}
|
|
5343
5372
|
}, [hfToken, effectiveNamespace, hfWriteEvent]);
|
|
5344
|
-
const currentGroup = (0,
|
|
5373
|
+
const currentGroup = (0, import_react25.useMemo)(() => {
|
|
5345
5374
|
if (!currentResult?.prompt) return [];
|
|
5346
5375
|
const groups = groupByPrompt(galleryItems.filter((g) => g.status === "done" && !!g.base64));
|
|
5347
5376
|
const group = groups.find((gr) => gr.prompt === currentResult.prompt);
|
|
5348
5377
|
return group ? group.items : [];
|
|
5349
5378
|
}, [galleryItems, currentResult?.prompt]);
|
|
5350
|
-
(0,
|
|
5379
|
+
(0, import_react25.useEffect)(() => {
|
|
5351
5380
|
if (!currentResult?.prompt || !hfToken || !effectiveNamespace || !hfState) return;
|
|
5352
5381
|
const siblings = galleryItemsRef.current.filter(
|
|
5353
5382
|
(g) => g.prompt === currentResult.prompt && !g.base64 && !hfImageNotFoundRef.current.has(g.id)
|
|
@@ -5373,9 +5402,20 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5373
5402
|
})();
|
|
5374
5403
|
}, [currentResult?.id, currentResult?.prompt]);
|
|
5375
5404
|
const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
|
|
5376
|
-
const
|
|
5405
|
+
const runningBadge = activeGenerationsCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
5406
|
+
"div",
|
|
5407
|
+
{
|
|
5408
|
+
className: "flex items-center gap-1 rounded-full bg-sky-500/15 border border-sky-400/30 px-2 shrink-0",
|
|
5409
|
+
style: { height: 24 },
|
|
5410
|
+
title: `${activeGenerationsCount} Generierung${activeGenerationsCount === 1 ? "" : "en"} l\xE4uft gerade`,
|
|
5411
|
+
children: [
|
|
5412
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-sky-300", style: { fontSize: 14, lineHeight: 1 }, children: "autorenew" }),
|
|
5413
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] font-bold text-sky-300 tabular-nums", children: activeGenerationsCount })
|
|
5414
|
+
]
|
|
5415
|
+
}
|
|
5416
|
+
) : null;
|
|
5377
5417
|
useKeyboardNavigation(history, currentResult, setCurrentResult);
|
|
5378
|
-
const getSubtreeFormat = (0,
|
|
5418
|
+
const getSubtreeFormat = (0, import_react25.useCallback)((nodeId, depth = 0) => {
|
|
5379
5419
|
const node = nodes.find((n) => n.id === nodeId);
|
|
5380
5420
|
if (!node) return "";
|
|
5381
5421
|
const childrenIds = edges.filter((e) => e.source === nodeId).map((e) => e.target);
|
|
@@ -5383,7 +5423,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5383
5423
|
return `${indent}- ${node.data.label || "(unbenannt)"}
|
|
5384
5424
|
` + childrenIds.map((id) => getSubtreeFormat(id, depth + 1)).join("");
|
|
5385
5425
|
}, [nodes, edges]);
|
|
5386
|
-
const activePath = (0,
|
|
5426
|
+
const activePath = (0, import_react25.useMemo)(() => {
|
|
5387
5427
|
if (!focusedNodeId) return /* @__PURE__ */ new Set();
|
|
5388
5428
|
const path = /* @__PURE__ */ new Set([focusedNodeId]);
|
|
5389
5429
|
let currId = focusedNodeId;
|
|
@@ -5446,6 +5486,15 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5446
5486
|
setActiveGenerationsCount((prev) => Math.max(0, prev - 1));
|
|
5447
5487
|
}
|
|
5448
5488
|
};
|
|
5489
|
+
const handleGenerateBatch = (customPrompt, useReferenceId, overrideNodeId, options = { silent: false }) => {
|
|
5490
|
+
const count = Math.max(1, Math.min(8, imageCount));
|
|
5491
|
+
return Promise.all(
|
|
5492
|
+
Array.from(
|
|
5493
|
+
{ length: count },
|
|
5494
|
+
(_, i) => handleGenerateImage(customPrompt, useReferenceId, overrideNodeId, { silent: options.silent || i > 0 })
|
|
5495
|
+
)
|
|
5496
|
+
);
|
|
5497
|
+
};
|
|
5449
5498
|
const handleSynthesizePrompt = async (nodeId, autoGenerate = false) => {
|
|
5450
5499
|
setIsSynthesizing(true);
|
|
5451
5500
|
try {
|
|
@@ -5732,7 +5781,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5732
5781
|
setTimeout(() => setProjectActionState("idle"), 4e3);
|
|
5733
5782
|
}
|
|
5734
5783
|
};
|
|
5735
|
-
(0,
|
|
5784
|
+
(0, import_react25.useEffect)(() => {
|
|
5736
5785
|
if (activeTab === "setup" || activeTab === "sync") fetchServerProjects();
|
|
5737
5786
|
}, [activeTab]);
|
|
5738
5787
|
const mergeWorkspaceTags = (local, remote) => {
|
|
@@ -6019,7 +6068,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6019
6068
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-2 px-3 border-b border-white/5 bg-black/30 shrink-0", style: { height: 52 }, children: [
|
|
6020
6069
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
|
|
6021
6070
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
|
|
6071
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
|
|
6022
6072
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1" }),
|
|
6073
|
+
runningBadge,
|
|
6023
6074
|
activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
|
|
6024
6075
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
|
|
6025
6076
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
|
|
@@ -6041,20 +6092,17 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6041
6092
|
),
|
|
6042
6093
|
activePrompt && !isSynthesizing && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActivePrompt(""), className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center text-white/20 active:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px]", children: "close" }) })
|
|
6043
6094
|
] }) }),
|
|
6044
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.
|
|
6095
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "px-3 pb-3 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
6045
6096
|
"button",
|
|
6046
6097
|
{
|
|
6047
|
-
onClick: () =>
|
|
6048
|
-
disabled: !activePrompt.trim()
|
|
6098
|
+
onClick: () => handleGenerateBatch(),
|
|
6099
|
+
disabled: !activePrompt.trim(),
|
|
6049
6100
|
className: "w-full flex items-center justify-center gap-2 rounded-xl font-bold text-[14px] uppercase tracking-wide transition-all disabled:opacity-30 active:scale-95",
|
|
6050
|
-
style: { height: 48, background: activePrompt.trim()
|
|
6051
|
-
children:
|
|
6052
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "w-4 h-4 border-t-2 border-white rounded-full animate-spin" }),
|
|
6053
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generiere..." })
|
|
6054
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
6101
|
+
style: { height: 48, background: activePrompt.trim() ? "#0284c7" : void 0, border: "1px solid rgba(255,255,255,0.1)" },
|
|
6102
|
+
children: [
|
|
6055
6103
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "bolt" }),
|
|
6056
6104
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generieren" })
|
|
6057
|
-
]
|
|
6105
|
+
]
|
|
6058
6106
|
}
|
|
6059
6107
|
) }),
|
|
6060
6108
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 min-h-0 px-3 pb-3 flex flex-col", children: [
|
|
@@ -6072,9 +6120,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6072
6120
|
setTouchStartX(null);
|
|
6073
6121
|
},
|
|
6074
6122
|
children: [
|
|
6075
|
-
currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-3", children: [
|
|
6076
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("
|
|
6077
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px]
|
|
6123
|
+
currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-3 opacity-40", children: [
|
|
6124
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
|
|
6125
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[11px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
|
|
6078
6126
|
] }),
|
|
6079
6127
|
currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "p-6 text-center flex flex-col items-center gap-3", children: [
|
|
6080
6128
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-red-400 text-[36px]", children: "warning" }),
|
|
@@ -6147,7 +6195,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6147
6195
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
|
|
6148
6196
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] text-white/60", children: "Prompt" })
|
|
6149
6197
|
] }),
|
|
6150
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () =>
|
|
6198
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => handleGenerateBatch(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl bg-white/10 active:bg-white/15 transition-colors", style: { height: 44 }, children: [
|
|
6151
6199
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[18px] text-white/80", children: "auto_fix_high" }),
|
|
6152
6200
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] text-white/80 font-bold", children: "Referenz" })
|
|
6153
6201
|
] }),
|
|
@@ -6164,7 +6212,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6164
6212
|
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" }) })
|
|
6165
6213
|
] }),
|
|
6166
6214
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
6167
|
-
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)) }),
|
|
6215
|
+
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)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
|
|
6168
6216
|
activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6169
6217
|
MediaLibrary,
|
|
6170
6218
|
{
|
|
@@ -6177,9 +6225,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6177
6225
|
onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
|
|
6178
6226
|
onSelect: handleGallerySelect,
|
|
6179
6227
|
onGenerateReference: (item) => {
|
|
6180
|
-
|
|
6228
|
+
handleGenerateBatch(item.prompt || activePrompt, item.mediaId, void 0, { silent: true });
|
|
6181
6229
|
setMobileTab("stage");
|
|
6182
|
-
}
|
|
6230
|
+
},
|
|
6231
|
+
visibleCount: galleryVisibleCount,
|
|
6232
|
+
onLoadMore: () => setGalleryVisibleCount((c) => c + 20)
|
|
6183
6233
|
}
|
|
6184
6234
|
),
|
|
6185
6235
|
activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InspectPanel, { currentResult, history, onSelect: (g) => {
|
|
@@ -6251,7 +6301,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6251
6301
|
}
|
|
6252
6302
|
) }),
|
|
6253
6303
|
workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { display: leftTab === "prompt" && activeTab !== "setup" && activeTab !== "sync" && activeTab !== "hftest" ? "flex" : "none" }, className: "absolute inset-0 flex-col", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => {
|
|
6254
|
-
|
|
6304
|
+
handleGenerateBatch(prompt);
|
|
6255
6305
|
setMobileTab("stage");
|
|
6256
6306
|
}, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage }) }),
|
|
6257
6307
|
activeTab === "setup" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo }),
|
|
@@ -6331,7 +6381,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6331
6381
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { height: 52, borderBottom: "1px solid rgba(255,255,255,0.05)", display: "flex", alignItems: "center", gap: 8, padding: "0 12px", flexShrink: 0 }, children: [
|
|
6332
6382
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
|
|
6333
6383
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
|
|
6384
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions }),
|
|
6334
6385
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { flex: 1 } }),
|
|
6386
|
+
runningBadge,
|
|
6335
6387
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: toggleContrast, style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: highContrast ? "light_mode" : "dark_mode" }) }),
|
|
6336
6388
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setShowStart(true), style: { color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 4, lineHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "apps" }) })
|
|
6337
6389
|
] }),
|
|
@@ -6347,22 +6399,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6347
6399
|
),
|
|
6348
6400
|
activePrompt && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setActivePrompt(""), style: { position: "absolute", top: 6, right: 6, width: 22, height: 22, display: "flex", alignItems: "center", justifyContent: "center", color: "rgba(255,255,255,0.2)", background: "none", border: "none", cursor: "pointer", padding: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 15 }, children: "close" }) })
|
|
6349
6401
|
] }) }),
|
|
6350
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.
|
|
6402
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { padding: "0 12px 10px", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
6351
6403
|
"button",
|
|
6352
6404
|
{
|
|
6353
|
-
onClick: () =>
|
|
6354
|
-
disabled: !activePrompt.trim()
|
|
6355
|
-
style: { width: "100%", height: 42, display: "flex", alignItems: "center", justifyContent: "center", gap: 8, borderRadius: 10, fontWeight: "bold", fontSize: 13, textTransform: "uppercase", letterSpacing: "0.05em", border: "1px solid rgba(255,255,255,0.1)", background: activePrompt.trim()
|
|
6356
|
-
children:
|
|
6357
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { style: { width: 14, height: 14, borderTop: "2px solid #fff", borderRadius: "50%", animation: "spin 1s linear infinite" } }),
|
|
6358
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generiere..." })
|
|
6359
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
6405
|
+
onClick: () => handleGenerateBatch(),
|
|
6406
|
+
disabled: !activePrompt.trim(),
|
|
6407
|
+
style: { width: "100%", height: 42, display: "flex", alignItems: "center", justifyContent: "center", gap: 8, borderRadius: 10, fontWeight: "bold", fontSize: 13, textTransform: "uppercase", letterSpacing: "0.05em", border: "1px solid rgba(255,255,255,0.1)", background: activePrompt.trim() ? "#0284c7" : "transparent", color: "#fff", cursor: activePrompt.trim() ? "pointer" : "default", opacity: !activePrompt.trim() ? 0.3 : 1, fontFamily: "inherit", transition: "background 0.2s" },
|
|
6408
|
+
children: [
|
|
6360
6409
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "bolt" }),
|
|
6361
6410
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Generieren" })
|
|
6362
|
-
]
|
|
6411
|
+
]
|
|
6363
6412
|
}
|
|
6364
6413
|
) }),
|
|
6365
|
-
/* @__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)) }) })
|
|
6414
|
+
/* @__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)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }) })
|
|
6366
6415
|
] }),
|
|
6367
6416
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
|
|
6368
6417
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
@@ -6378,9 +6427,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6378
6427
|
setTouchStartX(null);
|
|
6379
6428
|
},
|
|
6380
6429
|
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { height: "100%", width: "100%", borderRadius: 20, border: "1px solid rgba(255,255,255,0.05)", background: "rgba(0,0,0,0.4)", position: "relative", overflow: "hidden", display: "flex", alignItems: "center", justifyContent: "center" }, children: [
|
|
6381
|
-
currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
|
|
6382
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("
|
|
6383
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.
|
|
6430
|
+
currentResult?.status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 12, opacity: 0.4 }, children: [
|
|
6431
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 36 }, children: "hourglass_top" }),
|
|
6432
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { style: { fontSize: 10, color: "rgba(255,255,255,0.6)", textTransform: "uppercase", fontWeight: "bold", letterSpacing: "0.15em" }, children: "Erstelle Bild..." })
|
|
6384
6433
|
] }),
|
|
6385
6434
|
currentResult?.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { padding: 24, textAlign: "center", display: "flex", flexDirection: "column", alignItems: "center", gap: 12 }, children: [
|
|
6386
6435
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 32, color: "#f87171" }, children: "warning" }),
|
|
@@ -6410,7 +6459,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6410
6459
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "replay" }),
|
|
6411
6460
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Prompt" })
|
|
6412
6461
|
] }),
|
|
6413
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () =>
|
|
6462
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { onClick: () => handleGenerateBatch(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), style: { flex: 1, height: 40, display: "flex", alignItems: "center", justifyContent: "center", gap: 6, borderRadius: 10, border: "none", background: "rgba(255,255,255,0.1)", color: "rgba(255,255,255,0.8)", fontSize: 11, fontWeight: "bold", cursor: "pointer", fontFamily: "inherit" }, children: [
|
|
6414
6463
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "auto_fix_high" }),
|
|
6415
6464
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Referenz" })
|
|
6416
6465
|
] }),
|
|
@@ -6480,7 +6529,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6480
6529
|
isGeneratingNodeId: (id) => isSynthesizing && focusedNodeId === id
|
|
6481
6530
|
}
|
|
6482
6531
|
) }),
|
|
6483
|
-
leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) =>
|
|
6532
|
+
leftTab === "prompt" && workspaceTags && activeTab !== "tags" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PromptTab, { workspaceTags, onGenerate: handlePromptTabGenerate, isGenerating: isPromptTabGenerating, feedback: promptFeedback, promptResult: activePrompt || null, lastPayload: lastPromptPayload, onGenerateImage: (prompt) => handleGenerateBatch(prompt), onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage })
|
|
6484
6533
|
] })
|
|
6485
6534
|
] }),
|
|
6486
6535
|
!isLeftCollapsed && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { onMouseDown: startLeftResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
|
|
@@ -6488,7 +6537,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6488
6537
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-14 border-b border-white/5 flex items-center px-4 gap-2 justify-between shrink-0 bg-black/20", children: [
|
|
6489
6538
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
6490
6539
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
|
|
6491
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] })
|
|
6540
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
|
|
6541
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CompactDropdown, { value: String(imageCount), displayValue: `${imageCount}\xD7`, onChange: updateImageCount, options: imageCountOptions })
|
|
6492
6542
|
] }),
|
|
6493
6543
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-center gap-1 mx-auto", children: [
|
|
6494
6544
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
@@ -6518,7 +6568,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6518
6568
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "Ref" })
|
|
6519
6569
|
] }),
|
|
6520
6570
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
|
|
6521
|
-
|
|
6571
|
+
runningBadge,
|
|
6572
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "bolt", disabled: !activePrompt.trim(), onClick: () => handleGenerateBatch(), children: "Generieren" })
|
|
6522
6573
|
] })
|
|
6523
6574
|
] }),
|
|
6524
6575
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 flex flex-col overflow-hidden relative", children: [
|
|
@@ -6530,33 +6581,27 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6530
6581
|
const frame = item.frames[0];
|
|
6531
6582
|
if (frame?.base64) setCurrentResult(frameToGeneration(frame, item));
|
|
6532
6583
|
} }) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
|
|
6533
|
-
/* @__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.
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6584
|
+
/* @__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.jsx)("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: currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-4 opacity-40", children: [
|
|
6585
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px]", children: "hourglass_top" }),
|
|
6586
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[10px] uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
|
|
6587
|
+
] }) : 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: [
|
|
6588
|
+
/* @__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" }) }),
|
|
6589
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
6590
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
|
|
6591
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
|
|
6537
6592
|
] }),
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6543
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.
|
|
6544
|
-
|
|
6545
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
|
|
6546
|
-
] }),
|
|
6547
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
|
|
6548
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
|
|
6549
|
-
/* @__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" }),
|
|
6550
|
-
/* @__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: [
|
|
6551
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
|
|
6552
|
-
/* @__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" }),
|
|
6553
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
|
|
6554
|
-
] })
|
|
6555
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
6556
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
|
|
6557
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
6593
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
|
|
6594
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "h-full w-full relative flex items-center justify-center", children: [
|
|
6595
|
+
/* @__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" }),
|
|
6596
|
+
/* @__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: [
|
|
6597
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
|
|
6598
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateBatch(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
|
|
6599
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
|
|
6558
6600
|
] })
|
|
6559
|
-
] })
|
|
6601
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
6602
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
|
|
6603
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
6604
|
+
] }) }) }),
|
|
6560
6605
|
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: [
|
|
6561
6606
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6562
6607
|
"div",
|
|
@@ -6638,7 +6683,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6638
6683
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
|
|
6639
6684
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
|
|
6640
6685
|
] }) }),
|
|
6641
|
-
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)) }),
|
|
6686
|
+
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)), visibleCount: historyVisibleCount, onLoadMore: () => setHistoryVisibleCount((c) => c + 20) }),
|
|
6642
6687
|
activeTab === "gallery" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
6643
6688
|
MediaLibrary,
|
|
6644
6689
|
{
|
|
@@ -6650,7 +6695,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6650
6695
|
},
|
|
6651
6696
|
onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
|
|
6652
6697
|
onSelect: handleGallerySelect,
|
|
6653
|
-
onGenerateReference: (item) =>
|
|
6698
|
+
onGenerateReference: (item) => handleGenerateBatch(item.prompt || activePrompt, item.mediaId, void 0, { silent: true }),
|
|
6699
|
+
visibleCount: galleryVisibleCount,
|
|
6700
|
+
onLoadMore: () => setGalleryVisibleCount((c) => c + 20)
|
|
6654
6701
|
}
|
|
6655
6702
|
),
|
|
6656
6703
|
activeTab === "inspect" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
|
|
@@ -6686,7 +6733,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6686
6733
|
}
|
|
6687
6734
|
|
|
6688
6735
|
// src/components/FaApp.tsx
|
|
6689
|
-
var
|
|
6736
|
+
var import_react26 = require("react");
|
|
6690
6737
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
6691
6738
|
function FaApp({
|
|
6692
6739
|
onGenerateImage,
|
|
@@ -6706,8 +6753,8 @@ function FaApp({
|
|
|
6706
6753
|
onServerDelete,
|
|
6707
6754
|
buildInfo
|
|
6708
6755
|
}) {
|
|
6709
|
-
const [hfNamespace, setHfNamespace] = (0,
|
|
6710
|
-
(0,
|
|
6756
|
+
const [hfNamespace, setHfNamespace] = (0, import_react26.useState)(void 0);
|
|
6757
|
+
(0, import_react26.useEffect)(() => {
|
|
6711
6758
|
if (!serverBaseUrl) return;
|
|
6712
6759
|
fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
6713
6760
|
if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
|
|
@@ -6741,7 +6788,7 @@ function FaApp({
|
|
|
6741
6788
|
// src/index.ts
|
|
6742
6789
|
init_hfStateService();
|
|
6743
6790
|
init_hfStateService();
|
|
6744
|
-
var LIB_VERSION = "2.0.
|
|
6791
|
+
var LIB_VERSION = "2.0.61";
|
|
6745
6792
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6746
6793
|
0 && (module.exports = {
|
|
6747
6794
|
AvatarArchitectApp,
|