@rslsp1/fa-app-tools 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -297,6 +297,6 @@ interface ProjectSyncTabProps {
297
297
  }
298
298
  declare const ProjectSyncTab: React.FC<ProjectSyncTabProps>;
299
299
 
300
- declare const LIB_VERSION = "1.1.0";
300
+ declare const LIB_VERSION = "1.1.2";
301
301
 
302
302
  export { AvatarArchitectApp, type AvatarArchitectAppProps, CollapsibleCard, CompactDropdown, type ExtractedCharacter, FaToolsBadge, type FlowSdk, GLOBAL_STYLES, type Generation, HistoryPanel, InspectPanel, LIB_VERSION, ListView, type MediaItem, MediaLibrary, PillButton, type ProjectMeta, type ProjectSettings, ProjectSyncTab, PromptTab, SectionLabel, type SelectedTag, SetupPanel, type SyncDiff, type TagOption, type WorkspaceTags, buildFallbackPrompt, buildGenerationPrompt, buildImageGenerationOptions, buildPromptTabPayload, cleanAiResponse, createFlowServices, exportProjectToZip, formatTreeToMarkdown, getFormattedTimestamp, importProjectFromZip, injectXMPMetadata, interpretSdkError, parsePromptFile, parsePromptResponse, useKeyboardNavigation, useOnClickOutside };
package/dist/index.d.ts CHANGED
@@ -297,6 +297,6 @@ interface ProjectSyncTabProps {
297
297
  }
298
298
  declare const ProjectSyncTab: React.FC<ProjectSyncTabProps>;
299
299
 
300
- declare const LIB_VERSION = "1.1.0";
300
+ declare const LIB_VERSION = "1.1.2";
301
301
 
302
302
  export { AvatarArchitectApp, type AvatarArchitectAppProps, CollapsibleCard, CompactDropdown, type ExtractedCharacter, FaToolsBadge, type FlowSdk, GLOBAL_STYLES, type Generation, HistoryPanel, InspectPanel, LIB_VERSION, ListView, type MediaItem, MediaLibrary, PillButton, type ProjectMeta, type ProjectSettings, ProjectSyncTab, PromptTab, SectionLabel, type SelectedTag, SetupPanel, type SyncDiff, type TagOption, type WorkspaceTags, buildFallbackPrompt, buildGenerationPrompt, buildImageGenerationOptions, buildPromptTabPayload, cleanAiResponse, createFlowServices, exportProjectToZip, formatTreeToMarkdown, getFormattedTimestamp, importProjectFromZip, injectXMPMetadata, interpretSdkError, parsePromptFile, parsePromptResponse, useKeyboardNavigation, useOnClickOutside };
package/dist/index.js CHANGED
@@ -1717,6 +1717,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
1717
1717
  return false;
1718
1718
  }
1719
1719
  });
1720
+ const [activeReferenceId, setActiveReferenceId] = (0, import_react14.useState)(null);
1721
+ const [activeReferenceThumbnail, setActiveReferenceThumbnail] = (0, import_react14.useState)(null);
1720
1722
  const [touchStartX, setTouchStartX] = (0, import_react14.useState)(null);
1721
1723
  const [isFullscreen, setIsFullscreen] = (0, import_react14.useState)(false);
1722
1724
  const [zoomScale, setZoomScale] = (0, import_react14.useState)(1);
@@ -1773,6 +1775,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
1773
1775
  } catch {
1774
1776
  }
1775
1777
  };
1778
+ const handleSelectReference = async () => {
1779
+ const media = await onSelectMedia();
1780
+ if (!media?.length) return;
1781
+ const first = media[0];
1782
+ if (first.mediaId) {
1783
+ setActiveReferenceId(first.mediaId);
1784
+ setActiveReferenceThumbnail(`data:${first.mimeType};base64,${first.base64}`);
1785
+ }
1786
+ };
1787
+ const clearReference = () => {
1788
+ setActiveReferenceId(null);
1789
+ setActiveReferenceThumbnail(null);
1790
+ };
1776
1791
  const currentIndex = (0, import_react14.useMemo)(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
1777
1792
  const goToPrev = (0, import_react14.useCallback)(() => {
1778
1793
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
@@ -1814,7 +1829,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
1814
1829
  if (!options.silent) setCurrentResult(newGen);
1815
1830
  if (seedMode === "random") setSeed(activeSeed);
1816
1831
  try {
1817
- const { base64, mediaId } = await onGenerateImage(buildImageGenerationOptions(promptToUse, aspectRatio, selectedModel, useReferenceId));
1832
+ const { base64, mediaId } = await onGenerateImage(buildImageGenerationOptions(promptToUse, aspectRatio, selectedModel, useReferenceId ?? activeReferenceId ?? void 0));
1818
1833
  const finishedGen = { ...newGen, status: "done", base64: `data:image/png;base64,${base64}`, mediaId };
1819
1834
  setHistory((prev) => prev.map((g) => g.id === genId ? finishedGen : g));
1820
1835
  setGalleryItems((prev) => [finishedGen, ...prev]);
@@ -2205,6 +2220,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
2205
2220
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
2206
2221
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
2207
2222
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex-1" }),
2223
+ activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
2224
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
2225
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
2226
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 active:text-white/80 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
2227
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: handleSelectReference, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }) }),
2208
2228
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: toggleContrast, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: highContrast ? "light_mode" : "dark_mode" }) }),
2209
2229
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: () => setShowStart(true), className: "text-white/20 active:text-white/60 transition-colors mr-1", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-outlined text-[20px]", children: "desktop_windows" }) })
2210
2230
  ] }),
