@rslsp1/fa-app-tools 6.1.0 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-GHKN2VX3.mjs → chunk-B2YV4TNI.mjs} +319 -13
- package/dist/{hfEventTypes-Dkfrcd_t.d.mts → hfEventTypes-BUztJySs.d.mts} +1 -11
- package/dist/{hfEventTypes-C_PX6RFR.d.ts → hfEventTypes-fAdA-0A9.d.ts} +1 -11
- package/dist/index.d.mts +18 -49
- package/dist/index.d.ts +18 -49
- package/dist/index.js +635 -1481
- package/dist/index.mjs +207 -670
- package/dist/szenen.d.mts +2 -2
- package/dist/szenen.d.ts +2 -2
- package/dist/szenen.mjs +1 -2
- package/package.json +1 -1
- package/dist/chunk-NBUS7AWR.mjs +0 -418
- package/dist/chunk-UFXDXENC.mjs +0 -218
- package/dist/hfStateService-W7KO2FOH.mjs +0 -56
- package/dist/project-O4ORKXY5.mjs +0 -8
package/dist/index.mjs
CHANGED
|
@@ -2,37 +2,26 @@ import {
|
|
|
2
2
|
SzenenView,
|
|
3
3
|
alsFlowTextZugang,
|
|
4
4
|
applyEvents,
|
|
5
|
-
createFlowSzenenViewPort
|
|
6
|
-
} from "./chunk-GHKN2VX3.mjs";
|
|
7
|
-
import "./chunk-FUY2OCVC.mjs";
|
|
8
|
-
import {
|
|
9
|
-
exportProjectToZip,
|
|
10
|
-
importProjectFromZip,
|
|
11
|
-
injectXMPMetadata
|
|
12
|
-
} from "./chunk-UFXDXENC.mjs";
|
|
13
|
-
import {
|
|
5
|
+
createFlowSzenenViewPort,
|
|
14
6
|
getHFToken,
|
|
15
7
|
getSessionClientId,
|
|
16
8
|
hfBatchArchive,
|
|
17
9
|
hfBootstrapFromLegacy,
|
|
18
|
-
hfDeleteProject,
|
|
19
10
|
hfDownloadBinaryByPath,
|
|
20
|
-
hfDownloadProject,
|
|
21
11
|
hfListDir,
|
|
22
|
-
hfListProjects,
|
|
23
12
|
hfLoadImageAsBase64,
|
|
24
13
|
hfUploadImage,
|
|
25
|
-
hfUploadProjectForm,
|
|
26
14
|
hfUploadSmallFile,
|
|
27
15
|
loadHFState,
|
|
28
16
|
loadPendingEvents,
|
|
29
17
|
setHFToken,
|
|
30
18
|
tsFromEventPath,
|
|
31
19
|
writeHFEvent
|
|
32
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-B2YV4TNI.mjs";
|
|
21
|
+
import "./chunk-FUY2OCVC.mjs";
|
|
33
22
|
|
|
34
23
|
// package.json
|
|
35
|
-
var version = "
|
|
24
|
+
var version = "7.0.1";
|
|
36
25
|
|
|
37
26
|
// src/hooks/useOnClickOutside.ts
|
|
38
27
|
import { useEffect } from "react";
|
|
@@ -128,6 +117,125 @@ var GLOBAL_STYLES = `
|
|
|
128
117
|
@media (max-width: 760px) { .flow-szenen-shell__content { padding: 8px; } }
|
|
129
118
|
` + SZENEN_VIEW_STYLES;
|
|
130
119
|
|
|
120
|
+
// src/lib/metadata.ts
|
|
121
|
+
var crcTable = (() => {
|
|
122
|
+
let c;
|
|
123
|
+
const table = new Uint32Array(256);
|
|
124
|
+
for (let n = 0; n < 256; n++) {
|
|
125
|
+
c = n;
|
|
126
|
+
for (let k = 0; k < 8; k++) {
|
|
127
|
+
c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
128
|
+
}
|
|
129
|
+
table[n] = c;
|
|
130
|
+
}
|
|
131
|
+
return table;
|
|
132
|
+
})();
|
|
133
|
+
function calculateCRC(bytes) {
|
|
134
|
+
let crc = 4294967295;
|
|
135
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
136
|
+
crc = crcTable[(crc ^ bytes[i]) & 255] ^ crc >>> 8;
|
|
137
|
+
}
|
|
138
|
+
return (crc ^ 4294967295) >>> 0;
|
|
139
|
+
}
|
|
140
|
+
function indexOfBytes(buffer, search, start = 0) {
|
|
141
|
+
for (let i = start; i <= buffer.length - search.length; i++) {
|
|
142
|
+
let found = true;
|
|
143
|
+
for (let j = 0; j < search.length; j++) {
|
|
144
|
+
if (buffer[i + j] !== search[j]) {
|
|
145
|
+
found = false;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (found) return i;
|
|
150
|
+
}
|
|
151
|
+
return -1;
|
|
152
|
+
}
|
|
153
|
+
function createXMPPacket(prompt, seed, model, id, tags = [], hierarchy) {
|
|
154
|
+
const sanitize = (str) => (str || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
155
|
+
const escPrompt = sanitize(prompt);
|
|
156
|
+
const escModel = sanitize(model || "AI Model");
|
|
157
|
+
const escHierarchy = sanitize(hierarchy || "");
|
|
158
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
159
|
+
const allTags = [.../* @__PURE__ */ new Set([...tags, "Avatar Architect", escModel])];
|
|
160
|
+
const rdfTags = allTags.map((t) => `<rdf:li>${sanitize(t)}</rdf:li>`).join("");
|
|
161
|
+
const BOM = "\uFEFF";
|
|
162
|
+
return `<?xpacket begin="${BOM}" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
|
163
|
+
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c140">
|
|
164
|
+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
|
165
|
+
<rdf:Description rdf:about=""
|
|
166
|
+
xmlns:xmp="http://ns.adobe.com/xap/1.0/"
|
|
167
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
168
|
+
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/"
|
|
169
|
+
xmlns:ai="http://ns.flow.creative/ai/1.0/">
|
|
170
|
+
<dc:format>image/png</dc:format>
|
|
171
|
+
<dc:description><rdf:Alt><rdf:li xml:lang="x-default">${escPrompt}</rdf:li></rdf:Alt></dc:description>
|
|
172
|
+
<dc:subject><rdf:Bag>${rdfTags}</rdf:Bag></dc:subject>
|
|
173
|
+
<photoshop:Instructions>Seed: ${seed} | Model: ${escModel}</photoshop:Instructions>
|
|
174
|
+
<xmp:CreateDate>${timestamp}</xmp:CreateDate>
|
|
175
|
+
<ai:prompt>${escPrompt}</ai:prompt>
|
|
176
|
+
<ai:seed>${seed ?? "0"}</ai:seed>
|
|
177
|
+
<ai:model>${escModel}</ai:model>
|
|
178
|
+
<ai:hierarchy>${escHierarchy}</ai:hierarchy>
|
|
179
|
+
</rdf:Description>
|
|
180
|
+
</rdf:RDF>
|
|
181
|
+
</x:xmpmeta>${" ".repeat(1024)}<?xpacket end="w"?>`;
|
|
182
|
+
}
|
|
183
|
+
function bytesToBase64(bytes) {
|
|
184
|
+
let binary = "";
|
|
185
|
+
const len = bytes.byteLength;
|
|
186
|
+
for (let i = 0; i < len; i++) binary += String.fromCharCode(bytes[i]);
|
|
187
|
+
return btoa(binary);
|
|
188
|
+
}
|
|
189
|
+
function base64ToBytes(base64) {
|
|
190
|
+
const clean = base64.includes(",") ? base64.split(",")[1] : base64.trim();
|
|
191
|
+
try {
|
|
192
|
+
const binary = atob(clean);
|
|
193
|
+
const bytes = new Uint8Array(binary.length);
|
|
194
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
195
|
+
return bytes;
|
|
196
|
+
} catch (e) {
|
|
197
|
+
return new Uint8Array(0);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function injectXMPMetadata(base64, prompt, seed, model, id, tags = [], hierarchy) {
|
|
201
|
+
try {
|
|
202
|
+
const bytes = base64ToBytes(base64);
|
|
203
|
+
if (bytes.length < 8 || bytes[0] !== 137 || bytes[1] !== 80) {
|
|
204
|
+
console.warn("Metadaten-Injektion \xFCbersprungen: Datei ist kein PNG.");
|
|
205
|
+
return base64;
|
|
206
|
+
}
|
|
207
|
+
const xmpData = createXMPPacket(prompt, seed, model, id, tags, hierarchy);
|
|
208
|
+
const encoder = new TextEncoder();
|
|
209
|
+
const keyword = encoder.encode("XML:com.adobe.xmp");
|
|
210
|
+
const textBytes = encoder.encode(xmpData);
|
|
211
|
+
const chunkData = new Uint8Array(keyword.length + 5 + textBytes.length);
|
|
212
|
+
chunkData.set(keyword, 0);
|
|
213
|
+
chunkData.set(textBytes, keyword.length + 5);
|
|
214
|
+
const type = encoder.encode("iTXt");
|
|
215
|
+
const crcInput = new Uint8Array(type.length + chunkData.length);
|
|
216
|
+
crcInput.set(type, 0);
|
|
217
|
+
crcInput.set(chunkData, type.length);
|
|
218
|
+
const crc = calculateCRC(crcInput);
|
|
219
|
+
const fullChunk = new Uint8Array(4 + 4 + chunkData.length + 4);
|
|
220
|
+
const view = new DataView(fullChunk.buffer);
|
|
221
|
+
view.setUint32(0, chunkData.length);
|
|
222
|
+
fullChunk.set(type, 4);
|
|
223
|
+
fullChunk.set(chunkData, 8);
|
|
224
|
+
view.setUint32(8 + chunkData.length, crc);
|
|
225
|
+
const IDAT = encoder.encode("IDAT");
|
|
226
|
+
const idatPos = indexOfBytes(bytes, IDAT);
|
|
227
|
+
const insertPos = idatPos !== -1 ? idatPos - 4 : 8;
|
|
228
|
+
const result = new Uint8Array(bytes.length + fullChunk.length);
|
|
229
|
+
result.set(bytes.slice(0, insertPos), 0);
|
|
230
|
+
result.set(fullChunk, insertPos);
|
|
231
|
+
result.set(bytes.slice(insertPos), insertPos + fullChunk.length);
|
|
232
|
+
return bytesToBase64(result);
|
|
233
|
+
} catch (e) {
|
|
234
|
+
console.error("Fehler beim Einbetten der Metadaten:", e);
|
|
235
|
+
return base64;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
131
239
|
// src/lib/aiHelpers.ts
|
|
132
240
|
function buildGenerationPrompt(hierarchyText, mode = "creative") {
|
|
133
241
|
const safe = hierarchyText.length > 2500 ? hierarchyText.slice(0, 2500) + "..." : hierarchyText;
|
|
@@ -1446,7 +1554,7 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
|
|
|
1446
1554
|
}
|
|
1447
1555
|
|
|
1448
1556
|
// src/components/AvatarArchitectApp.tsx
|
|
1449
|
-
import { useState as useState25, useCallback as useCallback4, useMemo as useMemo6, useEffect as
|
|
1557
|
+
import { useState as useState25, useCallback as useCallback4, useMemo as useMemo6, useEffect as useEffect9, useRef as useRef10 } from "react";
|
|
1450
1558
|
|
|
1451
1559
|
// src/components/PromptTab.tsx
|
|
1452
1560
|
import { useRef as useRef5, useState as useState8 } from "react";
|
|
@@ -2033,374 +2141,50 @@ var TaskExecutor = ({ openTasks, onExecute, onTaskCompleted }) => {
|
|
|
2033
2141
|
] });
|
|
2034
2142
|
};
|
|
2035
2143
|
|
|
2036
|
-
// src/components/
|
|
2037
|
-
import {
|
|
2038
|
-
import {
|
|
2039
|
-
var
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
onWorkspaceImport,
|
|
2044
|
-
projectActionState,
|
|
2045
|
-
serverProjects,
|
|
2046
|
-
onServerSave,
|
|
2047
|
-
onServerLoad,
|
|
2048
|
-
onServerDelete,
|
|
2049
|
-
onRefreshServerProjects,
|
|
2050
|
-
onComputeSyncDiff,
|
|
2051
|
-
onExecuteSync,
|
|
2052
|
-
hfToken,
|
|
2053
|
-
onHfLoad,
|
|
2054
|
-
onProjectExportBase64,
|
|
2055
|
-
onHfInitialSync
|
|
2056
|
-
}) => {
|
|
2057
|
-
const projectInputRef = useRef7(null);
|
|
2058
|
-
const workspaceInputRef = useRef7(null);
|
|
2059
|
-
const [saveName, setSaveName] = useState10("");
|
|
2060
|
-
const [isSaving, setIsSaving] = useState10(false);
|
|
2061
|
-
const [isExporting, setIsExporting] = useState10(false);
|
|
2062
|
-
const [syncState, setSyncState] = useState10("idle");
|
|
2063
|
-
const [syncDiff, setSyncDiff] = useState10(null);
|
|
2064
|
-
const [selectedLocalIds, setSelectedLocalIds] = useState10(/* @__PURE__ */ new Set());
|
|
2065
|
-
const handleExport = async () => {
|
|
2066
|
-
if (!onProjectExport) return;
|
|
2067
|
-
setIsExporting(true);
|
|
2068
|
-
try {
|
|
2069
|
-
await onProjectExport();
|
|
2070
|
-
} finally {
|
|
2071
|
-
setIsExporting(false);
|
|
2072
|
-
}
|
|
2073
|
-
};
|
|
2074
|
-
const handleComputeDiff = async () => {
|
|
2075
|
-
if (!onComputeSyncDiff) return;
|
|
2076
|
-
setSyncState("computing");
|
|
2077
|
-
setSyncDiff(null);
|
|
2078
|
-
try {
|
|
2079
|
-
const diff = await onComputeSyncDiff();
|
|
2080
|
-
setSyncDiff(diff);
|
|
2081
|
-
setSelectedLocalIds(new Set(diff.localOnly.map((g) => g.id)));
|
|
2082
|
-
setSyncState("ready");
|
|
2083
|
-
} catch {
|
|
2084
|
-
setSyncState("error");
|
|
2085
|
-
setTimeout(() => setSyncState("idle"), 4e3);
|
|
2086
|
-
}
|
|
2087
|
-
};
|
|
2088
|
-
const handleExecuteSync = async () => {
|
|
2089
|
-
if (!onExecuteSync || !syncDiff) return;
|
|
2090
|
-
setSyncState("executing");
|
|
2091
|
-
try {
|
|
2092
|
-
await onExecuteSync([...selectedLocalIds]);
|
|
2093
|
-
setSyncState("done");
|
|
2094
|
-
setSyncDiff(null);
|
|
2095
|
-
setTimeout(() => setSyncState("idle"), 3e3);
|
|
2096
|
-
} catch {
|
|
2097
|
-
setSyncState("error");
|
|
2098
|
-
setTimeout(() => setSyncState("idle"), 4e3);
|
|
2099
|
-
}
|
|
2100
|
-
};
|
|
2101
|
-
const toggleLocalId = (id) => {
|
|
2102
|
-
setSelectedLocalIds((prev) => {
|
|
2103
|
-
const next = new Set(prev);
|
|
2104
|
-
if (next.has(id)) next.delete(id);
|
|
2105
|
-
else next.add(id);
|
|
2106
|
-
return next;
|
|
2107
|
-
});
|
|
2108
|
-
};
|
|
2109
|
-
const isWorking = projectActionState === "working" || projectActionState === "working-full";
|
|
2110
|
-
const [hfProjects, setHfProjects] = useState10([]);
|
|
2111
|
-
const [hfLoading, setHfLoading] = useState10(false);
|
|
2112
|
-
const [hfSaving, setHfSaving] = useState10(false);
|
|
2113
|
-
const [hfError, setHfError] = useState10(null);
|
|
2114
|
-
const [hfSaveName, setHfSaveName] = useState10("");
|
|
2115
|
-
const [hfSyncProgress, setHfSyncProgress] = useState10(null);
|
|
2116
|
-
const [hfSyncing, setHfSyncing] = useState10(false);
|
|
2117
|
-
const loadHfProjects = async (token) => {
|
|
2118
|
-
setHfLoading(true);
|
|
2119
|
-
setHfError(null);
|
|
2120
|
-
try {
|
|
2121
|
-
setHfProjects(await hfListProjects(token));
|
|
2122
|
-
} catch (e) {
|
|
2123
|
-
setHfError(e.message);
|
|
2124
|
-
} finally {
|
|
2125
|
-
setHfLoading(false);
|
|
2126
|
-
}
|
|
2127
|
-
};
|
|
2128
|
-
useEffect6(() => {
|
|
2129
|
-
if (hfToken) loadHfProjects(hfToken);
|
|
2130
|
-
}, [hfToken]);
|
|
2144
|
+
// src/components/HfMediaSyncTab.tsx
|
|
2145
|
+
import { useState as useState10 } from "react";
|
|
2146
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2147
|
+
var HfMediaSyncTab = ({ topSlot, onHfInitialSync }) => {
|
|
2148
|
+
const [error, setError] = useState10(null);
|
|
2149
|
+
const [progress, setProgress] = useState10(null);
|
|
2150
|
+
const [syncing, setSyncing] = useState10(false);
|
|
2131
2151
|
return /* @__PURE__ */ jsx15("div", { className: "absolute inset-0 overflow-y-auto dark-scrollbar", children: /* @__PURE__ */ jsxs13("div", { className: "p-6 flex flex-col gap-8", children: [
|
|
2132
2152
|
topSlot && /* @__PURE__ */ jsx15("div", { children: topSlot }),
|
|
2133
|
-
|
|
2134
|
-
/* @__PURE__ */ jsx15(SectionLabel, { children: "
|
|
2153
|
+
onHfInitialSync && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4", children: [
|
|
2154
|
+
/* @__PURE__ */ jsx15(SectionLabel, { children: "Hugging Face" }),
|
|
2135
2155
|
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-2", children: [
|
|
2136
|
-
onProjectExport && /* @__PURE__ */ jsx15(PillButton, { variant: "filled", icon: "download", loading: isExporting || isWorking, onClick: handleExport, children: "Exportieren (.zip)" }),
|
|
2137
|
-
onProjectImport && /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
2138
|
-
/* @__PURE__ */ jsx15(PillButton, { variant: "outline", icon: "upload", onClick: () => projectInputRef.current?.click(), children: "ZIP laden" }),
|
|
2139
|
-
/* @__PURE__ */ jsx15(
|
|
2140
|
-
"input",
|
|
2141
|
-
{
|
|
2142
|
-
ref: projectInputRef,
|
|
2143
|
-
type: "file",
|
|
2144
|
-
accept: ".zip",
|
|
2145
|
-
className: "hidden",
|
|
2146
|
-
onChange: (e) => {
|
|
2147
|
-
const f = e.target.files?.[0];
|
|
2148
|
-
if (f) onProjectImport(f);
|
|
2149
|
-
e.target.value = "";
|
|
2150
|
-
}
|
|
2151
|
-
}
|
|
2152
|
-
)
|
|
2153
|
-
] })
|
|
2154
|
-
] }),
|
|
2155
|
-
onWorkspaceImport && /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
2156
|
-
/* @__PURE__ */ jsx15(PillButton, { variant: "outline", icon: "upload_file", onClick: () => workspaceInputRef.current?.click(), children: "Tags laden (.json)" }),
|
|
2157
|
-
/* @__PURE__ */ jsx15(
|
|
2158
|
-
"input",
|
|
2159
|
-
{
|
|
2160
|
-
ref: workspaceInputRef,
|
|
2161
|
-
type: "file",
|
|
2162
|
-
accept: ".json",
|
|
2163
|
-
className: "hidden",
|
|
2164
|
-
onChange: (e) => {
|
|
2165
|
-
const f = e.target.files?.[0];
|
|
2166
|
-
if (f) onWorkspaceImport(f);
|
|
2167
|
-
e.target.value = "";
|
|
2168
|
-
}
|
|
2169
|
-
}
|
|
2170
|
-
)
|
|
2171
|
-
] })
|
|
2172
|
-
] }),
|
|
2173
|
-
(onServerSave || serverProjects || onServerDelete) && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4", children: [
|
|
2174
|
-
/* @__PURE__ */ jsx15(SectionLabel, { children: "Server-Speicher" }),
|
|
2175
|
-
onServerSave && /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
|
|
2176
|
-
/* @__PURE__ */ jsx15(
|
|
2177
|
-
"input",
|
|
2178
|
-
{
|
|
2179
|
-
type: "text",
|
|
2180
|
-
value: saveName,
|
|
2181
|
-
onChange: (e) => setSaveName(e.target.value),
|
|
2182
|
-
placeholder: "Name (optional)",
|
|
2183
|
-
className: "flex-1 bg-white/5 border border-white/10 rounded-xl px-3 text-[12px] text-white/70 outline-none placeholder:text-white/20",
|
|
2184
|
-
style: { height: 40 }
|
|
2185
|
-
}
|
|
2186
|
-
),
|
|
2187
|
-
/* @__PURE__ */ jsx15(
|
|
2188
|
-
PillButton,
|
|
2189
|
-
{
|
|
2190
|
-
variant: "filled",
|
|
2191
|
-
icon: "cloud_upload",
|
|
2192
|
-
loading: isSaving,
|
|
2193
|
-
onClick: async () => {
|
|
2194
|
-
setIsSaving(true);
|
|
2195
|
-
try {
|
|
2196
|
-
await onServerSave(saveName || void 0);
|
|
2197
|
-
setSaveName("");
|
|
2198
|
-
await onRefreshServerProjects?.();
|
|
2199
|
-
} finally {
|
|
2200
|
-
setIsSaving(false);
|
|
2201
|
-
}
|
|
2202
|
-
},
|
|
2203
|
-
children: "Speichern"
|
|
2204
|
-
}
|
|
2205
|
-
)
|
|
2206
|
-
] }),
|
|
2207
|
-
(!serverProjects || serverProjects.length === 0) && /* @__PURE__ */ jsx15("p", { className: "text-[10px] text-white/20 px-2", children: "Noch nichts gespeichert." }),
|
|
2208
|
-
serverProjects && serverProjects.length > 0 && /* @__PURE__ */ jsx15("div", { className: "flex flex-col gap-1", children: serverProjects.map((p) => /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 px-3 py-2 rounded-xl bg-white/5 border border-white/5", children: [
|
|
2209
|
-
/* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
|
|
2210
|
-
/* @__PURE__ */ jsx15("p", { className: "text-[11px] text-white/70 font-bold truncate", children: p.name }),
|
|
2211
|
-
/* @__PURE__ */ jsxs13("p", { className: "text-[9px] text-white/25", children: [
|
|
2212
|
-
new Date(p.saved_at).toLocaleString("de-DE", { dateStyle: "short", timeStyle: "short" }),
|
|
2213
|
-
" \xB7 ",
|
|
2214
|
-
(p.size / 1024).toFixed(0),
|
|
2215
|
-
" KB"
|
|
2216
|
-
] })
|
|
2217
|
-
] }),
|
|
2218
|
-
onServerLoad && /* @__PURE__ */ jsx15("button", { onClick: () => onServerLoad(p.id), className: "w-8 h-8 flex items-center justify-center text-white/30 active:text-white transition-colors", children: /* @__PURE__ */ jsx15("span", { className: "material-symbols-outlined text-[18px]", children: "cloud_download" }) }),
|
|
2219
|
-
/* @__PURE__ */ jsx15("button", { onClick: () => onServerDelete?.(p.id), className: "w-8 h-8 flex items-center justify-center text-white/20 active:text-red-400 transition-colors", children: /* @__PURE__ */ jsx15("span", { className: "material-symbols-outlined text-[18px]", children: "delete" }) })
|
|
2220
|
-
] }, p.id)) })
|
|
2221
|
-
] }),
|
|
2222
|
-
hfToken && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4", children: [
|
|
2223
|
-
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between", children: [
|
|
2224
|
-
/* @__PURE__ */ jsx15(SectionLabel, { children: "Hugging Face" }),
|
|
2225
|
-
/* @__PURE__ */ jsx15("button", { onClick: () => loadHfProjects(hfToken), className: "text-white/30 hover:text-white/60 transition", children: /* @__PURE__ */ jsx15("span", { className: `material-symbols-outlined text-[18px]${hfLoading ? " animate-spin" : ""}`, children: "refresh" }) })
|
|
2226
|
-
] }),
|
|
2227
|
-
onProjectExportBase64 && /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
|
|
2228
|
-
/* @__PURE__ */ jsx15(
|
|
2229
|
-
"input",
|
|
2230
|
-
{
|
|
2231
|
-
type: "text",
|
|
2232
|
-
value: hfSaveName,
|
|
2233
|
-
onChange: (e) => setHfSaveName(e.target.value),
|
|
2234
|
-
placeholder: "Name (optional)",
|
|
2235
|
-
className: "flex-1 bg-white/5 border border-white/10 rounded-xl px-3 text-[12px] text-white/70 outline-none placeholder:text-white/20",
|
|
2236
|
-
style: { height: 40 }
|
|
2237
|
-
}
|
|
2238
|
-
),
|
|
2239
|
-
/* @__PURE__ */ jsx15(
|
|
2240
|
-
PillButton,
|
|
2241
|
-
{
|
|
2242
|
-
variant: "filled",
|
|
2243
|
-
icon: "cloud_upload",
|
|
2244
|
-
loading: hfSaving,
|
|
2245
|
-
onClick: async () => {
|
|
2246
|
-
if (!onProjectExportBase64) return;
|
|
2247
|
-
setHfSaving(true);
|
|
2248
|
-
setHfError(null);
|
|
2249
|
-
try {
|
|
2250
|
-
const base64 = await onProjectExportBase64();
|
|
2251
|
-
const name = hfSaveName.trim() || `project_${(/* @__PURE__ */ new Date()).toISOString().slice(0, 16).replace("T", "_").replace(":", "")}`;
|
|
2252
|
-
await hfUploadProjectForm(base64, name, hfToken);
|
|
2253
|
-
setHfSaveName("");
|
|
2254
|
-
await loadHfProjects(hfToken);
|
|
2255
|
-
} catch (e) {
|
|
2256
|
-
setHfError(e.message);
|
|
2257
|
-
} finally {
|
|
2258
|
-
setHfSaving(false);
|
|
2259
|
-
}
|
|
2260
|
-
},
|
|
2261
|
-
children: "Speichern"
|
|
2262
|
-
}
|
|
2263
|
-
)
|
|
2264
|
-
] }),
|
|
2265
|
-
onHfInitialSync && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-2", children: [
|
|
2266
2156
|
/* @__PURE__ */ jsx15(
|
|
2267
2157
|
PillButton,
|
|
2268
2158
|
{
|
|
2269
2159
|
variant: "outline",
|
|
2270
2160
|
icon: "cloud_sync",
|
|
2271
|
-
loading:
|
|
2161
|
+
loading: syncing,
|
|
2272
2162
|
onClick: async () => {
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2163
|
+
setSyncing(true);
|
|
2164
|
+
setError(null);
|
|
2165
|
+
setProgress({ done: 0, total: 0 });
|
|
2276
2166
|
try {
|
|
2277
|
-
await onHfInitialSync((done, total) =>
|
|
2278
|
-
|
|
2167
|
+
await onHfInitialSync((done, total) => setProgress({ done, total }));
|
|
2168
|
+
setProgress(null);
|
|
2279
2169
|
} catch (e) {
|
|
2280
|
-
|
|
2281
|
-
|
|
2170
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
2171
|
+
setProgress(null);
|
|
2282
2172
|
} finally {
|
|
2283
|
-
|
|
2173
|
+
setSyncing(false);
|
|
2284
2174
|
}
|
|
2285
2175
|
},
|
|
2286
|
-
children:
|
|
2176
|
+
children: syncing && progress ? `${progress.done} / ${progress.total} Bilder` : "Initial-Sync nach HF"
|
|
2287
2177
|
}
|
|
2288
2178
|
),
|
|
2289
|
-
|
|
2179
|
+
syncing && progress && progress.total > 0 && /* @__PURE__ */ jsx15("div", { className: "w-full h-1 bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx15(
|
|
2290
2180
|
"div",
|
|
2291
2181
|
{
|
|
2292
2182
|
className: "h-full bg-blue-400 rounded-full transition-all",
|
|
2293
|
-
style: { width: `${Math.round(
|
|
2183
|
+
style: { width: `${Math.round(progress.done / progress.total * 100)}%` }
|
|
2294
2184
|
}
|
|
2295
2185
|
) })
|
|
2296
2186
|
] }),
|
|
2297
|
-
|
|
2298
|
-
!hfLoading && hfProjects.length === 0 && /* @__PURE__ */ jsx15("p", { className: "text-[10px] text-white/20 px-2", children: "Noch nichts auf HF gespeichert." }),
|
|
2299
|
-
hfProjects.map((p) => /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 px-3 py-2 rounded-xl bg-white/5 border border-white/5", children: [
|
|
2300
|
-
/* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
|
|
2301
|
-
/* @__PURE__ */ jsx15("p", { className: "text-[11px] text-white/70 font-bold truncate", children: p.name }),
|
|
2302
|
-
/* @__PURE__ */ jsxs13("p", { className: "text-[9px] text-white/25", children: [
|
|
2303
|
-
(p.size / 1024 / 1024).toFixed(1),
|
|
2304
|
-
" MB",
|
|
2305
|
-
p.isLfs ? " \xB7 LFS" : ""
|
|
2306
|
-
] })
|
|
2307
|
-
] }),
|
|
2308
|
-
onHfLoad && /* @__PURE__ */ jsx15(
|
|
2309
|
-
"button",
|
|
2310
|
-
{
|
|
2311
|
-
onClick: async () => {
|
|
2312
|
-
try {
|
|
2313
|
-
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-W7KO2FOH.mjs");
|
|
2314
|
-
const file = await hfDownloadProject2(p.path, hfToken);
|
|
2315
|
-
onHfLoad(file);
|
|
2316
|
-
} catch (e) {
|
|
2317
|
-
setHfError(e.message);
|
|
2318
|
-
}
|
|
2319
|
-
},
|
|
2320
|
-
className: "w-8 h-8 flex items-center justify-center text-white/30 active:text-white transition-colors",
|
|
2321
|
-
children: /* @__PURE__ */ jsx15("span", { className: "material-symbols-outlined text-[18px]", children: "cloud_download" })
|
|
2322
|
-
}
|
|
2323
|
-
),
|
|
2324
|
-
/* @__PURE__ */ jsx15(
|
|
2325
|
-
"button",
|
|
2326
|
-
{
|
|
2327
|
-
onClick: async () => {
|
|
2328
|
-
if (!confirm(`"${p.name}" auf HF l\xF6schen?`)) return;
|
|
2329
|
-
try {
|
|
2330
|
-
await hfDeleteProject(p.path, hfToken);
|
|
2331
|
-
await loadHfProjects(hfToken);
|
|
2332
|
-
} catch (e) {
|
|
2333
|
-
setHfError(e.message);
|
|
2334
|
-
}
|
|
2335
|
-
},
|
|
2336
|
-
className: "w-8 h-8 flex items-center justify-center text-white/20 active:text-red-400 transition-colors",
|
|
2337
|
-
children: /* @__PURE__ */ jsx15("span", { className: "material-symbols-outlined text-[18px]", children: "delete" })
|
|
2338
|
-
}
|
|
2339
|
-
)
|
|
2340
|
-
] }, p.id))
|
|
2341
|
-
] }),
|
|
2342
|
-
onComputeSyncDiff && onExecuteSync && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-4", children: [
|
|
2343
|
-
/* @__PURE__ */ jsx15(SectionLabel, { children: "Sync" }),
|
|
2344
|
-
(syncState === "idle" || syncState === "computing") && /* @__PURE__ */ jsx15(PillButton, { variant: "outline", icon: "compare_arrows", loading: syncState === "computing", onClick: handleComputeDiff, children: "Diff berechnen" }),
|
|
2345
|
-
syncState === "done" && /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 px-2 text-[11px] text-green-400", children: [
|
|
2346
|
-
/* @__PURE__ */ jsx15("span", { className: "material-symbols-outlined text-[16px]", children: "check_circle" }),
|
|
2347
|
-
"Sync abgeschlossen"
|
|
2348
|
-
] }),
|
|
2349
|
-
syncState === "error" && /* @__PURE__ */ jsx15("p", { className: "text-[11px] text-red-400 px-2", children: "Fehler beim Sync." }),
|
|
2350
|
-
syncDiff && (syncState === "ready" || syncState === "executing") && /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
2351
|
-
syncDiff.localOnly.length === 0 && syncDiff.serverOnly.length === 0 && /* @__PURE__ */ jsx15("p", { className: "text-[10px] text-white/30 px-2", children: "Alles synchron \u2014 keine Unterschiede." }),
|
|
2352
|
-
syncDiff.localOnly.length > 0 && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-2", children: [
|
|
2353
|
-
/* @__PURE__ */ jsxs13("p", { className: "text-[9px] text-white/30 uppercase tracking-widest px-1 font-bold", children: [
|
|
2354
|
-
"Nur lokal (",
|
|
2355
|
-
syncDiff.localOnly.length,
|
|
2356
|
-
")"
|
|
2357
|
-
] }),
|
|
2358
|
-
syncDiff.localOnly.map((gen) => /* @__PURE__ */ jsxs13(
|
|
2359
|
-
"button",
|
|
2360
|
-
{
|
|
2361
|
-
onClick: () => toggleLocalId(gen.id),
|
|
2362
|
-
className: `flex items-center gap-3 px-3 py-2 rounded-xl border transition-all text-left ${selectedLocalIds.has(gen.id) ? "bg-blue-500/10 border-blue-500/30" : "bg-white/3 border-white/5 opacity-60"}`,
|
|
2363
|
-
children: [
|
|
2364
|
-
/* @__PURE__ */ jsx15("div", { className: `w-4 h-4 rounded border flex items-center justify-center flex-shrink-0 ${selectedLocalIds.has(gen.id) ? "bg-blue-500 border-blue-500" : "border-white/20"}`, children: selectedLocalIds.has(gen.id) && /* @__PURE__ */ jsx15("span", { className: "material-symbols-outlined text-[11px] text-white", children: "check" }) }),
|
|
2365
|
-
gen.base64 && /* @__PURE__ */ jsx15("img", { src: gen.base64, className: "w-10 h-10 rounded object-cover flex-shrink-0" }),
|
|
2366
|
-
/* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
|
|
2367
|
-
/* @__PURE__ */ jsx15("p", { className: "text-[10px] text-white/60 truncate", children: gen.prompt || "Kein Prompt" }),
|
|
2368
|
-
/* @__PURE__ */ jsx15("p", { className: "text-[9px] text-white/25", children: new Date(gen.timestamp).toLocaleString("de-DE", { dateStyle: "short", timeStyle: "short" }) })
|
|
2369
|
-
] })
|
|
2370
|
-
]
|
|
2371
|
-
},
|
|
2372
|
-
gen.id
|
|
2373
|
-
))
|
|
2374
|
-
] }),
|
|
2375
|
-
syncDiff.serverOnly.length > 0 && /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-2", children: [
|
|
2376
|
-
/* @__PURE__ */ jsxs13("p", { className: "text-[9px] text-white/30 uppercase tracking-widest px-1 font-bold", children: [
|
|
2377
|
-
"Nur auf Server (",
|
|
2378
|
-
syncDiff.serverOnly.length,
|
|
2379
|
-
")"
|
|
2380
|
-
] }),
|
|
2381
|
-
syncDiff.serverOnly.map((gen) => /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-3 px-3 py-2 rounded-xl bg-white/3 border border-white/5 opacity-40", children: [
|
|
2382
|
-
gen.base64 && /* @__PURE__ */ jsx15("img", { src: gen.base64, className: "w-10 h-10 rounded object-cover flex-shrink-0" }),
|
|
2383
|
-
/* @__PURE__ */ jsxs13("div", { className: "flex-1 min-w-0", children: [
|
|
2384
|
-
/* @__PURE__ */ jsx15("p", { className: "text-[10px] text-white/60 truncate", children: gen.prompt || "Kein Prompt" }),
|
|
2385
|
-
/* @__PURE__ */ jsx15("p", { className: "text-[9px] text-white/25", children: new Date(gen.timestamp).toLocaleString("de-DE", { dateStyle: "short", timeStyle: "short" }) })
|
|
2386
|
-
] })
|
|
2387
|
-
] }, gen.id))
|
|
2388
|
-
] }),
|
|
2389
|
-
(syncDiff.localOnly.length > 0 || syncDiff.serverOnly.length > 0) && /* @__PURE__ */ jsxs13(
|
|
2390
|
-
PillButton,
|
|
2391
|
-
{
|
|
2392
|
-
variant: "solid",
|
|
2393
|
-
icon: "sync",
|
|
2394
|
-
loading: syncState === "executing",
|
|
2395
|
-
disabled: selectedLocalIds.size === 0,
|
|
2396
|
-
onClick: handleExecuteSync,
|
|
2397
|
-
children: [
|
|
2398
|
-
selectedLocalIds.size,
|
|
2399
|
-
" \xFCbertragen"
|
|
2400
|
-
]
|
|
2401
|
-
}
|
|
2402
|
-
)
|
|
2403
|
-
] })
|
|
2187
|
+
error && /* @__PURE__ */ jsx15("p", { className: "text-[10px] text-red-400 font-mono px-1", children: error })
|
|
2404
2188
|
] })
|
|
2405
2189
|
] }) });
|
|
2406
2190
|
};
|
|
@@ -2532,7 +2316,7 @@ function toPromptImages(images) {
|
|
|
2532
2316
|
}
|
|
2533
2317
|
|
|
2534
2318
|
// src/hooks/useHFState.ts
|
|
2535
|
-
import { useState as useState11, useEffect as
|
|
2319
|
+
import { useState as useState11, useEffect as useEffect6, useRef as useRef7, useCallback } from "react";
|
|
2536
2320
|
|
|
2537
2321
|
// src/lib/hfDag.ts
|
|
2538
2322
|
function buildDag(events) {
|
|
@@ -2622,9 +2406,9 @@ function useHFState(token, namespace) {
|
|
|
2622
2406
|
const [pendingBufferCount, setPendingBufferCount] = useState11(readOfflineBuffer().length);
|
|
2623
2407
|
const [lastEventTs, setLastEventTs] = useState11(0);
|
|
2624
2408
|
const [hasStateZip, setHasStateZip] = useState11(false);
|
|
2625
|
-
const knownEventPaths =
|
|
2626
|
-
const knownFilePaths =
|
|
2627
|
-
const allEventsRef =
|
|
2409
|
+
const knownEventPaths = useRef7(/* @__PURE__ */ new Set());
|
|
2410
|
+
const knownFilePaths = useRef7(/* @__PURE__ */ new Set());
|
|
2411
|
+
const allEventsRef = useRef7([]);
|
|
2628
2412
|
const applyNewEvents = useCallback((snapshot, newEvents) => {
|
|
2629
2413
|
if (!newEvents.length && allEventsRef.current.length === 0) {
|
|
2630
2414
|
setEventCount(0);
|
|
@@ -2701,10 +2485,10 @@ function useHFState(token, namespace) {
|
|
|
2701
2485
|
} catch {
|
|
2702
2486
|
}
|
|
2703
2487
|
}, [token, namespace, state, applyNewEvents]);
|
|
2704
|
-
|
|
2488
|
+
useEffect6(() => {
|
|
2705
2489
|
if (token && namespace) loadFull();
|
|
2706
2490
|
}, [token, namespace]);
|
|
2707
|
-
|
|
2491
|
+
useEffect6(() => {
|
|
2708
2492
|
if (!token || !namespace) return;
|
|
2709
2493
|
const id = setInterval(pollNew, POLL_INTERVAL_MS);
|
|
2710
2494
|
return () => clearInterval(id);
|
|
@@ -2759,7 +2543,7 @@ function useHFState(token, namespace) {
|
|
|
2759
2543
|
}
|
|
2760
2544
|
|
|
2761
2545
|
// src/hooks/useTagBase.ts
|
|
2762
|
-
import { useState as useState12, useEffect as
|
|
2546
|
+
import { useState as useState12, useEffect as useEffect7, useCallback as useCallback2, useRef as useRef8 } from "react";
|
|
2763
2547
|
|
|
2764
2548
|
// src/lib/hfTagBaseService.ts
|
|
2765
2549
|
import JSZip from "jszip";
|
|
@@ -2895,13 +2679,13 @@ function useTagBase(token, namespace) {
|
|
|
2895
2679
|
const [selectedContextId, setSelectedContextId] = useState12(() => readStoredId(CONTEXT_ID_KEY));
|
|
2896
2680
|
const [pickerMessage, setPickerMessage] = useState12(null);
|
|
2897
2681
|
const [pendingTags, setPendingTags] = useState12([]);
|
|
2898
|
-
const pendingIdCounter =
|
|
2899
|
-
const selectedUserIdRef =
|
|
2900
|
-
const selectedContextIdRef =
|
|
2901
|
-
|
|
2682
|
+
const pendingIdCounter = useRef8(-1);
|
|
2683
|
+
const selectedUserIdRef = useRef8(selectedUserId);
|
|
2684
|
+
const selectedContextIdRef = useRef8(selectedContextId);
|
|
2685
|
+
useEffect7(() => {
|
|
2902
2686
|
selectedUserIdRef.current = selectedUserId;
|
|
2903
2687
|
}, [selectedUserId]);
|
|
2904
|
-
|
|
2688
|
+
useEffect7(() => {
|
|
2905
2689
|
selectedContextIdRef.current = selectedContextId;
|
|
2906
2690
|
}, [selectedContextId]);
|
|
2907
2691
|
const load = useCallback2(async () => {
|
|
@@ -2946,7 +2730,7 @@ function useTagBase(token, namespace) {
|
|
|
2946
2730
|
setIsLoading(false);
|
|
2947
2731
|
}
|
|
2948
2732
|
}, [token, namespace]);
|
|
2949
|
-
|
|
2733
|
+
useEffect7(() => {
|
|
2950
2734
|
load();
|
|
2951
2735
|
}, [load]);
|
|
2952
2736
|
const selectUser = useCallback2((userId) => {
|
|
@@ -3045,7 +2829,7 @@ import { useState as useState15 } from "react";
|
|
|
3045
2829
|
|
|
3046
2830
|
// src/components/labs/LabImagePicker.tsx
|
|
3047
2831
|
import { useState as useState13 } from "react";
|
|
3048
|
-
import { Fragment as
|
|
2832
|
+
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3049
2833
|
var LabImagePicker = ({
|
|
3050
2834
|
availableItems,
|
|
3051
2835
|
recentItems,
|
|
@@ -3142,7 +2926,7 @@ var LabImagePicker = ({
|
|
|
3142
2926
|
}
|
|
3143
2927
|
) }),
|
|
3144
2928
|
/* @__PURE__ */ jsxs14("div", { className: "flex-1 overflow-y-auto dark-scrollbar px-3 pb-3", children: [
|
|
3145
|
-
recentItems.length > 0 && !search && /* @__PURE__ */ jsxs14(
|
|
2929
|
+
recentItems.length > 0 && !search && /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
3146
2930
|
/* @__PURE__ */ jsx16("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/30 mb-2 mt-1", children: "Zuletzt verwendet" }),
|
|
3147
2931
|
/* @__PURE__ */ jsx16("div", { className: "grid grid-cols-3 gap-2 mb-4", children: recentItems.slice(0, 6).map(renderItemCard) }),
|
|
3148
2932
|
/* @__PURE__ */ jsx16("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/30 mb-2", children: "Alle Bilder" })
|
|
@@ -3257,7 +3041,7 @@ function useGenerationSettings() {
|
|
|
3257
3041
|
}
|
|
3258
3042
|
|
|
3259
3043
|
// src/components/labs/LabRemix.tsx
|
|
3260
|
-
import { Fragment as
|
|
3044
|
+
import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3261
3045
|
var LabRemix = ({ services, onResult }) => {
|
|
3262
3046
|
const [showPicker, setShowPicker] = useState15(false);
|
|
3263
3047
|
const [selected, setSelected] = useState15(null);
|
|
@@ -3413,10 +3197,10 @@ var LabRemix = ({ services, onResult }) => {
|
|
|
3413
3197
|
onClick: handleGeneratePrompt,
|
|
3414
3198
|
disabled: !selected || !instruction.trim() || isGeneratingPrompt,
|
|
3415
3199
|
className: "w-full py-3 rounded-xl bg-white/10 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-white/15 flex items-center justify-center gap-2",
|
|
3416
|
-
children: isGeneratingPrompt ? /* @__PURE__ */ jsxs16(
|
|
3200
|
+
children: isGeneratingPrompt ? /* @__PURE__ */ jsxs16(Fragment6, { children: [
|
|
3417
3201
|
/* @__PURE__ */ jsx18("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
|
|
3418
3202
|
/* @__PURE__ */ jsx18("span", { children: "Generiere Prompt..." })
|
|
3419
|
-
] }) : /* @__PURE__ */ jsxs16(
|
|
3203
|
+
] }) : /* @__PURE__ */ jsxs16(Fragment6, { children: [
|
|
3420
3204
|
/* @__PURE__ */ jsx18("span", { className: "material-symbols-outlined text-[16px]", children: "auto_fix_high" }),
|
|
3421
3205
|
/* @__PURE__ */ jsx18("span", { children: "Prompt generieren" })
|
|
3422
3206
|
] })
|
|
@@ -3463,7 +3247,7 @@ var LabRemix = ({ services, onResult }) => {
|
|
|
3463
3247
|
|
|
3464
3248
|
// src/components/labs/LabBlend.tsx
|
|
3465
3249
|
import { useState as useState16 } from "react";
|
|
3466
|
-
import { Fragment as
|
|
3250
|
+
import { Fragment as Fragment7, jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3467
3251
|
var LabBlend = ({ services, onResult }) => {
|
|
3468
3252
|
const [showPickerFor, setShowPickerFor] = useState16(null);
|
|
3469
3253
|
const [selectedImages, setSelectedImages] = useState16([]);
|
|
@@ -3558,7 +3342,7 @@ var LabBlend = ({ services, onResult }) => {
|
|
|
3558
3342
|
/* @__PURE__ */ jsx19("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40", children: "Bilder" }),
|
|
3559
3343
|
selectedImages.map((img, i) => /* @__PURE__ */ jsxs17("div", { className: "flex gap-3 p-3 rounded-xl border border-white/10 bg-white/5", children: [
|
|
3560
3344
|
/* @__PURE__ */ jsx19("span", { className: "text-[10px] font-bold text-white/40 w-6 shrink-0 pt-1", children: autoLabel(i) }),
|
|
3561
|
-
img ? /* @__PURE__ */ jsxs17(
|
|
3345
|
+
img ? /* @__PURE__ */ jsxs17(Fragment7, { children: [
|
|
3562
3346
|
/* @__PURE__ */ jsx19("img", { src: img.frame.base64, className: "w-12 h-12 object-cover rounded-lg shrink-0", onClick: () => setShowPickerFor(i) }),
|
|
3563
3347
|
/* @__PURE__ */ jsxs17("div", { className: "flex-1 min-w-0 flex flex-col gap-1", children: [
|
|
3564
3348
|
/* @__PURE__ */ jsx19("p", { className: "text-[10px] text-white/50 line-clamp-1", children: img.item.prompt }),
|
|
@@ -3624,10 +3408,10 @@ var LabBlend = ({ services, onResult }) => {
|
|
|
3624
3408
|
onClick: handleGeneratePrompt,
|
|
3625
3409
|
disabled: selectedImages.filter(Boolean).length < 2 || !instruction.trim() || isGeneratingPrompt,
|
|
3626
3410
|
className: "w-full py-3 rounded-xl bg-white/10 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-white/15 flex items-center justify-center gap-2",
|
|
3627
|
-
children: isGeneratingPrompt ? /* @__PURE__ */ jsxs17(
|
|
3411
|
+
children: isGeneratingPrompt ? /* @__PURE__ */ jsxs17(Fragment7, { children: [
|
|
3628
3412
|
/* @__PURE__ */ jsx19("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
|
|
3629
3413
|
/* @__PURE__ */ jsx19("span", { children: "Blend l\xE4uft..." })
|
|
3630
|
-
] }) : /* @__PURE__ */ jsxs17(
|
|
3414
|
+
] }) : /* @__PURE__ */ jsxs17(Fragment7, { children: [
|
|
3631
3415
|
/* @__PURE__ */ jsx19("span", { className: "material-symbols-outlined text-[16px]", children: "merge" }),
|
|
3632
3416
|
/* @__PURE__ */ jsx19("span", { children: "Prompts blenden" })
|
|
3633
3417
|
] })
|
|
@@ -3674,7 +3458,7 @@ var LabBlend = ({ services, onResult }) => {
|
|
|
3674
3458
|
|
|
3675
3459
|
// src/components/labs/LabCompare.tsx
|
|
3676
3460
|
import { useState as useState17 } from "react";
|
|
3677
|
-
import { Fragment as
|
|
3461
|
+
import { Fragment as Fragment8, jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3678
3462
|
var LabCompare = ({ services, onResult }) => {
|
|
3679
3463
|
const [showPickerFor, setShowPickerFor] = useState17(null);
|
|
3680
3464
|
const [selectedImages, setSelectedImages] = useState17([]);
|
|
@@ -3756,7 +3540,7 @@ var LabCompare = ({ services, onResult }) => {
|
|
|
3756
3540
|
/* @__PURE__ */ jsx20("p", { className: "text-[9px] font-bold uppercase tracking-widest text-white/40", children: "Bilder zum Vergleichen" }),
|
|
3757
3541
|
selectedImages.map((img, i) => /* @__PURE__ */ jsxs18("div", { className: "flex gap-3 p-3 rounded-xl border border-white/10 bg-white/5", children: [
|
|
3758
3542
|
/* @__PURE__ */ jsx20("span", { className: "text-[10px] font-bold text-white/40 w-6 shrink-0 pt-1", children: autoLabel(i) }),
|
|
3759
|
-
img ? /* @__PURE__ */ jsxs18(
|
|
3543
|
+
img ? /* @__PURE__ */ jsxs18(Fragment8, { children: [
|
|
3760
3544
|
/* @__PURE__ */ jsx20("img", { src: img.frame.base64, className: "w-12 h-12 object-cover rounded-lg shrink-0 cursor-pointer", onClick: () => setShowPickerFor(i) }),
|
|
3761
3545
|
/* @__PURE__ */ jsxs18("div", { className: "flex-1 min-w-0 flex flex-col gap-1", children: [
|
|
3762
3546
|
/* @__PURE__ */ jsx20("p", { className: "text-[10px] text-white/50 line-clamp-1", children: img.item.prompt }),
|
|
@@ -3800,10 +3584,10 @@ var LabCompare = ({ services, onResult }) => {
|
|
|
3800
3584
|
onClick: handleAnalyze,
|
|
3801
3585
|
disabled: selectedImages.filter(Boolean).length < 1 || !instruction.trim() || isAnalyzing,
|
|
3802
3586
|
className: "w-full py-3 rounded-xl bg-white/10 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-white/15 flex items-center justify-center gap-2",
|
|
3803
|
-
children: isAnalyzing ? /* @__PURE__ */ jsxs18(
|
|
3587
|
+
children: isAnalyzing ? /* @__PURE__ */ jsxs18(Fragment8, { children: [
|
|
3804
3588
|
/* @__PURE__ */ jsx20("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
|
|
3805
3589
|
/* @__PURE__ */ jsx20("span", { children: "Analysiere..." })
|
|
3806
|
-
] }) : /* @__PURE__ */ jsxs18(
|
|
3590
|
+
] }) : /* @__PURE__ */ jsxs18(Fragment8, { children: [
|
|
3807
3591
|
/* @__PURE__ */ jsx20("span", { className: "material-symbols-outlined text-[16px]", children: "compare" }),
|
|
3808
3592
|
/* @__PURE__ */ jsx20("span", { children: "Analysieren" })
|
|
3809
3593
|
] })
|
|
@@ -3830,10 +3614,10 @@ var LabCompare = ({ services, onResult }) => {
|
|
|
3830
3614
|
onClick: handleGenerateImage,
|
|
3831
3615
|
disabled: !generatedPrompt.trim() || isGeneratingImage,
|
|
3832
3616
|
className: "w-full mt-2 py-3 rounded-xl bg-blue-600/80 text-white font-bold text-[12px] uppercase tracking-wide disabled:opacity-30 active:bg-blue-600 flex items-center justify-center gap-2",
|
|
3833
|
-
children: isGeneratingImage ? /* @__PURE__ */ jsxs18(
|
|
3617
|
+
children: isGeneratingImage ? /* @__PURE__ */ jsxs18(Fragment8, { children: [
|
|
3834
3618
|
/* @__PURE__ */ jsx20("div", { className: "w-3 h-3 border-t border-white rounded-full animate-spin" }),
|
|
3835
3619
|
/* @__PURE__ */ jsx20("span", { children: "Generiere..." })
|
|
3836
|
-
] }) : /* @__PURE__ */ jsxs18(
|
|
3620
|
+
] }) : /* @__PURE__ */ jsxs18(Fragment8, { children: [
|
|
3837
3621
|
/* @__PURE__ */ jsx20("span", { className: "material-symbols-outlined text-[16px]", children: "image" }),
|
|
3838
3622
|
/* @__PURE__ */ jsx20("span", { children: "Bild generieren" })
|
|
3839
3623
|
] })
|
|
@@ -4017,7 +3801,7 @@ var LabLoop = ({ services, onResult }) => {
|
|
|
4017
3801
|
};
|
|
4018
3802
|
|
|
4019
3803
|
// src/components/labs/LabFrameExtractor.tsx
|
|
4020
|
-
import { useRef as
|
|
3804
|
+
import { useRef as useRef9, useState as useState19, useCallback as useCallback3 } from "react";
|
|
4021
3805
|
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4022
3806
|
var formatTime = (s) => {
|
|
4023
3807
|
const m = Math.floor(s / 60);
|
|
@@ -4031,9 +3815,9 @@ var LabFrameExtractor = ({
|
|
|
4031
3815
|
onResult,
|
|
4032
3816
|
resolveVideoUrl
|
|
4033
3817
|
}) => {
|
|
4034
|
-
const videoRef =
|
|
4035
|
-
const canvasRef =
|
|
4036
|
-
const cancelledRef =
|
|
3818
|
+
const videoRef = useRef9(null);
|
|
3819
|
+
const canvasRef = useRef9(null);
|
|
3820
|
+
const cancelledRef = useRef9(false);
|
|
4037
3821
|
const [selectedItem, setSelectedItem] = useState19(null);
|
|
4038
3822
|
const [videoSrc, setVideoSrc] = useState19(null);
|
|
4039
3823
|
const [videoReady, setVideoReady] = useState19(false);
|
|
@@ -5425,7 +5209,7 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
|
|
|
5425
5209
|
}
|
|
5426
5210
|
|
|
5427
5211
|
// src/components/ServerTab.tsx
|
|
5428
|
-
import { useState as useState23, useEffect as
|
|
5212
|
+
import { useState as useState23, useEffect as useEffect8 } from "react";
|
|
5429
5213
|
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
5430
5214
|
function StarRating({ rating = 0 }) {
|
|
5431
5215
|
return /* @__PURE__ */ jsx27("div", { className: "flex gap-[2px]", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsx27("span", { className: `material-symbols-outlined text-[12px] ${i <= rating ? "text-yellow-400" : "text-white/15"}`, children: "star" }, i)) });
|
|
@@ -5452,7 +5236,7 @@ function ServerTab({ serverBaseUrl }) {
|
|
|
5452
5236
|
const [libError, setLibError] = useState23(null);
|
|
5453
5237
|
const [activeTag, setActiveTag] = useState23(null);
|
|
5454
5238
|
const [preview, setPreview] = useState23(null);
|
|
5455
|
-
|
|
5239
|
+
useEffect8(() => {
|
|
5456
5240
|
if (!serverBaseUrl) return;
|
|
5457
5241
|
setUsersLoading(true);
|
|
5458
5242
|
setUsersError(null);
|
|
@@ -5604,7 +5388,7 @@ function ServerTab({ serverBaseUrl }) {
|
|
|
5604
5388
|
|
|
5605
5389
|
// src/components/FlowWorkspacePicker.tsx
|
|
5606
5390
|
import { useMemo as useMemo5, useState as useState24 } from "react";
|
|
5607
|
-
import { Fragment as
|
|
5391
|
+
import { Fragment as Fragment9, jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
5608
5392
|
function FlowWorkspacePicker({
|
|
5609
5393
|
tagBase,
|
|
5610
5394
|
selectedUserId,
|
|
@@ -5646,7 +5430,7 @@ function FlowWorkspacePicker({
|
|
|
5646
5430
|
tagBase.meta.version,
|
|
5647
5431
|
" enth\xE4lt keine Benutzer."
|
|
5648
5432
|
] })
|
|
5649
|
-
] }) : /* @__PURE__ */ jsxs26(
|
|
5433
|
+
] }) : /* @__PURE__ */ jsxs26(Fragment9, { children: [
|
|
5650
5434
|
/* @__PURE__ */ jsx28("button", { className: "flow-workspace-picker__back", type: "button", onClick: back, children: "\u2190 Anderen Benutzer w\xE4hlen" }),
|
|
5651
5435
|
/* @__PURE__ */ jsxs26("div", { className: "flow-workspace-picker__choices", "aria-label": "Kontext w\xE4hlen", children: [
|
|
5652
5436
|
contexts.map((context) => /* @__PURE__ */ jsxs26("button", { type: "button", onClick: () => onSelectContext(context.id), children: [
|
|
@@ -5725,9 +5509,9 @@ function resolveBootstrapTarget(input) {
|
|
|
5725
5509
|
}
|
|
5726
5510
|
|
|
5727
5511
|
// src/components/AvatarArchitectApp.tsx
|
|
5728
|
-
import { Fragment as
|
|
5729
|
-
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, requireWorkspaceSelection = false, serverBaseUrl
|
|
5730
|
-
|
|
5512
|
+
import { Fragment as Fragment10, jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
5513
|
+
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, requireWorkspaceSelection = false, serverBaseUrl }) {
|
|
5514
|
+
useEffect9(() => {
|
|
5731
5515
|
const id = "flow-styles";
|
|
5732
5516
|
if (!document.getElementById(id)) {
|
|
5733
5517
|
const style = document.createElement("style");
|
|
@@ -5745,10 +5529,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5745
5529
|
return null;
|
|
5746
5530
|
}
|
|
5747
5531
|
});
|
|
5748
|
-
const [projectLoaded, setProjectLoaded] = useState25(false);
|
|
5749
5532
|
const [hfToken, setHfToken] = useState25(initialHfToken || "");
|
|
5750
5533
|
const [hfTokenInput, setHfTokenInput] = useState25(initialHfToken || "");
|
|
5751
|
-
const [isLoadingFromHF, setIsLoadingFromHF] = useState25(false);
|
|
5752
5534
|
const [hfNamespaceLocal, setHfNamespaceLocal] = useState25(() => {
|
|
5753
5535
|
try {
|
|
5754
5536
|
return normalizeSelectableNamespace(localStorage.getItem("aa-hf-namespace"));
|
|
@@ -5758,7 +5540,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5758
5540
|
});
|
|
5759
5541
|
const [hfNamespaceFromServer, setHfNamespaceFromServer] = useState25(null);
|
|
5760
5542
|
const [serverProbeFailed, setServerProbeFailed] = useState25(false);
|
|
5761
|
-
|
|
5543
|
+
useEffect9(() => {
|
|
5762
5544
|
if (hfNamespace !== void 0 || !serverBaseUrl) return;
|
|
5763
5545
|
fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
5764
5546
|
if (typeof d.hfNamespace === "string" && d.hfNamespace) setHfNamespaceFromServer(d.hfNamespace);
|
|
@@ -5776,7 +5558,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5776
5558
|
isStartDialogOpen: isDialogTarget && !targetConfirmed
|
|
5777
5559
|
});
|
|
5778
5560
|
const effectiveNamespace = bootstrapTarget.namespace ?? "";
|
|
5779
|
-
const kontextRef =
|
|
5561
|
+
const kontextRef = useRef10(null);
|
|
5780
5562
|
const szenenPort = useMemo6(() => hfToken && effectiveNamespace ? createFlowSzenenViewPort({
|
|
5781
5563
|
generateText: onGeneratePrompt,
|
|
5782
5564
|
token: hfToken,
|
|
@@ -5803,7 +5585,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5803
5585
|
const [bootstrapLog, setBootstrapLog] = useState25([]);
|
|
5804
5586
|
const [isBootstrapping, setIsBootstrapping] = useState25(false);
|
|
5805
5587
|
const [hfMissingImages, setHfMissingImages] = useState25([]);
|
|
5806
|
-
const syncTopSlot = /* @__PURE__ */ jsxs27(
|
|
5588
|
+
const syncTopSlot = /* @__PURE__ */ jsxs27(Fragment10, { children: [
|
|
5807
5589
|
localOnlyCount > 0 && /* @__PURE__ */ jsxs27("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: [
|
|
5808
5590
|
"\u26A0 ",
|
|
5809
5591
|
localOnlyCount,
|
|
@@ -5852,7 +5634,6 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5852
5634
|
bootstrapLog.length > 0 && /* @__PURE__ */ jsx29("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ jsx29("div", { children: l }, i)) })
|
|
5853
5635
|
] })
|
|
5854
5636
|
] });
|
|
5855
|
-
const wsInputRef = useRef11(null);
|
|
5856
5637
|
const startApp = (choice) => {
|
|
5857
5638
|
try {
|
|
5858
5639
|
localStorage.setItem("aa-layout", choice);
|
|
@@ -5866,11 +5647,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5866
5647
|
const [edges, setEdges] = useState25([]);
|
|
5867
5648
|
const [history, setHistory] = useState25([]);
|
|
5868
5649
|
const [galleryItems, setGalleryItems] = useState25([]);
|
|
5869
|
-
const galleryItemsRef =
|
|
5870
|
-
|
|
5650
|
+
const galleryItemsRef = useRef10([]);
|
|
5651
|
+
useEffect9(() => {
|
|
5871
5652
|
galleryItemsRef.current = galleryItems;
|
|
5872
5653
|
}, [galleryItems]);
|
|
5873
|
-
const hfImageNotFoundRef =
|
|
5654
|
+
const hfImageNotFoundRef = useRef10(/* @__PURE__ */ new Map());
|
|
5874
5655
|
const [galleryVisibleCount, setGalleryVisibleCount] = useState25(20);
|
|
5875
5656
|
const [historyVisibleCount, setHistoryVisibleCount] = useState25(20);
|
|
5876
5657
|
const loadThumbnailsForEntries = useCallback4(async (entries) => {
|
|
@@ -5892,7 +5673,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5892
5673
|
}
|
|
5893
5674
|
}
|
|
5894
5675
|
}, [hfToken, effectiveNamespace]);
|
|
5895
|
-
|
|
5676
|
+
useEffect9(() => {
|
|
5896
5677
|
if (!hfState) return;
|
|
5897
5678
|
if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
|
|
5898
5679
|
const hfIds = new Set(hfState.metadata.map((m) => m.id));
|
|
@@ -5919,14 +5700,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5919
5700
|
return [...localOnly, ...merged].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5920
5701
|
});
|
|
5921
5702
|
}, [hfState]);
|
|
5922
|
-
|
|
5703
|
+
useEffect9(() => {
|
|
5923
5704
|
if (!hfState) return;
|
|
5924
5705
|
const sortedMeta = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5925
5706
|
const skeletons = sortedMeta.map((m) => ({ id: m.id, prompt: m.prompt, timestamp: m.timestamp, status: "done", nodeId: m.id, tags: m.tags || [] }));
|
|
5926
5707
|
const repIds = new Set(groupByPrompt(skeletons).slice(0, galleryVisibleCount).map((g) => g.representative.id));
|
|
5927
5708
|
loadThumbnailsForEntries(sortedMeta.filter((e) => repIds.has(e.id)));
|
|
5928
5709
|
}, [hfState, galleryVisibleCount, loadThumbnailsForEntries]);
|
|
5929
|
-
|
|
5710
|
+
useEffect9(() => {
|
|
5930
5711
|
if (!hfState) return;
|
|
5931
5712
|
const sortedMeta = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
5932
5713
|
loadThumbnailsForEntries(sortedMeta.slice(0, historyVisibleCount));
|
|
@@ -5987,11 +5768,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5987
5768
|
}
|
|
5988
5769
|
});
|
|
5989
5770
|
const [isPromptCollapsed, setIsPromptCollapsed] = useState25(false);
|
|
5990
|
-
const [projectActionState, setProjectActionState] = useState25("idle");
|
|
5991
|
-
const syncServerDataRef = useRef11(null);
|
|
5992
5771
|
const [workspaceTags, setWorkspaceTags] = useState25(null);
|
|
5993
|
-
const [serverProjects, setServerProjects] = useState25([]);
|
|
5994
|
-
const [isLoadingFromServer, setIsLoadingFromServer] = useState25(false);
|
|
5995
5772
|
const [highContrast, setHighContrast] = useState25(() => {
|
|
5996
5773
|
try {
|
|
5997
5774
|
return localStorage.getItem("aa-contrast") === "high";
|
|
@@ -6006,9 +5783,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6006
5783
|
const [isFullscreen, setIsFullscreen] = useState25(false);
|
|
6007
5784
|
const [zoomScale, setZoomScale] = useState25(1);
|
|
6008
5785
|
const [zoomOffset, setZoomOffset] = useState25({ x: 0, y: 0 });
|
|
6009
|
-
const lastPinchDist =
|
|
6010
|
-
const lastTapTime =
|
|
6011
|
-
const dragStart =
|
|
5786
|
+
const lastPinchDist = useRef10(null);
|
|
5787
|
+
const lastTapTime = useRef10(0);
|
|
5788
|
+
const dragStart = useRef10(null);
|
|
6012
5789
|
const openFullscreen = () => {
|
|
6013
5790
|
setIsFullscreen(true);
|
|
6014
5791
|
setZoomScale(1);
|
|
@@ -6186,7 +5963,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6186
5963
|
const group = groups.find((gr) => gr.prompt === currentResult.prompt);
|
|
6187
5964
|
return group ? group.items : [];
|
|
6188
5965
|
}, [galleryItems, currentResult?.prompt]);
|
|
6189
|
-
|
|
5966
|
+
useEffect9(() => {
|
|
6190
5967
|
if (!currentResult?.prompt || !hfToken || !effectiveNamespace || !hfState) return;
|
|
6191
5968
|
const siblings = galleryItemsRef.current.filter(
|
|
6192
5969
|
(g) => g.prompt === currentResult.prompt && !g.base64 && !hfImageNotFoundRef.current.has(g.id)
|
|
@@ -6439,51 +6216,6 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6439
6216
|
console.error("Download Error", e);
|
|
6440
6217
|
}
|
|
6441
6218
|
};
|
|
6442
|
-
const handleProjectExport = async () => {
|
|
6443
|
-
setProjectActionState("working-full");
|
|
6444
|
-
try {
|
|
6445
|
-
const { base64 } = await exportProjectToZip(nodes, edges, history, galleryItems, { aspectRatio, selectedModel, seed, seedMode }, workspaceTags, recentLabItems.map((i) => i.id));
|
|
6446
|
-
await onDownload(base64, "application/zip", `avatar_project_${getFormattedTimestamp()}.zip`);
|
|
6447
|
-
setProjectActionState("done");
|
|
6448
|
-
setTimeout(() => setProjectActionState("idle"), 3e3);
|
|
6449
|
-
} catch {
|
|
6450
|
-
setProjectActionState("error");
|
|
6451
|
-
}
|
|
6452
|
-
};
|
|
6453
|
-
const handleProjectImport = async (input) => {
|
|
6454
|
-
const file = input instanceof FileList ? input[0] : input;
|
|
6455
|
-
if (!file) return;
|
|
6456
|
-
setProjectActionState("working-full");
|
|
6457
|
-
try {
|
|
6458
|
-
const data = await importProjectFromZip(file);
|
|
6459
|
-
if (data.nodes) setNodes(data.nodes);
|
|
6460
|
-
if (data.edges) setEdges(data.edges);
|
|
6461
|
-
if (data.history) {
|
|
6462
|
-
setHistory(data.history);
|
|
6463
|
-
if (data.history.length > 0) setCurrentResult(data.history[0]);
|
|
6464
|
-
}
|
|
6465
|
-
if (data.galleryItems) setGalleryItems(data.galleryItems);
|
|
6466
|
-
if (data.settings) {
|
|
6467
|
-
setAspectRatio(data.settings.aspectRatio || "1:1");
|
|
6468
|
-
setSelectedModel(data.settings.selectedModel || "\u{1F34C} Nano Banana Pro");
|
|
6469
|
-
setSeed(data.settings.seed || 0);
|
|
6470
|
-
setSeedMode(data.settings.seedMode || "random");
|
|
6471
|
-
}
|
|
6472
|
-
if (data.workspaceTags?.by_category) setWorkspaceTags(data.workspaceTags);
|
|
6473
|
-
if (data.recentLabItemIds?.length) {
|
|
6474
|
-
const allGens = [...data.history || [], ...data.galleryItems || []];
|
|
6475
|
-
const labItems = groupGenerationsToLabItems(allGens);
|
|
6476
|
-
const recent = data.recentLabItemIds.map((id) => labItems.find((item) => item.id === id)).filter(Boolean);
|
|
6477
|
-
setRecentLabItems(recent);
|
|
6478
|
-
}
|
|
6479
|
-
setProjectActionState("done");
|
|
6480
|
-
setProjectLoaded(true);
|
|
6481
|
-
setTimeout(() => setProjectActionState("idle"), 2e3);
|
|
6482
|
-
} catch {
|
|
6483
|
-
setProjectActionState("error");
|
|
6484
|
-
setTimeout(() => setProjectActionState("idle"), 4e3);
|
|
6485
|
-
}
|
|
6486
|
-
};
|
|
6487
6219
|
const handleWorkspaceImport = (file) => {
|
|
6488
6220
|
const reader = new FileReader();
|
|
6489
6221
|
reader.onload = (ev) => {
|
|
@@ -6505,37 +6237,6 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6505
6237
|
};
|
|
6506
6238
|
reader.readAsText(file);
|
|
6507
6239
|
};
|
|
6508
|
-
const fetchServerProjects = async () => {
|
|
6509
|
-
if (!onFetchServerProjects) return;
|
|
6510
|
-
try {
|
|
6511
|
-
setServerProjects(await onFetchServerProjects());
|
|
6512
|
-
} catch {
|
|
6513
|
-
}
|
|
6514
|
-
};
|
|
6515
|
-
const handleServerSave = async (name) => {
|
|
6516
|
-
if (!onServerSave) return;
|
|
6517
|
-
setProjectActionState("working-full");
|
|
6518
|
-
try {
|
|
6519
|
-
const { base64 } = await exportProjectToZip(nodes, edges, history, galleryItems, { aspectRatio, selectedModel, seed, seedMode }, workspaceTags, recentLabItems.map((i) => i.id));
|
|
6520
|
-
await onServerSave(base64, name || `avatar_project_${getFormattedTimestamp()}`);
|
|
6521
|
-
await fetchServerProjects();
|
|
6522
|
-
setProjectActionState("done");
|
|
6523
|
-
setTimeout(() => setProjectActionState("idle"), 2e3);
|
|
6524
|
-
} catch {
|
|
6525
|
-
setProjectActionState("error");
|
|
6526
|
-
setTimeout(() => setProjectActionState("idle"), 4e3);
|
|
6527
|
-
}
|
|
6528
|
-
};
|
|
6529
|
-
const handleServerLoad = async (id) => {
|
|
6530
|
-
if (!onServerLoad) return;
|
|
6531
|
-
const file = await onServerLoad(id);
|
|
6532
|
-
await handleProjectImport(file);
|
|
6533
|
-
};
|
|
6534
|
-
const handleServerDelete = async (id) => {
|
|
6535
|
-
if (!onServerDelete) return;
|
|
6536
|
-
await onServerDelete(id);
|
|
6537
|
-
await fetchServerProjects();
|
|
6538
|
-
};
|
|
6539
6240
|
const handleHfInitialSync = async (onProgress) => {
|
|
6540
6241
|
if (!hfToken || !effectiveNamespace) return;
|
|
6541
6242
|
const existingIds = new Set((hfState?.metadata || []).map((m) => m.id));
|
|
@@ -6563,45 +6264,6 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6563
6264
|
onProgress(done, total);
|
|
6564
6265
|
}
|
|
6565
6266
|
};
|
|
6566
|
-
const handleComputeSyncDiff = async () => {
|
|
6567
|
-
if (!onFetchServerProjects || !onServerLoad) throw new Error("Server nicht konfiguriert");
|
|
6568
|
-
const projects = await onFetchServerProjects();
|
|
6569
|
-
if (projects.length === 0) return { localOnly: [...history], serverOnly: [] };
|
|
6570
|
-
const file = await onServerLoad(projects[0].id);
|
|
6571
|
-
const serverData = await importProjectFromZip(file);
|
|
6572
|
-
syncServerDataRef.current = serverData;
|
|
6573
|
-
const localOnly = history.filter((h) => !(serverData.history || []).find((s) => s.id === h.id));
|
|
6574
|
-
const serverOnly = (serverData.history || []).filter((s) => !history.find((h) => h.id === s.id));
|
|
6575
|
-
return { localOnly, serverOnly };
|
|
6576
|
-
};
|
|
6577
|
-
const handleExecuteSync = async (selectedLocalIds) => {
|
|
6578
|
-
const serverData = syncServerDataRef.current;
|
|
6579
|
-
if (!serverData || !onServerSave) return;
|
|
6580
|
-
setProjectActionState("working-full");
|
|
6581
|
-
try {
|
|
6582
|
-
const selectedLocal = history.filter((h) => selectedLocalIds.includes(h.id));
|
|
6583
|
-
const mergedHistory = [...serverData.history || [], ...selectedLocal];
|
|
6584
|
-
const { base64 } = await exportProjectToZip(
|
|
6585
|
-
serverData.nodes || nodes,
|
|
6586
|
-
serverData.edges || edges,
|
|
6587
|
-
mergedHistory,
|
|
6588
|
-
serverData.galleryItems || galleryItems,
|
|
6589
|
-
serverData.settings || { aspectRatio, selectedModel, seed, seedMode },
|
|
6590
|
-
serverData.workspaceTags || workspaceTags,
|
|
6591
|
-
serverData.recentLabItemIds || recentLabItems.map((i) => i.id)
|
|
6592
|
-
);
|
|
6593
|
-
await onServerSave(base64, `sync_${getFormattedTimestamp()}`);
|
|
6594
|
-
await fetchServerProjects();
|
|
6595
|
-
setProjectActionState("done");
|
|
6596
|
-
setTimeout(() => setProjectActionState("idle"), 2e3);
|
|
6597
|
-
} catch {
|
|
6598
|
-
setProjectActionState("error");
|
|
6599
|
-
setTimeout(() => setProjectActionState("idle"), 4e3);
|
|
6600
|
-
}
|
|
6601
|
-
};
|
|
6602
|
-
useEffect10(() => {
|
|
6603
|
-
if (activeTab === "setup" || activeTab === "sync") fetchServerProjects();
|
|
6604
|
-
}, [activeTab]);
|
|
6605
6267
|
const mergeWorkspaceTags = (local, remote) => {
|
|
6606
6268
|
if (!remote?.by_category) return local;
|
|
6607
6269
|
const merged = {};
|
|
@@ -6654,7 +6316,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6654
6316
|
setZoomScale(1);
|
|
6655
6317
|
setZoomOffset({ x: 0, y: 0 });
|
|
6656
6318
|
}, className: "absolute top-4 left-4 w-10 h-10 flex items-center justify-center rounded-full bg-black/70 border border-white/20 z-10", children: /* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined text-[20px]", children: "zoom_out_map" }) }),
|
|
6657
|
-
history.length > 1 && /* @__PURE__ */ jsxs27(
|
|
6319
|
+
history.length > 1 && /* @__PURE__ */ jsxs27(Fragment10, { children: [
|
|
6658
6320
|
/* @__PURE__ */ jsx29("button", { onClick: () => {
|
|
6659
6321
|
if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
|
|
6660
6322
|
}, disabled: currentIndex <= 0, className: "absolute left-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0", children: /* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
|
|
@@ -6692,11 +6354,6 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6692
6354
|
}
|
|
6693
6355
|
if (showStart) {
|
|
6694
6356
|
return /* @__PURE__ */ jsxs27("div", { className: "fixed inset-0 bg-[#0e0e0e] flex flex-col items-center justify-center p-6", style: { gap: 28, ...hcStyle }, children: [
|
|
6695
|
-
/* @__PURE__ */ jsx29("input", { ref: wsInputRef, type: "file", accept: ".zip", className: "hidden", onChange: (e) => {
|
|
6696
|
-
const f = e.target.files?.[0];
|
|
6697
|
-
if (f) handleProjectImport(f);
|
|
6698
|
-
e.target.value = "";
|
|
6699
|
-
} }),
|
|
6700
6357
|
/* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-center gap-1", children: [
|
|
6701
6358
|
/* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined text-white/15 text-[44px]", children: "palette" }),
|
|
6702
6359
|
/* @__PURE__ */ jsx29("span", { className: "text-white/25 text-[10px] font-bold uppercase tracking-[0.25em]", children: "Avatar Architect" }),
|
|
@@ -6720,21 +6377,6 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6720
6377
|
]
|
|
6721
6378
|
}
|
|
6722
6379
|
),
|
|
6723
|
-
/* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
|
|
6724
|
-
/* @__PURE__ */ jsxs27(
|
|
6725
|
-
"button",
|
|
6726
|
-
{
|
|
6727
|
-
onClick: () => wsInputRef.current?.click(),
|
|
6728
|
-
className: "w-full flex items-center justify-center gap-3 rounded-2xl font-bold text-[14px] uppercase tracking-wide text-white active:scale-95 transition-transform",
|
|
6729
|
-
style: { height: 56, background: projectLoaded ? "#16a34a" : "#0284c7" },
|
|
6730
|
-
children: [
|
|
6731
|
-
/* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined text-[22px]", children: projectLoaded ? "check_circle" : "folder_zip" }),
|
|
6732
|
-
projectLoaded ? "Projekt geladen \u2713" : "Projekt laden (.zip)"
|
|
6733
|
-
]
|
|
6734
|
-
}
|
|
6735
|
-
),
|
|
6736
|
-
!projectLoaded && /* @__PURE__ */ jsx29("span", { className: "text-white/20 text-[10px] text-center", children: "Baum, Bilder und Einstellungen wiederherstellen" })
|
|
6737
|
-
] }),
|
|
6738
6380
|
/* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
|
|
6739
6381
|
!initialHfToken && /* @__PURE__ */ jsxs27("div", { className: "flex gap-2 w-full", children: [
|
|
6740
6382
|
/* @__PURE__ */ jsx29(
|
|
@@ -6785,64 +6427,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
6785
6427
|
},
|
|
6786
6428
|
ns
|
|
6787
6429
|
))
|
|
6788
|
-
] })
|
|
6789
|
-
hfToken && /* @__PURE__ */ jsxs27(
|
|
6790
|
-
"button",
|
|
6791
|
-
{
|
|
6792
|
-
disabled: isLoadingFromHF,
|
|
6793
|
-
onClick: async () => {
|
|
6794
|
-
setIsLoadingFromHF(true);
|
|
6795
|
-
try {
|
|
6796
|
-
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-W7KO2FOH.mjs");
|
|
6797
|
-
const projects = await hfListProjects2(hfToken);
|
|
6798
|
-
if (projects.length > 0) {
|
|
6799
|
-
const file = await hfDownloadProject2(projects[0].path, hfToken);
|
|
6800
|
-
await handleProjectImport(file);
|
|
6801
|
-
}
|
|
6802
|
-
} catch (e) {
|
|
6803
|
-
alert("HF Fehler: " + e.message);
|
|
6804
|
-
} finally {
|
|
6805
|
-
setIsLoadingFromHF(false);
|
|
6806
|
-
}
|
|
6807
|
-
},
|
|
6808
|
-
className: "w-full flex items-center justify-center gap-3 rounded-2xl font-bold text-[14px] uppercase tracking-wide text-white active:scale-95 transition-transform disabled:opacity-50",
|
|
6809
|
-
style: { height: 56, background: "#f59e0b" },
|
|
6810
|
-
children: [
|
|
6811
|
-
/* @__PURE__ */ jsx29("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromHF ? " animate-spin" : ""}`, children: isLoadingFromHF ? "sync" : "cloud_download" }),
|
|
6812
|
-
isLoadingFromHF ? "Laden\u2026" : "Von HF laden"
|
|
6813
|
-
]
|
|
6814
|
-
}
|
|
6815
|
-
),
|
|
6816
|
-
hfToken && /* @__PURE__ */ jsx29("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand von Hugging Face laden" })
|
|
6817
|
-
] }),
|
|
6818
|
-
onFetchServerProjects && /* @__PURE__ */ jsxs27("div", { className: "flex flex-col items-center gap-2 w-full max-w-[280px]", children: [
|
|
6819
|
-
/* @__PURE__ */ jsxs27(
|
|
6820
|
-
"button",
|
|
6821
|
-
{
|
|
6822
|
-
disabled: isLoadingFromServer,
|
|
6823
|
-
onClick: async () => {
|
|
6824
|
-
setIsLoadingFromServer(true);
|
|
6825
|
-
try {
|
|
6826
|
-
const projects = await onFetchServerProjects();
|
|
6827
|
-
setServerProjects(projects);
|
|
6828
|
-
if (projects.length > 0 && onServerLoad) {
|
|
6829
|
-
const file = await onServerLoad(projects[0].id);
|
|
6830
|
-
await handleProjectImport(file);
|
|
6831
|
-
}
|
|
6832
|
-
} catch {
|
|
6833
|
-
} finally {
|
|
6834
|
-
setIsLoadingFromServer(false);
|
|
6835
|
-
}
|
|
6836
|
-
},
|
|
6837
|
-
className: "w-full flex items-center justify-center gap-3 rounded-2xl font-bold text-[14px] uppercase tracking-wide text-white active:scale-95 transition-transform disabled:opacity-50",
|
|
6838
|
-
style: { height: 56, background: "#7c3aed" },
|
|
6839
|
-
children: [
|
|
6840
|
-
/* @__PURE__ */ jsx29("span", { className: `material-symbols-outlined text-[22px]${isLoadingFromServer ? " animate-spin" : ""}`, children: isLoadingFromServer ? "sync" : "cloud_download" }),
|
|
6841
|
-
isLoadingFromServer ? "Laden\u2026" : "Vom Server laden"
|
|
6842
|
-
]
|
|
6843
|
-
}
|
|
6844
|
-
),
|
|
6845
|
-
/* @__PURE__ */ jsx29("span", { className: "text-white/20 text-[10px] text-center", children: "Letzten Stand vom Server wiederherstellen" })
|
|
6430
|
+
] })
|
|
6846
6431
|
] }),
|
|
6847
6432
|
/* @__PURE__ */ jsxs27("div", { className: "flow-szenen-entry", children: [
|
|
6848
6433
|
/* @__PURE__ */ jsxs27(
|
|
@@ -7029,7 +6614,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
7029
6614
|
/* @__PURE__ */ jsx29("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
7030
6615
|
] }),
|
|
7031
6616
|
currentResult?.status === "done" && /* @__PURE__ */ jsx29("button", { onClick: openFullscreen, className: "absolute top-2 right-2 w-8 h-8 flex items-center justify-center rounded-full bg-black/60 border border-white/10 z-10", children: /* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined text-[18px]", children: "fullscreen" }) }),
|
|
7032
|
-
history.length > 1 && currentResult && /* @__PURE__ */ jsxs27(
|
|
6617
|
+
history.length > 1 && currentResult && /* @__PURE__ */ jsxs27(Fragment10, { children: [
|
|
7033
6618
|
/* @__PURE__ */ jsx29("button", { onClick: goToPrev, disabled: currentIndex <= 0, className: "absolute left-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0 transition-opacity", children: /* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_left" }) }),
|
|
7034
6619
|
/* @__PURE__ */ jsx29("button", { onClick: goToNext, disabled: currentIndex >= history.length - 1, className: "absolute right-2 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center rounded-full bg-black/60 border border-white/10 disabled:opacity-0 transition-opacity", children: /* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined text-[22px]", children: "chevron_right" }) }),
|
|
7035
6620
|
/* @__PURE__ */ jsxs27("div", { className: "absolute bottom-2 left-1/2 -translate-x-1/2 bg-black/60 rounded-full px-3 py-0.5 text-[10px] text-white/40 font-mono", children: [
|
|
@@ -7200,26 +6785,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
7200
6785
|
}, onTagCreate: handleTagCreate, onTagUpdate: handleTagUpdate, onTagDelete: handleTagDelete, onScanImage: handleScanImage, isScanning: isScanningImage }) }),
|
|
7201
6786
|
activeTab === "setup" && /* @__PURE__ */ jsx29(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo, tagBase: tagBaseResult }),
|
|
7202
6787
|
activeTab === "sync" && /* @__PURE__ */ jsx29(
|
|
7203
|
-
|
|
6788
|
+
HfMediaSyncTab,
|
|
7204
6789
|
{
|
|
7205
6790
|
topSlot: syncTopSlot,
|
|
7206
|
-
onProjectExport: handleProjectExport,
|
|
7207
|
-
onProjectImport: (f) => handleProjectImport(f),
|
|
7208
|
-
onWorkspaceImport: handleWorkspaceImport,
|
|
7209
|
-
projectActionState,
|
|
7210
|
-
serverProjects: onFetchServerProjects ? serverProjects : void 0,
|
|
7211
|
-
onServerSave: onServerSave ? handleServerSave : void 0,
|
|
7212
|
-
onServerLoad: onServerLoad ? handleServerLoad : void 0,
|
|
7213
|
-
onServerDelete: onServerDelete ? handleServerDelete : void 0,
|
|
7214
|
-
onRefreshServerProjects: onFetchServerProjects ? fetchServerProjects : void 0,
|
|
7215
|
-
onComputeSyncDiff: onFetchServerProjects && onServerLoad && onServerSave ? handleComputeSyncDiff : void 0,
|
|
7216
|
-
onExecuteSync: onFetchServerProjects && onServerLoad && onServerSave ? handleExecuteSync : void 0,
|
|
7217
|
-
hfToken: hfToken || void 0,
|
|
7218
|
-
onHfLoad: (f) => handleProjectImport(f),
|
|
7219
|
-
onProjectExportBase64: async () => {
|
|
7220
|
-
const { base64 } = await exportProjectToZip(nodes, edges, history, galleryItems, { aspectRatio, selectedModel, seed, seedMode }, workspaceTags, recentLabItems.map((i) => i.id));
|
|
7221
|
-
return base64;
|
|
7222
|
-
},
|
|
7223
6791
|
onHfInitialSync: hfToken ? handleHfInitialSync : void 0
|
|
7224
6792
|
}
|
|
7225
6793
|
),
|
|
@@ -7338,7 +6906,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
7338
6906
|
/* @__PURE__ */ jsx29("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
|
|
7339
6907
|
] }),
|
|
7340
6908
|
currentResult?.status === "done" && /* @__PURE__ */ jsx29("button", { onClick: openFullscreen, style: { position: "absolute", top: 8, right: 8, width: 32, height: 32, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff" }, children: /* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined", style: { fontSize: 18 }, children: "fullscreen" }) }),
|
|
7341
|
-
history.length > 1 && currentResult && /* @__PURE__ */ jsxs27(
|
|
6909
|
+
history.length > 1 && currentResult && /* @__PURE__ */ jsxs27(Fragment10, { children: [
|
|
7342
6910
|
/* @__PURE__ */ jsx29("button", { onClick: goToPrev, disabled: currentIndex <= 0, style: { position: "absolute", left: 8, top: "50%", transform: "translateY(-50%)", width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff", opacity: currentIndex <= 0 ? 0 : 1, transition: "opacity 0.2s" }, children: /* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_left" }) }),
|
|
7343
6911
|
/* @__PURE__ */ jsx29("button", { onClick: goToNext, disabled: currentIndex >= history.length - 1, style: { position: "absolute", right: 8, top: "50%", transform: "translateY(-50%)", width: 36, height: 36, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "1px solid rgba(255,255,255,0.1)", cursor: "pointer", color: "#fff", opacity: currentIndex >= history.length - 1 ? 0 : 1, transition: "opacity 0.2s" }, children: /* @__PURE__ */ jsx29("span", { className: "material-symbols-outlined", style: { fontSize: 20 }, children: "chevron_right" }) }),
|
|
7344
6912
|
/* @__PURE__ */ jsxs27("div", { style: { position: "absolute", bottom: 8, left: "50%", transform: "translateX(-50%)", background: "rgba(0,0,0,0.6)", borderRadius: 999, padding: "2px 12px", fontSize: 10, color: "rgba(255,255,255,0.4)", fontFamily: "monospace" }, children: [
|
|
@@ -7601,26 +7169,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
7601
7169
|
activeTab === "inspect" && /* @__PURE__ */ jsx29(InspectPanel, { currentResult, history, onSelect: setCurrentResult }),
|
|
7602
7170
|
activeTab === "setup" && /* @__PURE__ */ jsx29(SetupPanel, { onWorkspaceImport: handleWorkspaceImport, buildInfo, tagBase: tagBaseResult }),
|
|
7603
7171
|
activeTab === "sync" && /* @__PURE__ */ jsx29(
|
|
7604
|
-
|
|
7172
|
+
HfMediaSyncTab,
|
|
7605
7173
|
{
|
|
7606
7174
|
topSlot: syncTopSlot,
|
|
7607
|
-
onProjectExport: handleProjectExport,
|
|
7608
|
-
onProjectImport: (f) => handleProjectImport(f),
|
|
7609
|
-
onWorkspaceImport: handleWorkspaceImport,
|
|
7610
|
-
projectActionState,
|
|
7611
|
-
serverProjects: onFetchServerProjects ? serverProjects : void 0,
|
|
7612
|
-
onServerSave: onServerSave ? handleServerSave : void 0,
|
|
7613
|
-
onServerLoad: onServerLoad ? handleServerLoad : void 0,
|
|
7614
|
-
onServerDelete: onServerDelete ? handleServerDelete : void 0,
|
|
7615
|
-
onRefreshServerProjects: onFetchServerProjects ? fetchServerProjects : void 0,
|
|
7616
|
-
onComputeSyncDiff: onFetchServerProjects && onServerLoad && onServerSave ? handleComputeSyncDiff : void 0,
|
|
7617
|
-
onExecuteSync: onFetchServerProjects && onServerLoad && onServerSave ? handleExecuteSync : void 0,
|
|
7618
|
-
hfToken: hfToken || void 0,
|
|
7619
|
-
onHfLoad: (f) => handleProjectImport(f),
|
|
7620
|
-
onProjectExportBase64: async () => {
|
|
7621
|
-
const { base64 } = await import("./project-O4ORKXY5.mjs").then((m) => m.exportProjectToZip(nodes, edges, history, galleryItems, { aspectRatio, selectedModel, seed, seedMode }, workspaceTags, recentLabItems.map((i) => i.id)));
|
|
7622
|
-
return base64;
|
|
7623
|
-
},
|
|
7624
7175
|
onHfInitialSync: hfToken ? handleHfInitialSync : void 0
|
|
7625
7176
|
}
|
|
7626
7177
|
),
|
|
@@ -7631,7 +7182,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
7631
7182
|
}
|
|
7632
7183
|
|
|
7633
7184
|
// src/components/FaApp.tsx
|
|
7634
|
-
import { useState as useState26, useEffect as
|
|
7185
|
+
import { useState as useState26, useEffect as useEffect10, useMemo as useMemo7 } from "react";
|
|
7635
7186
|
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
7636
7187
|
function FaApp({
|
|
7637
7188
|
onGenerateImage,
|
|
@@ -7645,14 +7196,10 @@ function FaApp({
|
|
|
7645
7196
|
libToken,
|
|
7646
7197
|
allowDevNamespace,
|
|
7647
7198
|
serverBaseUrl,
|
|
7648
|
-
onFetchServerProjects,
|
|
7649
|
-
onServerSave,
|
|
7650
|
-
onServerLoad,
|
|
7651
|
-
onServerDelete,
|
|
7652
7199
|
buildInfo
|
|
7653
7200
|
}) {
|
|
7654
7201
|
const [hfNamespace, setHfNamespace] = useState26(void 0);
|
|
7655
|
-
|
|
7202
|
+
useEffect10(() => {
|
|
7656
7203
|
if (!serverBaseUrl) return;
|
|
7657
7204
|
fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
7658
7205
|
if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
|
|
@@ -7675,10 +7222,6 @@ function FaApp({
|
|
|
7675
7222
|
allowDevNamespace: !hfNamespace && allowDevNamespace,
|
|
7676
7223
|
requireWorkspaceSelection: true,
|
|
7677
7224
|
serverBaseUrl,
|
|
7678
|
-
onFetchServerProjects,
|
|
7679
|
-
onServerSave,
|
|
7680
|
-
onServerLoad,
|
|
7681
|
-
onServerDelete,
|
|
7682
7225
|
buildInfo
|
|
7683
7226
|
}
|
|
7684
7227
|
);
|
|
@@ -8252,6 +7795,7 @@ export {
|
|
|
8252
7795
|
FaToolsBadge,
|
|
8253
7796
|
FlowWorkspacePicker,
|
|
8254
7797
|
GLOBAL_STYLES,
|
|
7798
|
+
HfMediaSyncTab,
|
|
8255
7799
|
HistoryPanel,
|
|
8256
7800
|
InspectPanel,
|
|
8257
7801
|
LIBRARY_CUTOVER_MARKER,
|
|
@@ -8268,7 +7812,6 @@ export {
|
|
|
8268
7812
|
ListView,
|
|
8269
7813
|
MediaLibrary,
|
|
8270
7814
|
PillButton,
|
|
8271
|
-
ProjectSyncTab,
|
|
8272
7815
|
PromptTab,
|
|
8273
7816
|
SCOPE_MAP,
|
|
8274
7817
|
SectionLabel,
|
|
@@ -8302,7 +7845,6 @@ export {
|
|
|
8302
7845
|
createTagsDefault,
|
|
8303
7846
|
deriveTagBaseWorkspaceTags,
|
|
8304
7847
|
deriveTagViewModel,
|
|
8305
|
-
exportProjectToZip,
|
|
8306
7848
|
formatTreeToMarkdown,
|
|
8307
7849
|
frameToGeneration,
|
|
8308
7850
|
getFormattedTimestamp,
|
|
@@ -8311,15 +7853,10 @@ export {
|
|
|
8311
7853
|
groupGenerationsToLabItems,
|
|
8312
7854
|
hfBatchArchive,
|
|
8313
7855
|
hfBootstrapFromLegacy,
|
|
8314
|
-
hfDeleteProject,
|
|
8315
|
-
hfDownloadProject,
|
|
8316
7856
|
hfListDir,
|
|
8317
|
-
hfListProjects,
|
|
8318
7857
|
hfLoadImageAsBase64,
|
|
8319
7858
|
hfUploadImage,
|
|
8320
|
-
hfUploadProjectForm,
|
|
8321
7859
|
hfUploadSmallFile,
|
|
8322
|
-
importProjectFromZip,
|
|
8323
7860
|
injectXMPMetadata,
|
|
8324
7861
|
interpretSdkError,
|
|
8325
7862
|
libraryContract,
|