@rslsp1/fa-app-tools 1.3.16 → 2.0.12
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-WCFXXLKN.mjs +409 -0
- package/dist/hfStateService-6YYT6ATO.mjs +54 -0
- package/dist/index.d.mts +103 -9
- package/dist/index.d.ts +103 -9
- package/dist/index.js +811 -298
- package/dist/index.mjs +574 -252
- package/package.json +5 -4
- package/dist/chunk-X6S5BP36.mjs +0 -232
- package/dist/hfStateService-B62RV5K3.mjs +0 -32
package/dist/index.mjs
CHANGED
|
@@ -5,18 +5,23 @@ import {
|
|
|
5
5
|
} from "./chunk-UFXDXENC.mjs";
|
|
6
6
|
import {
|
|
7
7
|
getHFToken,
|
|
8
|
+
getSessionClientId,
|
|
9
|
+
hfBatchArchive,
|
|
10
|
+
hfBootstrapFromLegacy,
|
|
8
11
|
hfDeleteProject,
|
|
9
12
|
hfDownloadProject,
|
|
13
|
+
hfListDir,
|
|
10
14
|
hfListProjects,
|
|
11
15
|
hfLoadImageAsBase64,
|
|
12
|
-
hfLoadMetadata,
|
|
13
|
-
hfLoadTags,
|
|
14
|
-
hfSaveMetadata,
|
|
15
|
-
hfSaveTags,
|
|
16
16
|
hfUploadImage,
|
|
17
17
|
hfUploadProjectForm,
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
hfUploadSmallFile,
|
|
19
|
+
loadHFState,
|
|
20
|
+
loadPendingEvents,
|
|
21
|
+
setHFToken,
|
|
22
|
+
tsFromEventPath,
|
|
23
|
+
writeHFEvent
|
|
24
|
+
} from "./chunk-WCFXXLKN.mjs";
|
|
20
25
|
|
|
21
26
|
// src/hooks/useOnClickOutside.ts
|
|
22
27
|
import { useEffect } from "react";
|
|
@@ -793,7 +798,7 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
|
|
|
793
798
|
}
|
|
794
799
|
|
|
795
800
|
// src/components/AvatarArchitectApp.tsx
|
|
796
|
-
import { useState as
|
|
801
|
+
import { useState as useState15, useCallback as useCallback2, useMemo as useMemo2, useEffect as useEffect6, useRef as useRef7 } from "react";
|
|
797
802
|
|
|
798
803
|
// src/components/PromptTab.tsx
|
|
799
804
|
import { useRef as useRef4, useState as useState5 } from "react";
|
|
@@ -1320,6 +1325,7 @@ var PromptTab = ({
|
|
|
1320
1325
|
import { useRef as useRef5, useState as useState6, useEffect as useEffect4 } from "react";
|
|
1321
1326
|
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1322
1327
|
var ProjectSyncTab = ({
|
|
1328
|
+
topSlot,
|
|
1323
1329
|
onProjectExport,
|
|
1324
1330
|
onProjectImport,
|
|
1325
1331
|
onWorkspaceImport,
|
|
@@ -1411,6 +1417,7 @@ var ProjectSyncTab = ({
|
|
|
1411
1417
|
if (hfToken) loadHfProjects(hfToken);
|
|
1412
1418
|
}, [hfToken]);
|
|
1413
1419
|
return /* @__PURE__ */ jsx12("div", { className: "absolute inset-0 overflow-y-auto dark-scrollbar", children: /* @__PURE__ */ jsxs10("div", { className: "p-6 flex flex-col gap-8", children: [
|
|
1420
|
+
topSlot && /* @__PURE__ */ jsx12("div", { children: topSlot }),
|
|
1414
1421
|
(onProjectExport || onProjectImport || onWorkspaceImport) && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-4", children: [
|
|
1415
1422
|
/* @__PURE__ */ jsx12(SectionLabel, { children: "Projekt-ZIP" }),
|
|
1416
1423
|
/* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-2", children: [
|
|
@@ -1591,7 +1598,7 @@ var ProjectSyncTab = ({
|
|
|
1591
1598
|
{
|
|
1592
1599
|
onClick: async () => {
|
|
1593
1600
|
try {
|
|
1594
|
-
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-
|
|
1601
|
+
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-6YYT6ATO.mjs");
|
|
1595
1602
|
const file = await hfDownloadProject2(p.path, hfToken);
|
|
1596
1603
|
onHfLoad(file);
|
|
1597
1604
|
} catch (e) {
|
|
@@ -1812,14 +1819,254 @@ function toPromptImages(images) {
|
|
|
1812
1819
|
});
|
|
1813
1820
|
}
|
|
1814
1821
|
|
|
1822
|
+
// src/hooks/useHFState.ts
|
|
1823
|
+
import { useState as useState7, useEffect as useEffect5, useRef as useRef6, useCallback } from "react";
|
|
1824
|
+
|
|
1825
|
+
// src/lib/hfReducer.ts
|
|
1826
|
+
function applyEvent(state, event) {
|
|
1827
|
+
if (event.v.major > 1) return state;
|
|
1828
|
+
switch (event.type) {
|
|
1829
|
+
case "image_added": {
|
|
1830
|
+
const p = event.payload;
|
|
1831
|
+
if (state.metadata.some((m) => m.id === p.id)) return state;
|
|
1832
|
+
return { ...state, metadata: [...state.metadata, p] };
|
|
1833
|
+
}
|
|
1834
|
+
case "tag_upserted": {
|
|
1835
|
+
const p = event.payload;
|
|
1836
|
+
const tags = state.tags;
|
|
1837
|
+
const cat = tags.by_category[p.category] || [];
|
|
1838
|
+
const existing = cat.find((t) => t.value === p.value);
|
|
1839
|
+
const updated = { label: p.label, value: p.value, is_user_created: p.is_user_created, is_deleted: p.is_deleted };
|
|
1840
|
+
const newCat = existing ? cat.map((t) => t.value === p.value ? { ...t, ...updated } : t) : [...cat, updated];
|
|
1841
|
+
const newAll = tags.all.some((t) => t.value === p.value && t.category === p.category) ? tags.all.map((t) => t.value === p.value && t.category === p.category ? { ...t, ...updated, category: p.category } : t) : [...tags.all, { ...updated, category: p.category }];
|
|
1842
|
+
return { ...state, tags: { by_category: { ...tags.by_category, [p.category]: newCat }, all: newAll } };
|
|
1843
|
+
}
|
|
1844
|
+
case "metadata_updated": {
|
|
1845
|
+
const p = event.payload;
|
|
1846
|
+
return {
|
|
1847
|
+
...state,
|
|
1848
|
+
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, ...p.delta } : m)
|
|
1849
|
+
};
|
|
1850
|
+
}
|
|
1851
|
+
default:
|
|
1852
|
+
return state;
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
function applyEvents(state, events) {
|
|
1856
|
+
return events.reduce(applyEvent, state);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
// src/lib/hfDag.ts
|
|
1860
|
+
function buildDag(events) {
|
|
1861
|
+
const dag = /* @__PURE__ */ new Map();
|
|
1862
|
+
for (const event of events) {
|
|
1863
|
+
dag.set(event.ts, { event, children: [] });
|
|
1864
|
+
}
|
|
1865
|
+
for (const event of events) {
|
|
1866
|
+
for (const parent of event.prevTs) {
|
|
1867
|
+
const node = dag.get(parent);
|
|
1868
|
+
if (node && !node.children.includes(event.ts)) {
|
|
1869
|
+
node.children.push(event.ts);
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
return dag;
|
|
1874
|
+
}
|
|
1875
|
+
function findTips(dag) {
|
|
1876
|
+
return [...dag.values()].filter((n) => n.children.length === 0).map((n) => n.event.ts);
|
|
1877
|
+
}
|
|
1878
|
+
function findForks(dag) {
|
|
1879
|
+
const forks = [];
|
|
1880
|
+
for (const [ts, node] of dag) {
|
|
1881
|
+
if (node.children.length > 1) {
|
|
1882
|
+
forks.push({ parentTs: ts, childTs: node.children });
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
return forks;
|
|
1886
|
+
}
|
|
1887
|
+
function topoSort(events) {
|
|
1888
|
+
if (!events.length) return [];
|
|
1889
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
1890
|
+
const children = /* @__PURE__ */ new Map();
|
|
1891
|
+
const tsSet = new Set(events.map((e) => e.ts));
|
|
1892
|
+
for (const e of events) {
|
|
1893
|
+
inDegree.set(e.ts, 0);
|
|
1894
|
+
children.set(e.ts, []);
|
|
1895
|
+
}
|
|
1896
|
+
for (const e of events) {
|
|
1897
|
+
for (const p of e.prevTs) {
|
|
1898
|
+
if (tsSet.has(p)) {
|
|
1899
|
+
children.get(p).push(e.ts);
|
|
1900
|
+
inDegree.set(e.ts, (inDegree.get(e.ts) || 0) + 1);
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1904
|
+
const queue = events.filter((e) => (inDegree.get(e.ts) || 0) === 0).sort((a, b) => a.ts - b.ts);
|
|
1905
|
+
const result = [];
|
|
1906
|
+
const byTs = new Map(events.map((e) => [e.ts, e]));
|
|
1907
|
+
while (queue.length) {
|
|
1908
|
+
const node = queue.shift();
|
|
1909
|
+
result.push(node);
|
|
1910
|
+
for (const childTs of children.get(node.ts) || []) {
|
|
1911
|
+
const newDeg = (inDegree.get(childTs) || 0) - 1;
|
|
1912
|
+
inDegree.set(childTs, newDeg);
|
|
1913
|
+
if (newDeg === 0) {
|
|
1914
|
+
const child = byTs.get(childTs);
|
|
1915
|
+
const insertAt = queue.findIndex((q) => q.ts > child.ts);
|
|
1916
|
+
if (insertAt === -1) queue.push(child);
|
|
1917
|
+
else queue.splice(insertAt, 0, child);
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
return result;
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
// src/hooks/useHFState.ts
|
|
1925
|
+
var OFFLINE_BUFFER_KEY = "hf-offline-buffer";
|
|
1926
|
+
var POLL_INTERVAL_MS = 3e4;
|
|
1927
|
+
function readOfflineBuffer() {
|
|
1928
|
+
try {
|
|
1929
|
+
return JSON.parse(localStorage.getItem(OFFLINE_BUFFER_KEY) || "[]");
|
|
1930
|
+
} catch {
|
|
1931
|
+
return [];
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
function writeOfflineBuffer(events) {
|
|
1935
|
+
try {
|
|
1936
|
+
localStorage.setItem(OFFLINE_BUFFER_KEY, JSON.stringify(events));
|
|
1937
|
+
} catch {
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
function useHFState(token, namespace) {
|
|
1941
|
+
const [state, setState] = useState7(null);
|
|
1942
|
+
const [isLoading, setIsLoading] = useState7(false);
|
|
1943
|
+
const [error, setError] = useState7(null);
|
|
1944
|
+
const [eventCount, setEventCount] = useState7(0);
|
|
1945
|
+
const [forks, setForks] = useState7([]);
|
|
1946
|
+
const [pendingBufferCount, setPendingBufferCount] = useState7(readOfflineBuffer().length);
|
|
1947
|
+
const [lastEventTs, setLastEventTs] = useState7(0);
|
|
1948
|
+
const [hasStateZip, setHasStateZip] = useState7(false);
|
|
1949
|
+
const knownEventPaths = useRef6(/* @__PURE__ */ new Set());
|
|
1950
|
+
const allEventsRef = useRef6([]);
|
|
1951
|
+
const applyNewEvents = useCallback((snapshot, newEvents) => {
|
|
1952
|
+
if (!newEvents.length && allEventsRef.current.length === 0) {
|
|
1953
|
+
setEventCount(0);
|
|
1954
|
+
return snapshot;
|
|
1955
|
+
}
|
|
1956
|
+
const sorted = topoSort([...allEventsRef.current, ...newEvents]);
|
|
1957
|
+
allEventsRef.current = sorted;
|
|
1958
|
+
const afterConsolidation = sorted.filter((e) => e.ts > snapshot.meta.consolidatedAt);
|
|
1959
|
+
const dag = buildDag(afterConsolidation);
|
|
1960
|
+
setForks(findForks(dag));
|
|
1961
|
+
setEventCount(afterConsolidation.length);
|
|
1962
|
+
if (afterConsolidation.length) setLastEventTs(Math.max(...afterConsolidation.map((e) => e.ts)));
|
|
1963
|
+
return applyEvents(snapshot, afterConsolidation);
|
|
1964
|
+
}, []);
|
|
1965
|
+
const loadFull = useCallback(async () => {
|
|
1966
|
+
if (!token || !namespace) return;
|
|
1967
|
+
setIsLoading(true);
|
|
1968
|
+
setError(null);
|
|
1969
|
+
try {
|
|
1970
|
+
const snapshot = await loadHFState(namespace, token);
|
|
1971
|
+
setHasStateZip(snapshot !== null);
|
|
1972
|
+
const base = snapshot ?? {
|
|
1973
|
+
metadata: [],
|
|
1974
|
+
tags: { by_category: {}, all: [] },
|
|
1975
|
+
meta: { consolidatedAt: 0, version: 1 }
|
|
1976
|
+
};
|
|
1977
|
+
const events = await loadPendingEvents(namespace, token, base.meta.consolidatedAt);
|
|
1978
|
+
events.forEach((e) => knownEventPaths.current.add(`${e.ts}_${e.clientId}`));
|
|
1979
|
+
allEventsRef.current = [];
|
|
1980
|
+
const finalState = applyNewEvents(base, events);
|
|
1981
|
+
setState(finalState);
|
|
1982
|
+
const buffer = readOfflineBuffer();
|
|
1983
|
+
if (buffer.length) {
|
|
1984
|
+
for (const evt of buffer) {
|
|
1985
|
+
await writeHFEvent(namespace, token, evt.type, evt.payload, evt.prevTs).catch(() => {
|
|
1986
|
+
});
|
|
1987
|
+
}
|
|
1988
|
+
writeOfflineBuffer([]);
|
|
1989
|
+
setPendingBufferCount(0);
|
|
1990
|
+
const freshEvents = await loadPendingEvents(namespace, token, base.meta.consolidatedAt);
|
|
1991
|
+
freshEvents.forEach((e) => knownEventPaths.current.add(`${e.ts}_${e.clientId}`));
|
|
1992
|
+
setState((prev) => prev ? applyNewEvents(base, freshEvents) : prev);
|
|
1993
|
+
}
|
|
1994
|
+
} catch (e) {
|
|
1995
|
+
setError(e.message);
|
|
1996
|
+
} finally {
|
|
1997
|
+
setIsLoading(false);
|
|
1998
|
+
}
|
|
1999
|
+
}, [token, namespace, applyNewEvents]);
|
|
2000
|
+
const pollNew = useCallback(async () => {
|
|
2001
|
+
if (!token || !namespace || !state) return;
|
|
2002
|
+
try {
|
|
2003
|
+
const events = await loadPendingEvents(namespace, token, state.meta.consolidatedAt);
|
|
2004
|
+
const newEvents = events.filter((e) => !knownEventPaths.current.has(`${e.ts}_${e.clientId}`));
|
|
2005
|
+
if (!newEvents.length) return;
|
|
2006
|
+
newEvents.forEach((e) => knownEventPaths.current.add(`${e.ts}_${e.clientId}`));
|
|
2007
|
+
setState((prev) => prev ? applyNewEvents(prev, newEvents) : prev);
|
|
2008
|
+
} catch {
|
|
2009
|
+
}
|
|
2010
|
+
}, [token, namespace, state, applyNewEvents]);
|
|
2011
|
+
useEffect5(() => {
|
|
2012
|
+
if (token && namespace) loadFull();
|
|
2013
|
+
}, [token, namespace]);
|
|
2014
|
+
useEffect5(() => {
|
|
2015
|
+
if (!token || !namespace) return;
|
|
2016
|
+
const id = setInterval(pollNew, POLL_INTERVAL_MS);
|
|
2017
|
+
return () => clearInterval(id);
|
|
2018
|
+
}, [token, namespace, pollNew]);
|
|
2019
|
+
const writeEvent = useCallback(async (type, payload) => {
|
|
2020
|
+
const prevTs = lastEventTs ? [lastEventTs] : [state?.meta.consolidatedAt ?? 0];
|
|
2021
|
+
console.log("[HF] writeEvent called:", { type, namespace, tokenOk: !!token, prevTs });
|
|
2022
|
+
await pollNew();
|
|
2023
|
+
try {
|
|
2024
|
+
console.log("[HF] writeHFEvent start, path will be:", `${namespace}events/...`);
|
|
2025
|
+
const event = await writeHFEvent(namespace, token, type, payload, prevTs);
|
|
2026
|
+
console.log("[HF] writeHFEvent success:", event.ts);
|
|
2027
|
+
knownEventPaths.current.add(`${event.ts}_${event.clientId}`);
|
|
2028
|
+
setState((prev) => prev ? applyNewEvents(prev, [event]) : prev);
|
|
2029
|
+
setLastEventTs(event.ts);
|
|
2030
|
+
await pollNew();
|
|
2031
|
+
} catch (e) {
|
|
2032
|
+
console.error("[HF] writeHFEvent FAILED, going to offline buffer:", e);
|
|
2033
|
+
const buffer = readOfflineBuffer();
|
|
2034
|
+
const offline = {
|
|
2035
|
+
v: { major: 1, minor: 0 },
|
|
2036
|
+
type,
|
|
2037
|
+
ts: Date.now(),
|
|
2038
|
+
prevTs,
|
|
2039
|
+
clientId: getSessionClientId(),
|
|
2040
|
+
payload
|
|
2041
|
+
};
|
|
2042
|
+
writeOfflineBuffer([...buffer, offline]);
|
|
2043
|
+
setPendingBufferCount(buffer.length + 1);
|
|
2044
|
+
setState((prev) => prev ? applyNewEvents(prev, [offline]) : prev);
|
|
2045
|
+
}
|
|
2046
|
+
}, [namespace, token, lastEventTs, state, pollNew, applyNewEvents]);
|
|
2047
|
+
return {
|
|
2048
|
+
state,
|
|
2049
|
+
isLoading,
|
|
2050
|
+
error,
|
|
2051
|
+
pendingBufferCount,
|
|
2052
|
+
eventCount,
|
|
2053
|
+
forks,
|
|
2054
|
+
writeEvent,
|
|
2055
|
+
refresh: loadFull,
|
|
2056
|
+
lastEventTs,
|
|
2057
|
+
allEvents: allEventsRef.current,
|
|
2058
|
+
hasStateZip
|
|
2059
|
+
};
|
|
2060
|
+
}
|
|
2061
|
+
|
|
1815
2062
|
// src/components/labs/LabsTab.tsx
|
|
1816
|
-
import { useState as
|
|
2063
|
+
import { useState as useState13 } from "react";
|
|
1817
2064
|
|
|
1818
2065
|
// src/components/labs/LabRemix.tsx
|
|
1819
|
-
import { useState as
|
|
2066
|
+
import { useState as useState9 } from "react";
|
|
1820
2067
|
|
|
1821
2068
|
// src/components/labs/LabImagePicker.tsx
|
|
1822
|
-
import { useState as
|
|
2069
|
+
import { useState as useState8 } from "react";
|
|
1823
2070
|
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1824
2071
|
var LabImagePicker = ({
|
|
1825
2072
|
availableItems,
|
|
@@ -1828,8 +2075,8 @@ var LabImagePicker = ({
|
|
|
1828
2075
|
onClose,
|
|
1829
2076
|
title = "Bild w\xE4hlen"
|
|
1830
2077
|
}) => {
|
|
1831
|
-
const [search, setSearch] =
|
|
1832
|
-
const [drillItem, setDrillItem] =
|
|
2078
|
+
const [search, setSearch] = useState8("");
|
|
2079
|
+
const [drillItem, setDrillItem] = useState8(null);
|
|
1833
2080
|
const filtered = availableItems.filter(
|
|
1834
2081
|
(item) => !search || item.prompt.toLowerCase().includes(search.toLowerCase())
|
|
1835
2082
|
);
|
|
@@ -1931,13 +2178,13 @@ var LabImagePicker = ({
|
|
|
1931
2178
|
// src/components/labs/LabRemix.tsx
|
|
1932
2179
|
import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1933
2180
|
var LabRemix = ({ services, onResult }) => {
|
|
1934
|
-
const [showPicker, setShowPicker] =
|
|
1935
|
-
const [selected, setSelected] =
|
|
1936
|
-
const [instruction, setInstruction] =
|
|
1937
|
-
const [generatedPrompt, setGeneratedPrompt] =
|
|
1938
|
-
const [resultImage, setResultImage] =
|
|
1939
|
-
const [isGeneratingPrompt, setIsGeneratingPrompt] =
|
|
1940
|
-
const [isGeneratingImage, setIsGeneratingImage] =
|
|
2181
|
+
const [showPicker, setShowPicker] = useState9(false);
|
|
2182
|
+
const [selected, setSelected] = useState9(null);
|
|
2183
|
+
const [instruction, setInstruction] = useState9("");
|
|
2184
|
+
const [generatedPrompt, setGeneratedPrompt] = useState9("");
|
|
2185
|
+
const [resultImage, setResultImage] = useState9(null);
|
|
2186
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = useState9(false);
|
|
2187
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState9(false);
|
|
1941
2188
|
const handleSelectImage = (item, frame) => {
|
|
1942
2189
|
services.onItemUsed(item);
|
|
1943
2190
|
setSelected({
|
|
@@ -2120,16 +2367,16 @@ var LabRemix = ({ services, onResult }) => {
|
|
|
2120
2367
|
};
|
|
2121
2368
|
|
|
2122
2369
|
// src/components/labs/LabBlend.tsx
|
|
2123
|
-
import { useState as
|
|
2370
|
+
import { useState as useState10 } from "react";
|
|
2124
2371
|
import { Fragment as Fragment6, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2125
2372
|
var LabBlend = ({ services, onResult }) => {
|
|
2126
|
-
const [showPickerFor, setShowPickerFor] =
|
|
2127
|
-
const [selectedImages, setSelectedImages] =
|
|
2128
|
-
const [instruction, setInstruction] =
|
|
2129
|
-
const [generatedPrompt, setGeneratedPrompt] =
|
|
2130
|
-
const [resultImage, setResultImage] =
|
|
2131
|
-
const [isGeneratingPrompt, setIsGeneratingPrompt] =
|
|
2132
|
-
const [isGeneratingImage, setIsGeneratingImage] =
|
|
2373
|
+
const [showPickerFor, setShowPickerFor] = useState10(null);
|
|
2374
|
+
const [selectedImages, setSelectedImages] = useState10([]);
|
|
2375
|
+
const [instruction, setInstruction] = useState10("");
|
|
2376
|
+
const [generatedPrompt, setGeneratedPrompt] = useState10("");
|
|
2377
|
+
const [resultImage, setResultImage] = useState10(null);
|
|
2378
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = useState10(false);
|
|
2379
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState10(false);
|
|
2133
2380
|
const handleSelectImage = (index, item, frame) => {
|
|
2134
2381
|
services.onItemUsed(item);
|
|
2135
2382
|
const newImg = {
|
|
@@ -2316,17 +2563,17 @@ var LabBlend = ({ services, onResult }) => {
|
|
|
2316
2563
|
};
|
|
2317
2564
|
|
|
2318
2565
|
// src/components/labs/LabCompare.tsx
|
|
2319
|
-
import { useState as
|
|
2566
|
+
import { useState as useState11 } from "react";
|
|
2320
2567
|
import { Fragment as Fragment7, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2321
2568
|
var LabCompare = ({ services, onResult }) => {
|
|
2322
|
-
const [showPickerFor, setShowPickerFor] =
|
|
2323
|
-
const [selectedImages, setSelectedImages] =
|
|
2324
|
-
const [instruction, setInstruction] =
|
|
2325
|
-
const [analysis, setAnalysis] =
|
|
2326
|
-
const [generatedPrompt, setGeneratedPrompt] =
|
|
2327
|
-
const [resultImage, setResultImage] =
|
|
2328
|
-
const [isAnalyzing, setIsAnalyzing] =
|
|
2329
|
-
const [isGeneratingImage, setIsGeneratingImage] =
|
|
2569
|
+
const [showPickerFor, setShowPickerFor] = useState11(null);
|
|
2570
|
+
const [selectedImages, setSelectedImages] = useState11([]);
|
|
2571
|
+
const [instruction, setInstruction] = useState11("");
|
|
2572
|
+
const [analysis, setAnalysis] = useState11("");
|
|
2573
|
+
const [generatedPrompt, setGeneratedPrompt] = useState11("");
|
|
2574
|
+
const [resultImage, setResultImage] = useState11(null);
|
|
2575
|
+
const [isAnalyzing, setIsAnalyzing] = useState11(false);
|
|
2576
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState11(false);
|
|
2330
2577
|
const handleSelectImage = (index, item, frame) => {
|
|
2331
2578
|
services.onItemUsed(item);
|
|
2332
2579
|
const newImg = {
|
|
@@ -2489,14 +2736,14 @@ var LabCompare = ({ services, onResult }) => {
|
|
|
2489
2736
|
};
|
|
2490
2737
|
|
|
2491
2738
|
// src/components/labs/LabLoop.tsx
|
|
2492
|
-
import { useState as
|
|
2739
|
+
import { useState as useState12 } from "react";
|
|
2493
2740
|
import { Fragment as Fragment8, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2494
2741
|
var LabLoop = ({ services, onResult }) => {
|
|
2495
|
-
const [rounds, setRounds] =
|
|
2496
|
-
const [currentInstruction, setCurrentInstruction] =
|
|
2497
|
-
const [showPickerForRound, setShowPickerForRound] =
|
|
2498
|
-
const [pendingImages, setPendingImages] =
|
|
2499
|
-
const [isGenerating, setIsGenerating] =
|
|
2742
|
+
const [rounds, setRounds] = useState12([]);
|
|
2743
|
+
const [currentInstruction, setCurrentInstruction] = useState12("");
|
|
2744
|
+
const [showPickerForRound, setShowPickerForRound] = useState12(null);
|
|
2745
|
+
const [pendingImages, setPendingImages] = useState12([]);
|
|
2746
|
+
const [isGenerating, setIsGenerating] = useState12(false);
|
|
2500
2747
|
const currentPrompt = rounds.length > 0 ? rounds[rounds.length - 1].prompt : "";
|
|
2501
2748
|
const handleAddImage = (item, frame) => {
|
|
2502
2749
|
services.onItemUsed(item);
|
|
@@ -2660,7 +2907,7 @@ var TABS = [
|
|
|
2660
2907
|
{ key: "loop", label: "Loop", icon: "loop" }
|
|
2661
2908
|
];
|
|
2662
2909
|
var LabsTab = ({ services, onResult }) => {
|
|
2663
|
-
const [activeTab, setActiveTab] =
|
|
2910
|
+
const [activeTab, setActiveTab] = useState13("remix");
|
|
2664
2911
|
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
2665
2912
|
/* @__PURE__ */ jsx18("div", { className: "flex border-b border-white/5 shrink-0", children: TABS.map((tab) => /* @__PURE__ */ jsxs16(
|
|
2666
2913
|
"button",
|
|
@@ -2684,19 +2931,19 @@ var LabsTab = ({ services, onResult }) => {
|
|
|
2684
2931
|
};
|
|
2685
2932
|
|
|
2686
2933
|
// src/components/TagManagerPanel.tsx
|
|
2687
|
-
import { useState as
|
|
2934
|
+
import { useState as useState14 } from "react";
|
|
2688
2935
|
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2689
2936
|
function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete, onTagReorder, onTagMove }) {
|
|
2690
2937
|
const categories = Object.keys(workspaceTags.by_category).filter(
|
|
2691
2938
|
(cat) => (workspaceTags.by_category[cat] || []).some((t) => !t.is_deleted)
|
|
2692
2939
|
);
|
|
2693
|
-
const [selectedCategory, setSelectedCategory] =
|
|
2940
|
+
const [selectedCategory, setSelectedCategory] = useState14(categories[0] || "");
|
|
2694
2941
|
const effectiveCategory = categories.includes(selectedCategory) ? selectedCategory : categories[0] || "";
|
|
2695
|
-
const [editingLabel, setEditingLabel] =
|
|
2696
|
-
const [editState, setEditState] =
|
|
2697
|
-
const [newTag, setNewTag] =
|
|
2698
|
-
const [movingLabel, setMovingLabel] =
|
|
2699
|
-
const [moveTarget, setMoveTarget] =
|
|
2942
|
+
const [editingLabel, setEditingLabel] = useState14(null);
|
|
2943
|
+
const [editState, setEditState] = useState14({ label: "", value: "" });
|
|
2944
|
+
const [newTag, setNewTag] = useState14({ label: "", value: "" });
|
|
2945
|
+
const [movingLabel, setMovingLabel] = useState14(null);
|
|
2946
|
+
const [moveTarget, setMoveTarget] = useState14("");
|
|
2700
2947
|
const tags = (workspaceTags.by_category[effectiveCategory] || []).filter((t) => !t.is_deleted);
|
|
2701
2948
|
const otherCategories = categories.filter((c) => c !== effectiveCategory);
|
|
2702
2949
|
const startEdit = (tag) => {
|
|
@@ -2893,8 +3140,8 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
|
|
|
2893
3140
|
|
|
2894
3141
|
// src/components/AvatarArchitectApp.tsx
|
|
2895
3142
|
import { Fragment as Fragment9, jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2896
|
-
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
2897
|
-
|
|
3143
|
+
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
3144
|
+
useEffect6(() => {
|
|
2898
3145
|
const id = "flow-styles";
|
|
2899
3146
|
if (!document.getElementById(id)) {
|
|
2900
3147
|
const style = document.createElement("style");
|
|
@@ -2903,22 +3150,92 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2903
3150
|
document.head.appendChild(style);
|
|
2904
3151
|
}
|
|
2905
3152
|
}, []);
|
|
2906
|
-
const [showStart, setShowStart] =
|
|
2907
|
-
const [layoutChoice, setLayoutChoice] =
|
|
3153
|
+
const [showStart, setShowStart] = useState15(true);
|
|
3154
|
+
const [layoutChoice, setLayoutChoice] = useState15(() => {
|
|
2908
3155
|
try {
|
|
2909
3156
|
return localStorage.getItem("aa-layout") || null;
|
|
2910
3157
|
} catch {
|
|
2911
3158
|
return null;
|
|
2912
3159
|
}
|
|
2913
3160
|
});
|
|
2914
|
-
const [projectLoaded, setProjectLoaded] =
|
|
2915
|
-
const [hfToken, setHfToken] =
|
|
2916
|
-
const [hfTokenInput, setHfTokenInput] =
|
|
2917
|
-
const [isLoadingFromHF, setIsLoadingFromHF] =
|
|
2918
|
-
const [
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
3161
|
+
const [projectLoaded, setProjectLoaded] = useState15(false);
|
|
3162
|
+
const [hfToken, setHfToken] = useState15(initialHfToken || "");
|
|
3163
|
+
const [hfTokenInput, setHfTokenInput] = useState15(initialHfToken || "");
|
|
3164
|
+
const [isLoadingFromHF, setIsLoadingFromHF] = useState15(false);
|
|
3165
|
+
const [hfNamespaceLocal, setHfNamespaceLocal] = useState15(() => {
|
|
3166
|
+
try {
|
|
3167
|
+
const stored = localStorage.getItem("aa-hf-namespace");
|
|
3168
|
+
if (stored !== null) return stored;
|
|
3169
|
+
return allowDevNamespace ? "app.art-by-rolands.de/" : "";
|
|
3170
|
+
} catch {
|
|
3171
|
+
return "";
|
|
3172
|
+
}
|
|
3173
|
+
});
|
|
3174
|
+
const [hfNamespaceFromServer, setHfNamespaceFromServer] = useState15(null);
|
|
3175
|
+
useEffect6(() => {
|
|
3176
|
+
if (hfNamespace !== void 0) return;
|
|
3177
|
+
const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
|
|
3178
|
+
if (!backendUrl) return;
|
|
3179
|
+
fetch(`${backendUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
3180
|
+
if (typeof d.hfNamespace === "string" && d.hfNamespace) setHfNamespaceFromServer(d.hfNamespace);
|
|
3181
|
+
}).catch(() => {
|
|
3182
|
+
});
|
|
3183
|
+
}, [hfNamespace]);
|
|
3184
|
+
const effectiveNamespace = hfNamespace ?? hfNamespaceFromServer ?? hfNamespaceLocal;
|
|
3185
|
+
const {
|
|
3186
|
+
state: hfState,
|
|
3187
|
+
isLoading: isHfRefreshing,
|
|
3188
|
+
pendingBufferCount,
|
|
3189
|
+
eventCount,
|
|
3190
|
+
writeEvent: hfWriteEvent,
|
|
3191
|
+
refresh: refreshHF,
|
|
3192
|
+
hasStateZip
|
|
3193
|
+
} = useHFState(hfToken, effectiveNamespace);
|
|
3194
|
+
const [bootstrapLog, setBootstrapLog] = useState15([]);
|
|
3195
|
+
const [isBootstrapping, setIsBootstrapping] = useState15(false);
|
|
3196
|
+
const syncTopSlot = /* @__PURE__ */ jsxs18(Fragment9, { children: [
|
|
3197
|
+
pendingBufferCount > 0 && /* @__PURE__ */ jsxs18("div", { style: { background: "linear-gradient(90deg,#f59e0b,#ef4444)", padding: "4px 10px", fontSize: 11, color: "#fff", borderRadius: 4, marginBottom: 4 }, children: [
|
|
3198
|
+
pendingBufferCount,
|
|
3199
|
+
" \xC4nderung",
|
|
3200
|
+
pendingBufferCount > 1 ? "en" : "",
|
|
3201
|
+
" lokal \u2014 bei Flow-Reload verloren wenn nicht synchronisiert"
|
|
3202
|
+
] }),
|
|
3203
|
+
eventCount > 100 && /* @__PURE__ */ jsxs18("div", { style: { background: "#dc2626", color: "#fff", padding: "5px 10px", borderRadius: 4, marginBottom: 4, fontWeight: 600, fontSize: 11 }, children: [
|
|
3204
|
+
"\u26A0 ",
|
|
3205
|
+
eventCount,
|
|
3206
|
+
" Events nicht konsolidiert \u2014 Konsolidierung dringend empfohlen"
|
|
3207
|
+
] }),
|
|
3208
|
+
eventCount > 50 && eventCount <= 100 && /* @__PURE__ */ jsxs18("div", { style: { background: "#44403c", color: "#a8a29e", padding: "4px 10px", borderRadius: 4, marginBottom: 4, fontSize: 11 }, children: [
|
|
3209
|
+
eventCount,
|
|
3210
|
+
" Events seit letzter Konsolidierung \u2014 Konsolidierung empfohlen"
|
|
3211
|
+
] }),
|
|
3212
|
+
hfToken && !hasStateZip && !isHfRefreshing && /* @__PURE__ */ jsxs18("div", { style: { background: "#1c1917", border: "1px solid #44403c", borderRadius: 6, padding: "10px 12px" }, children: [
|
|
3213
|
+
/* @__PURE__ */ jsx20("div", { style: { fontSize: 12, color: "#a8a29e", marginBottom: 6 }, children: effectiveNamespace ? `Kein State-Snapshot in HF (${effectiveNamespace}) \u2014 aus Legacy-Daten (tags.json + metadata.json) migrieren?` : "Namespace wird geladen\u2026" }),
|
|
3214
|
+
/* @__PURE__ */ jsx20(
|
|
3215
|
+
"button",
|
|
3216
|
+
{
|
|
3217
|
+
disabled: isBootstrapping || !effectiveNamespace,
|
|
3218
|
+
onClick: async () => {
|
|
3219
|
+
setIsBootstrapping(true);
|
|
3220
|
+
setBootstrapLog([]);
|
|
3221
|
+
try {
|
|
3222
|
+
await hfBootstrapFromLegacy(effectiveNamespace, hfToken, (msg) => setBootstrapLog((prev) => [...prev, msg]));
|
|
3223
|
+
setBootstrapLog((prev) => [...prev, "\u2713 Fertig"]);
|
|
3224
|
+
setTimeout(() => refreshHF(), 1500);
|
|
3225
|
+
} catch (e) {
|
|
3226
|
+
setBootstrapLog((prev) => [...prev, `Fehler: ${e.message}`]);
|
|
3227
|
+
} finally {
|
|
3228
|
+
setIsBootstrapping(false);
|
|
3229
|
+
}
|
|
3230
|
+
},
|
|
3231
|
+
style: { padding: "5px 12px", background: "#0ea5e9", color: "#fff", border: "none", borderRadius: 4, cursor: isBootstrapping || !effectiveNamespace ? "not-allowed" : "pointer", fontSize: 11, fontWeight: 600, opacity: isBootstrapping || !effectiveNamespace ? 0.6 : 1 },
|
|
3232
|
+
children: isBootstrapping ? "Migriere\u2026" : "Legacy-Migration starten"
|
|
3233
|
+
}
|
|
3234
|
+
),
|
|
3235
|
+
bootstrapLog.length > 0 && /* @__PURE__ */ jsx20("div", { style: { marginTop: 6, fontFamily: "monospace", fontSize: 10, color: "#78716c", lineHeight: 1.6 }, children: bootstrapLog.map((l, i) => /* @__PURE__ */ jsx20("div", { children: l }, i)) })
|
|
3236
|
+
] })
|
|
3237
|
+
] });
|
|
3238
|
+
const wsInputRef = useRef7(null);
|
|
2922
3239
|
const startApp = (choice) => {
|
|
2923
3240
|
try {
|
|
2924
3241
|
localStorage.setItem("aa-layout", choice);
|
|
@@ -2927,70 +3244,110 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
2927
3244
|
setLayoutChoice(choice);
|
|
2928
3245
|
setShowStart(false);
|
|
2929
3246
|
};
|
|
2930
|
-
const [nodes, setNodes] =
|
|
2931
|
-
const [edges, setEdges] =
|
|
2932
|
-
const [history, setHistory] =
|
|
2933
|
-
const [galleryItems, setGalleryItems] =
|
|
2934
|
-
const galleryItemsRef =
|
|
2935
|
-
|
|
3247
|
+
const [nodes, setNodes] = useState15([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
|
|
3248
|
+
const [edges, setEdges] = useState15([]);
|
|
3249
|
+
const [history, setHistory] = useState15([]);
|
|
3250
|
+
const [galleryItems, setGalleryItems] = useState15([]);
|
|
3251
|
+
const galleryItemsRef = useRef7([]);
|
|
3252
|
+
useEffect6(() => {
|
|
2936
3253
|
galleryItemsRef.current = galleryItems;
|
|
2937
3254
|
}, [galleryItems]);
|
|
2938
|
-
const
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
3255
|
+
const hfImageNotFoundRef = useRef7(/* @__PURE__ */ new Set());
|
|
3256
|
+
useEffect6(() => {
|
|
3257
|
+
if (!hfState) return;
|
|
3258
|
+
if (hfState.tags?.by_category) setWorkspaceTags(hfState.tags);
|
|
3259
|
+
const hfIds = new Set(hfState.metadata.map((m) => m.id));
|
|
3260
|
+
const skeletons = hfState.metadata.map((m) => ({
|
|
3261
|
+
id: m.id,
|
|
3262
|
+
nodeId: m.id,
|
|
3263
|
+
prompt: m.prompt,
|
|
3264
|
+
seed: m.seed,
|
|
3265
|
+
model: m.model,
|
|
3266
|
+
tags: m.tags || [],
|
|
3267
|
+
timestamp: m.timestamp,
|
|
3268
|
+
status: "done"
|
|
3269
|
+
}));
|
|
3270
|
+
setGalleryItems((prev) => {
|
|
3271
|
+
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
3272
|
+
const merged = skeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
3273
|
+
return [...localOnly, ...merged];
|
|
3274
|
+
});
|
|
3275
|
+
setHistory((prev) => {
|
|
3276
|
+
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
3277
|
+
const merged = skeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
3278
|
+
return [...localOnly, ...merged];
|
|
3279
|
+
});
|
|
3280
|
+
for (const entry of hfState.metadata) {
|
|
3281
|
+
if (hfImageNotFoundRef.current.has(entry.id)) continue;
|
|
3282
|
+
hfLoadImageAsBase64(entry.id, hfToken).then((b64) => {
|
|
3283
|
+
if (!b64) {
|
|
3284
|
+
hfImageNotFoundRef.current.add(entry.id);
|
|
3285
|
+
return;
|
|
3286
|
+
}
|
|
3287
|
+
const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
|
|
3288
|
+
setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
3289
|
+
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
3290
|
+
}).catch(() => {
|
|
3291
|
+
hfImageNotFoundRef.current.add(entry.id);
|
|
3292
|
+
});
|
|
3293
|
+
}
|
|
3294
|
+
}, [hfState]);
|
|
3295
|
+
const [activePrompt, setActivePrompt] = useState15("");
|
|
3296
|
+
const [isSynthesizing, setIsSynthesizing] = useState15(false);
|
|
3297
|
+
const [activeGenerationsCount, setActiveGenerationsCount] = useState15(0);
|
|
3298
|
+
const [currentResult, setCurrentResult] = useState15(null);
|
|
3299
|
+
const [focusedNodeId, setFocusedNodeId] = useState15(null);
|
|
3300
|
+
const [leftTab, setLeftTab] = useState15("prompt");
|
|
3301
|
+
const [promptFeedback, setPromptFeedback] = useState15(null);
|
|
3302
|
+
const [lastPromptPayload, setLastPromptPayload] = useState15(null);
|
|
3303
|
+
const [isPromptTabGenerating, setIsPromptTabGenerating] = useState15(false);
|
|
3304
|
+
const [activeTab, setActiveTab] = useState15("history");
|
|
3305
|
+
const [mobileTab, setMobileTab] = useState15("stage");
|
|
3306
|
+
const [middlePanel, setMiddlePanel] = useState15("stage");
|
|
3307
|
+
const [recentLabItems, setRecentLabItems] = useState15([]);
|
|
3308
|
+
const [aspectRatio, setAspectRatio] = useState15("1:1");
|
|
3309
|
+
const [selectedModel, setSelectedModel] = useState15("\u{1F34C} Nano Banana Pro");
|
|
3310
|
+
const [seed, setSeed] = useState15(Math.floor(Math.random() * 1e6));
|
|
3311
|
+
const [seedMode, setSeedMode] = useState15("random");
|
|
3312
|
+
const [isLeftCollapsed, setIsLeftCollapsed] = useState15(false);
|
|
3313
|
+
const [isRightCollapsed, setIsRightCollapsed] = useState15(false);
|
|
3314
|
+
const [leftPanelWidth, setLeftPanelWidth] = useState15(() => {
|
|
2958
3315
|
try {
|
|
2959
3316
|
return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
|
|
2960
3317
|
} catch {
|
|
2961
3318
|
return 260;
|
|
2962
3319
|
}
|
|
2963
3320
|
});
|
|
2964
|
-
const [rightPanelWidth, setRightPanelWidth] =
|
|
3321
|
+
const [rightPanelWidth, setRightPanelWidth] = useState15(() => {
|
|
2965
3322
|
try {
|
|
2966
3323
|
return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
|
|
2967
3324
|
} catch {
|
|
2968
3325
|
return 320;
|
|
2969
3326
|
}
|
|
2970
3327
|
});
|
|
2971
|
-
const [isPromptCollapsed, setIsPromptCollapsed] =
|
|
2972
|
-
const [projectActionState, setProjectActionState] =
|
|
2973
|
-
const syncServerDataRef =
|
|
2974
|
-
const [workspaceTags, setWorkspaceTags] =
|
|
2975
|
-
const [serverProjects, setServerProjects] =
|
|
2976
|
-
const [isLoadingFromServer, setIsLoadingFromServer] =
|
|
2977
|
-
const [highContrast, setHighContrast] =
|
|
3328
|
+
const [isPromptCollapsed, setIsPromptCollapsed] = useState15(false);
|
|
3329
|
+
const [projectActionState, setProjectActionState] = useState15("idle");
|
|
3330
|
+
const syncServerDataRef = useRef7(null);
|
|
3331
|
+
const [workspaceTags, setWorkspaceTags] = useState15(null);
|
|
3332
|
+
const [serverProjects, setServerProjects] = useState15([]);
|
|
3333
|
+
const [isLoadingFromServer, setIsLoadingFromServer] = useState15(false);
|
|
3334
|
+
const [highContrast, setHighContrast] = useState15(() => {
|
|
2978
3335
|
try {
|
|
2979
3336
|
return localStorage.getItem("aa-contrast") === "high";
|
|
2980
3337
|
} catch {
|
|
2981
3338
|
return false;
|
|
2982
3339
|
}
|
|
2983
3340
|
});
|
|
2984
|
-
const [activeReferenceId, setActiveReferenceId] =
|
|
2985
|
-
const [activeReferenceThumbnail, setActiveReferenceThumbnail] =
|
|
2986
|
-
const [isScanningImage, setIsScanningImage] =
|
|
2987
|
-
const [touchStartX, setTouchStartX] =
|
|
2988
|
-
const [isFullscreen, setIsFullscreen] =
|
|
2989
|
-
const [zoomScale, setZoomScale] =
|
|
2990
|
-
const [zoomOffset, setZoomOffset] =
|
|
2991
|
-
const lastPinchDist =
|
|
2992
|
-
const lastTapTime =
|
|
2993
|
-
const dragStart =
|
|
3341
|
+
const [activeReferenceId, setActiveReferenceId] = useState15(null);
|
|
3342
|
+
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = useState15(null);
|
|
3343
|
+
const [isScanningImage, setIsScanningImage] = useState15(false);
|
|
3344
|
+
const [touchStartX, setTouchStartX] = useState15(null);
|
|
3345
|
+
const [isFullscreen, setIsFullscreen] = useState15(false);
|
|
3346
|
+
const [zoomScale, setZoomScale] = useState15(1);
|
|
3347
|
+
const [zoomOffset, setZoomOffset] = useState15({ x: 0, y: 0 });
|
|
3348
|
+
const lastPinchDist = useRef7(null);
|
|
3349
|
+
const lastTapTime = useRef7(0);
|
|
3350
|
+
const dragStart = useRef7(null);
|
|
2994
3351
|
const openFullscreen = () => {
|
|
2995
3352
|
setIsFullscreen(true);
|
|
2996
3353
|
setZoomScale(1);
|
|
@@ -3134,16 +3491,16 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3134
3491
|
}
|
|
3135
3492
|
};
|
|
3136
3493
|
const currentIndex = useMemo2(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
|
|
3137
|
-
const goToPrev =
|
|
3494
|
+
const goToPrev = useCallback2(() => {
|
|
3138
3495
|
if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
|
|
3139
3496
|
}, [currentIndex, history]);
|
|
3140
|
-
const goToNext =
|
|
3497
|
+
const goToNext = useCallback2(() => {
|
|
3141
3498
|
if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
|
|
3142
3499
|
}, [currentIndex, history]);
|
|
3143
3500
|
const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
|
|
3144
3501
|
const isGenerating = activeGenerationsCount > 0;
|
|
3145
3502
|
useKeyboardNavigation(history, currentResult, setCurrentResult);
|
|
3146
|
-
const getSubtreeFormat =
|
|
3503
|
+
const getSubtreeFormat = useCallback2((nodeId, depth = 0) => {
|
|
3147
3504
|
const node = nodes.find((n) => n.id === nodeId);
|
|
3148
3505
|
if (!node) return "";
|
|
3149
3506
|
const childrenIds = edges.filter((e) => e.source === nodeId).map((e) => e.target);
|
|
@@ -3183,7 +3540,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3183
3540
|
if (prev.id === genId || !options.silent) return finishedGen;
|
|
3184
3541
|
return prev;
|
|
3185
3542
|
});
|
|
3186
|
-
|
|
3543
|
+
console.log("[HF] handleGenerateImage \u2014 condition check:", { hfToken: !!hfToken, base64: !!base64, effectiveNamespace });
|
|
3544
|
+
if (hfToken && base64 && effectiveNamespace) {
|
|
3545
|
+
hfUploadImage(base64, genId, hfToken).catch((e) => {
|
|
3546
|
+
console.error("[HF] hfUploadImage failed:", e);
|
|
3547
|
+
});
|
|
3187
3548
|
const entry = {
|
|
3188
3549
|
id: genId,
|
|
3189
3550
|
prompt: promptToUse || void 0,
|
|
@@ -3193,20 +3554,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3193
3554
|
timestamp: Date.now(),
|
|
3194
3555
|
mimeType: "image/jpeg"
|
|
3195
3556
|
};
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
hfMetaSaveQueue.current = hfMetaSaveQueue.current.then(async () => {
|
|
3200
|
-
try {
|
|
3201
|
-
const existing = await hfLoadMetadata(token);
|
|
3202
|
-
const ids = new Set((existing || []).map((e) => e.id));
|
|
3203
|
-
if (!ids.has(genId)) {
|
|
3204
|
-
const next = [...existing || [], entry];
|
|
3205
|
-
await hfSaveMetadata(next, token);
|
|
3206
|
-
setHfMetadata(next);
|
|
3207
|
-
}
|
|
3208
|
-
} catch {
|
|
3209
|
-
}
|
|
3557
|
+
console.log("[HF] calling hfWriteEvent, namespace:", effectiveNamespace);
|
|
3558
|
+
hfWriteEvent("image_added", entry).catch((e) => {
|
|
3559
|
+
console.error("[HF] hfWriteEvent outer catch:", e);
|
|
3210
3560
|
});
|
|
3211
3561
|
}
|
|
3212
3562
|
} catch (err) {
|
|
@@ -3242,6 +3592,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3242
3592
|
all: [...prev.all, { ...newTagOption, category: tag.category }]
|
|
3243
3593
|
};
|
|
3244
3594
|
});
|
|
3595
|
+
if (hfToken && effectiveNamespace) {
|
|
3596
|
+
const p = { category: tag.category, label: tag.label, value: tag.value, is_user_created: true };
|
|
3597
|
+
hfWriteEvent("tag_upserted", p).catch(() => {
|
|
3598
|
+
});
|
|
3599
|
+
}
|
|
3245
3600
|
};
|
|
3246
3601
|
const handleTagUpdate = (originalLabel, originalCategory, updates) => {
|
|
3247
3602
|
setWorkspaceTags((prev) => {
|
|
@@ -3254,8 +3609,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3254
3609
|
);
|
|
3255
3610
|
return { by_category: { ...prev.by_category, [originalCategory]: updatedCat }, all: updatedAll };
|
|
3256
3611
|
});
|
|
3612
|
+
if (hfToken && effectiveNamespace) {
|
|
3613
|
+
const p = { category: originalCategory, label: updates.label, value: updates.value, is_user_created: true };
|
|
3614
|
+
hfWriteEvent("tag_upserted", p).catch(() => {
|
|
3615
|
+
});
|
|
3616
|
+
}
|
|
3257
3617
|
};
|
|
3258
3618
|
const handleTagDelete = (label, category) => {
|
|
3619
|
+
const tagValue = workspaceTags?.by_category[category]?.find((t) => t.label === label)?.value;
|
|
3259
3620
|
setWorkspaceTags((prev) => {
|
|
3260
3621
|
if (!prev) return prev;
|
|
3261
3622
|
const updatedCat = (prev.by_category[category] || []).map(
|
|
@@ -3266,6 +3627,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3266
3627
|
);
|
|
3267
3628
|
return { by_category: { ...prev.by_category, [category]: updatedCat }, all: updatedAll };
|
|
3268
3629
|
});
|
|
3630
|
+
if (hfToken && effectiveNamespace && tagValue) {
|
|
3631
|
+
const p = { category, label, value: tagValue, is_deleted: true };
|
|
3632
|
+
hfWriteEvent("tag_upserted", p).catch(() => {
|
|
3633
|
+
});
|
|
3634
|
+
}
|
|
3269
3635
|
};
|
|
3270
3636
|
const handleTagReorder = (category, reorderedTags) => {
|
|
3271
3637
|
setWorkspaceTags((prev) => {
|
|
@@ -3415,38 +3781,39 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3415
3781
|
await fetchServerProjects();
|
|
3416
3782
|
};
|
|
3417
3783
|
const handleHfInitialSync = async (onProgress) => {
|
|
3418
|
-
if (!hfToken) return;
|
|
3419
|
-
const
|
|
3784
|
+
if (!hfToken || !effectiveNamespace) return;
|
|
3785
|
+
const existingIds = new Set((hfState?.metadata || []).map((m) => m.id));
|
|
3786
|
+
const gens = galleryItems.filter((g) => g.base64 && g.status === "done" && !existingIds.has(g.id));
|
|
3420
3787
|
const total = gens.length;
|
|
3421
3788
|
onProgress(0, total);
|
|
3422
3789
|
let done = 0;
|
|
3423
3790
|
for (const gen of gens) {
|
|
3424
3791
|
const raw = gen.base64.includes(",") ? gen.base64.split(",")[1] : gen.base64;
|
|
3425
3792
|
const mimeType = gen.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg";
|
|
3426
|
-
await hfUploadImage(raw, gen.id, hfToken, mimeType)
|
|
3793
|
+
await hfUploadImage(raw, gen.id, hfToken, mimeType).catch(() => {
|
|
3794
|
+
});
|
|
3795
|
+
const entry = {
|
|
3796
|
+
id: gen.id,
|
|
3797
|
+
prompt: gen.prompt || void 0,
|
|
3798
|
+
seed: gen.seed,
|
|
3799
|
+
model: gen.model,
|
|
3800
|
+
tags: gen.tags || [],
|
|
3801
|
+
timestamp: gen.timestamp,
|
|
3802
|
+
mimeType
|
|
3803
|
+
};
|
|
3804
|
+
await hfWriteEvent("image_added", entry).catch(() => {
|
|
3805
|
+
});
|
|
3427
3806
|
done++;
|
|
3428
3807
|
onProgress(done, total);
|
|
3429
3808
|
}
|
|
3430
|
-
const localEntries = gens.map((g) => ({
|
|
3431
|
-
id: g.id,
|
|
3432
|
-
prompt: g.prompt || void 0,
|
|
3433
|
-
seed: g.seed,
|
|
3434
|
-
model: g.model,
|
|
3435
|
-
tags: g.tags || [],
|
|
3436
|
-
timestamp: g.timestamp,
|
|
3437
|
-
mimeType: g.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg"
|
|
3438
|
-
}));
|
|
3439
|
-
const existingMeta = await hfLoadMetadata(hfToken);
|
|
3440
|
-
const existingIds = new Set((existingMeta || []).map((e) => e.id));
|
|
3441
|
-
const newEntries = localEntries.filter((e) => !existingIds.has(e.id));
|
|
3442
|
-
const mergedMeta = [...existingMeta || [], ...newEntries];
|
|
3443
|
-
await hfSaveMetadata(mergedMeta, hfToken);
|
|
3444
|
-
setHfMetadata(mergedMeta);
|
|
3445
3809
|
if (workspaceTags) {
|
|
3446
|
-
const
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3810
|
+
for (const [category, tags] of Object.entries(workspaceTags.by_category)) {
|
|
3811
|
+
for (const tag of tags) {
|
|
3812
|
+
const p = { category, label: tag.label, value: tag.value, is_user_created: tag.is_user_created, is_deleted: tag.is_deleted };
|
|
3813
|
+
await hfWriteEvent("tag_upserted", p).catch(() => {
|
|
3814
|
+
});
|
|
3815
|
+
}
|
|
3816
|
+
}
|
|
3450
3817
|
}
|
|
3451
3818
|
};
|
|
3452
3819
|
const handleComputeSyncDiff = async () => {
|
|
@@ -3485,87 +3852,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3485
3852
|
setTimeout(() => setProjectActionState("idle"), 4e3);
|
|
3486
3853
|
}
|
|
3487
3854
|
};
|
|
3488
|
-
|
|
3855
|
+
useEffect6(() => {
|
|
3489
3856
|
if (activeTab === "setup" || activeTab === "sync") fetchServerProjects();
|
|
3490
3857
|
}, [activeTab]);
|
|
3491
|
-
const [isHfRefreshing, setIsHfRefreshing] = useState14(false);
|
|
3492
|
-
const loadFromHF = useCallback(async (token) => {
|
|
3493
|
-
setIsHfRefreshing(true);
|
|
3494
|
-
try {
|
|
3495
|
-
hfLoadTags(token).then((tags) => {
|
|
3496
|
-
if (tags?.by_category) setWorkspaceTags(tags);
|
|
3497
|
-
}).catch(() => {
|
|
3498
|
-
});
|
|
3499
|
-
const entries = await hfLoadMetadata(token);
|
|
3500
|
-
if (!Array.isArray(entries) || entries.length === 0) return;
|
|
3501
|
-
setHfMetadata(entries);
|
|
3502
|
-
const hfIds = new Set(entries.map((e) => e.id));
|
|
3503
|
-
const hfSkeletons = entries.map((e) => ({
|
|
3504
|
-
id: e.id,
|
|
3505
|
-
nodeId: e.id,
|
|
3506
|
-
prompt: e.prompt,
|
|
3507
|
-
seed: e.seed,
|
|
3508
|
-
model: e.model,
|
|
3509
|
-
tags: e.tags || [],
|
|
3510
|
-
timestamp: e.timestamp,
|
|
3511
|
-
status: "done"
|
|
3512
|
-
}));
|
|
3513
|
-
setGalleryItems((prev) => {
|
|
3514
|
-
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
3515
|
-
const merged = hfSkeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
3516
|
-
return [...localOnly, ...merged];
|
|
3517
|
-
});
|
|
3518
|
-
setHistory((prev) => {
|
|
3519
|
-
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
3520
|
-
const merged = hfSkeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
3521
|
-
return [...localOnly, ...merged];
|
|
3522
|
-
});
|
|
3523
|
-
for (const entry of entries) {
|
|
3524
|
-
hfLoadImageAsBase64(entry.id, token).then((b64) => {
|
|
3525
|
-
if (!b64) return;
|
|
3526
|
-
const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
|
|
3527
|
-
setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
3528
|
-
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
3529
|
-
}).catch(() => {
|
|
3530
|
-
});
|
|
3531
|
-
}
|
|
3532
|
-
const localOnlyItems = galleryItemsRef.current.filter((g) => !hfIds.has(g.id) && g.base64 && g.status === "done");
|
|
3533
|
-
if (localOnlyItems.length > 0) {
|
|
3534
|
-
hfMetaSaveQueue.current = hfMetaSaveQueue.current.then(async () => {
|
|
3535
|
-
try {
|
|
3536
|
-
let currentMeta = await hfLoadMetadata(token);
|
|
3537
|
-
const existingIds = new Set((currentMeta || []).map((e) => e.id));
|
|
3538
|
-
for (const gen of localOnlyItems) {
|
|
3539
|
-
if (existingIds.has(gen.id)) continue;
|
|
3540
|
-
const raw = gen.base64.includes(",") ? gen.base64.split(",")[1] : gen.base64;
|
|
3541
|
-
const mimeType = gen.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg";
|
|
3542
|
-
await hfUploadImage(raw, gen.id, token, mimeType).catch(() => {
|
|
3543
|
-
});
|
|
3544
|
-
const entry = {
|
|
3545
|
-
id: gen.id,
|
|
3546
|
-
prompt: gen.prompt || void 0,
|
|
3547
|
-
seed: gen.seed,
|
|
3548
|
-
model: gen.model,
|
|
3549
|
-
tags: gen.tags || [],
|
|
3550
|
-
timestamp: gen.timestamp,
|
|
3551
|
-
mimeType
|
|
3552
|
-
};
|
|
3553
|
-
currentMeta = [...currentMeta || [], entry];
|
|
3554
|
-
existingIds.add(gen.id);
|
|
3555
|
-
}
|
|
3556
|
-
await hfSaveMetadata(currentMeta, token);
|
|
3557
|
-
setHfMetadata(currentMeta);
|
|
3558
|
-
} catch {
|
|
3559
|
-
}
|
|
3560
|
-
});
|
|
3561
|
-
}
|
|
3562
|
-
} finally {
|
|
3563
|
-
setIsHfRefreshing(false);
|
|
3564
|
-
}
|
|
3565
|
-
}, []);
|
|
3566
|
-
useEffect5(() => {
|
|
3567
|
-
if (hfToken) loadFromHF(hfToken);
|
|
3568
|
-
}, [hfToken]);
|
|
3569
3858
|
const mergeWorkspaceTags = (local, remote) => {
|
|
3570
3859
|
if (!remote?.by_category) return local;
|
|
3571
3860
|
const merged = {};
|
|
@@ -3585,22 +3874,6 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3585
3874
|
const all = Object.entries(merged).flatMap(([cat, tags]) => tags.map((t) => ({ ...t, category: cat })));
|
|
3586
3875
|
return { by_category: merged, all };
|
|
3587
3876
|
};
|
|
3588
|
-
useEffect5(() => {
|
|
3589
|
-
if (!hfToken || !workspaceTags) return;
|
|
3590
|
-
if (hfTagSaveTimer.current) clearTimeout(hfTagSaveTimer.current);
|
|
3591
|
-
hfTagSaveTimer.current = setTimeout(async () => {
|
|
3592
|
-
const remote = await hfLoadTags(hfToken).catch(() => null);
|
|
3593
|
-
const merged = mergeWorkspaceTags(workspaceTags, remote);
|
|
3594
|
-
await hfSaveTags(merged, hfToken).catch(() => {
|
|
3595
|
-
});
|
|
3596
|
-
if (Object.values(merged.by_category).some(
|
|
3597
|
-
(tags, i) => tags.length !== Object.values(workspaceTags.by_category)[i]?.length
|
|
3598
|
-
)) setWorkspaceTags(merged);
|
|
3599
|
-
}, 1500);
|
|
3600
|
-
return () => {
|
|
3601
|
-
if (hfTagSaveTimer.current) clearTimeout(hfTagSaveTimer.current);
|
|
3602
|
-
};
|
|
3603
|
-
}, [workspaceTags, hfToken]);
|
|
3604
3877
|
if (isFullscreen && currentResult?.base64) {
|
|
3605
3878
|
const fsBase64 = currentResult.base64.startsWith("data:") ? currentResult.base64 : `data:image/png;base64,${currentResult.base64}`;
|
|
3606
3879
|
return /* @__PURE__ */ jsxs18(
|
|
@@ -3732,7 +4005,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3732
4005
|
onClick: async () => {
|
|
3733
4006
|
setIsLoadingFromHF(true);
|
|
3734
4007
|
try {
|
|
3735
|
-
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-
|
|
4008
|
+
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-6YYT6ATO.mjs");
|
|
3736
4009
|
const projects = await hfListProjects2(hfToken);
|
|
3737
4010
|
if (projects.length > 0) {
|
|
3738
4011
|
const file = await hfDownloadProject2(projects[0].path, hfToken);
|
|
@@ -3805,6 +4078,28 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3805
4078
|
)) }),
|
|
3806
4079
|
layoutChoice === "mobile-desktop" && /* @__PURE__ */ jsx20("span", { className: "text-white/20 text-[9px] text-center", children: "Mobil-Layout skaliert f\xFCr Desktop-Modus" }),
|
|
3807
4080
|
layoutChoice === "tablet-landscape" && /* @__PURE__ */ jsx20("span", { className: "text-white/20 text-[9px] text-center", children: "2-Spalten-Layout f\xFCr Landscape-Tablet im Desktop-Mode" })
|
|
4081
|
+
] }),
|
|
4082
|
+
!hfNamespace && !hfNamespaceFromServer && /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3 w-full max-w-[280px]", children: [
|
|
4083
|
+
/* @__PURE__ */ jsx20("span", { className: "text-white/25 text-[10px] uppercase tracking-widest font-bold", children: "State:" }),
|
|
4084
|
+
["app.art-by-rolands.de/", "dev-app.art-by-rolands.de/"].map((ns, i) => /* @__PURE__ */ jsx20(
|
|
4085
|
+
"button",
|
|
4086
|
+
{
|
|
4087
|
+
onClick: () => {
|
|
4088
|
+
setHfNamespaceLocal(ns);
|
|
4089
|
+
try {
|
|
4090
|
+
localStorage.setItem("aa-hf-namespace", ns);
|
|
4091
|
+
} catch {
|
|
4092
|
+
}
|
|
4093
|
+
},
|
|
4094
|
+
className: "px-3 py-1 rounded-lg text-[11px] font-bold transition-colors",
|
|
4095
|
+
style: {
|
|
4096
|
+
background: hfNamespaceLocal === ns ? "#e7e5e4" : "#44403c",
|
|
4097
|
+
color: hfNamespaceLocal === ns ? "#1c1917" : "#e7e5e4"
|
|
4098
|
+
},
|
|
4099
|
+
children: i === 0 ? "PROD" : "DEV"
|
|
4100
|
+
},
|
|
4101
|
+
ns
|
|
4102
|
+
))
|
|
3808
4103
|
] })
|
|
3809
4104
|
] });
|
|
3810
4105
|
}
|
|
@@ -3941,7 +4236,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
3941
4236
|
mobileTab === "browse" && /* @__PURE__ */ jsxs18("div", { className: "flex flex-col flex-1 min-h-0", children: [
|
|
3942
4237
|
/* @__PURE__ */ jsxs18("div", { className: "flex border-b border-white/5 shrink-0", style: { height: 52 }, children: [
|
|
3943
4238
|
["history", "gallery", "inspect"].map((tab) => /* @__PURE__ */ jsx20("button", { onClick: () => setActiveTab(tab), className: `flex-1 flex items-center justify-center gap-1.5 transition-colors text-[11px] font-bold uppercase tracking-wide ${activeTab === tab ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ jsx20("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : "info" }) }, tab)),
|
|
3944
|
-
hfToken && /* @__PURE__ */ jsx20("button", { onClick: () =>
|
|
4239
|
+
hfToken && /* @__PURE__ */ jsx20("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__ */ jsx20("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
|
|
3945
4240
|
] }),
|
|
3946
4241
|
/* @__PURE__ */ jsxs18("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
3947
4242
|
activeTab === "history" && /* @__PURE__ */ jsx20(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: (g) => {
|
|
@@ -4039,6 +4334,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4039
4334
|
activeTab === "sync" && /* @__PURE__ */ jsx20(
|
|
4040
4335
|
ProjectSyncTab,
|
|
4041
4336
|
{
|
|
4337
|
+
topSlot: syncTopSlot,
|
|
4042
4338
|
onProjectExport: handleProjectExport,
|
|
4043
4339
|
onProjectImport: (f) => handleProjectImport(f),
|
|
4044
4340
|
onWorkspaceImport: handleWorkspaceImport,
|
|
@@ -4331,7 +4627,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4331
4627
|
setActiveTab(tab);
|
|
4332
4628
|
setIsRightCollapsed(false);
|
|
4333
4629
|
}, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ jsx20("span", { className: "material-symbols-outlined text-[20px]", children: tab === "history" ? "history" : tab === "gallery" ? "photo_library" : tab === "inspect" ? "info" : tab === "setup" ? "settings" : tab === "sync" ? "cloud_sync" : "label" }) }, tab)) }),
|
|
4334
|
-
hfToken && /* @__PURE__ */ jsx20("button", { onClick: () =>
|
|
4630
|
+
hfToken && /* @__PURE__ */ jsx20("button", { onClick: () => refreshHF(), disabled: isHfRefreshing, className: "w-10 flex items-center justify-center text-white/20 hover:text-white/60 transition-colors disabled:opacity-30", children: /* @__PURE__ */ jsx20("span", { className: `material-symbols-outlined text-[18px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) }),
|
|
4335
4631
|
/* @__PURE__ */ jsx20("button", { onClick: () => setIsRightCollapsed(!isRightCollapsed), className: "w-10 flex items-center justify-center text-white/20 hover:text-white", children: /* @__PURE__ */ jsx20("span", { className: "material-symbols-outlined text-[18px]", children: isRightCollapsed ? "chevron_left" : "chevron_right" }) })
|
|
4336
4632
|
] }),
|
|
4337
4633
|
!isRightCollapsed && /* @__PURE__ */ jsxs18("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
@@ -4370,6 +4666,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4370
4666
|
activeTab === "sync" && /* @__PURE__ */ jsx20(
|
|
4371
4667
|
ProjectSyncTab,
|
|
4372
4668
|
{
|
|
4669
|
+
topSlot: syncTopSlot,
|
|
4373
4670
|
onProjectExport: handleProjectExport,
|
|
4374
4671
|
onProjectImport: (f) => handleProjectImport(f),
|
|
4375
4672
|
onWorkspaceImport: handleWorkspaceImport,
|
|
@@ -4396,6 +4693,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4396
4693
|
}
|
|
4397
4694
|
|
|
4398
4695
|
// src/components/FaApp.tsx
|
|
4696
|
+
import { useState as useState16, useEffect as useEffect7 } from "react";
|
|
4399
4697
|
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
4400
4698
|
function FaApp({
|
|
4401
4699
|
onGenerateImage,
|
|
@@ -4407,12 +4705,22 @@ function FaApp({
|
|
|
4407
4705
|
onFlowUpload: _onFlowUpload,
|
|
4408
4706
|
onFlowMediaUpload: _onFlowMediaUpload,
|
|
4409
4707
|
libToken,
|
|
4708
|
+
allowDevNamespace,
|
|
4709
|
+
serverBaseUrl,
|
|
4410
4710
|
onFetchServerProjects,
|
|
4411
4711
|
onServerSave,
|
|
4412
4712
|
onServerLoad,
|
|
4413
4713
|
onServerDelete,
|
|
4414
4714
|
buildInfo
|
|
4415
4715
|
}) {
|
|
4716
|
+
const [hfNamespace, setHfNamespace] = useState16(void 0);
|
|
4717
|
+
useEffect7(() => {
|
|
4718
|
+
if (!serverBaseUrl) return;
|
|
4719
|
+
fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
4720
|
+
if (typeof d.hfNamespace === "string") setHfNamespace(d.hfNamespace);
|
|
4721
|
+
}).catch(() => {
|
|
4722
|
+
});
|
|
4723
|
+
}, [serverBaseUrl]);
|
|
4416
4724
|
const wrappedPrompt = async (text, options) => {
|
|
4417
4725
|
const result = await onGeneratePrompt(text, options);
|
|
4418
4726
|
return result.text;
|
|
@@ -4424,7 +4732,9 @@ function FaApp({
|
|
|
4424
4732
|
onGeneratePrompt: wrappedPrompt,
|
|
4425
4733
|
onDownload,
|
|
4426
4734
|
onSelectMedia,
|
|
4427
|
-
initialHfToken: libToken,
|
|
4735
|
+
initialHfToken: libToken ? libToken.startsWith("hf_") ? libToken : `hf_${libToken}` : void 0,
|
|
4736
|
+
hfNamespace,
|
|
4737
|
+
allowDevNamespace: !hfNamespace && allowDevNamespace,
|
|
4428
4738
|
onFetchServerProjects,
|
|
4429
4739
|
onServerSave,
|
|
4430
4740
|
onServerLoad,
|
|
@@ -4435,7 +4745,7 @@ function FaApp({
|
|
|
4435
4745
|
}
|
|
4436
4746
|
|
|
4437
4747
|
// src/index.ts
|
|
4438
|
-
var LIB_VERSION = "
|
|
4748
|
+
var LIB_VERSION = "2.0.12";
|
|
4439
4749
|
export {
|
|
4440
4750
|
AvatarArchitectApp,
|
|
4441
4751
|
CollapsibleCard,
|
|
@@ -4460,9 +4770,12 @@ export {
|
|
|
4460
4770
|
SectionLabel,
|
|
4461
4771
|
SetupPanel,
|
|
4462
4772
|
TagManagerPanel,
|
|
4773
|
+
applyEvent,
|
|
4774
|
+
applyEvents,
|
|
4463
4775
|
autoLabel,
|
|
4464
4776
|
buildBlendInstruction,
|
|
4465
4777
|
buildCompareInstruction,
|
|
4778
|
+
buildDag,
|
|
4466
4779
|
buildFallbackPrompt,
|
|
4467
4780
|
buildGenerationPrompt,
|
|
4468
4781
|
buildImageGenerationOptions,
|
|
@@ -4474,27 +4787,36 @@ export {
|
|
|
4474
4787
|
cleanAiResponse,
|
|
4475
4788
|
createFlowServices,
|
|
4476
4789
|
exportProjectToZip,
|
|
4790
|
+
findForks,
|
|
4791
|
+
findTips,
|
|
4477
4792
|
formatTreeToMarkdown,
|
|
4478
4793
|
frameToGeneration,
|
|
4479
4794
|
getFormattedTimestamp,
|
|
4480
4795
|
getHFToken,
|
|
4796
|
+
getSessionClientId,
|
|
4481
4797
|
groupGenerationsToLabItems,
|
|
4798
|
+
hfBatchArchive,
|
|
4799
|
+
hfBootstrapFromLegacy,
|
|
4482
4800
|
hfDeleteProject,
|
|
4483
4801
|
hfDownloadProject,
|
|
4802
|
+
hfListDir,
|
|
4484
4803
|
hfListProjects,
|
|
4485
4804
|
hfLoadImageAsBase64,
|
|
4486
|
-
hfLoadMetadata,
|
|
4487
|
-
hfLoadTags,
|
|
4488
|
-
hfSaveMetadata,
|
|
4489
|
-
hfSaveTags,
|
|
4490
4805
|
hfUploadImage,
|
|
4491
4806
|
hfUploadProjectForm,
|
|
4807
|
+
hfUploadSmallFile,
|
|
4492
4808
|
importProjectFromZip,
|
|
4493
4809
|
injectXMPMetadata,
|
|
4494
4810
|
interpretSdkError,
|
|
4811
|
+
loadHFState,
|
|
4812
|
+
loadPendingEvents,
|
|
4495
4813
|
parsePromptFile,
|
|
4496
4814
|
parsePromptResponse,
|
|
4497
4815
|
setHFToken,
|
|
4816
|
+
topoSort,
|
|
4817
|
+
tsFromEventPath,
|
|
4818
|
+
useHFState,
|
|
4498
4819
|
useKeyboardNavigation,
|
|
4499
|
-
useOnClickOutside
|
|
4820
|
+
useOnClickOutside,
|
|
4821
|
+
writeHFEvent
|
|
4500
4822
|
};
|