@@ -2573,6 +2593,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
2573
2593
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] })
2574
2594
  ] }),
2575
2595
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
2596
+ activeReferenceThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden", style: { height: 28 }, children: [
2597
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
2598
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
2599
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 hover:text-white/80 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
2600
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("button", { onClick: handleSelectReference, className: "flex items-center gap-1 h-7 px-2 rounded-lg border border-white/10 text-white/30 hover:text-white/60 hover:border-white/20 transition-colors text-[10px] font-bold uppercase tracking-wide", children: [
2601
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
2602
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Ref" })
2603
+ ] }),
2576
2604
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
2577
2605
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PillButton, { variant: "solid", icon: "bolt", loading: isGenerating, disabled: !activePrompt.trim(), onClick: () => handleGenerateImage(), children: "Generieren" })
2578
2606
  ] })
@@ -2659,7 +2687,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
2659
2687
  }
2660
2688
 
2661
2689
  // src/index.ts
2662
- var LIB_VERSION = "1.1.0";
2690
+ var LIB_VERSION = "1.1.2";
2663
2691
  // Annotate the CommonJS export names for ESM import in node:
2664
2692
  0 && (module.exports = {
2665
2693
  AvatarArchitectApp,
package/dist/index.mjs CHANGED
@@ -1651,6 +1651,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
1651
1651
  return false;
1652
1652
  }
1653
1653
  });
1654
+ const [activeReferenceId, setActiveReferenceId] = useState6(null);
1655
+ const [activeReferenceThumbnail, setActiveReferenceThumbnail] = useState6(null);
1654
1656
  const [touchStartX, setTouchStartX] = useState6(null);
1655
1657
  const [isFullscreen, setIsFullscreen] = useState6(false);
1656
1658
  const [zoomScale, setZoomScale] = useState6(1);
@@ -1707,6 +1709,19 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
1707
1709
  } catch {
1708
1710
  }
1709
1711
  };
1712
+ const handleSelectReference = async () => {
1713
+ const media = await onSelectMedia();
1714
+ if (!media?.length) return;
1715
+ const first = media[0];
1716
+ if (first.mediaId) {
1717
+ setActiveReferenceId(first.mediaId);
1718
+ setActiveReferenceThumbnail(`data:${first.mimeType};base64,${first.base64}`);
1719
+ }
1720
+ };
1721
+ const clearReference = () => {
1722
+ setActiveReferenceId(null);
1723
+ setActiveReferenceThumbnail(null);
1724
+ };
1710
1725
  const currentIndex = useMemo2(() => history.findIndex((h) => h.id === currentResult?.id), [history, currentResult]);
