@rslsp1/fa-app-tools 2.0.30 → 2.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-UCEQOGPT.mjs → chunk-TTJTQP43.mjs} +30 -21
- package/dist/{hfStateService-TC65WQXK.mjs → hfStateService-5BU5DVQ6.mjs} +1 -1
- package/dist/index.d.mts +42 -39
- package/dist/index.d.ts +42 -39
- package/dist/index.js +635 -431
- package/dist/index.mjs +558 -357
- package/package.json +2 -2
package/dist/index.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,33 @@ 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";
|
|
358
|
+
|
|
359
|
+
// src/lib/grouping.ts
|
|
360
|
+
function groupByPrompt(items) {
|
|
361
|
+
const map = /* @__PURE__ */ new Map();
|
|
362
|
+
for (const item of items) {
|
|
363
|
+
const key = item.prompt ?? "";
|
|
364
|
+
if (!map.has(key)) map.set(key, []);
|
|
365
|
+
map.get(key).push(item);
|
|
366
|
+
}
|
|
367
|
+
const groups = [];
|
|
368
|
+
for (const [prompt, groupItems] of map) {
|
|
369
|
+
const titled = groupItems.filter((i) => i.titleTs);
|
|
370
|
+
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);
|
|
371
|
+
groups.push({ prompt, items: groupItems, representative });
|
|
372
|
+
}
|
|
373
|
+
return groups.sort((a, b) => {
|
|
374
|
+
const aMax = Math.max(...a.items.map((i) => i.timestamp));
|
|
375
|
+
const bMax = Math.max(...b.items.map((i) => i.timestamp));
|
|
376
|
+
return bMax - aMax;
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// src/components/HistoryPanel.tsx
|
|
357
381
|
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
382
|
+
var PAGE_SIZE = 20;
|
|
358
383
|
var formatFriendlyTimestamp = (timestamp) => {
|
|
359
384
|
const date = new Date(timestamp);
|
|
360
385
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -367,38 +392,75 @@ var formatFriendlyTimestamp = (timestamp) => {
|
|
|
367
392
|
return `${date.toLocaleDateString([], { day: "2-digit", month: "2-digit" })}, ${timeStr}`;
|
|
368
393
|
};
|
|
369
394
|
var HistoryPanel = ({ history, currentResultId, onSelect, onDelete }) => {
|
|
395
|
+
const [visibleCount, setVisibleCount] = useState2(PAGE_SIZE);
|
|
396
|
+
const doneItems = history.filter((g) => g.status === "done");
|
|
397
|
+
const processingItems = history.filter((g) => g.status !== "done");
|
|
398
|
+
const groups = groupByPrompt(doneItems);
|
|
399
|
+
const visibleGroups = groups.slice(0, visibleCount);
|
|
370
400
|
if (history.length === 0) {
|
|
371
401
|
return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col items-center justify-center py-20 text-center gap-4 opacity-10", children: [
|
|
372
402
|
/* @__PURE__ */ jsx5("span", { className: "material-symbols-outlined text-[64px]", children: "history" }),
|
|
373
403
|
/* @__PURE__ */ jsx5("p", { className: "text-[10px] font-bold uppercase tracking-widest", children: "Keine Historie" })
|
|
374
404
|
] });
|
|
375
405
|
}
|
|
376
|
-
return /* @__PURE__ */
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
/* @__PURE__ */ jsxs3("div", { className: "flex
|
|
385
|
-
/* @__PURE__ */ jsx5("span", { className: "text-[7px] font-bold text-white/20 uppercase
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
'"'
|
|
406
|
+
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: [
|
|
407
|
+
processingItems.map((gen) => /* @__PURE__ */ jsxs3(
|
|
408
|
+
"div",
|
|
409
|
+
{
|
|
410
|
+
className: "flex gap-3 p-2 bg-white/5 border border-white/5 rounded-2xl cursor-pointer group transition-all relative",
|
|
411
|
+
onClick: () => onSelect(gen),
|
|
412
|
+
children: [
|
|
413
|
+
/* @__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: /* @__PURE__ */ jsx5("div", { className: "w-5 h-5 border-t-2 border-white rounded-full animate-spin" }) }),
|
|
414
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex-1 py-0.5 overflow-hidden", children: [
|
|
415
|
+
/* @__PURE__ */ jsx5("span", { className: "text-[7px] font-bold text-white/20 uppercase", children: "Generiere..." }),
|
|
416
|
+
/* @__PURE__ */ jsxs3("p", { className: "text-[9px] text-white/40 line-clamp-2 leading-tight mt-1", children: [
|
|
417
|
+
'"',
|
|
418
|
+
gen.prompt,
|
|
419
|
+
'"'
|
|
420
|
+
] })
|
|
392
421
|
] })
|
|
393
|
-
]
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
422
|
+
]
|
|
423
|
+
},
|
|
424
|
+
gen.id
|
|
425
|
+
)),
|
|
426
|
+
visibleGroups.map((group) => {
|
|
427
|
+
const rep = group.representative;
|
|
428
|
+
const isActive = group.items.some((i) => i.id === currentResultId);
|
|
429
|
+
return /* @__PURE__ */ jsxs3(
|
|
430
|
+
"div",
|
|
431
|
+
{
|
|
432
|
+
className: `flex gap-3 p-2 bg-white/5 border rounded-2xl cursor-pointer group transition-all relative ${isActive ? "border-white/40 bg-white/10 shadow-lg" : "border-white/5 hover:border-white/20"}`,
|
|
433
|
+
onClick: () => onSelect(rep),
|
|
434
|
+
children: [
|
|
435
|
+
/* @__PURE__ */ jsxs3("div", { className: "w-14 h-14 rounded-xl overflow-hidden bg-black shrink-0 border border-white/5 relative", children: [
|
|
436
|
+
/* @__PURE__ */ jsx5("img", { src: rep.base64 ? rep.base64.startsWith("data:") ? rep.base64 : `data:image/png;base64,${rep.base64}` : "", className: "w-full h-full object-cover", alt: "Thumbnail" }),
|
|
437
|
+
group.items.length > 1 && /* @__PURE__ */ jsx5("div", { className: "absolute bottom-0.5 right-0.5 px-1 bg-black/80 rounded text-[7px] font-bold text-white/70", children: group.items.length })
|
|
438
|
+
] }),
|
|
439
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex-1 py-0.5 overflow-hidden", children: [
|
|
440
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between mb-1", children: [
|
|
441
|
+
/* @__PURE__ */ jsx5("span", { className: "text-[7px] font-bold text-white/20 uppercase whitespace-nowrap", children: formatFriendlyTimestamp(rep.timestamp) }),
|
|
442
|
+
rep.model && /* @__PURE__ */ jsx5("span", { className: "text-[7px] font-bold text-white/40 bg-white/5 px-1 rounded uppercase truncate max-w-[60px]", children: rep.model })
|
|
443
|
+
] }),
|
|
444
|
+
/* @__PURE__ */ jsxs3("p", { className: "text-[9px] text-white/60 line-clamp-2 leading-tight", children: [
|
|
445
|
+
'"',
|
|
446
|
+
rep.prompt,
|
|
447
|
+
'"'
|
|
448
|
+
] })
|
|
449
|
+
] }),
|
|
450
|
+
/* @__PURE__ */ jsx5("button", { onClick: (e) => {
|
|
451
|
+
e.stopPropagation();
|
|
452
|
+
onDelete(rep.id);
|
|
453
|
+
}, className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 w-6 h-6 flex items-center justify-center bg-red-500/20 text-red-400 hover:bg-red-500 hover:text-white rounded-md transition-all", children: /* @__PURE__ */ jsx5("span", { className: "material-symbols-outlined text-[14px]", children: "delete" }) })
|
|
454
|
+
]
|
|
455
|
+
},
|
|
456
|
+
rep.id
|
|
457
|
+
);
|
|
458
|
+
}),
|
|
459
|
+
visibleCount < groups.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: [
|
|
460
|
+
groups.length - visibleCount,
|
|
461
|
+
" weitere laden"
|
|
462
|
+
] })
|
|
463
|
+
] });
|
|
402
464
|
};
|
|
403
465
|
|
|
404
466
|
// src/components/InspectPanel.tsx
|
|
@@ -467,7 +529,7 @@ var InspectPanel = ({ currentResult, history, onSelect, workspaceTags, onTagTogg
|
|
|
467
529
|
};
|
|
468
530
|
|
|
469
531
|
// src/components/SetupPanel.tsx
|
|
470
|
-
import { useRef as useRef2, useState as
|
|
532
|
+
import { useRef as useRef2, useState as useState3 } from "react";
|
|
471
533
|
import { motion as motion3 } from "motion/react";
|
|
472
534
|
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
473
535
|
var PRESET_URLS = [
|
|
@@ -477,11 +539,11 @@ var PRESET_URLS = [
|
|
|
477
539
|
];
|
|
478
540
|
var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
479
541
|
const workspaceInputRef = useRef2(null);
|
|
480
|
-
const [urlInput, setUrlInput] =
|
|
481
|
-
const [tokenInput, setTokenInput] =
|
|
482
|
-
const [testStatus, setTestStatus] =
|
|
483
|
-
const [result, setResult] =
|
|
484
|
-
const [fetchError, setFetchError] =
|
|
542
|
+
const [urlInput, setUrlInput] = useState3("");
|
|
543
|
+
const [tokenInput, setTokenInput] = useState3("");
|
|
544
|
+
const [testStatus, setTestStatus] = useState3("idle");
|
|
545
|
+
const [result, setResult] = useState3(null);
|
|
546
|
+
const [fetchError, setFetchError] = useState3(null);
|
|
485
547
|
const runTest = async (url) => {
|
|
486
548
|
if (!url.trim()) return;
|
|
487
549
|
setTestStatus("loading");
|
|
@@ -644,18 +706,25 @@ var SetupPanel = ({ onWorkspaceImport, buildInfo }) => {
|
|
|
644
706
|
};
|
|
645
707
|
|
|
646
708
|
// src/components/MediaLibrary.tsx
|
|
709
|
+
import { useState as useState4 } from "react";
|
|
647
710
|
import { motion as motion4 } from "motion/react";
|
|
648
711
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
712
|
+
var PAGE_SIZE2 = 20;
|
|
649
713
|
var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, onBatchDownload, onGenerateReference }) => {
|
|
714
|
+
const [visibleCount, setVisibleCount] = useState4(PAGE_SIZE2);
|
|
650
715
|
const selectedCount = items.filter((i) => i.selectedForExport).length;
|
|
716
|
+
const groups = groupByPrompt(items);
|
|
717
|
+
const visibleGroups = groups.slice(0, visibleCount);
|
|
651
718
|
return /* @__PURE__ */ jsxs6("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
652
719
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col p-4 border-b border-white/5 gap-3 bg-black/20", children: [
|
|
653
720
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between", children: [
|
|
654
721
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col", children: [
|
|
655
722
|
/* @__PURE__ */ jsx8("span", { className: "text-[10px] font-bold text-white uppercase tracking-widest", children: "Projekt Galerie" }),
|
|
656
723
|
/* @__PURE__ */ jsxs6("span", { className: "text-[9px] text-white/30 uppercase tracking-tighter", children: [
|
|
724
|
+
visibleCount < groups.length ? `${visibleCount} / ${groups.length}` : groups.length,
|
|
725
|
+
" Gruppen \xB7 ",
|
|
657
726
|
items.length,
|
|
658
|
-
" Assets
|
|
727
|
+
" Assets"
|
|
659
728
|
] })
|
|
660
729
|
] }),
|
|
661
730
|
/* @__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 +743,57 @@ var MediaLibrary = ({ items, onImport, onDelete, onSelect, onToggleSelection, on
|
|
|
674
743
|
] })
|
|
675
744
|
] })
|
|
676
745
|
] }),
|
|
677
|
-
/* @__PURE__ */ jsx8("div", { className: "flex-1 overflow-y-auto p-4 dark-scrollbar", children:
|
|
746
|
+
/* @__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
747
|
/* @__PURE__ */ jsx8("span", { className: "material-symbols-outlined text-[64px]", children: "photo_library" }),
|
|
679
748
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-1", children: [
|
|
680
749
|
/* @__PURE__ */ jsx8("p", { className: "text-[12px] font-bold uppercase tracking-widest", children: "Keine Medien" }),
|
|
681
750
|
/* @__PURE__ */ jsx8("p", { className: "text-[10px] italic", children: "Importiere Assets aus deinem Projekt." })
|
|
682
751
|
] })
|
|
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
|
-
|
|
752
|
+
] }) : /* @__PURE__ */ jsxs6("div", { className: "grid grid-cols-2 gap-3 pb-10", children: [
|
|
753
|
+
visibleGroups.map((group) => {
|
|
754
|
+
const rep = group.representative;
|
|
755
|
+
return /* @__PURE__ */ jsxs6(
|
|
756
|
+
motion4.div,
|
|
757
|
+
{
|
|
758
|
+
initial: { opacity: 0, scale: 0.9 },
|
|
759
|
+
animate: { opacity: 1, scale: 1 },
|
|
760
|
+
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",
|
|
761
|
+
onClick: () => onSelect(rep),
|
|
762
|
+
children: [
|
|
763
|
+
/* @__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 }),
|
|
764
|
+
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: [
|
|
765
|
+
/* @__PURE__ */ jsx8("span", { className: "material-symbols-outlined text-[10px]", children: "photo_library" }),
|
|
766
|
+
group.items.length
|
|
767
|
+
] }),
|
|
768
|
+
/* @__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: [
|
|
769
|
+
/* @__PURE__ */ jsx8("span", { className: "text-[8px] font-bold text-white/80 truncate max-w-[80px] uppercase tracking-tighter", children: rep.prompt || "Importiert" }),
|
|
770
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1", children: [
|
|
771
|
+
onGenerateReference && /* @__PURE__ */ jsx8("button", { type: "button", onClick: (e) => {
|
|
772
|
+
e.stopPropagation();
|
|
773
|
+
onGenerateReference(rep);
|
|
774
|
+
}, 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" }) }),
|
|
775
|
+
/* @__PURE__ */ jsx8("button", { type: "button", onClick: (e) => {
|
|
776
|
+
e.stopPropagation();
|
|
777
|
+
onDelete(rep.id);
|
|
778
|
+
}, 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" }) })
|
|
779
|
+
] })
|
|
780
|
+
] }) }),
|
|
781
|
+
/* @__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" })
|
|
782
|
+
]
|
|
783
|
+
},
|
|
784
|
+
rep.id
|
|
785
|
+
);
|
|
786
|
+
}),
|
|
787
|
+
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: [
|
|
788
|
+
groups.length - visibleCount,
|
|
789
|
+
" weitere laden"
|
|
790
|
+
] }) })
|
|
791
|
+
] }) })
|
|
707
792
|
] });
|
|
708
793
|
};
|
|
709
794
|
|
|
710
795
|
// src/components/ListView.tsx
|
|
711
|
-
import { useEffect as useEffect3, useRef as useRef3, useState as
|
|
796
|
+
import { useEffect as useEffect3, useRef as useRef3, useState as useState5 } from "react";
|
|
712
797
|
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
713
798
|
var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, isActive, isInPath, onFocus, onGenerate, onGenerateBranch, onGenerateSubtree, isGenerating, isCollapsed, toggleCollapse, renderNode, children }) => {
|
|
714
799
|
const inputRef = useRef3(null);
|
|
@@ -773,7 +858,7 @@ var ListNode = ({ node, depth, onNodeChange, onAddChild, onDeleteNode, onMoveNod
|
|
|
773
858
|
] });
|
|
774
859
|
};
|
|
775
860
|
function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMoveNode, onIndentNode, onOutdentNode, onAddSibling, focusedNodeId, onFocus, activePath, onGenerate, onGenerateBranch, onGenerateSubtree, isGeneratingNodeId }) {
|
|
776
|
-
const [collapsed, setCollapsed] =
|
|
861
|
+
const [collapsed, setCollapsed] = useState5(/* @__PURE__ */ new Set());
|
|
777
862
|
const toggleCollapse = (id) => {
|
|
778
863
|
setCollapsed((prev) => {
|
|
779
864
|
const next = new Set(prev);
|
|
@@ -801,13 +886,13 @@ function ListView({ nodes, edges, onNodeChange, onAddChild, onDeleteNode, onMove
|
|
|
801
886
|
}
|
|
802
887
|
|
|
803
888
|
// src/components/AvatarArchitectApp.tsx
|
|
804
|
-
import { useState as
|
|
889
|
+
import { useState as useState20, useCallback as useCallback3, useMemo as useMemo2, useEffect as useEffect7, useRef as useRef8 } from "react";
|
|
805
890
|
|
|
806
891
|
// src/components/PromptTab.tsx
|
|
807
|
-
import { useRef as useRef4, useState as
|
|
892
|
+
import { useRef as useRef4, useState as useState7 } from "react";
|
|
808
893
|
|
|
809
894
|
// src/components/CollapsibleCard.tsx
|
|
810
|
-
import { useState as
|
|
895
|
+
import { useState as useState6 } from "react";
|
|
811
896
|
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
812
897
|
var CollapsibleCard = ({
|
|
813
898
|
title,
|
|
@@ -818,7 +903,7 @@ var CollapsibleCard = ({
|
|
|
818
903
|
collapsible = true,
|
|
819
904
|
className = ""
|
|
820
905
|
}) => {
|
|
821
|
-
const [isOpen, setIsOpen] =
|
|
906
|
+
const [isOpen, setIsOpen] = useState6(defaultOpen);
|
|
822
907
|
return /* @__PURE__ */ jsxs8("div", { className: `border border-neutral-800 rounded-lg ${className}`, children: [
|
|
823
908
|
/* @__PURE__ */ jsxs8(
|
|
824
909
|
"div",
|
|
@@ -865,18 +950,18 @@ var PromptTab = ({
|
|
|
865
950
|
onTagUpdate,
|
|
866
951
|
onTagDelete
|
|
867
952
|
}) => {
|
|
868
|
-
const [selectedLabels, setSelectedLabels] =
|
|
869
|
-
const [instructions, setInstructions] =
|
|
870
|
-
const [rules, setRules] =
|
|
871
|
-
const [activeCategory, setActiveCategory] =
|
|
872
|
-
const [copied, setCopied] =
|
|
953
|
+
const [selectedLabels, setSelectedLabels] = useState7(/* @__PURE__ */ new Set());
|
|
954
|
+
const [instructions, setInstructions] = useState7("");
|
|
955
|
+
const [rules, setRules] = useState7("");
|
|
956
|
+
const [activeCategory, setActiveCategory] = useState7(null);
|
|
957
|
+
const [copied, setCopied] = useState7(false);
|
|
873
958
|
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] =
|
|
959
|
+
const [addingInCat, setAddingInCat] = useState7(null);
|
|
960
|
+
const [newLabel, setNewLabel] = useState7("");
|
|
961
|
+
const [newValue, setNewValue] = useState7("");
|
|
962
|
+
const [editingTag, setEditingTag] = useState7(null);
|
|
963
|
+
const [editLabel, setEditLabel] = useState7("");
|
|
964
|
+
const [editValue, setEditValue] = useState7("");
|
|
880
965
|
const longPressTimer = useRef4(null);
|
|
881
966
|
const longPressActivated = useRef4(false);
|
|
882
967
|
const toggleTag = (label) => {
|
|
@@ -1325,7 +1410,7 @@ var PromptTab = ({
|
|
|
1325
1410
|
};
|
|
1326
1411
|
|
|
1327
1412
|
// src/components/ProjectSyncTab.tsx
|
|
1328
|
-
import { useRef as useRef5, useState as
|
|
1413
|
+
import { useRef as useRef5, useState as useState8, useEffect as useEffect4 } from "react";
|
|
1329
1414
|
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1330
1415
|
var ProjectSyncTab = ({
|
|
1331
1416
|
topSlot,
|
|
@@ -1347,12 +1432,12 @@ var ProjectSyncTab = ({
|
|
|
1347
1432
|
}) => {
|
|
1348
1433
|
const projectInputRef = useRef5(null);
|
|
1349
1434
|
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] =
|
|
1435
|
+
const [saveName, setSaveName] = useState8("");
|
|
1436
|
+
const [isSaving, setIsSaving] = useState8(false);
|
|
1437
|
+
const [isExporting, setIsExporting] = useState8(false);
|
|
1438
|
+
const [syncState, setSyncState] = useState8("idle");
|
|
1439
|
+
const [syncDiff, setSyncDiff] = useState8(null);
|
|
1440
|
+
const [selectedLocalIds, setSelectedLocalIds] = useState8(/* @__PURE__ */ new Set());
|
|
1356
1441
|
const handleExport = async () => {
|
|
1357
1442
|
if (!onProjectExport) return;
|
|
1358
1443
|
setIsExporting(true);
|
|
@@ -1398,13 +1483,13 @@ var ProjectSyncTab = ({
|
|
|
1398
1483
|
});
|
|
1399
1484
|
};
|
|
1400
1485
|
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] =
|
|
1486
|
+
const [hfProjects, setHfProjects] = useState8([]);
|
|
1487
|
+
const [hfLoading, setHfLoading] = useState8(false);
|
|
1488
|
+
const [hfSaving, setHfSaving] = useState8(false);
|
|
1489
|
+
const [hfError, setHfError] = useState8(null);
|
|
1490
|
+
const [hfSaveName, setHfSaveName] = useState8("");
|
|
1491
|
+
const [hfSyncProgress, setHfSyncProgress] = useState8(null);
|
|
1492
|
+
const [hfSyncing, setHfSyncing] = useState8(false);
|
|
1408
1493
|
const loadHfProjects = async (token) => {
|
|
1409
1494
|
setHfLoading(true);
|
|
1410
1495
|
setHfError(null);
|
|
@@ -1601,7 +1686,7 @@ var ProjectSyncTab = ({
|
|
|
1601
1686
|
{
|
|
1602
1687
|
onClick: async () => {
|
|
1603
1688
|
try {
|
|
1604
|
-
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-
|
|
1689
|
+
const { hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-5BU5DVQ6.mjs");
|
|
1605
1690
|
const file = await hfDownloadProject2(p.path, hfToken);
|
|
1606
1691
|
onHfLoad(file);
|
|
1607
1692
|
} catch (e) {
|
|
@@ -1823,7 +1908,7 @@ function toPromptImages(images) {
|
|
|
1823
1908
|
}
|
|
1824
1909
|
|
|
1825
1910
|
// src/hooks/useHFState.ts
|
|
1826
|
-
import { useState as
|
|
1911
|
+
import { useState as useState9, useEffect as useEffect5, useRef as useRef6, useCallback } from "react";
|
|
1827
1912
|
|
|
1828
1913
|
// src/lib/hfReducer.ts
|
|
1829
1914
|
function applyEvent(state, event) {
|
|
@@ -1844,6 +1929,13 @@ function applyEvent(state, event) {
|
|
|
1844
1929
|
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
1930
|
return { ...state, tags: { by_category: { ...tags.by_category, [p.category]: newCat }, all: newAll } };
|
|
1846
1931
|
}
|
|
1932
|
+
case "thumb_added": {
|
|
1933
|
+
const p = event.payload;
|
|
1934
|
+
return {
|
|
1935
|
+
...state,
|
|
1936
|
+
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, hasThumb: true } : m)
|
|
1937
|
+
};
|
|
1938
|
+
}
|
|
1847
1939
|
case "metadata_updated": {
|
|
1848
1940
|
const p = event.payload;
|
|
1849
1941
|
return {
|
|
@@ -1851,6 +1943,13 @@ function applyEvent(state, event) {
|
|
|
1851
1943
|
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, ...p.delta } : m)
|
|
1852
1944
|
};
|
|
1853
1945
|
}
|
|
1946
|
+
case "title_set": {
|
|
1947
|
+
const p = event.payload;
|
|
1948
|
+
return {
|
|
1949
|
+
...state,
|
|
1950
|
+
metadata: state.metadata.map((m) => m.id === p.id ? { ...m, titleTs: event.ts } : m)
|
|
1951
|
+
};
|
|
1952
|
+
}
|
|
1854
1953
|
default:
|
|
1855
1954
|
return state;
|
|
1856
1955
|
}
|
|
@@ -1941,15 +2040,15 @@ function writeOfflineBuffer(events) {
|
|
|
1941
2040
|
}
|
|
1942
2041
|
}
|
|
1943
2042
|
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] =
|
|
2043
|
+
const [state, setState] = useState9(null);
|
|
2044
|
+
const [isLoading, setIsLoading] = useState9(false);
|
|
2045
|
+
const [error, setError] = useState9(null);
|
|
2046
|
+
const [eventCount, setEventCount] = useState9(0);
|
|
2047
|
+
const [localOnlyCount, setLocalOnlyCount] = useState9(0);
|
|
2048
|
+
const [forks, setForks] = useState9([]);
|
|
2049
|
+
const [pendingBufferCount, setPendingBufferCount] = useState9(readOfflineBuffer().length);
|
|
2050
|
+
const [lastEventTs, setLastEventTs] = useState9(0);
|
|
2051
|
+
const [hasStateZip, setHasStateZip] = useState9(false);
|
|
1953
2052
|
const knownEventPaths = useRef6(/* @__PURE__ */ new Set());
|
|
1954
2053
|
const allEventsRef = useRef6([]);
|
|
1955
2054
|
const applyNewEvents = useCallback((snapshot, newEvents) => {
|
|
@@ -2085,13 +2184,13 @@ function useHFState(token, namespace) {
|
|
|
2085
2184
|
}
|
|
2086
2185
|
|
|
2087
2186
|
// src/components/labs/LabsTab.tsx
|
|
2088
|
-
import { useState as
|
|
2187
|
+
import { useState as useState16 } from "react";
|
|
2089
2188
|
|
|
2090
2189
|
// src/components/labs/LabRemix.tsx
|
|
2091
|
-
import { useState as
|
|
2190
|
+
import { useState as useState11 } from "react";
|
|
2092
2191
|
|
|
2093
2192
|
// src/components/labs/LabImagePicker.tsx
|
|
2094
|
-
import { useState as
|
|
2193
|
+
import { useState as useState10 } from "react";
|
|
2095
2194
|
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2096
2195
|
var LabImagePicker = ({
|
|
2097
2196
|
availableItems,
|
|
@@ -2100,8 +2199,8 @@ var LabImagePicker = ({
|
|
|
2100
2199
|
onClose,
|
|
2101
2200
|
title = "Bild w\xE4hlen"
|
|
2102
2201
|
}) => {
|
|
2103
|
-
const [search, setSearch] =
|
|
2104
|
-
const [drillItem, setDrillItem] =
|
|
2202
|
+
const [search, setSearch] = useState10("");
|
|
2203
|
+
const [drillItem, setDrillItem] = useState10(null);
|
|
2105
2204
|
const filtered = availableItems.filter(
|
|
2106
2205
|
(item) => !search || item.prompt.toLowerCase().includes(search.toLowerCase())
|
|
2107
2206
|
);
|
|
@@ -2203,13 +2302,13 @@ var LabImagePicker = ({
|
|
|
2203
2302
|
// src/components/labs/LabRemix.tsx
|
|
2204
2303
|
import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2205
2304
|
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] =
|
|
2305
|
+
const [showPicker, setShowPicker] = useState11(false);
|
|
2306
|
+
const [selected, setSelected] = useState11(null);
|
|
2307
|
+
const [instruction, setInstruction] = useState11("");
|
|
2308
|
+
const [generatedPrompt, setGeneratedPrompt] = useState11("");
|
|
2309
|
+
const [resultImage, setResultImage] = useState11(null);
|
|
2310
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = useState11(false);
|
|
2311
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState11(false);
|
|
2213
2312
|
const handleSelectImage = (item, frame) => {
|
|
2214
2313
|
services.onItemUsed(item);
|
|
2215
2314
|
setSelected({
|
|
@@ -2392,16 +2491,16 @@ var LabRemix = ({ services, onResult }) => {
|
|
|
2392
2491
|
};
|
|
2393
2492
|
|
|
2394
2493
|
// src/components/labs/LabBlend.tsx
|
|
2395
|
-
import { useState as
|
|
2494
|
+
import { useState as useState12 } from "react";
|
|
2396
2495
|
import { Fragment as Fragment6, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2397
2496
|
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] =
|
|
2497
|
+
const [showPickerFor, setShowPickerFor] = useState12(null);
|
|
2498
|
+
const [selectedImages, setSelectedImages] = useState12([]);
|
|
2499
|
+
const [instruction, setInstruction] = useState12("");
|
|
2500
|
+
const [generatedPrompt, setGeneratedPrompt] = useState12("");
|
|
2501
|
+
const [resultImage, setResultImage] = useState12(null);
|
|
2502
|
+
const [isGeneratingPrompt, setIsGeneratingPrompt] = useState12(false);
|
|
2503
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState12(false);
|
|
2405
2504
|
const handleSelectImage = (index, item, frame) => {
|
|
2406
2505
|
services.onItemUsed(item);
|
|
2407
2506
|
const newImg = {
|
|
@@ -2588,17 +2687,17 @@ var LabBlend = ({ services, onResult }) => {
|
|
|
2588
2687
|
};
|
|
2589
2688
|
|
|
2590
2689
|
// src/components/labs/LabCompare.tsx
|
|
2591
|
-
import { useState as
|
|
2690
|
+
import { useState as useState13 } from "react";
|
|
2592
2691
|
import { Fragment as Fragment7, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2593
2692
|
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] =
|
|
2693
|
+
const [showPickerFor, setShowPickerFor] = useState13(null);
|
|
2694
|
+
const [selectedImages, setSelectedImages] = useState13([]);
|
|
2695
|
+
const [instruction, setInstruction] = useState13("");
|
|
2696
|
+
const [analysis, setAnalysis] = useState13("");
|
|
2697
|
+
const [generatedPrompt, setGeneratedPrompt] = useState13("");
|
|
2698
|
+
const [resultImage, setResultImage] = useState13(null);
|
|
2699
|
+
const [isAnalyzing, setIsAnalyzing] = useState13(false);
|
|
2700
|
+
const [isGeneratingImage, setIsGeneratingImage] = useState13(false);
|
|
2602
2701
|
const handleSelectImage = (index, item, frame) => {
|
|
2603
2702
|
services.onItemUsed(item);
|
|
2604
2703
|
const newImg = {
|
|
@@ -2761,14 +2860,14 @@ var LabCompare = ({ services, onResult }) => {
|
|
|
2761
2860
|
};
|
|
2762
2861
|
|
|
2763
2862
|
// src/components/labs/LabLoop.tsx
|
|
2764
|
-
import { useState as
|
|
2863
|
+
import { useState as useState14 } from "react";
|
|
2765
2864
|
import { Fragment as Fragment8, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2766
2865
|
var LabLoop = ({ services, onResult }) => {
|
|
2767
|
-
const [rounds, setRounds] =
|
|
2768
|
-
const [currentInstruction, setCurrentInstruction] =
|
|
2769
|
-
const [showPickerForRound, setShowPickerForRound] =
|
|
2770
|
-
const [pendingImages, setPendingImages] =
|
|
2771
|
-
const [isGenerating, setIsGenerating] =
|
|
2866
|
+
const [rounds, setRounds] = useState14([]);
|
|
2867
|
+
const [currentInstruction, setCurrentInstruction] = useState14("");
|
|
2868
|
+
const [showPickerForRound, setShowPickerForRound] = useState14(null);
|
|
2869
|
+
const [pendingImages, setPendingImages] = useState14([]);
|
|
2870
|
+
const [isGenerating, setIsGenerating] = useState14(false);
|
|
2772
2871
|
const currentPrompt = rounds.length > 0 ? rounds[rounds.length - 1].prompt : "";
|
|
2773
2872
|
const handleAddImage = (item, frame) => {
|
|
2774
2873
|
services.onItemUsed(item);
|
|
@@ -2924,7 +3023,7 @@ var LabLoop = ({ services, onResult }) => {
|
|
|
2924
3023
|
};
|
|
2925
3024
|
|
|
2926
3025
|
// src/components/labs/LabFrameExtractor.tsx
|
|
2927
|
-
import { useRef as useRef7, useState as
|
|
3026
|
+
import { useRef as useRef7, useState as useState15, useCallback as useCallback2 } from "react";
|
|
2928
3027
|
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2929
3028
|
var formatTime = (s) => {
|
|
2930
3029
|
const m = Math.floor(s / 60);
|
|
@@ -2941,12 +3040,12 @@ var LabFrameExtractor = ({
|
|
|
2941
3040
|
const videoRef = useRef7(null);
|
|
2942
3041
|
const canvasRef = useRef7(null);
|
|
2943
3042
|
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] =
|
|
3043
|
+
const [selectedItem, setSelectedItem] = useState15(null);
|
|
3044
|
+
const [videoSrc, setVideoSrc] = useState15(null);
|
|
3045
|
+
const [videoReady, setVideoReady] = useState15(false);
|
|
3046
|
+
const [frames, setFrames] = useState15([]);
|
|
3047
|
+
const [isExtracting, setIsExtracting] = useState15(false);
|
|
3048
|
+
const [intervalSec, setIntervalSec] = useState15("1");
|
|
2950
3049
|
const handleVideoSelect = (item) => {
|
|
2951
3050
|
const mediaId = item.frames[0]?.mediaId;
|
|
2952
3051
|
if (!mediaId) return;
|
|
@@ -3183,7 +3282,7 @@ var BASE_TABS = [
|
|
|
3183
3282
|
];
|
|
3184
3283
|
var FRAMES_TAB = { key: "frames", label: "Frames", icon: "crop_original" };
|
|
3185
3284
|
var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
|
|
3186
|
-
const [activeTab, setActiveTab] =
|
|
3285
|
+
const [activeTab, setActiveTab] = useState16("remix");
|
|
3187
3286
|
const showFrames = !!(videoItems && resolveVideoUrl);
|
|
3188
3287
|
const tabs = showFrames ? [...BASE_TABS, FRAMES_TAB] : BASE_TABS;
|
|
3189
3288
|
return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col h-full overflow-hidden", children: [
|
|
@@ -3217,19 +3316,19 @@ var LabsTab = ({ services, onResult, videoItems, resolveVideoUrl }) => {
|
|
|
3217
3316
|
};
|
|
3218
3317
|
|
|
3219
3318
|
// src/components/TagManagerPanel.tsx
|
|
3220
|
-
import { useState as
|
|
3319
|
+
import { useState as useState17 } from "react";
|
|
3221
3320
|
import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3222
3321
|
function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete, onTagReorder, onTagMove }) {
|
|
3223
3322
|
const categories = Object.keys(workspaceTags.by_category).filter(
|
|
3224
3323
|
(cat) => (workspaceTags.by_category[cat] || []).some((t) => !t.is_deleted)
|
|
3225
3324
|
);
|
|
3226
|
-
const [selectedCategory, setSelectedCategory] =
|
|
3325
|
+
const [selectedCategory, setSelectedCategory] = useState17(categories[0] || "");
|
|
3227
3326
|
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] =
|
|
3327
|
+
const [editingLabel, setEditingLabel] = useState17(null);
|
|
3328
|
+
const [editState, setEditState] = useState17({ label: "", value: "" });
|
|
3329
|
+
const [newTag, setNewTag] = useState17({ label: "", value: "" });
|
|
3330
|
+
const [movingLabel, setMovingLabel] = useState17(null);
|
|
3331
|
+
const [moveTarget, setMoveTarget] = useState17("");
|
|
3233
3332
|
const tags = (workspaceTags.by_category[effectiveCategory] || []).filter((t) => !t.is_deleted);
|
|
3234
3333
|
const otherCategories = categories.filter((c) => c !== effectiveCategory);
|
|
3235
3334
|
const startEdit = (tag) => {
|
|
@@ -3425,7 +3524,7 @@ function TagManagerPanel({ workspaceTags, onTagCreate, onTagUpdate, onTagDelete,
|
|
|
3425
3524
|
}
|
|
3426
3525
|
|
|
3427
3526
|
// src/components/HFTestTab.tsx
|
|
3428
|
-
import { useState as
|
|
3527
|
+
import { useState as useState18 } from "react";
|
|
3429
3528
|
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3430
3529
|
var HF_BASE = "https://huggingface.co";
|
|
3431
3530
|
var HF_REPO = "RolandSch/fa-app-state";
|
|
@@ -3618,7 +3717,7 @@ function tryFmt(s) {
|
|
|
3618
3717
|
}
|
|
3619
3718
|
}
|
|
3620
3719
|
function CopyBtn({ text }) {
|
|
3621
|
-
const [done, setDone] =
|
|
3720
|
+
const [done, setDone] = useState18(false);
|
|
3622
3721
|
return /* @__PURE__ */ jsxs19(
|
|
3623
3722
|
"button",
|
|
3624
3723
|
{
|
|
@@ -3789,10 +3888,10 @@ function EventMonitor({ events, confirmedEventKeys, galleryItems, imageUploadSta
|
|
|
3789
3888
|
] })
|
|
3790
3889
|
] });
|
|
3791
3890
|
}
|
|
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] =
|
|
3891
|
+
function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEventKeys = /* @__PURE__ */ new Set(), imageUploadStatus = /* @__PURE__ */ new Map(), missingImages = [] }) {
|
|
3892
|
+
const [selected, setSelected] = useState18(null);
|
|
3893
|
+
const [results, setResults] = useState18({});
|
|
3894
|
+
const [expanded, setExpanded] = useState18({});
|
|
3796
3895
|
const withResults = galleryItems.filter((g) => g.base64 && g.status === "done");
|
|
3797
3896
|
const setRunning = (id) => setResults((r) => ({ ...r, [id]: { status: "running", steps: [], totalMs: 0 } }));
|
|
3798
3897
|
const setDone = (id, steps, t0) => {
|
|
@@ -3859,6 +3958,33 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
|
|
|
3859
3958
|
)
|
|
3860
3959
|
}
|
|
3861
3960
|
) }),
|
|
3961
|
+
missingImages.length > 0 && /* @__PURE__ */ jsx21("div", { style: { marginBottom: 12 }, children: /* @__PURE__ */ jsx21(
|
|
3962
|
+
CollapsibleCard,
|
|
3963
|
+
{
|
|
3964
|
+
title: `Fehlende Bilder auf HF (${missingImages.length})`,
|
|
3965
|
+
icon: /* @__PURE__ */ jsx21("span", { className: "material-symbols-outlined", style: { fontSize: 16 }, children: "broken_image" }),
|
|
3966
|
+
defaultOpen: false,
|
|
3967
|
+
children: /* @__PURE__ */ jsxs19("div", { style: { padding: "8px 10px 4px" }, children: [
|
|
3968
|
+
/* @__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." }),
|
|
3969
|
+
/* @__PURE__ */ jsxs19("div", { style: { display: "flex", gap: 8, marginBottom: 8, fontSize: 11, color: "rgba(255,255,255,0.5)" }, children: [
|
|
3970
|
+
/* @__PURE__ */ jsxs19("span", { children: [
|
|
3971
|
+
"UUID (Flow-App): ",
|
|
3972
|
+
missingImages.filter((e) => !e.filename).length
|
|
3973
|
+
] }),
|
|
3974
|
+
/* @__PURE__ */ jsx21("span", { children: "\xB7" }),
|
|
3975
|
+
/* @__PURE__ */ jsxs19("span", { children: [
|
|
3976
|
+
"Filename (Server-Upload): ",
|
|
3977
|
+
missingImages.filter((e) => !!e.filename).length
|
|
3978
|
+
] })
|
|
3979
|
+
] }),
|
|
3980
|
+
/* @__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: [
|
|
3981
|
+
/* @__PURE__ */ jsx21("span", { style: { color: e.filename ? "#fb923c" : "#60a5fa", minWidth: 60 }, children: e.filename ? "filename" : "uuid" }),
|
|
3982
|
+
/* @__PURE__ */ jsx21("span", { style: { flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: e.filename ?? e.id }),
|
|
3983
|
+
/* @__PURE__ */ jsx21("span", { style: { color: "rgba(255,255,255,0.3)" }, children: new Date(e.timestamp).toLocaleDateString("de") })
|
|
3984
|
+
] }, e.id)) })
|
|
3985
|
+
] })
|
|
3986
|
+
}
|
|
3987
|
+
) }),
|
|
3862
3988
|
/* @__PURE__ */ jsx21(
|
|
3863
3989
|
CollapsibleCard,
|
|
3864
3990
|
{
|
|
@@ -3963,75 +4089,44 @@ function HFTestTab({ token, namespace, galleryItems, allEvents = [], confirmedEv
|
|
|
3963
4089
|
}
|
|
3964
4090
|
|
|
3965
4091
|
// 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
|
|
4092
|
+
import { useState as useState19, useEffect as useEffect6 } from "react";
|
|
4002
4093
|
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4003
4094
|
function StarRating({ rating = 0 }) {
|
|
4004
4095
|
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
4096
|
}
|
|
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 [
|
|
4097
|
+
async function serverGet(baseUrl, path) {
|
|
4098
|
+
const url = `${baseUrl.replace(/\/$/, "")}${path}`;
|
|
4099
|
+
const res = await fetch(url, { credentials: "include" });
|
|
4100
|
+
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
|
|
4101
|
+
const json = await res.json();
|
|
4102
|
+
return json && typeof json === "object" && "data" in json ? json.data : json;
|
|
4103
|
+
}
|
|
4104
|
+
function ServerTab({ serverBaseUrl }) {
|
|
4105
|
+
const [step, setStep] = useState19("user");
|
|
4106
|
+
const [users, setUsers] = useState19([]);
|
|
4107
|
+
const [usersLoading, setUsersLoading] = useState19(false);
|
|
4108
|
+
const [usersError, setUsersError] = useState19(null);
|
|
4109
|
+
const [selectedUser, setSelectedUser] = useState19(null);
|
|
4110
|
+
const [contexts, setContexts] = useState19([]);
|
|
4111
|
+
const [contextsLoading, setContextsLoading] = useState19(false);
|
|
4112
|
+
const [selectedContext, setSelectedContext] = useState19(null);
|
|
4113
|
+
const [tags, setTags] = useState19([]);
|
|
4114
|
+
const [items, setItems] = useState19([]);
|
|
4115
|
+
const [libLoading, setLibLoading] = useState19(false);
|
|
4116
|
+
const [libError, setLibError] = useState19(null);
|
|
4117
|
+
const [activeTag, setActiveTag] = useState19(null);
|
|
4118
|
+
const [preview, setPreview] = useState19(null);
|
|
4024
4119
|
useEffect6(() => {
|
|
4025
|
-
if (!
|
|
4120
|
+
if (!serverBaseUrl) return;
|
|
4026
4121
|
setUsersLoading(true);
|
|
4027
4122
|
setUsersError(null);
|
|
4028
|
-
|
|
4029
|
-
}, [
|
|
4123
|
+
serverGet(serverBaseUrl, "/api/v2/users").then(setUsers).catch((e) => setUsersError(String(e))).finally(() => setUsersLoading(false));
|
|
4124
|
+
}, [serverBaseUrl]);
|
|
4030
4125
|
const selectUser = async (user) => {
|
|
4031
4126
|
setSelectedUser(user);
|
|
4032
4127
|
setContextsLoading(true);
|
|
4033
4128
|
try {
|
|
4034
|
-
const data = await
|
|
4129
|
+
const data = await serverGet(serverBaseUrl, `/api2/contexts?user_id=${user.id}`);
|
|
4035
4130
|
if (data.length === 1) {
|
|
4036
4131
|
await loadLibrary(user, data[0]);
|
|
4037
4132
|
} else {
|
|
@@ -4051,12 +4146,11 @@ function ServerTab({ hfToken }) {
|
|
|
4051
4146
|
setLibError(null);
|
|
4052
4147
|
try {
|
|
4053
4148
|
const [tagsRes, libRes] = await Promise.all([
|
|
4054
|
-
|
|
4055
|
-
|
|
4149
|
+
serverGet(serverBaseUrl, `/api2/tags?user_id=${user.id}`),
|
|
4150
|
+
serverGet(serverBaseUrl, `/api/storage/${user.id}/library`)
|
|
4056
4151
|
]);
|
|
4057
4152
|
setTags(Array.isArray(tagsRes) ? tagsRes : []);
|
|
4058
|
-
|
|
4059
|
-
setItems(raw);
|
|
4153
|
+
setItems(Array.isArray(libRes) ? libRes : []);
|
|
4060
4154
|
} catch (e) {
|
|
4061
4155
|
setLibError(String(e));
|
|
4062
4156
|
} finally {
|
|
@@ -4075,13 +4169,7 @@ function ServerTab({ hfToken }) {
|
|
|
4075
4169
|
setLibError(null);
|
|
4076
4170
|
};
|
|
4077
4171
|
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
|
-
}
|
|
4172
|
+
if (!serverBaseUrl) return null;
|
|
4085
4173
|
return /* @__PURE__ */ jsxs20("div", { className: "flex flex-col h-full min-h-0", children: [
|
|
4086
4174
|
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-white/8", children: [
|
|
4087
4175
|
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 +4177,7 @@ function ServerTab({ hfToken }) {
|
|
|
4089
4177
|
step === "user" && "Server Browser",
|
|
4090
4178
|
step === "context" && `${selectedUser?.username} \u2014 Kontext w\xE4hlen`,
|
|
4091
4179
|
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
|
-
)) })
|
|
4180
|
+
] })
|
|
4102
4181
|
] }),
|
|
4103
4182
|
step === "user" && /* @__PURE__ */ jsxs20("div", { className: "flex flex-col flex-1 min-h-0 overflow-y-auto p-3 gap-2", children: [
|
|
4104
4183
|
usersLoading && /* @__PURE__ */ jsx22("p", { className: "text-white/30 text-[11px] text-center py-4", children: "Lade User\u2026" }),
|
|
@@ -4189,7 +4268,7 @@ function ServerTab({ hfToken }) {
|
|
|
4189
4268
|
|
|
4190
4269
|
// src/components/AvatarArchitectApp.tsx
|
|
4191
4270
|
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 }) {
|
|
4271
|
+
function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onSelectMedia, buildInfo, initialHfToken, hfNamespace, allowDevNamespace, serverBaseUrl, onFetchServerProjects, onServerSave, onServerLoad, onServerDelete }) {
|
|
4193
4272
|
useEffect7(() => {
|
|
4194
4273
|
const id = "flow-styles";
|
|
4195
4274
|
if (!document.getElementById(id)) {
|
|
@@ -4199,19 +4278,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4199
4278
|
document.head.appendChild(style);
|
|
4200
4279
|
}
|
|
4201
4280
|
}, []);
|
|
4202
|
-
const [showStart, setShowStart] =
|
|
4203
|
-
const [layoutChoice, setLayoutChoice] =
|
|
4281
|
+
const [showStart, setShowStart] = useState20(true);
|
|
4282
|
+
const [layoutChoice, setLayoutChoice] = useState20(() => {
|
|
4204
4283
|
try {
|
|
4205
4284
|
return localStorage.getItem("aa-layout") || null;
|
|
4206
4285
|
} catch {
|
|
4207
4286
|
return null;
|
|
4208
4287
|
}
|
|
4209
4288
|
});
|
|
4210
|
-
const [projectLoaded, setProjectLoaded] =
|
|
4211
|
-
const [hfToken, setHfToken] =
|
|
4212
|
-
const [hfTokenInput, setHfTokenInput] =
|
|
4213
|
-
const [isLoadingFromHF, setIsLoadingFromHF] =
|
|
4214
|
-
const [hfNamespaceLocal, setHfNamespaceLocal] =
|
|
4289
|
+
const [projectLoaded, setProjectLoaded] = useState20(false);
|
|
4290
|
+
const [hfToken, setHfToken] = useState20(initialHfToken || "");
|
|
4291
|
+
const [hfTokenInput, setHfTokenInput] = useState20(initialHfToken || "");
|
|
4292
|
+
const [isLoadingFromHF, setIsLoadingFromHF] = useState20(false);
|
|
4293
|
+
const [hfNamespaceLocal, setHfNamespaceLocal] = useState20(() => {
|
|
4215
4294
|
try {
|
|
4216
4295
|
const stored = localStorage.getItem("aa-hf-namespace");
|
|
4217
4296
|
if (stored !== null) return stored;
|
|
@@ -4220,7 +4299,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4220
4299
|
return "";
|
|
4221
4300
|
}
|
|
4222
4301
|
});
|
|
4223
|
-
const [hfNamespaceFromServer, setHfNamespaceFromServer] =
|
|
4302
|
+
const [hfNamespaceFromServer, setHfNamespaceFromServer] = useState20(null);
|
|
4224
4303
|
useEffect7(() => {
|
|
4225
4304
|
if (hfNamespace !== void 0) return;
|
|
4226
4305
|
const backendUrl = typeof window !== "undefined" ? window.BACKEND_URL || window.location.origin : null;
|
|
@@ -4243,9 +4322,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4243
4322
|
refresh: refreshHF,
|
|
4244
4323
|
hasStateZip
|
|
4245
4324
|
} = useHFState(hfToken, effectiveNamespace);
|
|
4246
|
-
const [imageUploadStatus, setImageUploadStatus] =
|
|
4247
|
-
const [bootstrapLog, setBootstrapLog] =
|
|
4248
|
-
const [isBootstrapping, setIsBootstrapping] =
|
|
4325
|
+
const [imageUploadStatus, setImageUploadStatus] = useState20(/* @__PURE__ */ new Map());
|
|
4326
|
+
const [bootstrapLog, setBootstrapLog] = useState20([]);
|
|
4327
|
+
const [isBootstrapping, setIsBootstrapping] = useState20(false);
|
|
4328
|
+
const [hfMissingImages, setHfMissingImages] = useState20([]);
|
|
4249
4329
|
const syncTopSlot = /* @__PURE__ */ jsxs21(Fragment9, { children: [
|
|
4250
4330
|
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
4331
|
"\u26A0 ",
|
|
@@ -4304,10 +4384,10 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4304
4384
|
setLayoutChoice(choice);
|
|
4305
4385
|
setShowStart(false);
|
|
4306
4386
|
};
|
|
4307
|
-
const [nodes, setNodes] =
|
|
4308
|
-
const [edges, setEdges] =
|
|
4309
|
-
const [history, setHistory] =
|
|
4310
|
-
const [galleryItems, setGalleryItems] =
|
|
4387
|
+
const [nodes, setNodes] = useState20([{ id: "1", type: "custom", position: { x: 0, y: 0 }, data: { label: "Fine Art Project", placeholder: "Name..." } }]);
|
|
4388
|
+
const [edges, setEdges] = useState20([]);
|
|
4389
|
+
const [history, setHistory] = useState20([]);
|
|
4390
|
+
const [galleryItems, setGalleryItems] = useState20([]);
|
|
4311
4391
|
const galleryItemsRef = useRef8([]);
|
|
4312
4392
|
useEffect7(() => {
|
|
4313
4393
|
galleryItemsRef.current = galleryItems;
|
|
@@ -4325,7 +4405,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4325
4405
|
model: m.model,
|
|
4326
4406
|
tags: m.tags || [],
|
|
4327
4407
|
timestamp: m.timestamp,
|
|
4328
|
-
status: "done"
|
|
4408
|
+
status: "done",
|
|
4409
|
+
filename: m.filename,
|
|
4410
|
+
hasThumb: m.hasThumb
|
|
4329
4411
|
}));
|
|
4330
4412
|
setGalleryItems((prev) => {
|
|
4331
4413
|
const localOnly = prev.filter((g) => !hfIds.has(g.id));
|
|
@@ -4337,77 +4419,83 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4337
4419
|
const merged = skeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
|
|
4338
4420
|
return [...localOnly, ...merged].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
4339
4421
|
});
|
|
4340
|
-
const
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4422
|
+
const sortedEntries = [...hfState.metadata].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0));
|
|
4423
|
+
(async () => {
|
|
4424
|
+
for (const entry of sortedEntries) {
|
|
4425
|
+
if (galleryItemsRef.current.find((g) => g.id === entry.id)?.base64) continue;
|
|
4426
|
+
if (hfImageNotFoundRef.current.has(entry.id)) continue;
|
|
4427
|
+
try {
|
|
4428
|
+
const b64 = await hfLoadImageAsBase64(entry.id, hfToken, effectiveNamespace, entry.filename, void 0, entry.mimeType, entry.hasThumb);
|
|
4429
|
+
if (!b64) {
|
|
4430
|
+
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
4431
|
+
setHfMissingImages((prev) => {
|
|
4432
|
+
if (prev.find((e) => e.id === entry.id)) return prev;
|
|
4433
|
+
return [...prev, { id: entry.id, filename: entry.filename, mimeType: entry.mimeType, timestamp: entry.timestamp }];
|
|
4434
|
+
});
|
|
4435
|
+
continue;
|
|
4436
|
+
}
|
|
4437
|
+
const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
|
|
4438
|
+
setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
4439
|
+
setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
|
|
4440
|
+
} catch {
|
|
4347
4441
|
hfImageNotFoundRef.current.set(entry.id, Date.now());
|
|
4348
|
-
return;
|
|
4349
4442
|
}
|
|
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
|
-
}
|
|
4443
|
+
}
|
|
4444
|
+
})();
|
|
4357
4445
|
}, [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] =
|
|
4446
|
+
const [activePrompt, setActivePrompt] = useState20("");
|
|
4447
|
+
const [isSynthesizing, setIsSynthesizing] = useState20(false);
|
|
4448
|
+
const [activeGenerationsCount, setActiveGenerationsCount] = useState20(0);
|
|
4449
|
+
const [currentResult, setCurrentResult] = useState20(null);
|
|
4450
|
+
const [focusedNodeId, setFocusedNodeId] = useState20(null);
|
|
4451
|
+
const [leftTab, setLeftTab] = useState20("prompt");
|
|
4452
|
+
const [promptFeedback, setPromptFeedback] = useState20(null);
|
|
4453
|
+
const [lastPromptPayload, setLastPromptPayload] = useState20(null);
|
|
4454
|
+
const [isPromptTabGenerating, setIsPromptTabGenerating] = useState20(false);
|
|
4455
|
+
const [activeTab, setActiveTab] = useState20("history");
|
|
4456
|
+
const [mobileTab, setMobileTab] = useState20("stage");
|
|
4457
|
+
const [middlePanel, setMiddlePanel] = useState20("stage");
|
|
4458
|
+
const [recentLabItems, setRecentLabItems] = useState20([]);
|
|
4459
|
+
const [aspectRatio, setAspectRatio] = useState20("1:1");
|
|
4460
|
+
const [selectedModel, setSelectedModel] = useState20("\u{1F34C} Nano Banana Pro");
|
|
4461
|
+
const [seed, setSeed] = useState20(Math.floor(Math.random() * 1e6));
|
|
4462
|
+
const [seedMode, setSeedMode] = useState20("random");
|
|
4463
|
+
const [isLeftCollapsed, setIsLeftCollapsed] = useState20(false);
|
|
4464
|
+
const [isRightCollapsed, setIsRightCollapsed] = useState20(false);
|
|
4465
|
+
const [leftPanelWidth, setLeftPanelWidth] = useState20(() => {
|
|
4378
4466
|
try {
|
|
4379
4467
|
return parseInt(localStorage.getItem("aa-left-width") || "260", 10);
|
|
4380
4468
|
} catch {
|
|
4381
4469
|
return 260;
|
|
4382
4470
|
}
|
|
4383
4471
|
});
|
|
4384
|
-
const [rightPanelWidth, setRightPanelWidth] =
|
|
4472
|
+
const [rightPanelWidth, setRightPanelWidth] = useState20(() => {
|
|
4385
4473
|
try {
|
|
4386
4474
|
return parseInt(localStorage.getItem("aa-right-width") || "320", 10);
|
|
4387
4475
|
} catch {
|
|
4388
4476
|
return 320;
|
|
4389
4477
|
}
|
|
4390
4478
|
});
|
|
4391
|
-
const [isPromptCollapsed, setIsPromptCollapsed] =
|
|
4392
|
-
const [projectActionState, setProjectActionState] =
|
|
4479
|
+
const [isPromptCollapsed, setIsPromptCollapsed] = useState20(false);
|
|
4480
|
+
const [projectActionState, setProjectActionState] = useState20("idle");
|
|
4393
4481
|
const syncServerDataRef = useRef8(null);
|
|
4394
|
-
const [workspaceTags, setWorkspaceTags] =
|
|
4395
|
-
const [serverProjects, setServerProjects] =
|
|
4396
|
-
const [isLoadingFromServer, setIsLoadingFromServer] =
|
|
4397
|
-
const [highContrast, setHighContrast] =
|
|
4482
|
+
const [workspaceTags, setWorkspaceTags] = useState20(null);
|
|
4483
|
+
const [serverProjects, setServerProjects] = useState20([]);
|
|
4484
|
+
const [isLoadingFromServer, setIsLoadingFromServer] = useState20(false);
|
|
4485
|
+
const [highContrast, setHighContrast] = useState20(() => {
|
|
4398
4486
|
try {
|
|
4399
4487
|
return localStorage.getItem("aa-contrast") === "high";
|
|
4400
4488
|
} catch {
|
|
4401
4489
|
return false;
|
|
4402
4490
|
}
|
|
4403
4491
|
});
|
|
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] =
|
|
4492
|
+
const [activeReferenceId, setActiveReferenceId] = useState20(null);
|
|
4493
|
+
const [activeReferenceThumbnail, setActiveReferenceThumbnail] = useState20(null);
|
|
4494
|
+
const [isScanningImage, setIsScanningImage] = useState20(false);
|
|
4495
|
+
const [touchStartX, setTouchStartX] = useState20(null);
|
|
4496
|
+
const [isFullscreen, setIsFullscreen] = useState20(false);
|
|
4497
|
+
const [zoomScale, setZoomScale] = useState20(1);
|
|
4498
|
+
const [zoomOffset, setZoomOffset] = useState20({ x: 0, y: 0 });
|
|
4411
4499
|
const lastPinchDist = useRef8(null);
|
|
4412
4500
|
const lastTapTime = useRef8(0);
|
|
4413
4501
|
const dragStart = useRef8(null);
|
|
@@ -4560,6 +4648,34 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4560
4648
|
const goToNext = useCallback3(() => {
|
|
4561
4649
|
if (currentIndex < history.length - 1) setCurrentResult(history[currentIndex + 1]);
|
|
4562
4650
|
}, [currentIndex, history]);
|
|
4651
|
+
const handleGallerySelect = useCallback3((g) => {
|
|
4652
|
+
setCurrentResult(g);
|
|
4653
|
+
setMobileTab("stage");
|
|
4654
|
+
if (g.filename && hfToken && !g.fullBase64) {
|
|
4655
|
+
hfLoadImageAsBase64(g.id, hfToken, effectiveNamespace, g.filename, void 0, g.mimeType, false).then((b64) => {
|
|
4656
|
+
if (!b64) return;
|
|
4657
|
+
const full = `data:${g.mimeType || "image/jpeg"};base64,${b64}`;
|
|
4658
|
+
setCurrentResult((prev) => prev?.id === g.id ? { ...prev, fullBase64: full } : prev);
|
|
4659
|
+
setGalleryItems((prev) => prev.map((item) => item.id === g.id ? { ...item, fullBase64: full } : item));
|
|
4660
|
+
}).catch(() => {
|
|
4661
|
+
});
|
|
4662
|
+
}
|
|
4663
|
+
}, [hfToken, effectiveNamespace]);
|
|
4664
|
+
const handleTitleSet = useCallback3((id) => {
|
|
4665
|
+
const ts = Date.now();
|
|
4666
|
+
setGalleryItems((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
|
|
4667
|
+
setHistory((prev) => prev.map((g) => g.id === id ? { ...g, titleTs: ts } : g));
|
|
4668
|
+
if (hfToken && effectiveNamespace) {
|
|
4669
|
+
hfWriteEvent("title_set", { id }).catch(() => {
|
|
4670
|
+
});
|
|
4671
|
+
}
|
|
4672
|
+
}, [hfToken, effectiveNamespace, hfWriteEvent]);
|
|
4673
|
+
const currentGroup = useMemo2(() => {
|
|
4674
|
+
if (!currentResult?.prompt) return [];
|
|
4675
|
+
const groups = groupByPrompt(galleryItems.filter((g) => g.status === "done" && !!g.base64));
|
|
4676
|
+
const group = groups.find((gr) => gr.prompt === currentResult.prompt);
|
|
4677
|
+
return group ? group.items : [];
|
|
4678
|
+
}, [galleryItems, currentResult?.prompt]);
|
|
4563
4679
|
const hcStyle = highContrast ? { filter: "brightness(1.6) contrast(1.05)" } : void 0;
|
|
4564
4680
|
const isGenerating = activeGenerationsCount > 0;
|
|
4565
4681
|
useKeyboardNavigation(history, currentResult, setCurrentResult);
|
|
@@ -4741,8 +4857,9 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4741
4857
|
const handleDownloadSingle = async () => {
|
|
4742
4858
|
if (!currentResult?.base64) return;
|
|
4743
4859
|
try {
|
|
4744
|
-
const
|
|
4745
|
-
const
|
|
4860
|
+
const downloadSrc = currentResult.fullBase64 || currentResult.base64;
|
|
4861
|
+
const base64Data = downloadSrc.split(",")[1];
|
|
4862
|
+
const mimeType = downloadSrc.split(";")[0].split(":")[1] || "image/png";
|
|
4746
4863
|
let finalBase64 = base64Data;
|
|
4747
4864
|
if (mimeType === "image/png") finalBase64 = injectXMPMetadata(base64Data, currentResult.prompt || "", currentResult.seed, currentResult.model, currentResult.id, currentResult.tags || [], getSubtreeFormat(currentResult.nodeId));
|
|
4748
4865
|
await onDownload(finalBase64, mimeType, `avatar_${currentResult.id.slice(0, 5)}.${mimeType.split("/")[1]}`);
|
|
@@ -4942,7 +5059,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
4942
5059
|
return { by_category: merged, all };
|
|
4943
5060
|
};
|
|
4944
5061
|
if (isFullscreen && currentResult?.base64) {
|
|
4945
|
-
const
|
|
5062
|
+
const fsRaw = currentResult.fullBase64 || currentResult.base64;
|
|
5063
|
+
const fsBase64 = fsRaw.startsWith("data:") ? fsRaw : `data:image/png;base64,${fsRaw}`;
|
|
4946
5064
|
return /* @__PURE__ */ jsxs21(
|
|
4947
5065
|
"div",
|
|
4948
5066
|
{
|
|
@@ -5094,7 +5212,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5094
5212
|
onClick: async () => {
|
|
5095
5213
|
setIsLoadingFromHF(true);
|
|
5096
5214
|
try {
|
|
5097
|
-
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-
|
|
5215
|
+
const { hfListProjects: hfListProjects2, hfDownloadProject: hfDownloadProject2 } = await import("./hfStateService-5BU5DVQ6.mjs");
|
|
5098
5216
|
const projects = await hfListProjects2(hfToken);
|
|
5099
5217
|
if (projects.length > 0) {
|
|
5100
5218
|
const file = await hfDownloadProject2(projects[0].path, hfToken);
|
|
@@ -5189,7 +5307,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5189
5307
|
setMobileTab("stage");
|
|
5190
5308
|
}
|
|
5191
5309
|
} }) }),
|
|
5192
|
-
mobileTab === "server" && /* @__PURE__ */ jsx23("div", { className: "flex flex-col flex-1 min-h-0 relative", children: /* @__PURE__ */ jsx23(ServerTab, {
|
|
5310
|
+
mobileTab === "server" && /* @__PURE__ */ jsx23("div", { className: "flex flex-col flex-1 min-h-0 relative", children: /* @__PURE__ */ jsx23(ServerTab, { serverBaseUrl }) }),
|
|
5193
5311
|
mobileTab === "tags" && workspaceTags && /* @__PURE__ */ jsx23("div", { className: "flex flex-col flex-1 min-h-0", children: /* @__PURE__ */ jsx23(
|
|
5194
5312
|
TagManagerPanel,
|
|
5195
5313
|
{
|
|
@@ -5267,7 +5385,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5267
5385
|
/* @__PURE__ */ jsx23("p", { className: "text-white/50 text-[13px]", children: currentResult.error?.message }),
|
|
5268
5386
|
/* @__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
5387
|
] }),
|
|
5270
|
-
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx23("img", { src: currentResult.base64, className: "w-full h-full object-contain" }),
|
|
5388
|
+
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx23("img", { src: currentResult.fullBase64 || currentResult.base64, className: "w-full h-full object-contain" }),
|
|
5271
5389
|
!currentResult && /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
5272
5390
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[64px]", children: "palette" }),
|
|
5273
5391
|
/* @__PURE__ */ jsx23("span", { className: "text-[11px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
@@ -5285,6 +5403,49 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5285
5403
|
]
|
|
5286
5404
|
}
|
|
5287
5405
|
),
|
|
5406
|
+
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: [
|
|
5407
|
+
/* @__PURE__ */ jsx23(
|
|
5408
|
+
"div",
|
|
5409
|
+
{
|
|
5410
|
+
onClick: () => handleGallerySelect(item),
|
|
5411
|
+
style: {
|
|
5412
|
+
width: 44,
|
|
5413
|
+
height: 44,
|
|
5414
|
+
borderRadius: 8,
|
|
5415
|
+
overflow: "hidden",
|
|
5416
|
+
cursor: "pointer",
|
|
5417
|
+
border: item.id === currentResult.id ? "2px solid rgba(255,255,255,0.8)" : "2px solid rgba(255,255,255,0.15)",
|
|
5418
|
+
opacity: item.id === currentResult.id ? 1 : 0.55
|
|
5419
|
+
},
|
|
5420
|
+
children: /* @__PURE__ */ jsx23("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
|
|
5421
|
+
}
|
|
5422
|
+
),
|
|
5423
|
+
/* @__PURE__ */ jsx23(
|
|
5424
|
+
"button",
|
|
5425
|
+
{
|
|
5426
|
+
onClick: (e) => {
|
|
5427
|
+
e.stopPropagation();
|
|
5428
|
+
handleTitleSet(item.id);
|
|
5429
|
+
},
|
|
5430
|
+
style: {
|
|
5431
|
+
position: "absolute",
|
|
5432
|
+
bottom: 2,
|
|
5433
|
+
right: 2,
|
|
5434
|
+
width: 14,
|
|
5435
|
+
height: 14,
|
|
5436
|
+
background: item.titleTs ? "#f59e0b" : "rgba(0,0,0,0.75)",
|
|
5437
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
5438
|
+
borderRadius: 3,
|
|
5439
|
+
cursor: "pointer",
|
|
5440
|
+
padding: 0,
|
|
5441
|
+
display: "flex",
|
|
5442
|
+
alignItems: "center",
|
|
5443
|
+
justifyContent: "center"
|
|
5444
|
+
},
|
|
5445
|
+
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" })
|
|
5446
|
+
}
|
|
5447
|
+
)
|
|
5448
|
+
] }, item.id)) }),
|
|
5288
5449
|
currentResult?.status === "done" && /* @__PURE__ */ jsxs21("div", { className: "flex gap-2 mt-3", children: [
|
|
5289
5450
|
/* @__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
5451
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[18px] text-white/60", children: "replay" }),
|
|
@@ -5307,10 +5468,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5307
5468
|
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
5469
|
] }),
|
|
5309
5470
|
/* @__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)) }),
|
|
5471
|
+
activeTab === "history" && /* @__PURE__ */ jsx23(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
|
|
5314
5472
|
activeTab === "gallery" && /* @__PURE__ */ jsx23(
|
|
5315
5473
|
MediaLibrary,
|
|
5316
5474
|
{
|
|
@@ -5321,10 +5479,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5321
5479
|
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
5480
|
},
|
|
5323
5481
|
onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
|
|
5324
|
-
onSelect:
|
|
5325
|
-
setCurrentResult(g);
|
|
5326
|
-
setMobileTab("stage");
|
|
5327
|
-
},
|
|
5482
|
+
onSelect: handleGallerySelect,
|
|
5328
5483
|
onGenerateReference: (item) => {
|
|
5329
5484
|
handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true });
|
|
5330
5485
|
setMobileTab("stage");
|
|
@@ -5364,7 +5519,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5364
5519
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[20px]", children: "biotech" }),
|
|
5365
5520
|
"HF"
|
|
5366
5521
|
] }),
|
|
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" }) }),
|
|
5522
|
+
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
5523
|
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
5524
|
] }),
|
|
5370
5525
|
/* @__PURE__ */ jsxs21("div", { className: "flex-1 overflow-hidden relative", children: [
|
|
@@ -5447,10 +5602,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5447
5602
|
galleryItems,
|
|
5448
5603
|
allEvents: hfAllEvents,
|
|
5449
5604
|
confirmedEventKeys: hfConfirmedKeys,
|
|
5450
|
-
imageUploadStatus
|
|
5605
|
+
imageUploadStatus,
|
|
5606
|
+
missingImages: hfMissingImages
|
|
5451
5607
|
}
|
|
5452
5608
|
) }),
|
|
5453
|
-
activeTab === "server" && /* @__PURE__ */ jsx23("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx23(ServerTab, {
|
|
5609
|
+
activeTab === "server" && /* @__PURE__ */ jsx23("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx23(ServerTab, { serverBaseUrl }) })
|
|
5454
5610
|
] })
|
|
5455
5611
|
] }),
|
|
5456
5612
|
/* @__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 +5615,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5459
5615
|
{ id: "labs", icon: "science", label: "Labs" },
|
|
5460
5616
|
...workspaceTags ? [{ id: "tags", icon: "label", label: "Tags" }] : [],
|
|
5461
5617
|
{ id: "browse", icon: "photo_library", label: "Galerie" },
|
|
5462
|
-
{ id: "server", icon: "storage", label: "Server" }
|
|
5618
|
+
...serverBaseUrl ? [{ id: "server", icon: "storage", label: "Server" }] : []
|
|
5463
5619
|
].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
5620
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[24px]", children: tab.icon }),
|
|
5465
5621
|
/* @__PURE__ */ jsx23("span", { className: "text-[10px] font-bold uppercase tracking-wide", children: tab.label })
|
|
@@ -5510,7 +5666,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5510
5666
|
] })
|
|
5511
5667
|
}
|
|
5512
5668
|
) }),
|
|
5513
|
-
/* @__PURE__ */ jsx23("div", { style: { flex: 1, overflow: "hidden", position: "relative" }, children: /* @__PURE__ */ jsx23(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect:
|
|
5669
|
+
/* @__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
5670
|
] }),
|
|
5515
5671
|
/* @__PURE__ */ jsxs21("div", { style: { flex: 1, height: tlH, display: "flex", flexDirection: "column", background: "#0b0b0b" }, children: [
|
|
5516
5672
|
/* @__PURE__ */ jsx23(
|
|
@@ -5535,7 +5691,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5535
5691
|
/* @__PURE__ */ jsx23("p", { style: { fontSize: 11, color: "rgba(255,255,255,0.5)", margin: 0 }, children: currentResult.error?.message }),
|
|
5536
5692
|
/* @__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
5693
|
] }),
|
|
5538
|
-
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx23("img", { src: currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
|
|
5694
|
+
currentResult?.status === "done" && currentResult.base64 && /* @__PURE__ */ jsx23("img", { src: currentResult.fullBase64 || currentResult.base64, style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain" } }),
|
|
5539
5695
|
!currentResult && /* @__PURE__ */ jsxs21("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 8, opacity: 0.1 }, children: [
|
|
5540
5696
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined", style: { fontSize: 64 }, children: "palette" }),
|
|
5541
5697
|
/* @__PURE__ */ jsx23("span", { style: { fontSize: 11, fontWeight: "bold", textTransform: "uppercase", letterSpacing: "0.2em" }, children: "Avatar Architect" })
|
|
@@ -5677,33 +5833,81 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5677
5833
|
middlePanel === "labs" ? /* @__PURE__ */ jsx23("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx23(LabsTab, { services: labServices, onResult: (item) => {
|
|
5678
5834
|
const frame = item.frames[0];
|
|
5679
5835
|
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 })
|
|
5836
|
+
} }) }) : /* @__PURE__ */ jsxs21("div", { className: "flex-1 overflow-hidden flex flex-col", children: [
|
|
5837
|
+
/* @__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: [
|
|
5838
|
+
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: [
|
|
5839
|
+
/* @__PURE__ */ jsx23("div", { className: "w-3 h-3 border-t-2 border-white rounded-full animate-spin" }),
|
|
5840
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px] text-white/60 uppercase font-bold tracking-widest", children: "Neue Referenz..." })
|
|
5693
5841
|
] }),
|
|
5694
|
-
/* @__PURE__ */
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
/* @__PURE__ */ jsxs21("div", { className: "
|
|
5698
|
-
/* @__PURE__ */ jsx23(
|
|
5699
|
-
/* @__PURE__ */
|
|
5700
|
-
|
|
5842
|
+
currentResult ? currentResult.status === "processing" ? /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-4", children: [
|
|
5843
|
+
/* @__PURE__ */ jsx23("div", { className: "w-10 h-10 border-t-2 border-white rounded-full animate-spin" }),
|
|
5844
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px] text-white/40 uppercase font-bold tracking-widest", children: "Erstelle Bild..." })
|
|
5845
|
+
] }) : currentResult.status === "error" ? /* @__PURE__ */ jsxs21("div", { className: "p-10 text-center flex flex-col items-center gap-5 max-w-md", children: [
|
|
5846
|
+
/* @__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" }) }),
|
|
5847
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex flex-col gap-2", children: [
|
|
5848
|
+
/* @__PURE__ */ jsx23("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-red-400", children: "Generierungsfehler" }),
|
|
5849
|
+
/* @__PURE__ */ jsx23("p", { className: "text-white/60 text-[12px] leading-relaxed", children: currentResult.error?.message })
|
|
5850
|
+
] }),
|
|
5851
|
+
/* @__PURE__ */ jsx23(PillButton, { variant: "outline", icon: "refresh", onClick: () => handleGenerateImage(currentResult.prompt), children: "Erneut versuchen" })
|
|
5852
|
+
] }) : /* @__PURE__ */ jsxs21("div", { className: "h-full w-full relative flex items-center justify-center", children: [
|
|
5853
|
+
/* @__PURE__ */ jsx23("img", { src: currentResult.fullBase64 || currentResult.base64, className: "max-h-full max-w-full object-contain rounded-xl shadow-2xl" }),
|
|
5854
|
+
/* @__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: [
|
|
5855
|
+
/* @__PURE__ */ jsx23(PillButton, { variant: "outline", icon: "replay", onClick: () => setActivePrompt(currentResult.prompt || ""), children: "Prompt" }),
|
|
5856
|
+
/* @__PURE__ */ jsx23(PillButton, { variant: "solid", icon: "auto_fix_high", onClick: () => handleGenerateImage(currentResult.prompt || activePrompt, currentResult.mediaId, void 0, { silent: true }), children: "Referenz" }),
|
|
5857
|
+
/* @__PURE__ */ jsx23(PillButton, { variant: "outline", icon: "download", onClick: handleDownloadSingle, children: "Speichern" })
|
|
5858
|
+
] })
|
|
5859
|
+
] }) : /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-2 opacity-10", children: [
|
|
5860
|
+
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[100px]", children: "palette" }),
|
|
5861
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[12px] font-bold uppercase tracking-[0.2em]", children: "Avatar Architect" })
|
|
5701
5862
|
] })
|
|
5702
|
-
] })
|
|
5703
|
-
|
|
5704
|
-
/* @__PURE__ */ jsx23(
|
|
5705
|
-
|
|
5706
|
-
|
|
5863
|
+
] }) }),
|
|
5864
|
+
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: [
|
|
5865
|
+
/* @__PURE__ */ jsx23(
|
|
5866
|
+
"div",
|
|
5867
|
+
{
|
|
5868
|
+
onClick: () => handleGallerySelect(item),
|
|
5869
|
+
style: {
|
|
5870
|
+
width: 52,
|
|
5871
|
+
height: 52,
|
|
5872
|
+
borderRadius: 10,
|
|
5873
|
+
overflow: "hidden",
|
|
5874
|
+
cursor: "pointer",
|
|
5875
|
+
border: item.id === currentResult.id ? "2px solid rgba(255,255,255,0.8)" : "2px solid rgba(255,255,255,0.12)",
|
|
5876
|
+
opacity: item.id === currentResult.id ? 1 : 0.5,
|
|
5877
|
+
transition: "opacity 0.15s, border-color 0.15s"
|
|
5878
|
+
},
|
|
5879
|
+
className: "hover:opacity-80",
|
|
5880
|
+
children: /* @__PURE__ */ jsx23("img", { src: item.base64, style: { width: "100%", height: "100%", objectFit: "cover" }, alt: "" })
|
|
5881
|
+
}
|
|
5882
|
+
),
|
|
5883
|
+
/* @__PURE__ */ jsx23(
|
|
5884
|
+
"button",
|
|
5885
|
+
{
|
|
5886
|
+
onClick: (e) => {
|
|
5887
|
+
e.stopPropagation();
|
|
5888
|
+
handleTitleSet(item.id);
|
|
5889
|
+
},
|
|
5890
|
+
title: "Als Titel markieren",
|
|
5891
|
+
style: {
|
|
5892
|
+
position: "absolute",
|
|
5893
|
+
bottom: 3,
|
|
5894
|
+
right: 3,
|
|
5895
|
+
width: 16,
|
|
5896
|
+
height: 16,
|
|
5897
|
+
background: item.titleTs ? "#f59e0b" : "rgba(0,0,0,0.75)",
|
|
5898
|
+
border: "1px solid rgba(255,255,255,0.25)",
|
|
5899
|
+
borderRadius: 4,
|
|
5900
|
+
cursor: "pointer",
|
|
5901
|
+
padding: 0,
|
|
5902
|
+
display: "flex",
|
|
5903
|
+
alignItems: "center",
|
|
5904
|
+
justifyContent: "center"
|
|
5905
|
+
},
|
|
5906
|
+
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" })
|
|
5907
|
+
}
|
|
5908
|
+
)
|
|
5909
|
+
] }, item.id)) })
|
|
5910
|
+
] })
|
|
5707
5911
|
] })
|
|
5708
5912
|
] }),
|
|
5709
5913
|
!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 +5918,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5714
5918
|
setActiveTab(tab);
|
|
5715
5919
|
setIsRightCollapsed(false);
|
|
5716
5920
|
}, 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: () => {
|
|
5921
|
+
serverBaseUrl && /* @__PURE__ */ jsx23("button", { onClick: () => {
|
|
5718
5922
|
setActiveTab("server");
|
|
5719
5923
|
setIsRightCollapsed(false);
|
|
5720
5924
|
}, 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 +5942,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5738
5942
|
/* @__PURE__ */ jsx23("span", { className: "material-symbols-outlined text-[40px] text-white/10 block mb-3", children: "label_off" }),
|
|
5739
5943
|
/* @__PURE__ */ jsx23("p", { className: "text-[11px] text-white/20", children: "Erst Workspace importieren um Tags zu verwalten." })
|
|
5740
5944
|
] }) }),
|
|
5741
|
-
activeTab === "history" && /* @__PURE__ */ jsx23(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect:
|
|
5945
|
+
activeTab === "history" && /* @__PURE__ */ jsx23(HistoryPanel, { history, currentResultId: currentResult?.id || null, onSelect: handleGallerySelect, onDelete: (id) => setHistory((h) => h.filter((x) => x.id !== id)) }),
|
|
5742
5946
|
activeTab === "gallery" && /* @__PURE__ */ jsx23(
|
|
5743
5947
|
MediaLibrary,
|
|
5744
5948
|
{
|
|
@@ -5749,7 +5953,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5749
5953
|
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
5954
|
},
|
|
5751
5955
|
onDelete: (id) => setGalleryItems((g) => g.filter((x) => x.id !== id)),
|
|
5752
|
-
onSelect:
|
|
5956
|
+
onSelect: handleGallerySelect,
|
|
5753
5957
|
onGenerateReference: (item) => handleGenerateImage(item.prompt || activePrompt, item.mediaId, void 0, { silent: true })
|
|
5754
5958
|
}
|
|
5755
5959
|
),
|
|
@@ -5779,14 +5983,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
|
|
|
5779
5983
|
onHfInitialSync: hfToken ? handleHfInitialSync : void 0
|
|
5780
5984
|
}
|
|
5781
5985
|
),
|
|
5782
|
-
activeTab === "server" && /* @__PURE__ */ jsx23(ServerTab, {
|
|
5986
|
+
activeTab === "server" && /* @__PURE__ */ jsx23(ServerTab, { serverBaseUrl })
|
|
5783
5987
|
] })
|
|
5784
5988
|
] })
|
|
5785
5989
|
] });
|
|
5786
5990
|
}
|
|
5787
5991
|
|
|
5788
5992
|
// src/components/FaApp.tsx
|
|
5789
|
-
import { useState as
|
|
5993
|
+
import { useState as useState21, useEffect as useEffect8 } from "react";
|
|
5790
5994
|
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
5791
5995
|
function FaApp({
|
|
5792
5996
|
onGenerateImage,
|
|
@@ -5806,7 +6010,7 @@ function FaApp({
|
|
|
5806
6010
|
onServerDelete,
|
|
5807
6011
|
buildInfo
|
|
5808
6012
|
}) {
|
|
5809
|
-
const [hfNamespace, setHfNamespace] =
|
|
6013
|
+
const [hfNamespace, setHfNamespace] = useState21(void 0);
|
|
5810
6014
|
useEffect8(() => {
|
|
5811
6015
|
if (!serverBaseUrl) return;
|
|
5812
6016
|
fetch(`${serverBaseUrl}/api/status`).then((r) => r.json()).then((d) => {
|
|
@@ -5828,6 +6032,7 @@ function FaApp({
|
|
|
5828
6032
|
initialHfToken: libToken ? libToken.startsWith("hf_") ? libToken : `hf_${libToken}` : void 0,
|
|
5829
6033
|
hfNamespace,
|
|
5830
6034
|
allowDevNamespace: !hfNamespace && allowDevNamespace,
|
|
6035
|
+
serverBaseUrl,
|
|
5831
6036
|
onFetchServerProjects,
|
|
5832
6037
|
onServerSave,
|
|
5833
6038
|
onServerLoad,
|
|
@@ -5838,7 +6043,7 @@ function FaApp({
|
|
|
5838
6043
|
}
|
|
5839
6044
|
|
|
5840
6045
|
// src/index.ts
|
|
5841
|
-
var LIB_VERSION = "2.0.
|
|
6046
|
+
var LIB_VERSION = "2.0.46";
|
|
5842
6047
|
export {
|
|
5843
6048
|
AvatarArchitectApp,
|
|
5844
6049
|
CollapsibleCard,
|
|
@@ -5882,10 +6087,6 @@ export {
|
|
|
5882
6087
|
cleanAiResponse,
|
|
5883
6088
|
createFlowServices,
|
|
5884
6089
|
exportProjectToZip,
|
|
5885
|
-
faServerDelete,
|
|
5886
|
-
faServerGet,
|
|
5887
|
-
faServerPost,
|
|
5888
|
-
faServerPut,
|
|
5889
6090
|
findForks,
|
|
5890
6091
|
findTips,
|
|
5891
6092
|
formatTreeToMarkdown,
|