@rslsp1/fa-app-tools 2.0.30 → 2.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-UCEQOGPT.mjs → chunk-TTJTQP43.mjs} +30 -21
- package/dist/{hfStateService-TC65WQXK.mjs → hfStateService-5BU5DVQ6.mjs} +1 -1
- package/dist/index.d.mts +42 -39
- package/dist/index.d.ts +42 -39
- package/dist/index.js +616 -432
- package/dist/index.mjs +539 -358
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
setHFToken,
|
|
22
22
|
tsFromEventPath,
|
|
23
23
|
writeHFEvent
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-TTJTQP43.mjs";
|
|
25
25
|
|
|
26
26
|
// src/hooks/useOnClickOutside.ts
|
|
27
27
|
import { useEffect } from "react";
|
|
@@ -353,8 +353,10 @@ var CompactDropdown = ({
|
|
|
353
353
|
};
|
|
354
354
|
|
|
355
355
|
// src/components/HistoryPanel.tsx
|
|
356
|
+
import { useState as useState2 } from "react";
|
|
356
357
|
import { motion } from "motion/react";
|
|
357
358
|
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
359
|
+
var PAGE_SIZE = 20;
|
|
358
360
|
var formatFriendlyTimestamp = (timestamp) => {
|
|
359
361
|
const date = new Date(timestamp);
|
|
360
362
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -367,38 +369,55 @@ var formatFriendlyTimestamp = (timestamp) => {
|
|
|
367
369
|
return `${date.toLocaleDateString([], { day: "2-digit", month: "2-digit" })}, ${timeStr}`;
|
|
368
370
|
};
|
|
369
371
|
var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
|
|
372
|
+
const [visibleCount, setVisibleCount] = useState2(PAGE_SIZE);
|
|
373
|
+
const visibleHistory = history.slice(0, visibleCount);
|
|
370
374
|
if (history.length === 0) {
|
|
371
375
|
return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col items-center justify-center py-20 text-center gap-4 opacity-10", children: [
|
|
372
376
|
/* @__PURE__ */ jsx5("span", { className: "material-symbols-outlined text-[64px]", children: "history" }),
|
|
373
377
|
/* @__PURE__ */ jsx5("p", { className: "text-[10px] font-bold uppercase tracking-widest", children: "Keine Historie" })
|
|
374
378
|
] });
|
|
375
379
|
}
|
|
376
|
-
return /* @__PURE__ */
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
/* @__PURE__ */ jsxs3("div", { className: "flex
|
|
385
|
-
/* @__PURE__ */
|
|
386
|
-
|
|
380
|
+
return /* @__PURE__ */ jsxs3(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "absolute inset-0 p-4 flex flex-col gap-3 overflow-y-auto dark-scrollbar", children: [
|
|
381
|
+
visibleHistory.map((gen) => /* @__PURE__ */ jsxs3(
|
|
382
|
+
"div",
|
|
383
|
+
{
|
|
384
|
+
className: `flex gap-3 p-2 bg-white/5 border rounded-2xl cursor-pointer group transition-all relative ${currentResultId === gen.id ? "border-white/40 bg-white/10 shadow-lg" : "border-white/5 hover:border-white/20"}`,
|
|
385
|
+
onClick: () => onSelect(gen),
|
|
386
|
+
children: [
|
|
387
|
+
/* @__PURE__ */ jsx5("div", { className: "w-14 h-14 rounded-xl overflow-hidden bg-black shrink-0 border border-white/5 flex items-center justify-center", children: gen.status === "processing" ? /* @__PURE__ */ jsx5("div", { className: "w-5 h-5 border-t-2 border-white/40 rounded-full animate-spin" }) : gen.status === "error" ? /* @__PURE__ */ jsx5("span", { className: "material-symbols-outlined text-red-400 text-[20px]", children: "warning" }) : /* @__PURE__ */ jsx5("img", { src: gen.base64 ? gen.base64.startsWith("data:") ? gen.base64 : `data:image/png;base64,${gen.base64}` : "", className: "w-full h-full object-cover", alt: "Thumbnail" }) }),
|
|
388
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex-1 py-0.5 overflow-hidden", children: [
|
|
389
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between mb-1", children: [
|
|
390
|
+
/* @__PURE__ */ jsx5("span", { className: "text-[7px] font-bold text-white/20 uppercase whitespace-nowrap", children: formatFriendlyTimestamp(gen.timestamp) }),
|
|
391
|
+
gen.model && /* @__PURE__ */ jsx5("span", { className: "text-[7px] font-bold text-white/40 bg-white/5 px-1 rounded uppercase truncate max-w-[60px]", children: gen.model })
|
|
392
|
+
] }),
|
|
393
|
+
/* @__PURE__ */ jsxs3("p", { className: "text-[9px] text-white/60 line-clamp-2 leading-tight", children: [
|
|
394
|
+
'"',
|
|
395
|
+
gen.prompt,
|
|
396
|
+
'"'
|
|
397
|
+
] }),
|
|
398
|
+
gen.status === "processing" && /* @__PURE__ */ jsx5("p", { className: "text-[8px] text-white/30 mt-0.5", children: "Generiert\u2026" }),
|
|
399
|
+
gen.status === "error" && /* @__PURE__ */ jsx5("p", { className: "text-[8px] text-red-400/70 mt-0.5 truncate", children: gen.error?.message })
|
|
387
400
|
] }),
|
|
388
|
-
/* @__PURE__ */
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
401
|
+
/* @__PURE__ */ jsx5(
|
|
402
|
+
"button",
|
|
403
|
+
{
|
|
404
|
+
onClick: (e) => {
|
|
405
|
+
e.stopPropagation();
|
|
406
|
+
onDelete(gen.id);
|
|
407
|
+
},
|
|
408
|
+
className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 w-6 h-6 flex items-center justify-center bg-red-500/20 text-red-400 hover:bg-red-500 hover:text-white rounded-md transition-all",
|
|
409
|
+
children: /* @__PURE__ */ jsx5("span", { className: "material-symbols-outlined text-[14px]", children: "delete" })
|
|
410
|
+
}
|
|
411
|
+
)
|
|
412
|
+
]
|
|
413
|
+
},
|
|
414
|
+
gen.id
|
|
415
|
+
)),
|
|
416
|
+
visibleCount < history.length && /* @__PURE__ */ jsxs3("button", { type: "button", onClick: () => setVisibleCount((c) => c + PAGE_SIZE), className: "w-full py-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-xl text-[10px] font-bold uppercase text-white/60 hover:text-white transition-all", children: [
|
|
417
|
+
history.length - visibleCount,
|
|
418
|
+
" weitere laden"
|
|
419
|
+
] })
|
|
420
|
+
] });
|
|
402
421
|
};
|
|
403
422
|
|
|
404
423
|
// src/components/InspectPanel.tsx
|
|
@@ -467,7 +486,7 @@ var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagTogg
|
|
|
467
486
|
};
|
|
468
487
|
|
|
469
488
|
// src/components/SetupPanel.tsx
|
|
470
|
-
import { useRef as useRef2, useState as
|
|
489
|
+
import { useRef as useRef2, useState as useState3 } from "react";
|
|
471
490
|
import { motion as motion3 } from "motion/react";
|
|
472
491
|
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
473
492
|
var PRESET_URLS = [
|
|
@@ -477,11 +496,11 @@ var PRESET_URLS = [
|
|
|
477
496
|
];
|
|
478
497
|
var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
479
498
|
const workspaceInputRef = useRef2(null);
|
|
480
|
-
const [urlInput, setUrlInput] =
|
|
481
|
-
const [tokenInput, setTokenInput] =
|
|
482
|
-
const [testStatus, setTestStatus] =
|
|
483
|
-
const [result, setResult] =
|
|
484
|
-
const [fetchError, setFetchError] =
|
|
499
|
+
const [urlInput, setUrlInput] = useState3("");
|
|
500
|
+
const [tokenInput, setTokenInput] = useState3("");
|
|
501
|
+
const [testStatus, setTestStatus] = useState3("idle");
|
|
502
|
+
const [result, setResult] = useState3(null);
|
|
503
|
+
const [fetchError, setFetchError] = useState3(null);
|
|
485
504
|
const runTest = async (url) => {
|
|
486
505
|
if (!url.trim()) return;
|
|
487
506
|
setTestStatus("loading");
|
|
@@ -644,18 +663,48 @@ var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
|
644
663
|
};
|
|
645
664
|
|
|
646
665
|
// src/components/MediaLibrary.tsx
|
|
666
|
+
import { useState as useState4 } from "react";
|
|
647
667
|
import { motion as motion4 } from "motion/react";
|
|
668
|
+
|
|
669
|
+
// src/lib/grouping.ts
|
|
670
|
+
function groupByPrompt(items) {
|
|
671
|
+
const map = /* @__PURE__ */ new Map();
|
|
672
|
+
for (const item of items) {
|
|
673
|
+
const key = item.prompt ?? "";
|
|
674
|
+
if (!map.has(key)) map.set(key, []);
|
|
675
|
+
map.get(key).push(item);
|
|
676
|
+
}
|
|
677
|
+
const groups = [];
|
|
678
|
+
for (const [prompt, groupItems] of map) {
|
|
679
|
+
const titled = groupItems.filter((i) => i.titleTs);
|
|
680
|
+
const representative = titled.length > 0 ? titled.reduce((a, b) => a.titleTs > b.titleTs ? a : b) : groupItems.reduce((a, b) => a.timestamp > b.timestamp ? a : b);
|
|
681
|
+
groups.push({ prompt, items: groupItems, representative });
|
|
682
|
+
}
|
|
683
|
+
return groups.sort((a, b) => {
|
|
684
|
+
const aMax = Math.max(...a.items.map((i) => i.timestamp));
|
|
685
|
+
const bMax = Math.max(...b.items.map((i) => i.timestamp));
|
|
686
|
+
return bMax - aMax;
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// src/components/MediaLibrary.tsx
|
|
648
691
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
692
|
+
var PAGE_SIZE2 = 20;
|
|
649
693
|
var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, onBatchDownload, onGenerateReference }) => {
|
|
694
|
+
const [visibleCount, setVisibleCount] = useState4(PAGE_SIZE2);
|
|
650
695
|
const selectedCount = items.filter((i) => i.selectedForExport).length;
|
|
696
|
+
const groups = groupByPrompt(items);
|
|
697
|
+
const visibleGroups = groups.slice(0, visibleCount);
|
|
651
698
|
return /* @__PURE__ */ jsxs6("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
652
699
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col p-4 border-b border-white/5 gap-3 bg-black/20", children: [
|
|
653
700
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between", children: [
|
|
654
701
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col", children: [
|
|
655
702
|
/* @__PURE__ */ jsx8("span", { className: "text-[10px] font-bold text-white uppercase tracking-widest", children: "Projekt Galerie" }),
|
|
656
703
|
/* @__PURE__ */ jsxs6("span", { className: "text-[9px] text-white/30 uppercase tracking-tighter", children: [
|
|
704
|
+
visibleCount < groups.length ? `${visibleCount} / ${groups.length}` : groups.length,
|
|
705
|
+
" Gruppen \xB7 ",
|
|
657
706
|
items.length,
|
|
658
|
-
" Assets
|
|
707
|
+
" Assets"
|
|
659
708
|
] })
|
|
660
709
|
] }),
|
|
661
710
|
/* @__PURE__ */ jsxs6("button", { type: "button", onClick: () => onImport?.(), className: "flex items-center gap-1.5 px-3 py-1.5 bg-blue-500 hover:bg-blue-400 text-white rounded-lg text-[10px] font-bold uppercase transition-all shadow-[0_0_15px_rgba(59,130,246,0.3)]", children: [
|
|
@@ -674,41 +723,57 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
|
|
|
674
723
|
] })
|
|
675
724
|
] })
|
|
676
725
|
] }),
|
|
677
|
-
/* @__PURE__ */ jsx8("div", { className: "flex-1 overflow-y-auto p-4 dark-scrollbar", children:
|
|
726
|
+
/* @__PURE__ */ jsx8("div", { className: "flex-1 overflow-y-auto p-4 dark-scrollbar", children: groups.length === 0 ? /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center justify-center py-20 text-center gap-4 opacity-10", children: [
|
|
678
727
|
/* @__PURE__ */ jsx8("span", { className: "material-symbols-outlined text-[64px]", children: "photo_library" }),
|
|
679
728
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-1", children: [
|
|
680
729
|
/* @__PURE__ */ jsx8("p", { className: "text-[12px] font-bold uppercase tracking-widest", children: "Keine Medien" }),
|
|
681
730
|
/* @__PURE__ */ jsx8("p", { className: "text-[10px] italic", children: "Importiere Assets aus deinem Projekt." })
|
|
682
731
|
] })
|
|
683
|
-
] }) : /* @__PURE__ */
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
/* @__PURE__ */
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
732
|
+
] }) : /* @__PURE__ */ jsxs6("div", { className: "grid grid-cols-2 gap-3 pb-10", children: [
|
|
733
|
+
visibleGroups.map((group) => {
|
|
734
|
+
const rep = group.representative;
|
|
735
|
+
return /* @__PURE__ */ jsxs6(
|
|
736
|
+
motion4.div,
|
|
737
|
+
{
|
|
738
|
+
initial: { opacity: 0, scale: 0.9 },
|
|
739
|
+
animate: { opacity: 1, scale: 1 },
|
|
740
|
+
className: "relative aspect-square group/item rounded-xl overflow-hidden border border-white/10 opacity-70 hover:opacity-100 transition-all bg-white/5 cursor-pointer shadow-lg",
|
|
741
|
+
onClick: () => onSelect(rep),
|
|
742
|
+
children: [
|
|
743
|
+
/* @__PURE__ */ jsx8("img", { src: rep.base64 ? rep.base64.startsWith("data:") ? rep.base64 : `data:image/png;base64,${rep.base64}` : "", className: "w-full h-full object-cover transition-transform duration-500 group-hover/item:scale-110", alt: rep.prompt }),
|
|
744
|
+
group.items.length > 1 && /* @__PURE__ */ jsxs6("div", { className: "absolute top-1.5 left-1.5 px-1.5 py-0.5 bg-black/70 backdrop-blur-md rounded text-[8px] font-bold text-white/80 flex items-center gap-1", children: [
|
|
745
|
+
/* @__PURE__ */ jsx8("span", { className: "material-symbols-outlined text-[10px]", children: "photo_library" }),
|
|
746
|
+
group.items.length
|
|
747
|
+
] }),
|
|
748
|
+
/* @__PURE__ */ jsx8("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-transparent to-transparent opacity-0 group-hover/item:opacity-100 transition-opacity flex flex-col justify-end p-2 gap-2 pointer-events-none", children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between", children: [
|
|
749
|
+
/* @__PURE__ */ jsx8("span", { className: "text-[8px] font-bold text-white/80 truncate max-w-[80px] uppercase tracking-tighter", children: rep.prompt || "Importiert" }),
|
|
750
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1", children: [
|
|
751
|
+
onGenerateReference && /* @__PURE__ */ jsx8("button", { type: "button", onClick: (e) => {
|
|
752
|
+
e.stopPropagation();
|
|
753
|
+
onGenerateReference(rep);
|
|
754
|
+
}, className: "w-6 h-6 flex items-center justify-center bg-blue-500/20 text-blue-400 hover:bg-blue-500 rounded-md transition-all hover:text-white pointer-events-auto", children: /* @__PURE__ */ jsx8("span", { className: "material-symbols-outlined text-[14px]", children: "auto_fix_high" }) }),
|
|
755
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: (e) => {
|
|
756
|
+
e.stopPropagation();
|
|
757
|
+
onDelete(rep.id);
|
|
758
|
+
}, className: "w-6 h-6 flex items-center justify-center bg-red-500/20 text-red-400 hover:bg-red-500 rounded-md transition-all hover:text-white pointer-events-auto", children: /* @__PURE__ */ jsx8("span", { className: "material-symbols-outlined text-[14px]", children: "delete" }) })
|
|
759
|
+
] })
|
|
760
|
+
] }) }),
|
|
761
|
+
/* @__PURE__ */ jsx8("div", { className: "absolute top-1 right-1 px-1.5 py-0.5 bg-black/60 backdrop-blur-md rounded text-[7px] font-bold text-white/60 uppercase tracking-tight", children: rep.type === "import" ? "Library" : "Gen" })
|
|
762
|
+
]
|
|
763
|
+
},
|
|
764
|
+
rep.id
|
|
765
|
+
);
|
|
766
|
+
}),
|
|
767
|
+
visibleCount < groups.length && /* @__PURE__ */ jsx8("div", { className: "col-span-2 flex justify-center pt-2 pb-4", children: /* @__PURE__ */ jsxs6("button", { type: "button", onClick: () => setVisibleCount((c) => c + PAGE_SIZE2), className: "px-4 py-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-lg text-[10px] font-bold uppercase text-white/60 hover:text-white transition-all", children: [
|
|
768
|
+
groups.length - visibleCount,
|
|
769
|
+
" weitere laden"
|
|
770
|
+
] }) })
|
|
771
|
+
] }) })
|
|
707
772
|
] });
|
|
708
773
|
};
|
|
709
774
|
|
|
710
775
|
// src/components/ListView.tsx
|
|
711
|
-
import { useEffect as useEffect3, useRef as useRef3, useState as
|
|
776
|
+
import { useEffect as useEffect3, useRef as useRef3, useState as useState5 } from "react";
|
|
712
777
|
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
713
778
|
var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, isActive, isInPath, onFocus, onGenerate, onGenerateBranch, onGenerateSubtree, isGenerating, isCollapsed, toggleCollapse, renderNode, children }) => {
|
|
714
779
|
const inputRef = useRef3(null);
|
|
@@ -773,7 +838,7 @@ var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNod
|
|
|
773
838
|
] });
|
|
774
839
|
};
|
|
775
840
|
function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, focusedNodeId, onFocus, activePath, onGenerate, onGenerateBranch, onGenerateSubtree, isGeneratingNodeId }) {
|
|
776
|
-
const [collapsed, setCollapsed] =
|
|
841
|
+
const [collapsed, setCollapsed] = useState5(/* @__PURE__ */ new Set());
|
|
777
842
|
const toggleCollapse = (id) => {
|
|
778
843
|
setCollapsed((prev) => {
|
|
779
844
|
const next = new Set(prev);
|
|
@@ -801,13 +866,13 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
|
|
|
801
866
|
}
|
|
802
867
|
|
|
803
868
|
// src/components/AvatarArchitectApp.tsx
|
|
804
|
-
import { useState as
|
|
869
|
+
import { useState as useState20, useCallback as useCallback3, useMemo as useMemo2, useEffect as useEffect7, useRef as useRef8 } from "react";
|
|
805
870
|
|
|
806
871
|
// src/components/PromptTab.tsx
|
|
807
|
-
import { useRef as useRef4, useState as
|
|
872
|
+
import { useRef as useRef4, useState as useState7 } from "react";
|
|
808
873
|
|
|
809
874
|
// src/components/CollapsibleCard.tsx
|
|
810
|
-
import { useState as
|
|
875
|
+
import { useState as useState6 } from "react";
|
|
811
876
|
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
812
877
|
var CollapsibleCard = ({
|
|
813
878
|
title,
|
|
@@ -818,7 +883,7 @@ var CollapsibleCard = ({
|
|
|
818
883
|
collapsible = true,
|
|
819
884
|
className = ""
|
|
820
885
|
}) => {
|
|
821
|
-
const [isOpen, setIsOpen] =
|
|
886
|
+
const [isOpen, setIsOpen] = useState6(defaultOpen);
|
|
822
887
|
return /* @__PURE__ */ jsxs8("div", { className: `border border-neutral-800 rounded-lg ${className}`, children: [
|
|
823
888
|
/* @__PURE__ */ jsxs8(
|
|
824
889
|
"div",
|
|
@@ -865,18 +930,18 @@ var PromptTab = ({
|
|
|
865
930
|
onTagUpdate,
|
|
866
931
|
onTagDelete
|
|
867
932
|
}) => {
|
|
868
|
-
const [selectedLabels, setSelectedLabels] =
|
|
869
|
-
const [instructions, setInstructions] =
|
|
870
|
-
const [rules, setRules] =
|
|
871
|
-
const [activeCategory, setActiveCategory] =
|
|
872
|
-
const [copied, setCopied] =
|
|
933
|
+
const [selectedLabels, setSelectedLabels] = useState7(/* @__PURE__ */ new Set());
|
|
934
|
+
const [instructions, setInstructions] = useState7("");
|
|
935
|
+
const [rules, setRules] = useState7("");
|
|
936
|
+
const [activeCategory, setActiveCategory] = useState7(null);
|
|
937
|
+
const [copied, setCopied] = useState7(false);
|
|
873
938
|
const imgInputRef = useRef4(null);
|
|
874
|
-
const [addingInCat, setAddingInCat] =
|
|
875
|
-
const [newLabel, setNewLabel] =
|
|
876
|
-
const [newValue, setNewValue] =
|
|
877
|
-
const [editingTag, setEditingTag] =
|
|
878
|
-
const [editLabel, setEditLabel] =
|
|
879
|
-
const [editValue, setEditValue] =
|
|
939
|
+
const [addingInCat, setAddingInCat] = useState7(null);
|
|
940
|
+
const [newLabel, setNewLabel] = useState7("");
|
|
941
|
+
const [newValue, setNewValue] = useState7("");
|
|
942
|
+
const [editingTag, setEditingTag] = useState7(null);
|
|
943
|
+
const [editLabel, setEditLabel] = useState7("");
|
|
944
|
+
const [editValue, setEditValue] = useState7("");
|
|
880
945
|
const longPressTimer = useRef4(null);
|
|
881
946
|
const longPressActivated = useRef4(false);
|
|
882
947
|
const toggleTag = (label) => {
|
|
@@ -1325,7 +1390,7 @@ var PromptTab = ({
|
|
|
1325
1390
|
};
|
|
1326
1391
|
|
|
1327
1392
|
// src/components/ProjectSyncTab.tsx
|
|
1328
|
-
import { useRef as useRef5, useState as
|
|
1393
|
+
import { useRef as useRef5, useState as useState8, useEffect as useEffect4 } from "react";
|
|
1329
1394
|
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1330
1395
|
var ProjectSyncTab = ({
|
|
1331
1396
|
topSlot,
|
|
@@ -1347,12 +1412,12 @@ var ProjectSyncTab = ({
|
|
|
1347
1412
|
}) => {
|
|
1348
1413
|
const projectInputRef = useRef5(null);
|
|
1349
1414
|
const workspaceInputRef = useRef5(null);
|
|
1350
|
-
const [saveName, setSaveName] =
|
|
1351
|
-
const [isSaving, setIsSaving] =
|
|
1352
|
-
const [isExporting, setIsExporting] =
|
|
1353
|
-
const [syncState, setSyncState] =
|
|
1354
|
-
const [syncDiff, setSyncDiff] =
|
|
1355
|
-
const [selectedLocalIds, setSelectedLocalIds] =
|
|
1415
|
+
const [saveName, setSaveName] = useState8("");
|
|
1416
|
+
const [isSaving, setIsSaving] = useState8(false);
|
|
1417
|
+
const [isExporting, setIsExporting] = useState8(false);
|
|
1418
|
+
const [syncState, setSyncState] = useState8("idle");
|
|
1419
|
+
const [syncDiff, setSyncDiff] = useState8(null);
|
|
1420
|
+
const [selectedLocalIds, setSelectedLocalIds] = useState8(/* @__PURE__ */ new Set());
|
|
1356
1421
|
const handleExport = async () => {
|
|
1357
1422
|
if (!onProjectExport) return;
|
|
1358
1423
|
setIsExporting(true);
|
|
@@ -1398,13 +1463,13 @@ var ProjectSyncTab = ({
|
|
|
1398
1463
|
});
|
|
1399
1464
|
};
|
|
1400
1465
|
const isWorking = projectActionState === "working" || projectActionState === "working-full";
|
|
1401
|
-
const [hfProjects, setHfProjects] =
|
|
1402
|
-
const [hfLoading, setHfLoading] =
|
|
1403
|
-
const [hfSaving, setHfSaving] =
|
|
1404
|
-
const [hfError, setHfError] =
|
|
1405
|
-
const [hfSaveName, setHfSaveName] =
|
|
1406
|
-
const [hfSyncProgress, setHfSyncProgress] =
|
|
1407
|
-
const [hfSyncing, setHfSyncing] =
|
|
1466
|
+
const [hfProjects, setHfProjects] = useState8([]);
|
|
1467
|
+
const [hfLoading, setHfLoading] = useState8(false);
|
|
1468
|
+
const [hfSaving, setHfSaving] = useState8(false);
|
|
1469
|
+
const [hfError, setHfError] = useState8(null);
|
|
1470
|
+
const [hfSaveName, setHfSaveName] = useState8("");
|
|
1471
|
+
const [hfSyncProgress, setHfSyncProgress] = useState8(null);
|
|
1472
|
+
const [hfSyncing, setHfSyncing] = useState8(false);
|
|
1408
1473
|
const loadHfProjects = async (token) => {
|
|
1409
1474
|
setHfLoading(true);
|
|
1410
1475
|
setHfError(null);
|
|
@@ -1601,7 +1666,7 @@ var ProjectSyncTab = ({
|
|
|
1601
1666
|
{
|
|
1602
1667
|
onClick: async () => {
|
|
1603
1668
|
try {
|
|
1604
|
-
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-
|
|
1669
|
+
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-5BU5DVQ6.mjs");
|
|
1605
1670
|
const file = await hfDownloadProject2(p.path, hfToken);
|
|
1606
1671
|
onHfLoad(file);
|
|
1607
1672
|
} catch (e) {
|
|
@@ -1823,7 +1888,7 @@ function toPromptImages(images) {
|
|
|
1823
1888
|
}
|
|
1824
1889
|
|
|
1825
1890
|
// src/hooks/useHFState.ts
|
|
1826
|
-
import { useState as
|
|
1891
|
+
import { useState as useState9, useEffect as useEffect5, useRef as useRef6, useCallback } from "react";
|
|
1827
1892
|
|
|
1828
1893
|
// src/lib/hfReducer.ts
|
|
1829
1894
|
function applyEvent(state, event) {
|
|
@@ -1844,6 +1909,13 @@ function applyEvent(state, event) {
|
|
|
1844
1909
|
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 }];
|
|
1845
1910
|
return { ...state, tags: { by_category: { ...tags.by_category, [p.category]: newCat }, all: newAll } };
|
|
1846
1911
|
}
|
|
1912
|
+
case "thumb_added": {
|
|
1913
|
+
const p = event.payload;
|
|
1914
|
+
return {
|
|
1915
|
+
...state,
|
|
1916
|
+
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, hasThumb: true } : m)
|
|
1917
|
+
};
|
|
1918
|
+
}
|
|
1847
1919
|
case "metadata_updated": {
|
|
1848
1920
|
const p = event.payload;
|
|
1849
1921
|
return {
|
|
@@ -1851,6 +1923,13 @@ function applyEvent(state, event) {
|
|
|
1851
1923
|
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, ...p.delta } : m)
|
|
1852
1924
|
};
|
|
1853
1925
|
}
|
|
1926
|
+
case "title_set": {
|
|
1927
|
+
const p = event.payload;
|
|
1928
|
+
return {
|
|
1929
|
+
...state,
|
|
1930
|
+
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, titleTs: event.ts } : m)
|
|
1931
|
+
};
|
|
1932
|
+
}
|
|
1854
1933
|
default:
|
|
1855
1934
|
return state;
|
|
1856
1935
|
}
|
|
@@ -1941,15 +2020,15 @@ function writeOfflineBuffer(events) {
|
|
|
1941
2020
|
}
|
|
1942
2021
|
}
|
|
1943
2022
|
function useHFState(token, namespace) {
|
|
1944
|
-
const [state, setState] =
|
|
1945
|
-
const [isLoading, setIsLoading] =
|
|
1946
|
-
const [error, setError] =
|
|
1947
|
-
const [eventCount, setEventCount] =
|
|
1948
|
-
const [localOnlyCount, setLocalOnlyCount] =
|
|
1949
|
-
const [forks, setForks] =
|
|
1950
|
-
const [pendingBufferCount, setPendingBufferCount] =
|
|
1951
|
-
const [lastEventTs, setLastEventTs] =
|
|
1952
|
-
const [hasStateZip, setHasStateZip] =
|
|
2023
|
+
const [state, setState] = useState9(null);
|
|
2024
|
+
const [isLoading, setIsLoading] = useState9(false);
|
|
2025
|
+
const [error, setError] = useState9(null);
|
|
2026
|
+
const [eventCount, setEventCount] = useState9(0);
|
|
2027
|
+
const [localOnlyCount, setLocalOnlyCount] = useState9(0);
|
|
2028
|
+
const [forks, setForks] = useState9([]);
|
|
2029
|
+
const [pendingBufferCount, setPendingBufferCount] = useState9(readOfflineBuffer().length);
|
|
2030
|
+
const [lastEventTs, setLastEventTs] = useState9(0);
|
|
2031
|
+
const [hasStateZip, setHasStateZip] = useState9(false);
|
|
1953
2032
|
const knownEventPaths = useRef6(/* @__PURE__ */ new Set());
|
|
1954
2033
|
const allEventsRef = useRef6([]);
|
|
1955
2034
|
const applyNewEvents = useCallback((snapshot, newEvents) => {
|
|
@@ -2085,13 +2164,13 @@ function useHFState(token, namespace) {
|
|
|
2085
2164
|
}
|
|
2086
2165
|
|
|
2087
2166
|
// src/components/labs/LabsTab.tsx
|
|
2088
|
-
import { useState as
|
|
2167
|
+
import { useState as useState16 } from "react";
|
|
2089
2168
|
|
|
2090
2169
|
// src/components/labs/LabRemix.tsx
|
|
2091
|
-
import { useState as
|
|
2170
|
+
import { useState as useState11 } from "react";
|
|
2092
2171
|
|
|
2093
2172
|
// src/components/labs/LabImagePicker.tsx
|
|
2094
|
-
import { useState as
|
|
2173
|
+
import { useState as useState10 } from "react";
|
|
2095
2174
|
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2096
2175
|
var LabImagePicker = ({
|
|
2097
2176
|
availableItems,
|
|
@@ -2100,8 +2179,8 @@ var LabImagePicker = ({
|
|
|
2100
2179
|
onClose,
|
|
2101
2180
|
title = "Bild w\xE4hlen"
|
|
2102
2181
|
}) => {
|
|
2103
|
-
const [search, setSearch] =
|
|
2104
|
-
const [drillItem, setDrillItem] =
|
|
2182
|
+
const [search, setSearch] = useState10("");
|
|
2183
|
+
const [drillItem, setDrillItem] = useState10(null);
|
|
2105
2184
|
const filtered = availableItems.filter(
|
|
2106
2185
|
(item) => !search || item.prompt.toLowerCase().includes(search.toLowerCase())
|
|
2107
2186
|
);
|
|
@@ -2203,13 +2282,13 @@ var LabImagePicker = ({
|
|
|
2203
2282
|
// src/components/labs/LabRemix.tsx
|
|
2204
2283
|
import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2205
2284
|
var LabRemix = ({ services, onResult }) => {
|
|
2206
|
-
const [showPicker, setShowPicker] =
|
|
2207
|
-
const [selected, setSelected] =
|
|
2208
|
-
const [instruction, setInstruction] =
|
|
2209
|
-
const [generatedPrompt, setGeneratedPrompt] =
|
|
2210
|
-
const [resultImage, setResultImage] =
|
|
2211
|
-
const [isGeneratingPrompt, setIsGeneratingPrompt] =
|
|
2212
|
-
const [isGeneratingImage, setIsGeneratingImage] =
|
|
2285
|
+
const [showPicker, setShowPicker] = useState11(false);
|
|
2286
|
+
const [selected, setSelected] = useState11(null);
|
|
2287
|
+
const [instruction, setInstruction] = useState11("");
|
|
2288
|
+
const [generatedPrompt, setGeneratedPrompt] = useState11("");
|
|
2289
|
+
const [resultImage, setResultImage] = useState11(null);
|
|
2290
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = useState11(false);
|
|
2291
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState11(false);
|
|
2213
2292
|
const handleSelectImage = (item, frame) => {
|
|
2214
2293
|
services.onItemUsed(item);
|
|
2215
2294
|
setSelected({
|
|
@@ -2392,16 +2471,16 @@ var LabRemix = ({ services, onResult }) => {
|
|
|
2392
2471
|
};
|
|
2393
2472
|
|
|
2394
2473
|
// src/components/labs/LabBlend.tsx
|
|
2395
|
-
import { useState as
|
|
2474
|
+
import { useState as useState12 } from "react";
|
|
2396
2475
|
import { Fragment as Fragment6, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2397
2476
|
var LabBlend = ({ services, onResult }) => {
|
|
2398
|
-
const [showPickerFor, setShowPickerFor] =
|
|
2399
|
-
const [selectedImages, setSelectedImages] =
|
|
2400
|
-
const [instruction, setInstruction] =
|
|
2401
|
-
const [generatedPrompt, setGeneratedPrompt] =
|
|
2402
|
-
const [resultImage, setResultImage] =
|
|
2403
|
-
const [isGeneratingPrompt, setIsGeneratingPrompt] =
|
|
2404
|
-
const [isGeneratingImage, setIsGeneratingImage] =
|
|
2477
|
+
const [showPickerFor, setShowPickerFor] = useState12(null);
|
|
2478
|
+
const [selectedImages, setSelectedImages] = useState12([]);
|
|
2479
|
+
const [instruction, setInstruction] = useState12("");
|
|
2480
|
+
const [generatedPrompt, setGeneratedPrompt] = useState12("");
|
|
2481
|
+
const [resultImage, setResultImage] = useState12(null);
|
|
2482
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = useState12(false);
|
|
2483
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState12(false);
|
|
2405
2484
|
const handleSelectImage = (index, item, frame) => {
|
|
2406
2485
|
services.onItemUsed(item);
|
|
2407
2486
|
const newImg = {
|
|
@@ -2588,17 +2667,17 @@ var LabBlend = ({ services, onResult }) => {
|
|
|
2588
2667
|
};
|
|
2589
2668
|
|
|
2590
2669
|
// src/components/labs/LabCompare.tsx
|
|
2591
|
-
import { useState as
|
|
2670
|
+
import { useState as useState13 } from "react";
|
|
2592
2671
|
import { Fragment as Fragment7, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2593
2672
|
var LabCompare = ({ services, onResult }) => {
|
|
2594
|
-
const [showPickerFor, setShowPickerFor] =
|
|
2595
|
-
const [selectedImages, setSelectedImages] =
|
|
2596
|
-
const [instruction, setInstruction] =
|
|
2597
|
-
const [analysis, setAnalysis] =
|
|
2598
|
-
const [generatedPrompt, setGeneratedPrompt] =
|
|
2599
|
-
const [resultImage, setResultImage] =
|
|
2600
|
-
const [isAnalyzing, setIsAnalyzing] =
|
|
2601
|
-
const [isGeneratingImage, setIsGeneratingImage] =
|
|
2673
|
+
const [showPickerFor, setShowPickerFor] = useState13(null);
|
|
2674
|
+
const [selectedImages, setSelectedImages] = useState13([]);
|
|
2675
|
+
const [instruction, setInstruction] = useState13("");
|
|
2676
|
+
const [analysis, setAnalysis] = useState13("");
|
|
2677
|
+
const [generatedPrompt, setGeneratedPrompt] = useState13("");
|
|
2678
|
+
const [resultImage, setResultImage] = useState13(null);
|
|
2679
|
+
const [isAnalyzing, setIsAnalyzing] = useState13(false);
|
|
2680
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState13(false);
|
|
2602
2681
|
const handleSelectImage = (index, item, frame) => {
|
|
2603
2682
|
services.onItemUsed(item);
|
|
2604
2683
|
const newImg = {
|
|
@@ -2761,14 +2840,14 @@ var LabCompare = ({ services, onResult }) => {
|
|
|
2761
2840
|
};
|
|
2762
2841
|
|
|
2763
2842
|
// src/components/labs/LabLoop.tsx
|
|
2764
|
-
import { useState as
|
|
2843
|
+
import { useState as useState14 } from "react";
|
|
2765
2844
|
import { Fragment as Fragment8, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2766
2845
|
var LabLoop = ({ services, onResult }) => {
|
|
2767
|
-
const [rounds, setRounds] =
|
|
2768
|
-
const [currentInstruction, setCurrentInstruction] =
|
|
2769
|
-
const [showPickerForRound, setShowPickerForRound] =
|
|
2770
|
-
const [pendingImages, setPendingImages] =
|
|
2771
|
-
const [isGenerating, setIsGenerating] =
|
|
2846
|
+
const [rounds, setRounds] = useState14([]);
|
|
2847
|
+
const [currentInstruction, setCurrentInstruction] = useState14("");
|
|
2848
|
+
const [showPickerForRound, setShowPickerForRound] = useState14(null);
|
|
2849
|
+
const [pendingImages, setPendingImages] = useState14([]);
|
|
2850
|
+
const [isGenerating, setIsGenerating] = useState14(false);
|
|
2772
2851
|
const currentPrompt = rounds.length > 0 ? rounds[rounds.length - 1].prompt : "";
|
|
2773
2852
|
const handleAddImage = (item, frame) => {
|
|
2774
2853
|
services.onItemUsed(item);
|
|
@@ -2924,7 +3003,7 @@ var LabLoop = ({ services, onResult }) => {
|
|
|
2924
3003
|
};
|
|
2925
3004
|
|
|
2926
3005
|
// src/components/labs/LabFrameExtractor.tsx
|
|
2927
|
-
import { useRef as useRef7, useState as
|
|
3006
|
+
import { useRef as useRef7, useState as useState15, useCallback as useCallback2 } from "react";
|
|
2928
3007
|
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2929
3008
|
var formatTime = (s) => {
|
|
2930
3009
|
const m = Math.floor(s / 60);
|
|
@@ -2941,12 +3020,12 @@ var LabFrameExtractor = ({
|
|
|
2941
3020
|
const videoRef = useRef7(null);
|
|
2942
3021
|
const canvasRef = useRef7(null);
|
|
2943
3022
|
const cancelledRef = useRef7(false);
|
|
2944
|
-
const [selectedItem, setSelectedItem] =
|
|
2945
|
-
const [videoSrc, setVideoSrc] =
|
|
2946
|
-
const [videoReady, setVideoReady] =
|
|
2947
|
-
const [frames, setFrames] =
|
|
2948
|
-
const [isExtracting, setIsExtracting] =
|
|
2949
|
-
const [intervalSec, setIntervalSec] =
|
|
3023
|
+
const [selectedItem, setSelectedItem] = useState15(null);
|
|
3024
|
+
const [videoSrc, setVideoSrc] = useState15(null);
|
|
3025
|
+
const [videoReady, setVideoReady] = useState15(false);
|
|
3026
|
+
const [frames, setFrames] = useState15([]);
|
|
3027
|
+
const [isExtracting, setIsExtracting] = useState15(false);
|
|
3028
|
+
const [intervalSec, setIntervalSec] = useState15("1");
|
|
2950
3029
|
const handleVideoSelect = (item) => {
|
|
2951
3030
|
const mediaId = item.frames[0]?.mediaId;
|
|
2952
3031
|
if (!mediaId) return;
|
|
@@ -3183,7 +3262,7 @@ var BASE_TABS = [
|
|
|
3183
3262
|
];
|
|
3184
3263
|
var FRAMES_TAB = { key: "frames", label: "Frames", icon: "crop_original" };
|
|
3185
3264
|
var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
|
|
3186
|
-
const [activeTab, setActiveTab] =
|
|
3265
|
+
const [activeTab, setActiveTab] = useState16("remix");
|
|
3187
3266
|
const showFrames = !!(videoItems && resolveVideoUrl);
|
|
3188
3267
|
const tabs = showFrames ? [...BASE_TABS, FRAMES_TAB] : BASE_TABS;
|
|
3189
3268
|
return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
@@ -3217,19 +3296,19 @@ var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
|
|
|
3217
3296
|
};
|
|
3218
3297
|
|
|
3219
3298
|
// src/components/TagManagerPanel.tsx
|
|
3220
|
-
import { useState as
|
|
3299
|
+
import { useState as useState17 } from "react";
|
|
3221
3300
|
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3222
3301
|
function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete, onTagReorder, onTagMove }) {
|
|
3223
3302
|
const categories = Object.keys(workspaceTags.by_category).filter(
|
|
3224
3303
|
(cat) => (workspaceTags.by_category[cat] || []).some((t) => !t.is_deleted)
|
|
3225
3304
|
);
|
|
3226
|
-
const [selectedCategory, setSelectedCategory] =
|
|
3305
|
+
const [selectedCategory, setSelectedCategory] = useState17(categories[0] || "");
|
|
3227
3306
|
const effectiveCategory = categories.includes(selectedCategory) ? selectedCategory : categories[0] || "";
|
|
3228
|
-
const [editingLabel, setEditingLabel] =
|
|
3229
|
-
const [editState, setEditState] =
|
|
3230
|
-
const [newTag, setNewTag] =
|
|
3231
|
-
const [movingLabel, setMovingLabel] =
|
|
3232
|
-
const [moveTarget, setMoveTarget] =
|
|
3307
|
+
const [editingLabel, setEditingLabel] = useState17(null);
|
|
3308
|
+
const [editState, setEditState] = useState17({ label: "", value: "" });
|
|
3309
|
+
const [newTag, setNewTag] = useState17({ label: "", value: "" });
|
|
3310
|
+
const [movingLabel, setMovingLabel] = useState17(null);
|
|
3311
|
+
const [moveTarget, setMoveTarget] = useState17("");
|
|
3233
3312
|
const tags = (workspaceTags.by_category[effectiveCategory] || []).filter((t) => !t.is_deleted);
|
|
3234
3313
|
const otherCategories = categories.filter((c) => c !== effectiveCategory);
|
|
3235
3314
|
const startEdit = (tag) => {
|
|
@@ -3425,7 +3504,7 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
|
|
|
3425
3504
|
}
|
|
3426
3505
|
|
|
3427
3506
|
// src/components/HFTestTab.tsx
|
|
3428
|
-
import { useState as
|
|
3507
|
+
import { useState as useState18 } from "react";
|
|
3429
3508
|
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3430
3509
|
var HF_BASE = "https://huggingface.co";
|
|
3431
3510
|
var HF_REPO = "RolandSch/fa-app-state";
|
|
@@ -3618,7 +3697,7 @@ function tryFmt(s) {
|
|
|
3618
3697
|
}
|
|
3619
3698
|
}
|
|
3620
3699
|
function CopyBtn({ text }) {
|
|
3621
|
-
const [done, setDone] =
|
|
3700
|
+
const [done, setDone] = useState18(false);
|
|
3622
3701
|
return /* @__PURE__ */ jsxs19(
|
|
3623
3702
|
"button",
|
|
3624
3703
|
{
|
|
@@ -3789,10 +3868,10 @@ function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadSta
|
|
|
3789
3868
|
] })
|
|
3790
3869
|
] });
|
|
3791
3870
|
}
|
|
3792
|
-
function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEventKeys = /* @__PURE__ */ new Set(), imageUploadStatus = /* @__PURE__ */ new Map() }) {
|
|
3793
|
-
const [selected, setSelected] =
|
|
3794
|
-
const [results, setResults] =
|
|
3795
|
-
const [expanded, setExpanded] =
|
|
3871
|
+
function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEventKeys = /* @__PURE__ */ new Set(), imageUploadStatus = /* @__PURE__ */ new Map(), missingImages = [] }) {
|
|
3872
|
+
const [selected, setSelected] = useState18(null);
|
|
3873
|
+
const [results, setResults] = useState18({});
|
|
3874
|
+
const [expanded, setExpanded] = useState18({});
|
|
3796
3875
|
const withResults = galleryItems.filter((g) => g.base64 && g.status === "done");
|
|
3797
3876
|
const setRunning = (id) => setResults((r) => ({ ...r, [id]: { status: "running", steps: [], totalMs: 0 } }));
|
|
3798
3877
|
const setDone = (id, steps, t0) => {
|
|
@@ -3859,6 +3938,33 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
|
|
|
3859
3938
|
)
|
|
3860
3939
|
}
|
|
3861
3940
|
) }),
|
|
3941
|
+
missingImages.length > 0 && /* @__PURE__ */ jsx21("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ jsx21(
|
|
3942
|
+
CollapsibleCard,
|
|
3943
|
+
{
|
|
3944
|
+
title: `Fehlende Bilder auf HF (${missingImages.length})`,
|
|
3945
|
+
icon: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "broken_image" }),
|
|
3946
|
+
defaultOpen: false,
|
|
3947
|
+
children: /* @__PURE__ */ jsxs19("div", { style: { padding: "8px 10px 4px" }, children: [
|
|
3948
|
+
/* @__PURE__ */ jsx21("div", { style: { fontSize: 11, color: "rgba(255,255,255,0.4)", marginBottom: 8 }, children: "Metadata-Eintr\xE4ge ohne Bild auf HuggingFace \u2014 Orphaned entries." }),
|
|
3949
|
+
/* @__PURE__ */ jsxs19("div", { style: { display: "flex", gap: 8, marginBottom: 8, fontSize: 11, color: "rgba(255,255,255,0.5)" }, children: [
|
|
3950
|
+
/* @__PURE__ */ jsxs19("span", { children: [
|
|
3951
|
+
"UUID (Flow-App): ",
|
|
3952
|
+
missingImages.filter((e) => !e.filename).length
|
|
3953
|
+
] }),
|
|
3954
|
+
/* @__PURE__ */ jsx21("span", { children: "\xB7" }),
|
|
3955
|
+
/* @__PURE__ */ jsxs19("span", { children: [
|
|
3956
|
+
"Filename (Server-Upload): ",
|
|
3957
|
+
missingImages.filter((e) => !!e.filename).length
|
|
3958
|
+
] })
|
|
3959
|
+
] }),
|
|
3960
|
+
/* @__PURE__ */ jsx21("div", { style: { maxHeight: 300, overflowY: "auto", fontFamily: "monospace", fontSize: 10 }, children: missingImages.map((e) => /* @__PURE__ */ jsxs19("div", { style: { padding: "3px 0", borderBottom: "1px solid rgba(255,255,255,0.04)", color: "rgba(255,255,255,0.5)", display: "flex", gap: 8 }, children: [
|
|
3961
|
+
/* @__PURE__ */ jsx21("span", { style: { color: e.filename ? "#fb923c" : "#60a5fa", minWidth: 60 }, children: e.filename ? "filename" : "uuid" }),
|
|
3962
|
+
/* @__PURE__ */ jsx21("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: e.filename ?? e.id }),
|
|
3963
|
+
/* @__PURE__ */ jsx21("span", { style: { color: "rgba(255,255,255,0.3)" }, children: new Date(e.timestamp).toLocaleDateString("de") })
|
|
3964
|
+
] }, e.id)) })
|
|
3965
|
+
] })
|
|
3966
|
+
}
|
|
3967
|
+
) }),
|
|
3862
3968
|
/* @__PURE__ */ jsx21(
|
|
3863
3969
|
CollapsibleCard,
|
|
3864
3970
|
{
|
|
@@ -3963,75 +4069,44 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
|
|
|
3963
4069
|
}
|
|
3964
4070
|
|
|
3965
4071
|
// src/components/ServerTab.tsx
|
|
3966
|
-
import { useState as
|
|
3967
|
-
|
|
3968
|
-
// src/lib/faHfServerService.ts
|
|
3969
|
-
var FA_APP_SPACE = "https://rolandsch-fa-app.hf.space";
|
|
3970
|
-
async function request(method, path, env = "prod", body, tokenOverride) {
|
|
3971
|
-
const token = tokenOverride || getHFToken();
|
|
3972
|
-
if (!token) throw new Error("fa-app gateway: kein HF Token gesetzt");
|
|
3973
|
-
const res = await fetch(`${FA_APP_SPACE}/${path.replace(/^\//, "")}`, {
|
|
3974
|
-
method,
|
|
3975
|
-
headers: {
|
|
3976
|
-
"Authorization": `Bearer ${token}`,
|
|
3977
|
-
"X-Env": env,
|
|
3978
|
-
...body !== void 0 ? { "Content-Type": "application/json" } : {}
|
|
3979
|
-
},
|
|
3980
|
-
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
3981
|
-
});
|
|
3982
|
-
if (!res.ok) {
|
|
3983
|
-
const text = await res.text().catch(() => "");
|
|
3984
|
-
throw new Error(`fa-app gateway ${method} /${path} [${env}] \u2192 ${res.status}: ${text.slice(0, 200)}`);
|
|
3985
|
-
}
|
|
3986
|
-
return res.json();
|
|
3987
|
-
}
|
|
3988
|
-
function faServerGet(path, env = "prod", token) {
|
|
3989
|
-
return request("GET", path, env, void 0, token);
|
|
3990
|
-
}
|
|
3991
|
-
function faServerPost(path, body, env = "prod", token) {
|
|
3992
|
-
return request("POST", path, env, body, token);
|
|
3993
|
-
}
|
|
3994
|
-
function faServerPut(path, body, env = "prod", token) {
|
|
3995
|
-
return request("PUT", path, env, body, token);
|
|
3996
|
-
}
|
|
3997
|
-
function faServerDelete(path, env = "prod", token) {
|
|
3998
|
-
return request("DELETE", path, env, void 0, token);
|
|
3999
|
-
}
|
|
4000
|
-
|
|
4001
|
-
// src/components/ServerTab.tsx
|
|
4072
|
+
import { useState as useState19, useEffect as useEffect6 } from "react";
|
|
4002
4073
|
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4003
4074
|
function StarRating({ rating = 0 }) {
|
|
4004
4075
|
return /* @__PURE__ */ jsx22("div", { className: "flex gap-[2px]", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsx22("span", { className: `material-symbols-outlined text-[12px] ${i <= rating ? "text-yellow-400" : "text-white/15"}`, children: "star" }, i)) });
|
|
4005
4076
|
}
|
|
4006
|
-
function
|
|
4007
|
-
const
|
|
4008
|
-
const
|
|
4009
|
-
|
|
4010
|
-
const
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
const [
|
|
4015
|
-
const [
|
|
4016
|
-
const [
|
|
4017
|
-
const [
|
|
4018
|
-
const [
|
|
4019
|
-
const [
|
|
4020
|
-
const [
|
|
4021
|
-
const [
|
|
4022
|
-
const [
|
|
4023
|
-
const [
|
|
4077
|
+
async function serverGet(baseUrl, path) {
|
|
4078
|
+
const url = `${baseUrl.replace(/\/$/, "")}${path}`;
|
|
4079
|
+
const res = await fetch(url, { credentials: "include" });
|
|
4080
|
+
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
|
|
4081
|
+
const json = await res.json();
|
|
4082
|
+
return json && typeof json === "object" && "data" in json ? json.data : json;
|
|
4083
|
+
}
|
|
4084
|
+
function ServerTab({ serverBaseUrl }) {
|
|
4085
|
+
const [step, setStep] = useState19("user");
|
|
4086
|
+
const [users, setUsers] = useState19([]);
|
|
4087
|
+
const [usersLoading, setUsersLoading] = useState19(false);
|
|
4088
|
+
const [usersError, setUsersError] = useState19(null);
|
|
4089
|
+
const [selectedUser, setSelectedUser] = useState19(null);
|
|
4090
|
+
const [contexts, setContexts] = useState19([]);
|
|
4091
|
+
const [contextsLoading, setContextsLoading] = useState19(false);
|
|
4092
|
+
const [selectedContext, setSelectedContext] = useState19(null);
|
|
4093
|
+
const [tags, setTags] = useState19([]);
|
|
4094
|
+
const [items, setItems] = useState19([]);
|
|
4095
|
+
const [libLoading, setLibLoading] = useState19(false);
|
|
4096
|
+
const [libError, setLibError] = useState19(null);
|
|
4097
|
+
const [activeTag, setActiveTag] = useState19(null);
|
|
4098
|
+
const [preview, setPreview] = useState19(null);
|
|
4024
4099
|
useEffect6(() => {
|
|
4025
|
-
if (!
|
|
4100
|
+
if (!serverBaseUrl) return;
|
|
4026
4101
|
setUsersLoading(true);
|
|
4027
4102
|
setUsersError(null);
|
|
4028
|
-
|
|
4029
|
-
}, [
|
|
4103
|
+
serverGet(serverBaseUrl, "/api/v2/users").then(setUsers).catch((e) => setUsersError(String(e))).finally(() => setUsersLoading(false));
|
|
4104
|
+
}, [serverBaseUrl]);
|
|
4030
4105
|
const selectUser = async (user) => {
|
|
4031
4106
|
setSelectedUser(user);
|
|
4032
4107
|
setContextsLoading(true);
|
|
4033
4108
|
try {
|
|
4034
|
-
const data = await
|
|
4109
|
+
const data = await serverGet(serverBaseUrl, `/api2/contexts?user_id=${user.id}`);
|
|
4035
4110
|
if (data.length === 1) {
|
|
4036
4111
|
await loadLibrary(user, data[0]);
|
|
4037
4112
|
} else {
|
|
@@ -4051,12 +4126,11 @@ function ServerTab({ hfToken }) {
|
|
|
4051
4126
|
setLibError(null);
|
|
4052
4127
|
try {
|
|
4053
4128
|
const [tagsRes, libRes] = await Promise.all([
|
|
4054
|
-
|
|
4055
|
-
|
|
4129
|
+
serverGet(serverBaseUrl, `/api2/tags?user_id=${user.id}`),
|
|
4130
|
+
serverGet(serverBaseUrl, `/api/storage/${user.id}/library`)
|
|
4056
4131
|
]);
|
|
4057
4132
|
setTags(Array.isArray(tagsRes) ? tagsRes : []);
|
|
4058
|
-
|
|
4059
|
-
setItems(raw);
|
|
4133
|
+
setItems(Array.isArray(libRes) ? libRes : []);
|
|
4060
4134
|
} catch (e) {
|
|
4061
4135
|
setLibError(String(e));
|
|
4062
4136
|
} finally {
|
|
@@ -4075,13 +4149,7 @@ function ServerTab({ hfToken }) {
|
|
|
4075
4149
|
setLibError(null);
|
|
4076
4150
|
};
|
|
4077
4151
|
const filteredItems = activeTag ? items.filter((item) => item.tags?.some((t) => t.l === activeTag)) : items;
|
|
4078
|
-
if (!
|
|
4079
|
-
return /* @__PURE__ */ jsx22("div", { className: "flex items-center justify-center h-full p-6", children: /* @__PURE__ */ jsxs20("p", { className: "text-white/30 text-[12px] text-center", children: [
|
|
4080
|
-
"Kein HF Token gesetzt.",
|
|
4081
|
-
/* @__PURE__ */ jsx22("br", {}),
|
|
4082
|
-
"Bitte zuerst im Setup-Tab einrichten."
|
|
4083
|
-
] }) });
|
|
4084
|
-
}
|
|
4152
|
+
if (!serverBaseUrl) return null;
|
|
4085
4153
|
return /* @__PURE__ */ jsxs20("div", { className: "flex flex-col h-full min-h-0", children: [
|
|
4086
4154
|
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-white/8", children: [
|
|
4087
4155
|
step !== "user" && /* @__PURE__ */ jsx22("button", { onClick: reset, className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ jsx22("span", { className: "material-symbols-outlined text-[18px]", children: "arrow_back" }) }),
|
|
@@ -4089,16 +4157,7 @@ function ServerTab({ hfToken }) {
|
|
|
4089
4157
|
step === "user" && "Server Browser",
|
|
4090
4158
|
step === "context" && `${selectedUser?.username} \u2014 Kontext w\xE4hlen`,
|
|
4091
4159
|
step === "library" && `${selectedUser?.username} / ${selectedContext?.label || selectedContext?.name || selectedContext?.id}`
|
|
4092
|
-
] })
|
|
4093
|
-
step === "user" && /* @__PURE__ */ jsx22("div", { className: "flex gap-1", children: ["prod", "dev"].map((e) => /* @__PURE__ */ jsx22(
|
|
4094
|
-
"button",
|
|
4095
|
-
{
|
|
4096
|
-
onClick: () => setEnv(e),
|
|
4097
|
-
className: `text-[10px] font-bold px-2 py-0.5 rounded-lg transition-colors ${env === e ? "bg-white/15 text-white" : "text-white/30 hover:text-white/60"}`,
|
|
4098
|
-
children: e
|
|
4099
|
-
},
|
|
4100
|
-
e
|
|
4101
|
-
)) })
|
|
4160
|
+
] })
|
|
4102
4161
|
] }),
|
|
4103
4162
|
step === "user" && /* @__PURE__ */ jsxs20("div", { className: "flex flex-col flex-1 min-h-0 overflow-y-auto p-3 gap-2", children: [
|
|
4104
4163
|
usersLoading && /* @__PURE__ */ jsx22("p", { className: "text-white/30 text-[11px] text-center py-4", children: "Lade User\u2026" }),
|
|
@@ -4189,7 +4248,7 @@ function ServerTab({ hfToken }) {
|
|
|
4189
4248
|
|
|
4190
4249
|
// src/components/AvatarArchitectApp.tsx
|
|
4191
4250
|
import { Fragment as Fragment9, jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4192
|
-
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
4251
|
+
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, serverBaseUrl, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
4193
4252
|
useEffect7(() => {
|
|
4194
4253
|
const id = "flow-styles";
|
|
4195
4254
|
if (!document.getElementById(id)) {
|
|
@@ -4199,28 +4258,28 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4199
4258
|
document.head.appendChild(style);
|
|
4200
4259
|
}
|
|
4201
4260
|
}, []);
|
|
4202
|
-
const [showStart, setShowStart] =
|
|
4203
|
-
const [layoutChoice, setLayoutChoice] =
|
|
4261
|
+
const [showStart, setShowStart] = useState20(true);
|
|
4262
|
+
const [layoutChoice, setLayoutChoice] = useState20(() => {
|
|
4204
4263
|
try {
|
|
4205
4264
|
return localStorage.getItem("aa-layout") || null;
|
|
4206
4265
|
} catch {
|
|
4207
4266
|
return null;
|
|
4208
4267
|
}
|
|
4209
4268
|
});
|
|
4210
|
-
const [projectLoaded, setProjectLoaded] =
|
|
4211
|
-
const [hfToken, setHfToken] =
|
|
4212
|
-
const [hfTokenInput, setHfTokenInput] =
|
|
4213
|
-
const [isLoadingFromHF, setIsLoadingFromHF] =
|
|
4214
|
-
const [hfNamespaceLocal, setHfNamespaceLocal] =
|
|
4269
|
+
const [projectLoaded, setProjectLoaded] = useState20(false);
|
|
4270
|
+
const [hfToken, setHfToken] = useState20(initialHfToken || "");
|
|
4271
|
+
const [hfTokenInput, setHfTokenInput] = useState20(initialHfToken || "");
|
|
4272
|
+
const [isLoadingFromHF, setIsLoadingFromHF] = useState20(false);
|
|
4273
|
+
const [hfNamespaceLocal, setHfNamespaceLocal] = useState20(() => {
|
|
4215
4274
|
try {
|
|
4216
4275
|
const stored = localStorage.getItem("aa-hf-namespace");
|
|
4217
4276
|
if (stored !== null) return stored;
|
|
4218
|
-
return
|
|
4277
|
+
return "app.art-by-rolands.de/";
|
|
4219
4278
|
} catch {
|
|
4220
4279
|
return "";
|
|
4221
4280
|
}
|
|
4222
4281
|
});
|
|
4223
|
-
const [hfNamespaceFromServer, setHfNamespaceFromServer] =
|
|
4282
|
+
const [hfNamespaceFromServer, setHfNamespaceFromServer] = useState20(null);
|
|
4224
4283
|
useEffect7(() => {
|
|
4225
4284
|
if (hfNamespace !== void 0) return;
|
|
4226
4285
|
const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
|
|
@@ -4243,9 +4302,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4243
4302
|
refresh: refreshHF,
|
|
4244
4303
|
hasStateZip
|
|
4245
4304
|
} = useHFState(hfToken, effectiveNamespace);
|
|
4246
|
-
const [imageUploadStatus, setImageUploadStatus] =
|
|
4247
|
-
const [bootstrapLog, setBootstrapLog] =
|
|
4248
|
-
const [isBootstrapping, setIsBootstrapping] =
|
|
4305
|
+
const [imageUploadStatus, setImageUploadStatus] = useState20(/* @__PURE__ */ new Map());
|
|
4306
|
+
const [bootstrapLog, setBootstrapLog] = useState20([]);
|
|
4307
|
+
const [isBootstrapping, setIsBootstrapping] = useState20(false);
|
|
4308
|
+
const [hfMissingImages, setHfMissingImages] = useState20([]);
|
|
4249
4309
|
const syncTopSlot = /* @__PURE__ */ jsxs21(Fragment9, { children: [
|
|
4250
4310
|
localOnlyCount > 0 && /* @__PURE__ */ jsxs21("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: [
|
|
4251
4311
|
"\u26A0 ",
|
|
@@ -4304,10 +4364,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4304
4364
|
setLayoutChoice(choice);
|
|
4305
4365
|
setShowStart(false);
|
|
4306
4366
|
};
|
|
4307
|
-
const [nodes, setNodes] =
|
|
4308
|
-
const [edges, setEdges] =
|
|
4309
|
-
const [history, setHistory] =
|
|
4310
|
-
const [galleryItems, setGalleryItems] =
|
|
4367
|
+
const [nodes, setNodes] = useState20([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
|
|
4368
|
+
const [edges, setEdges] = useState20([]);
|
|
4369
|
+
const [history, setHistory] = useState20([]);
|
|
4370
|
+
const [galleryItems, setGalleryItems] = useState20([]);
|
|
4311
4371
|
const galleryItemsRef = useRef8([]);
|
|
4312
4372
|
useEffect7(() => {
|
|
4313
4373
|
galleryItemsRef.current = galleryItems;
|
|
@@ -4325,7 +4385,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4325
4385
|
model: m.model,
|
|
4326
4386
|
tags: m.tags || [],
|
|
4327
4387
|
timestamp: m.timestamp,
|
|
4328
|
-
status: "done"
|
|
4388
|
+
status: "done",
|
|
4389
|
+
filename: m.filename,
|
|
4390
|
+
hasThumb: m.hasThumb
|
|
4329
4391
|
}));
|
|
4330
4392
|
setGalleryItems((prev) => {
|
|
4331
4393
|
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
@@ -4337,77 +4399,83 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4337
4399
|
const merged = skeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
4338
4400
|
return [...localOnly, ...merged].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
4339
4401
|
});
|
|
4340
|
-
const
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4402
|
+
const sortedEntries = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
4403
|
+
(async () => {
|
|
4404
|
+
for (const entry of sortedEntries) {
|
|
4405
|
+
if (galleryItemsRef.current.find((g) => g.id === entry.id)?.base64) continue;
|
|
4406
|
+
if (hfImageNotFoundRef.current.has(entry.id)) continue;
|
|
4407
|
+
try {
|
|
4408
|
+
const b64 = await hfLoadImageAsBase64(entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb);
|
|
4409
|
+
if (!b64) {
|
|
4410
|
+
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
4411
|
+
setHfMissingImages((prev) => {
|
|
4412
|
+
if (prev.find((e) => e.id === entry.id)) return prev;
|
|
4413
|
+
return [...prev, { id: entry.id, filename: entry.filename, mimeType: entry.mimeType, timestamp: entry.timestamp }];
|
|
4414
|
+
});
|
|
4415
|
+
continue;
|
|
4416
|
+
}
|
|
4417
|
+
const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
|
|
4418
|
+
setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
4419
|
+
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
4420
|
+
} catch {
|
|
4347
4421
|
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
4348
|
-
return;
|
|
4349
4422
|
}
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
4353
|
-
}).catch(() => {
|
|
4354
|
-
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
4355
|
-
});
|
|
4356
|
-
}
|
|
4423
|
+
}
|
|
4424
|
+
})();
|
|
4357
4425
|
}, [hfState]);
|
|
4358
|
-
const [activePrompt, setActivePrompt] =
|
|
4359
|
-
const [isSynthesizing, setIsSynthesizing] =
|
|
4360
|
-
const [activeGenerationsCount, setActiveGenerationsCount] =
|
|
4361
|
-
const [currentResult, setCurrentResult] =
|
|
4362
|
-
const [focusedNodeId, setFocusedNodeId] =
|
|
4363
|
-
const [leftTab, setLeftTab] =
|
|
4364
|
-
const [promptFeedback, setPromptFeedback] =
|
|
4365
|
-
const [lastPromptPayload, setLastPromptPayload] =
|
|
4366
|
-
const [isPromptTabGenerating, setIsPromptTabGenerating] =
|
|
4367
|
-
const [activeTab, setActiveTab] =
|
|
4368
|
-
const [mobileTab, setMobileTab] =
|
|
4369
|
-
const [middlePanel, setMiddlePanel] =
|
|
4370
|
-
const [recentLabItems, setRecentLabItems] =
|
|
4371
|
-
const [aspectRatio, setAspectRatio] =
|
|
4372
|
-
const [selectedModel, setSelectedModel] =
|
|
4373
|
-
const [seed, setSeed] =
|
|
4374
|
-
const [seedMode, setSeedMode] =
|
|
4375
|
-
const [isLeftCollapsed, setIsLeftCollapsed] =
|
|
4376
|
-
const [isRightCollapsed, setIsRightCollapsed] =
|
|
4377
|
-
const [leftPanelWidth, setLeftPanelWidth] =
|
|
4426
|
+
const [activePrompt, setActivePrompt] = useState20("");
|
|
4427
|
+
const [isSynthesizing, setIsSynthesizing] = useState20(false);
|
|
4428
|
+
const [activeGenerationsCount, setActiveGenerationsCount] = useState20(0);
|
|
4429
|
+
const [currentResult, setCurrentResult] = useState20(null);
|
|
4430
|
+
const [focusedNodeId, setFocusedNodeId] = useState20(null);
|
|
4431
|
+
const [leftTab, setLeftTab] = useState20("prompt");
|
|
4432
|
+
const [promptFeedback, setPromptFeedback] = useState20(null);
|
|
4433
|
+
const [lastPromptPayload, setLastPromptPayload] = useState20(null);
|
|
4434
|
+
const [isPromptTabGenerating, setIsPromptTabGenerating] = useState20(false);
|
|
4435
|
+
const [activeTab, setActiveTab] = useState20("history");
|
|
4436
|
+
const [mobileTab, setMobileTab] = useState20("stage");
|
|
4437
|
+
const [middlePanel, setMiddlePanel] = useState20("stage");
|
|
4438
|
+
const [recentLabItems, setRecentLabItems] = useState20([]);
|
|
4439
|
+
const [aspectRatio, setAspectRatio] = useState20("1:1");
|
|
4440
|
+
const [selectedModel, setSelectedModel] = useState20("\u{1F34C} Nano Banana Pro");
|
|
4441
|
+
const [seed, setSeed] = useState20(Math.floor(Math.random() * 1e6));
|
|
4442
|
+
const [seedMode, setSeedMode] = useState20("random");
|
|
4443
|
+
const [isLeftCollapsed, setIsLeftCollapsed] = useState20(false);
|
|
4444
|
+
const [isRightCollapsed, setIsRightCollapsed] = useState20(false);
|
|
4445
|
+
const [leftPanelWidth, setLeftPanelWidth] = useState20(() => {
|
|
4378
4446
|
try {
|
|
4379
4447
|
return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
|
|
4380
4448
|
} catch {
|
|
4381
4449
|
return 260;
|
|
4382
4450
|
}
|
|
4383
4451
|
});
|
|
4384
|
-
const [rightPanelWidth, setRightPanelWidth] =
|
|
4452
|
+
const [rightPanelWidth, setRightPanelWidth] = useState20(() => {
|
|
4385
4453
|
try {
|
|
4386
4454
|
return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
|
|
4387
4455
|
} catch {
|
|
4388
4456
|
return 320;
|
|
4389
4457
|
}
|
|
4390
4458
|
});
|
|
4391
|
-
const [isPromptCollapsed, setIsPromptCollapsed] =
|
|
4392
|
-
const [projectActionState, setProjectActionState] =
|
|
4459
|
+
const [isPromptCollapsed, setIsPromptCollapsed] = useState20(false);
|
|
4460
|
+
const [projectActionState, setProjectActionState] = useState20("idle");
|
|
4393
4461
|
const syncServerDataRef = useRef8(null);
|
|
4394
|
-
const [workspaceTags, setWorkspaceTags] =
|
|
4395
|
-
const [serverProjects, setServerProjects] =
|
|
4396
|
-
const [isLoadingFromServer, setIsLoadingFromServer] =
|
|
4397
|
-
const [highContrast, setHighContrast] =
|
|
4462
|
+
const [workspaceTags, setWorkspaceTags] = useState20(null);
|
|
4463
|
+
const [serverProjects, setServerProjects] = useState20([]);
|
|
4464
|
+
const [isLoadingFromServer, setIsLoadingFromServer] = useState20(false);
|
|
4465
|
+
const [highContrast, setHighContrast] = useState20(() => {
|
|
4398
4466
|
try {
|
|
4399
4467
|
return localStorage.getItem("aa-contrast") === "high";
|
|
4400
4468
|
} catch {
|
|
4401
4469
|
return false;
|
|
4402
4470
|
}
|
|
4403
4471
|
});
|
|
4404
|
-
const [activeReferenceId, setActiveReferenceId] =
|
|
4405
|
-
const [activeReferenceThumbnail, setActiveReferenceThumbnail] =
|
|
4406
|
-
const [isScanningImage, setIsScanningImage] =
|
|
4407
|
-
const [touchStartX, setTouchStartX] =
|
|
4408
|
-
const [isFullscreen, setIsFullscreen] =
|
|
4409
|
-
const [zoomScale, setZoomScale] =
|
|
4410
|
-
const [zoomOffset, setZoomOffset] =
|
|
4472
|
+
const [activeReferenceId, setActiveReferenceId] = useState20(null);
|
|
4473
|
+
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = useState20(null);
|
|
4474
|
+
const [isScanningImage, setIsScanningImage] = useState20(false);
|
|
4475
|
+
const [touchStartX, setTouchStartX] = useState20(null);
|
|
4476
|
+
const [isFullscreen, setIsFullscreen] = useState20(false);
|
|
4477
|
+
const [zoomScale, setZoomScale] = useState20(1);
|
|
4478
|
+
const [zoomOffset, setZoomOffset] = useState20({ x: 0, y: 0 });
|
|
4411
4479
|
const lastPinchDist = useRef8(null);
|
|
4412
4480
|
const lastTapTime = useRef8(0);
|
|
4413
4481
|
const dragStart = useRef8(null);
|
|
@@ -4560,6 +4628,34 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4560
4628
|
const goToNext = useCallback3(() => {
|
|
4561
4629
|
if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
|
|
4562
4630
|
}, [currentIndex, history]);
|
|
4631
|
+
const handleGallerySelect = useCallback3((g) => {
|
|
4632
|
+
setCurrentResult(g);
|
|
4633
|
+
setMobileTab("stage");
|
|
4634
|
+
if (g.filename && hfToken && !g.fullBase64) {
|
|
4635
|
+
hfLoadImageAsBase64(g.id, hfToken, effectiveNamespace, g.filename, void 0, g.mimeType, false).then((b64) => {
|
|
4636
|
+
if (!b64) return;
|
|
4637
|
+
const full = `data:${g.mimeType || "image/jpeg"};base64,${b64}`;
|
|
4638
|
+
setCurrentResult((prev) => prev?.id === g.id ? { ...prev, fullBase64: full } : prev);
|
|
4639
|
+
setGalleryItems((prev) => prev.map((item) => item.id === g.id ? { ...item, fullBase64: full } : item));
|
|
4640
|
+
}).catch(() => {
|
|
4641
|
+
});
|
|
4642
|
+
}
|
|
4643
|
+
}, [hfToken, effectiveNamespace]);
|
|
4644
|
+
const handleTitleSet = useCallback3((id) => {
|
|
4645
|
+
const ts = Date.now();
|
|
4646
|
+
setGalleryItems((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
|
|
4647
|
+
setHistory((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
|
|
4648
|
+
if (hfToken && effectiveNamespace) {
|
|
4649
|
+
hfWriteEvent("title_set", { id }).catch(() => {
|
|
4650
|
+
});
|
|
4651
|
+
}
|
|
4652
|
+
}, [hfToken, effectiveNamespace, hfWriteEvent]);
|
|
4653
|
+
const currentGroup = useMemo2(() => {
|
|
4654
|
+
if (!currentResult?.prompt) return [];
|
|
4655
|
+
const groups = groupByPrompt(galleryItems.filter((g) => g.status === "done" && !!g.base64));
|
|
4656
|
+
const group = groups.find((gr) => gr.prompt === currentResult.prompt);
|
|
4657
|
+
return group ? group.items : [];
|
|
4658
|
+
}, [galleryItems, currentResult?.prompt]);
|
|
4563
4659
|
const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
|
|
4564
4660
|
const isGenerating = activeGenerationsCount > 0;
|
|
4565
4661
|
useKeyboardNavigation(history, currentResult, setCurrentResult);
|
|
@@ -4741,8 +4837,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4741
4837
|
const handleDownloadSingle = async () => {
|
|
4742
4838
|
if (!currentResult?.base64) return;
|
|
4743
4839
|
try {
|
|
4744
|
-
const
|
|
4745
|
-
const
|
|
4840
|
+
const downloadSrc = currentResult.fullBase64 || currentResult.base64;
|
|
4841
|
+
const base64Data = downloadSrc.split(",")[1];
|
|
4842
|
+
const mimeType = downloadSrc.split(";")[0].split(":")[1] || "image/png";
|
|
4746
4843
|
let finalBase64 = base64Data;
|
|
4747
4844
|
if (mimeType === "image/png") finalBase64 = injectXMPMetadata(base64Data, currentResult.prompt || "", currentResult.seed, currentResult.model, currentResult.id, currentResult.tags || [], getSubtreeFormat(currentResult.nodeId));
|
|
4748
4845
|
await onDownload(finalBase64, mimeType, `avatar_${currentResult.id.slice(0, 5)}.${mimeType.split("/")[1]}`);
|
|
@@ -4942,7 +5039,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4942
5039
|
return { by_category: merged, all };
|
|
4943
5040
|
};
|
|
4944
5041
|
if (isFullscreen && currentResult?.base64) {
|
|
4945
|
-
const
|
|
5042
|
+
const fsRaw = currentResult.fullBase64 || currentResult.base64;
|
|
5043
|
+
const fsBase64 = fsRaw.startsWith("data:") ? fsRaw : `data:image/png;base64,${fsRaw}`;
|
|
4946
5044
|
return /* @__PURE__ */ jsxs21(
|
|
4947
5045
|
"div",
|
|
4948
5046
|
{
|
|
@@ -5094,7 +5192,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5094
5192
|
onClick: async () => {
|
|
5095
5193
|
setIsLoadingFromHF(true);
|
|
5096
5194
|
try {
|
|
5097
|
-
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-
|
|
5195
|
+
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-5BU5DVQ6.mjs");
|
|
5098
5196
|
const projects = await hfListProjects2(hfToken);
|
|
5099
5197
|
if (projects.length > 0) {
|
|
5100
5198
|
const file = await hfDownloadProject2(projects[0].path, hfToken);
|
|
@@ -5189,7 +5287,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5189
5287
|
setMobileTab("stage");
|
|
5190
5288
|
}
|
|
5191
5289
|
} }) }),
|
|
5192
|
-
mobileTab === "server" && /* @__PURE__ */ jsx23("div", { className: "flex flex-col flex-1 min-h-0 relative", children: /* @__PURE__ */ jsx23(ServerTab, {
|
|
5290
|
+
mobileTab === "server" && /* @__PURE__ */ jsx23("div", { className: "flex flex-col flex-1 min-h-0 relative", children: /* @__PURE__ */ jsx23(ServerTab, { serverBaseUrl }) }),
|
|
5193
5291
|
mobileTab === "tags" && workspaceTags && /* @__PURE__ */ jsx23("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ jsx23(
|
|
5194
5292
|
TagManagerPanel,
|
|
5195
5293
|
{
|
|
@@ -5267,7 +5365,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5267
5365
|
/* @__PURE__ */ jsx23("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
|
|
5268
5366
|
/* @__PURE__ */ jsx23("button", { onClick: () => handleGenerateImage(currentResult.prompt), className: "px-4 py-2 rounded-lg border border-white/20 text-[13px] text-white/70 active:bg-white/10", children: "Erneut versuchen" })
|
|
5269
5367
|
] }),
|
|
5270
|
-
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx23("img", { src: currentResult.base64, className: "w-full h-full object-contain" }),
|
|
5368
|
+
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx23("img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
|
|
5271
5369
|
!currentResult && /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
5272
5370
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
|
|
5273
5371
|
/* @__PURE__ */ jsx23("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
@@ -5285,6 +5383,49 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5285
5383
|
]
|
|
5286
5384
|
}
|
|
5287
5385
|
),
|
|
5386
|
+
currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ jsx23("div", { className: "mt-2 flex gap-1.5 overflow-x-auto pb-1", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ jsxs21("div", { style: { position: "relative", flexShrink: 0 }, children: [
|
|
5387
|
+
/* @__PURE__ */ jsx23(
|
|
5388
|
+
"div",
|
|
5389
|
+
{
|
|
5390
|
+
onClick: () => handleGallerySelect(item),
|
|
5391
|
+
style: {
|
|
5392
|
+
width: 44,
|
|
5393
|
+
height: 44,
|
|
5394
|
+
borderRadius: 8,
|
|
5395
|
+
overflow: "hidden",
|
|
5396
|
+
cursor: "pointer",
|
|
5397
|
+
border: item.id === currentResult.id ? "2px solid rgba(255,255,255,0.8)" : "2px solid rgba(255,255,255,0.15)",
|
|
5398
|
+
opacity: item.id === currentResult.id ? 1 : 0.55
|
|
5399
|
+
},
|
|
5400
|
+
children: /* @__PURE__ */ jsx23("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
|
|
5401
|
+
}
|
|
5402
|
+
),
|
|
5403
|
+
/* @__PURE__ */ jsx23(
|
|
5404
|
+
"button",
|
|
5405
|
+
{
|
|
5406
|
+
onClick: (e) => {
|
|
5407
|
+
e.stopPropagation();
|
|
5408
|
+
handleTitleSet(item.id);
|
|
5409
|
+
},
|
|
5410
|
+
style: {
|
|
5411
|
+
position: "absolute",
|
|
5412
|
+
bottom: 2,
|
|
5413
|
+
right: 2,
|
|
5414
|
+
width: 14,
|
|
5415
|
+
height: 14,
|
|
5416
|
+
background: item.titleTs ? "#f59e0b" : "rgba(0,0,0,0.75)",
|
|
5417
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
5418
|
+
borderRadius: 3,
|
|
5419
|
+
cursor: "pointer",
|
|
5420
|
+
padding: 0,
|
|
5421
|
+
display: "flex",
|
|
5422
|
+
alignItems: "center",
|
|
5423
|
+
justifyContent: "center"
|
|
5424
|
+
},
|
|
5425
|
+
children: /* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined", style: { fontSize: 9, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
|
|
5426
|
+
}
|
|
5427
|
+
)
|
|
5428
|
+
] }, item.id)) }),
|
|
5288
5429
|
currentResult?.status === "done" && /* @__PURE__ */ jsxs21("div", { className: "flex gap-2 mt-3", children: [
|
|
5289
5430
|
/* @__PURE__ */ jsxs21("button", { onClick: () => setActivePrompt(currentResult.prompt || ""), className: "flex-1 flex items-center justify-center gap-1.5 rounded-xl border border-white/10 bg-white/5 active:bg-white/10 transition-colors", style: { height: 44 }, children: [
|
|
5290
5431
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
|
|
@@ -5307,10 +5448,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5307
5448
|
hfToken && /* @__PURE__ */ jsx23("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__ */ jsx23("span", { className: `material-symbols-outlined text-[20px]${isHfRefreshing ? " animate-spin" : ""}`, children: "sync" }) })
|
|
5308
5449
|
] }),
|
|
5309
5450
|
/* @__PURE__ */ jsxs21("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
5310
|
-
activeTab === "history" && /* @__PURE__ */ jsx23(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: (
|
|
5311
|
-
setCurrentResult(g);
|
|
5312
|
-
setMobileTab("stage");
|
|
5313
|
-
}, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
|
|
5451
|
+
activeTab === "history" && /* @__PURE__ */ jsx23(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
|
|
5314
5452
|
activeTab === "gallery" && /* @__PURE__ */ jsx23(
|
|
5315
5453
|
MediaLibrary,
|
|
5316
5454
|
{
|
|
@@ -5321,10 +5459,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5321
5459
|
setGalleryItems((prev) => [...media.map((m) => ({ id: crypto.randomUUID(), nodeId: "1", base64: `data:${m.mimeType};base64,${m.base64}`, mediaId: m.mediaId, prompt: m.name || "Importiert", timestamp: Date.now(), status: "done", tags: [], type: "import" })), ...prev]);
|
|
5322
5460
|
},
|
|
5323
5461
|
onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
|
|
5324
|
-
onSelect:
|
|
5325
|
-
setCurrentResult(g);
|
|
5326
|
-
setMobileTab("stage");
|
|
5327
|
-
},
|
|
5462
|
+
onSelect: handleGallerySelect,
|
|
5328
5463
|
onGenerateReference: (item) => {
|
|
5329
5464
|
handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true });
|
|
5330
5465
|
setMobileTab("stage");
|
|
@@ -5364,7 +5499,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5364
5499
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
|
|
5365
5500
|
"HF"
|
|
5366
5501
|
] }),
|
|
5367
|
-
/* @__PURE__ */ jsx23("button", { onClick: () => setActiveTab("server"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "server" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) }),
|
|
5502
|
+
serverBaseUrl && /* @__PURE__ */ jsx23("button", { onClick: () => setActiveTab("server"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "server" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) }),
|
|
5368
5503
|
workspaceTags && /* @__PURE__ */ jsx23("button", { onClick: () => setActiveTab("tags"), className: `flex-1 flex items-center justify-center gap-1.5 text-[11px] font-bold uppercase tracking-wide transition-colors ${activeTab === "tags" ? "text-white border-b-2 border-white" : "text-white/30"}`, children: /* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[20px]", children: "label" }) })
|
|
5369
5504
|
] }),
|
|
5370
5505
|
/* @__PURE__ */ jsxs21("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
@@ -5447,10 +5582,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5447
5582
|
galleryItems,
|
|
5448
5583
|
allEvents: hfAllEvents,
|
|
5449
5584
|
confirmedEventKeys: hfConfirmedKeys,
|
|
5450
|
-
imageUploadStatus
|
|
5585
|
+
imageUploadStatus,
|
|
5586
|
+
missingImages: hfMissingImages
|
|
5451
5587
|
}
|
|
5452
5588
|
) }),
|
|
5453
|
-
activeTab === "server" && /* @__PURE__ */ jsx23("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx23(ServerTab, {
|
|
5589
|
+
activeTab === "server" && /* @__PURE__ */ jsx23("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx23(ServerTab, { serverBaseUrl }) })
|
|
5454
5590
|
] })
|
|
5455
5591
|
] }),
|
|
5456
5592
|
/* @__PURE__ */ jsx23("div", { className: "flex border-t border-white/10 bg-black shrink-0", style: { height: 56, paddingBottom: "env(safe-area-inset-bottom, 0px)" }, children: [
|
|
@@ -5459,7 +5595,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5459
5595
|
{ id: "labs", icon: "science", label: "Labs" },
|
|
5460
5596
|
...workspaceTags ? [{ id: "tags", icon: "label", label: "Tags" }] : [],
|
|
5461
5597
|
{ id: "browse", icon: "photo_library", label: "Galerie" },
|
|
5462
|
-
{ id: "server", icon: "storage", label: "Server" }
|
|
5598
|
+
...serverBaseUrl ? [{ id: "server", icon: "storage", label: "Server" }] : []
|
|
5463
5599
|
].map((tab) => /* @__PURE__ */ jsxs21("button", { onClick: () => setMobileTab(tab.id), className: `flex-1 flex flex-col items-center justify-center gap-0.5 transition-colors ${mobileTab === tab.id ? "text-white" : "text-white/30"}`, children: [
|
|
5464
5600
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
|
|
5465
5601
|
/* @__PURE__ */ jsx23("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
|
|
@@ -5510,7 +5646,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5510
5646
|
] })
|
|
5511
5647
|
}
|
|
5512
5648
|
) }),
|
|
5513
|
-
/* @__PURE__ */ jsx23("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ jsx23(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect:
|
|
5649
|
+
/* @__PURE__ */ jsx23("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ jsx23(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }) })
|
|
5514
5650
|
] }),
|
|
5515
5651
|
/* @__PURE__ */ jsxs21("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
|
|
5516
5652
|
/* @__PURE__ */ jsx23(
|
|
@@ -5535,7 +5671,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5535
5671
|
/* @__PURE__ */ jsx23("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
|
|
5536
5672
|
/* @__PURE__ */ jsx23("button", { onClick: () => handleGenerateImage(currentResult.prompt), style: { padding: "8px 16px", borderRadius: 8, border: "1px solid rgba(255,255,255,0.2)", fontSize: 11, color: "rgba(255,255,255,0.7)", background: "none", cursor: "pointer", fontFamily: "inherit" }, children: "Erneut versuchen" })
|
|
5537
5673
|
] }),
|
|
5538
|
-
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx23("img", { src: currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
|
|
5674
|
+
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx23("img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
|
|
5539
5675
|
!currentResult && /* @__PURE__ */ jsxs21("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
|
|
5540
5676
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
|
|
5541
5677
|
/* @__PURE__ */ jsx23("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
|
|
@@ -5677,33 +5813,81 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5677
5813
|
middlePanel === "labs" ? /* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx23(LabsTab, { services: labServices, onResult: (item) => {
|
|
5678
5814
|
const frame = item.frames[0];
|
|
5679
5815
|
if (frame?.base64) setCurrentResult(frameToGeneration(frame, item));
|
|
5680
|
-
} }) }) : /* @__PURE__ */
|
|
5681
|
-
|
|
5682
|
-
/* @__PURE__ */
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-4", children: [
|
|
5686
|
-
/* @__PURE__ */ jsx23("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
|
|
5687
|
-
/* @__PURE__ */ jsx23("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
|
|
5688
|
-
] }) : currentResult.status === "error" ? /* @__PURE__ */ jsxs21("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
|
|
5689
|
-
/* @__PURE__ */ jsx23("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
|
|
5690
|
-
/* @__PURE__ */ jsxs21("div", { className: "flex flex-col gap-2", children: [
|
|
5691
|
-
/* @__PURE__ */ jsx23("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
|
|
5692
|
-
/* @__PURE__ */ jsx23("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
|
|
5816
|
+
} }) }) : /* @__PURE__ */ jsxs21("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
|
|
5817
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-1 p-6 overflow-hidden flex items-center justify-center", children: /* @__PURE__ */ jsxs21("div", { className: "h-full w-full max-w-4xl aspect-square rounded-3xl border border-white/5 bg-black/40 relative overflow-hidden flex items-center justify-center group shadow-2xl", children: [
|
|
5818
|
+
isGenerating && currentResult?.status === "done" && /* @__PURE__ */ jsxs21("div", { className: "absolute top-6 right-6 z-30 bg-black/60 backdrop-blur-md px-4 py-2 rounded-full border border-white/10 flex items-center gap-3", children: [
|
|
5819
|
+
/* @__PURE__ */ jsx23("div", { className: "w-3 h-3 border-t-2 border-white rounded-full animate-spin" }),
|
|
5820
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px] text-white/60 uppercase font-bold tracking-widest", children: "Neue Referenz..." })
|
|
5693
5821
|
] }),
|
|
5694
|
-
/* @__PURE__ */
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
/* @__PURE__ */ jsxs21("div", { className: "
|
|
5698
|
-
/* @__PURE__ */ jsx23(
|
|
5699
|
-
/* @__PURE__ */
|
|
5700
|
-
|
|
5822
|
+
currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-4", children: [
|
|
5823
|
+
/* @__PURE__ */ jsx23("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
|
|
5824
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
|
|
5825
|
+
] }) : currentResult.status === "error" ? /* @__PURE__ */ jsxs21("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
|
|
5826
|
+
/* @__PURE__ */ jsx23("div", { className: "w-16 h-16 rounded-full bg-red-500/10 flex items-center justify-center", children: /* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-red-500 text-[32px]", children: "warning" }) }),
|
|
5827
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex flex-col gap-2", children: [
|
|
5828
|
+
/* @__PURE__ */ jsx23("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
|
|
5829
|
+
/* @__PURE__ */ jsx23("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
|
|
5830
|
+
] }),
|
|
5831
|
+
/* @__PURE__ */ jsx23(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
|
|
5832
|
+
] }) : /* @__PURE__ */ jsxs21("div", { className: "h-full w-full relative flex items-center justify-center", children: [
|
|
5833
|
+
/* @__PURE__ */ jsx23("img", { src: currentResult.fullBase64 || currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
|
|
5834
|
+
/* @__PURE__ */ jsxs21("div", { className: "absolute bottom-6 flex gap-2 opacity-0 group-hover:opacity-100 transition-all translate-y-4 group-hover:translate-y-0 z-20", children: [
|
|
5835
|
+
/* @__PURE__ */ jsx23(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
|
|
5836
|
+
/* @__PURE__ */ jsx23(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
|
|
5837
|
+
/* @__PURE__ */ jsx23(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
|
|
5838
|
+
] })
|
|
5839
|
+
] }) : /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
5840
|
+
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
|
|
5841
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
5701
5842
|
] })
|
|
5702
|
-
] })
|
|
5703
|
-
|
|
5704
|
-
/* @__PURE__ */ jsx23(
|
|
5705
|
-
|
|
5706
|
-
|
|
5843
|
+
] }) }),
|
|
5844
|
+
currentResult?.status === "done" && currentGroup.length > 1 && /* @__PURE__ */ jsx23("div", { className: "px-6 pb-4 shrink-0 flex gap-2 overflow-x-auto", style: { scrollbarWidth: "none" }, children: currentGroup.map((item) => /* @__PURE__ */ jsxs21("div", { style: { position: "relative", flexShrink: 0 }, children: [
|
|
5845
|
+
/* @__PURE__ */ jsx23(
|
|
5846
|
+
"div",
|
|
5847
|
+
{
|
|
5848
|
+
onClick: () => handleGallerySelect(item),
|
|
5849
|
+
style: {
|
|
5850
|
+
width: 52,
|
|
5851
|
+
height: 52,
|
|
5852
|
+
borderRadius: 10,
|
|
5853
|
+
overflow: "hidden",
|
|
5854
|
+
cursor: "pointer",
|
|
5855
|
+
border: item.id === currentResult.id ? "2px solid rgba(255,255,255,0.8)" : "2px solid rgba(255,255,255,0.12)",
|
|
5856
|
+
opacity: item.id === currentResult.id ? 1 : 0.5,
|
|
5857
|
+
transition: "opacity 0.15s, border-color 0.15s"
|
|
5858
|
+
},
|
|
5859
|
+
className: "hover:opacity-80",
|
|
5860
|
+
children: /* @__PURE__ */ jsx23("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
|
|
5861
|
+
}
|
|
5862
|
+
),
|
|
5863
|
+
/* @__PURE__ */ jsx23(
|
|
5864
|
+
"button",
|
|
5865
|
+
{
|
|
5866
|
+
onClick: (e) => {
|
|
5867
|
+
e.stopPropagation();
|
|
5868
|
+
handleTitleSet(item.id);
|
|
5869
|
+
},
|
|
5870
|
+
title: "Als Titel markieren",
|
|
5871
|
+
style: {
|
|
5872
|
+
position: "absolute",
|
|
5873
|
+
bottom: 3,
|
|
5874
|
+
right: 3,
|
|
5875
|
+
width: 16,
|
|
5876
|
+
height: 16,
|
|
5877
|
+
background: item.titleTs ? "#f59e0b" : "rgba(0,0,0,0.75)",
|
|
5878
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
5879
|
+
borderRadius: 4,
|
|
5880
|
+
cursor: "pointer",
|
|
5881
|
+
padding: 0,
|
|
5882
|
+
display: "flex",
|
|
5883
|
+
alignItems: "center",
|
|
5884
|
+
justifyContent: "center"
|
|
5885
|
+
},
|
|
5886
|
+
children: /* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined", style: { fontSize: 10, color: item.titleTs ? "#fff" : "rgba(255,255,255,0.5)", lineHeight: 1 }, children: "star" })
|
|
5887
|
+
}
|
|
5888
|
+
)
|
|
5889
|
+
] }, item.id)) })
|
|
5890
|
+
] })
|
|
5707
5891
|
] })
|
|
5708
5892
|
] }),
|
|
5709
5893
|
!isRightCollapsed && /* @__PURE__ */ jsx23("div", { onMouseDown: startRightResize, className: "w-1 shrink-0 cursor-col-resize hover:bg-white/20 active:bg-white/30 transition-colors", style: { background: "transparent" } }),
|
|
@@ -5714,7 +5898,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5714
5898
|
setActiveTab(tab);
|
|
5715
5899
|
setIsRightCollapsed(false);
|
|
5716
5900
|
}, className: `flex-1 flex items-center justify-center relative transition-colors ${activeTab === tab ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ jsx23("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)),
|
|
5717
|
-
/* @__PURE__ */ jsx23("button", { onClick: () => {
|
|
5901
|
+
serverBaseUrl && /* @__PURE__ */ jsx23("button", { onClick: () => {
|
|
5718
5902
|
setActiveTab("server");
|
|
5719
5903
|
setIsRightCollapsed(false);
|
|
5720
5904
|
}, className: `w-10 flex items-center justify-center relative transition-colors ${activeTab === "server" ? "text-white" : "text-white/20"}`, children: /* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[20px]", children: "storage" }) })
|
|
@@ -5738,7 +5922,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5738
5922
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
|
|
5739
5923
|
/* @__PURE__ */ jsx23("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
|
|
5740
5924
|
] }) }),
|
|
5741
|
-
activeTab === "history" && /* @__PURE__ */ jsx23(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect:
|
|
5925
|
+
activeTab === "history" && /* @__PURE__ */ jsx23(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
|
|
5742
5926
|
activeTab === "gallery" && /* @__PURE__ */ jsx23(
|
|
5743
5927
|
MediaLibrary,
|
|
5744
5928
|
{
|
|
@@ -5749,7 +5933,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5749
5933
|
setGalleryItems((prev) => [...media.map((m) => ({ id: crypto.randomUUID(), nodeId: "1", base64: `data:${m.mimeType};base64,${m.base64}`, mediaId: m.mediaId, prompt: m.name || "Importiert", timestamp: Date.now(), status: "done", tags: [], type: "import" })), ...prev]);
|
|
5750
5934
|
},
|
|
5751
5935
|
onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
|
|
5752
|
-
onSelect:
|
|
5936
|
+
onSelect: handleGallerySelect,
|
|
5753
5937
|
onGenerateReference: (item) => handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true })
|
|
5754
5938
|
}
|
|
5755
5939
|
),
|
|
@@ -5779,14 +5963,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5779
5963
|
onHfInitialSync: hfToken ? handleHfInitialSync : void 0
|
|
5780
5964
|
}
|
|
5781
5965
|
),
|
|
5782
|
-
activeTab === "server" && /* @__PURE__ */ jsx23(ServerTab, {
|
|
5966
|
+
activeTab === "server" && /* @__PURE__ */ jsx23(ServerTab, { serverBaseUrl })
|
|
5783
5967
|
] })
|
|
5784
5968
|
] })
|
|
5785
5969
|
] });
|
|
5786
5970
|
}
|
|
5787
5971
|
|
|
5788
5972
|
// src/components/FaApp.tsx
|
|
5789
|
-
import { useState as
|
|
5973
|
+
import { useState as useState21, useEffect as useEffect8 } from "react";
|
|
5790
5974
|
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
5791
5975
|
function FaApp({
|
|
5792
5976
|
onGenerateImage,
|
|
@@ -5806,7 +5990,7 @@ function FaApp({
|
|
|
5806
5990
|
onServerDelete,
|
|
5807
5991
|
buildInfo
|
|
5808
5992
|
}) {
|
|
5809
|
-
const [hfNamespace, setHfNamespace] =
|
|
5993
|
+
const [hfNamespace, setHfNamespace] = useState21(void 0);
|
|
5810
5994
|
useEffect8(() => {
|
|
5811
5995
|
if (!serverBaseUrl) return;
|
|
5812
5996
|
fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
@@ -5828,6 +6012,7 @@ function FaApp({
|
|
|
5828
6012
|
initialHfToken: libToken ? libToken.startsWith("hf_") ? libToken : `hf_${libToken}` : void 0,
|
|
5829
6013
|
hfNamespace,
|
|
5830
6014
|
allowDevNamespace: !hfNamespace && allowDevNamespace,
|
|
6015
|
+
serverBaseUrl,
|
|
5831
6016
|
onFetchServerProjects,
|
|
5832
6017
|
onServerSave,
|
|
5833
6018
|
onServerLoad,
|
|
@@ -5838,7 +6023,7 @@ function FaApp({
|
|
|
5838
6023
|
}
|
|
5839
6024
|
|
|
5840
6025
|
// src/index.ts
|
|
5841
|
-
var LIB_VERSION = "2.0.
|
|
6026
|
+
var LIB_VERSION = "2.0.48";
|
|
5842
6027
|
export {
|
|
5843
6028
|
AvatarArchitectApp,
|
|
5844
6029
|
CollapsibleCard,
|
|
@@ -5882,10 +6067,6 @@ export {
|
|
|
5882
6067
|
cleanAiResponse,
|
|
5883
6068
|
createFlowServices,
|
|
5884
6069
|
exportProjectToZip,
|
|
5885
|
-
faServerDelete,
|
|
5886
|
-
faServerGet,
|
|
5887
|
-
faServerPost,
|
|
5888
|
-
faServerPut,
|
|
5889
6070
|
findForks,
|
|
5890
6071
|
findTips,
|
|
5891
6072
|
formatTreeToMarkdown,
|