1711
1726
  const goToPrev = useCallback(() => {
1712
1727
  if (currentIndex > 0) setCurrentResult(history[currentIndex - 1]);
@@ -1748,7 +1763,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
1748
1763
  if (!options.silent) setCurrentResult(newGen);
1749
1764
  if (seedMode === "random") setSeed(activeSeed);
1750
1765
  try {
1751
- const { base64, mediaId } = await onGenerateImage(buildImageGenerationOptions(promptToUse, aspectRatio, selectedModel, useReferenceId));
1766
+ const { base64, mediaId } = await onGenerateImage(buildImageGenerationOptions(promptToUse, aspectRatio, selectedModel, useReferenceId ?? activeReferenceId ?? void 0));
1752
1767
  const finishedGen = { ...newGen, status: "done", base64: `data:image/png;base64,${base64}`, mediaId };
1753
1768
  setHistory((prev) => prev.map((g) => g.id === genId ? finishedGen : g));
1754
1769
  setGalleryItems((prev) => [finishedGen, ...prev]);
@@ -2139,6 +2154,11 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
2139
2154
  /* @__PURE__ */ jsx13(CompactDropdown, { value: aspectRatio, onChange: setAspectRatio, options: [{ label: "1:1", value: "1:1" }, { label: "16:9", value: "16:9" }, { label: "9:16", value: "9:16" }] }),
2140
2155
  /* @__PURE__ */ jsx13(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] }),
2141
2156
  /* @__PURE__ */ jsx13("div", { className: "flex-1" }),
2157
+ activeReferenceThumbnail ? /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden mr-2", style: { height: 28 }, children: [
2158
+ /* @__PURE__ */ jsx13("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
2159
+ /* @__PURE__ */ jsx13("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
2160
+ /* @__PURE__ */ jsx13("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 active:text-white/80 transition-colors", children: /* @__PURE__ */ jsx13("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
2161
+ ] }) : /* @__PURE__ */ jsx13("button", { onClick: handleSelectReference, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ jsx13("span", { className: "material-symbols-outlined text-[20px]", children: "add_photo_alternate" }) }),
2142
2162
  /* @__PURE__ */ jsx13("button", { onClick: toggleContrast, className: "text-white/20 active:text-white/60 transition-colors mr-2", children: /* @__PURE__ */ jsx13("span", { className: "material-symbols-outlined text-[20px]", children: highContrast ? "light_mode" : "dark_mode" }) }),
2143
2163
  /* @__PURE__ */ jsx13("button", { onClick: () => setShowStart(true), className: "text-white/20 active:text-white/60 transition-colors mr-1", children: /* @__PURE__ */ jsx13("span", { className: "material-symbols-outlined text-[20px]", children: "desktop_windows" }) })
2144
2164
  ] }),
@@ -2507,6 +2527,14 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
2507
2527
  /* @__PURE__ */ jsx13(CompactDropdown, { value: selectedModel, onChange: setSelectedModel, options: [{ value: "\u{1F34C} Nano Banana Pro", label: "\u{1F34C} Nano Banana Pro" }, { value: "\u{1F34C} Nano Banana 2", label: "\u{1F34C} Nano Banana 2" }, { value: "Imagen 4", label: "Imagen 4" }] })
2508
2528
  ] }),
2509
2529
  /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2", children: [
2530
+ activeReferenceThumbnail ? /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 rounded-lg border border-white/20 bg-white/5 overflow-hidden", style: { height: 28 }, children: [
2531
+ /* @__PURE__ */ jsx13("img", { src: activeReferenceThumbnail, className: "h-full aspect-square object-cover" }),
2532
+ /* @__PURE__ */ jsx13("span", { className: "text-[10px] text-white/60 font-bold uppercase tracking-wide px-1", children: "Ref" }),
2533
+ /* @__PURE__ */ jsx13("button", { onClick: clearReference, className: "w-6 h-full flex items-center justify-center text-white/30 hover:text-white/80 transition-colors", children: /* @__PURE__ */ jsx13("span", { className: "material-symbols-outlined text-[14px]", children: "close" }) })
2534
+ ] }) : /* @__PURE__ */ jsxs11("button", { onClick: handleSelectReference, className: "flex items-center gap-1 h-7 px-2 rounded-lg border border-white/10 text-white/30 hover:text-white/60 hover:border-white/20 transition-colors text-[10px] font-bold uppercase tracking-wide", children: [
2535
+ /* @__PURE__ */ jsx13("span", { className: "material-symbols-outlined text-[14px]", children: "add_photo_alternate" }),
2536
+ /* @__PURE__ */ jsx13("span", { children: "Ref" })
2537
+ ] }),
2510
2538
  /* @__PURE__ */ jsx13("button", { onClick: () => setIsPromptCollapsed(!isPromptCollapsed), className: "text-white/40 hover:text-white transition-colors", children: /* @__PURE__ */ jsx13("span", { className: "material-symbols-outlined", children: isPromptCollapsed ? "expand_more" : "expand_less" }) }),
2511
2539
  /* @__PURE__ */ jsx13(PillButton, { variant: "solid", icon: "bolt", loading: isGenerating, disabled: !activePrompt.trim(), onClick: () => handleGenerateImage(), children: "Generieren" })
2512
2540
  ] })
@@ -2593,7 +2621,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
2593
2621
  }
2594
2622
 
2595
2623
  // src/index.ts
2596
- var LIB_VERSION = "1.1.0";
2624
+ var LIB_VERSION = "1.1.2";
2597
2625
  export {
2598
2626
  AvatarArchitectApp,
2599
2627
  CollapsibleCard,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rslsp1/fa-app-tools",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Shared tools and hooks for Fine Art flow apps",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",