From 78b59ba6785e033d55481f18e0cc8e3be7f3d404 Mon Sep 17 00:00:00 2001 From: Immac Date: Sun, 1 Mar 2026 21:37:47 -0600 Subject: [PATCH] style: make mix cover image square (aspectRatio 1:1) --- ...yleMixerPanel-VKyuy2q1.js => StyleMixerPanel-D2mbBoah.js} | 2 +- dist/immac_style_mixer/main.js | 4 ++-- ui/src/components/MixCard.tsx | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) rename dist/immac_style_mixer/{StyleMixerPanel-VKyuy2q1.js => StyleMixerPanel-D2mbBoah.js} (96%) diff --git a/dist/immac_style_mixer/StyleMixerPanel-VKyuy2q1.js b/dist/immac_style_mixer/StyleMixerPanel-D2mbBoah.js similarity index 96% rename from dist/immac_style_mixer/StyleMixerPanel-VKyuy2q1.js rename to dist/immac_style_mixer/StyleMixerPanel-D2mbBoah.js index d9cffb5..d0ea7e7 100644 --- a/dist/immac_style_mixer/StyleMixerPanel-VKyuy2q1.js +++ b/dist/immac_style_mixer/StyleMixerPanel-D2mbBoah.js @@ -1 +1 @@ -import{j as t}from"./main.js";import{r as l,b as P}from"./vendor-DPfS0z4g.js";const B={styles:[],mixes:[],current_mix_id:null},E="/immac_style_mixer/api/data";function $(){const[e,a]=l.useState(B),[d,o]=l.useState(!0),[u,v]=l.useState(null),h=l.useRef(null);l.useEffect(()=>{fetch(E).then(c=>{if(!c.ok)throw new Error(`HTTP ${c.status}`);return c.json()}).then(c=>a(c)).catch(c=>v(String(c))).finally(()=>o(!1))},[]);const m=l.useCallback(c=>{a(y=>{const b=typeof c=="function"?c(y):c;return h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{fetch(E,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(b)}).catch(j=>console.error("[ImmacStyleMixer] Save failed",j))},400),b})},[]);return{data:e,loading:d,error:u,update:m}}async function U(e){const a=new FormData;a.append("image",e),a.append("subfolder","immac_style_mixer/styles"),a.append("type","input");const d=await fetch("/upload/image",{method:"POST",body:a});if(!d.ok)throw new Error(`Upload failed: HTTP ${d.status}`);return(await d.json()).name}function M(e){return`/view?filename=${encodeURIComponent(e)}&subfolder=immac_style_mixer%2Fstyles&type=input`}async function L(e){const a=new FormData;a.append("image",e),a.append("subfolder","immac_style_mixer/mixes"),a.append("type","input");const d=await fetch("/upload/image",{method:"POST",body:a});if(!d.ok)throw new Error(`Upload failed: HTTP ${d.status}`);return(await d.json()).name}function F(e){return`/view?filename=${encodeURIComponent(e)}&subfolder=immac_style_mixer%2Fmixes&type=input`}function A({src:e,alt:a,onClose:d}){return l.useEffect(()=>{function o(u){u.key==="Escape"&&d()}return window.addEventListener("keydown",o),()=>window.removeEventListener("keydown",o)},[d]),P.createPortal(t.jsxs("div",{onClick:d,style:{position:"fixed",inset:0,zIndex:99999,background:"rgba(0,0,0,0.85)",display:"flex",alignItems:"center",justifyContent:"center",cursor:"zoom-out"},children:[t.jsx("img",{src:e,alt:a??"",onClick:o=>o.stopPropagation(),style:{maxWidth:"90vw",maxHeight:"90vh",objectFit:"contain",borderRadius:8,boxShadow:"0 8px 40px rgba(0,0,0,0.7)",cursor:"default"}}),t.jsx("button",{onClick:d,title:"Close",style:{position:"fixed",top:16,right:20,background:"none",border:"none",color:"#fff",fontSize:28,cursor:"pointer",lineHeight:1,opacity:.8},children:"✕"})]}),document.body)}function V({mix:e,styles:a,isActive:d,onActivate:o,onUpdate:u,onDelete:v}){const[h,m]=l.useState(!1),[c,y]=l.useState(e.name),[b,j]=l.useState(!1),[f,w]=l.useState(!1),k=l.useRef(null);async function n(i){if(i.type.startsWith("image/")){j(!0);try{const x=await L(i);u({...e,image_filename:x})}catch(x){console.error("[ImmacStyleMixer] Mix image upload failed",x)}finally{j(!1)}}}function r(){m(!1),c.trim()!==e.name&&u({...e,name:c.trim()||e.name})}function p(i,x){const S=e.styles.map((_,H)=>H===i?{..._,...x}:_);u({...e,styles:S})}function C(i){u({...e,styles:e.styles.filter((x,S)=>S!==i)})}function s(i){e.styles.some(x=>x.style_id===i)||u({...e,styles:[...e.styles,{style_id:i,weight:1,enabled:!0}]})}const g=a.filter(i=>!e.styles.some(x=>x.style_id===i.id));return t.jsxs("div",{style:{border:`2px solid ${d?"var(--p-primary-color, #6c6)":"var(--p-surface-border, #444)"}`,borderRadius:8,padding:10,background:"var(--p-surface-section, #1e1e1e)",display:"flex",flexDirection:"column",gap:8,minWidth:240,maxWidth:340,flexShrink:0},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[t.jsx("input",{type:"radio",title:"Set as current mix",checked:d,onChange:o,style:{cursor:"pointer",flexShrink:0}}),h?t.jsx("input",{autoFocus:!0,value:c,onChange:i=>y(i.target.value),onBlur:r,onKeyDown:i=>{i.key==="Enter"&&r(),i.key==="Escape"&&m(!1)},style:z}):t.jsx("span",{title:"Double-click to rename",onDoubleClick:()=>{y(e.name),m(!0)},style:{fontWeight:600,flex:1,cursor:"text",fontSize:13},children:e.name}),t.jsx("button",{title:e.favorite?"Unfavorite":"Favorite",onClick:()=>u({...e,favorite:!e.favorite}),style:D,children:e.favorite?"★":"☆"}),t.jsx("button",{title:"Delete mix",onClick:v,style:{...D,color:"#e55"},children:"✕"})]}),t.jsxs("div",{style:{position:"relative",width:"100%"},children:[t.jsx("div",{title:"Click or drop an image to set mix cover",onClick:()=>{var i;return(i=k.current)==null?void 0:i.click()},onDragOver:i=>i.preventDefault(),onDrop:i=>{i.preventDefault();const x=i.dataTransfer.files[0];x&&n(x)},style:{width:"100%",height:90,borderRadius:6,border:"1px dashed var(--p-surface-border, #555)",overflow:"hidden",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",background:"var(--p-surface-ground, #141414)",fontSize:11,color:"#888",flexShrink:0,position:"relative"},children:b?"Uploading…":e.image_filename?t.jsx("img",{src:F(e.image_filename),alt:e.name,style:{width:"100%",height:"100%",objectFit:"cover"}}):"+ cover image"}),!b&&e.image_filename&&t.jsx("button",{title:"View full size",onClick:i=>{i.stopPropagation(),w(!0)},style:K,children:t.jsx("i",{className:"pi pi-search-plus"})})]}),f&&e.image_filename&&t.jsx(A,{src:F(e.image_filename),alt:e.name,onClose:()=>w(!1)}),t.jsx("input",{ref:k,type:"file",accept:"image/*",style:{display:"none"},onChange:i=>{var S;const x=(S=i.target.files)==null?void 0:S[0];x&&n(x),i.target.value=""}}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:6,maxHeight:240,overflowY:"auto"},children:[e.styles.length===0&&t.jsx("div",{style:{fontSize:11,color:"#666"},children:"No styles added yet."}),e.styles.map((i,x)=>{const S=a.find(_=>_.id===i.style_id);return t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[t.jsx("button",{title:i.enabled?"Disable":"Enable",onClick:()=>p(x,{enabled:!i.enabled}),style:{...D,fontSize:11,padding:"2px 5px",border:"1px solid var(--p-surface-border, #555)",borderRadius:4,background:i.enabled?"var(--p-primary-color, #557755)":"transparent",color:i.enabled?"#fff":"#888",minWidth:32},children:i.enabled?"ON":"OFF"}),t.jsx("span",{style:{fontSize:12,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:(S==null?void 0:S.name)??i.style_id}),t.jsx("input",{type:"number",min:0,max:2,step:.05,value:i.weight,onChange:_=>p(x,{weight:parseFloat(_.target.value)||0}),style:{...z,width:52,textAlign:"right"}}),t.jsx("button",{title:"Remove from mix",onClick:()=>C(x),style:{...D,color:"#e55",fontSize:13},children:"✕"})]},i.style_id)})]}),t.jsxs("select",{value:"",disabled:g.length===0,onChange:i=>{i.target.value&&s(i.target.value)},style:{...z,cursor:g.length===0?"not-allowed":"pointer",opacity:g.length===0?.45:1},title:g.length===0?"All library styles are already in this mix":"Add a style to this mix",children:[t.jsx("option",{value:"",children:g.length===0?"— all styles already added —":"+ add style…"}),g.map(i=>t.jsx("option",{value:i.id,children:i.name},i.id))]})]})}const D={background:"none",border:"none",cursor:"pointer",fontSize:16,padding:"0 2px",color:"inherit",lineHeight:1,flexShrink:0},K={position:"absolute",top:6,left:6,background:"rgba(255,255,255,0.92)",border:"none",borderRadius:6,cursor:"pointer",fontSize:13,padding:"3px 6px",lineHeight:1,color:"#222",boxShadow:"0 1px 4px rgba(0,0,0,0.25)"},z={background:"var(--p-surface-ground, #141414)",border:"1px solid var(--p-surface-border, #444)",borderRadius:4,color:"inherit",padding:"2px 4px",fontSize:12,boxSizing:"border-box"};function Y({style:e,onUpdate:a,onDelete:d}){const[o,u]=l.useState(!1),[v,h]=l.useState(!1),[m,c]=l.useState(e.name),[y,b]=l.useState(e.value),[j,f]=l.useState(!1),[w,k]=l.useState(!1),n=l.useRef(null);function r(){u(!1),m.trim()!==e.name&&a({...e,name:m.trim()||e.name})}function p(){h(!1),y!==e.value&&a({...e,value:y})}async function C(s){if(s.type.startsWith("image/")){f(!0);try{const g=await U(s);a({...e,image_filename:g})}catch(g){console.error("[ImmacStyleMixer] Image upload failed",g)}finally{f(!1)}}}return t.jsxs("div",{style:{border:"1px solid var(--p-surface-border, #444)",borderRadius:8,padding:8,width:180,flexShrink:0,background:"var(--p-surface-section, #1e1e1e)",display:"flex",flexDirection:"column",gap:6,position:"relative"},children:[t.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[t.jsx("button",{title:e.favorite?"Unfavorite":"Favorite",onClick:()=>a({...e,favorite:!e.favorite}),style:N,children:e.favorite?"★":"☆"}),t.jsx("button",{title:"Delete style",onClick:d,style:{...N,color:"#e55"},children:"✕"})]}),t.jsxs("div",{style:{position:"relative",width:"100%",aspectRatio:"1"},children:[t.jsx("div",{title:"Click or drop to upload image",onClick:()=>{var s;return(s=n.current)==null?void 0:s.click()},onDragOver:s=>s.preventDefault(),onDrop:s=>{s.preventDefault();const g=s.dataTransfer.files[0];g&&C(g)},style:{width:"100%",height:"100%",borderRadius:6,border:"1px dashed var(--p-surface-border, #555)",overflow:"hidden",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",background:"var(--p-surface-ground, #141414)",fontSize:11,color:"#888",flexShrink:0},children:j?"Uploading…":e.image_filename?t.jsx("img",{src:M(e.image_filename),alt:e.name,style:{width:"100%",height:"100%",objectFit:"cover"}}):"+ image"}),!j&&e.image_filename&&t.jsx("button",{title:"View full size",onClick:s=>{s.stopPropagation(),k(!0)},style:G,children:t.jsx("i",{className:"pi pi-search-plus"})})]}),w&&e.image_filename&&t.jsx(A,{src:M(e.image_filename),alt:e.name,onClose:()=>k(!1)}),t.jsx("input",{ref:n,type:"file",accept:"image/*",style:{display:"none"},onChange:s=>{var i;const g=(i=s.target.files)==null?void 0:i[0];g&&C(g),s.target.value=""}}),o?t.jsx("input",{autoFocus:!0,value:m,onChange:s=>c(s.target.value),onBlur:r,onKeyDown:s=>{s.key==="Enter"&&r(),s.key==="Escape"&&u(!1)},style:T}):t.jsx("div",{title:"Click to rename",onDoubleClick:()=>{c(e.name),u(!0)},style:{fontWeight:600,fontSize:13,cursor:"text",wordBreak:"break-word"},children:e.name}),v?t.jsx("textarea",{autoFocus:!0,value:y,onChange:s=>b(s.target.value),onBlur:p,onKeyDown:s=>{s.key==="Escape"&&h(!1)},rows:3,style:{...T,resize:"vertical"}}):t.jsx("div",{title:"Click to edit prompt text",onDoubleClick:()=>{b(e.value),h(!0)},style:{fontSize:11,color:"#aaa",cursor:"text",wordBreak:"break-word",minHeight:32},children:e.value||t.jsx("span",{style:{color:"#555"},children:"double-click to add prompt…"})})]})}const N={background:"none",border:"none",cursor:"pointer",fontSize:16,padding:"0 2px",color:"inherit",lineHeight:1},G={position:"absolute",top:6,left:6,background:"rgba(255,255,255,0.92)",border:"none",borderRadius:6,cursor:"pointer",fontSize:13,padding:"3px 6px",lineHeight:1,color:"#222",boxShadow:"0 1px 4px rgba(0,0,0,0.25)"},T={width:"100%",boxSizing:"border-box",background:"var(--p-surface-ground, #141414)",border:"1px solid var(--p-primary-color, #6c6)",borderRadius:4,color:"inherit",padding:"2px 4px",fontSize:12};function J({styles:e,onUpdate:a,onDelete:d,onAdd:o}){const[u,v]=l.useState(""),[h,m]=l.useState(!1);function c(){const f=u.trim();f&&(o(f),v(""),m(!1))}const y=e.filter(f=>f.favorite),b=e.filter(f=>!f.favorite),j=[...y,...b];return t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:10},children:t.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:10},children:[j.map(f=>t.jsx(Y,{style:f,onUpdate:a,onDelete:()=>d(f.id)},f.id)),h?t.jsxs("div",{style:{border:"1px dashed var(--p-primary-color, #6c6)",borderRadius:8,padding:10,width:180,display:"flex",flexDirection:"column",gap:8,background:"var(--p-surface-section, #1e1e1e)",flexShrink:0},children:[t.jsx("input",{autoFocus:!0,placeholder:"Style name…",value:u,onChange:f=>v(f.target.value),onKeyDown:f=>{f.key==="Enter"&&c(),f.key==="Escape"&&m(!1)},style:q}),t.jsxs("div",{style:{display:"flex",gap:6},children:[t.jsx("button",{onClick:c,style:W,children:"Add"}),t.jsx("button",{onClick:()=>{m(!1),v("")},style:{...W,background:"transparent",color:"#aaa"},children:"Cancel"})]})]}):t.jsx("button",{title:"Add a new style",onClick:()=>m(!0),style:{width:180,aspectRatio:"unset",minHeight:80,border:"1px dashed var(--p-surface-border, #555)",borderRadius:8,background:"transparent",color:"#666",cursor:"pointer",fontSize:24,flexShrink:0},children:"+"})]})})}const q={width:"100%",boxSizing:"border-box",background:"var(--p-surface-ground, #141414)",border:"1px solid var(--p-primary-color, #6c6)",borderRadius:4,color:"inherit",padding:"4px 6px",fontSize:13},W={flex:1,background:"var(--p-primary-color, #557755)",border:"none",borderRadius:4,color:"#fff",cursor:"pointer",padding:"4px 8px",fontSize:12};function O(){return crypto.randomUUID()}function R({title:e,children:a}){return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[t.jsx("div",{style:{fontWeight:700,fontSize:12,textTransform:"uppercase",letterSpacing:"0.08em",color:"#888",borderBottom:"1px solid var(--p-surface-border, #333)",paddingBottom:4},children:e}),a]})}function Z(){const{data:e,loading:a,error:d,update:o}=$(),u=e.mixes.find(n=>n.id===e.current_mix_id)??null,v=l.useCallback(n=>{const r={id:O(),name:n,value:"",favorite:!1,image_filename:null};o(p=>({...p,styles:[...p.styles,r]}))},[o]),h=l.useCallback(n=>{o(r=>({...r,styles:r.styles.map(p=>p.id===n.id?n:p)}))},[o]),m=l.useCallback(n=>{o(r=>({...r,styles:r.styles.filter(p=>p.id!==n),mixes:r.mixes.map(p=>({...p,styles:p.styles.filter(C=>C.style_id!==n)}))}))},[o]),c=l.useCallback(()=>{const n={id:O(),name:`Mix ${e.mixes.length+1}`,favorite:!1,image_filename:null,styles:[]};o(r=>({...r,mixes:[...r.mixes,n]}))},[e.mixes.length,o]),y=l.useCallback(n=>{o(r=>({...r,mixes:r.mixes.map(p=>p.id===n.id?n:p)}))},[o]),b=l.useCallback(n=>{o(r=>({...r,mixes:r.mixes.filter(p=>p.id!==n),current_mix_id:r.current_mix_id===n?null:r.current_mix_id}))},[o]),j=l.useCallback(n=>{o(r=>({...r,current_mix_id:n}))},[o]);if(a)return t.jsx("div",{style:I,children:"Loading…"});if(d)return t.jsxs("div",{style:{...I,color:"#e55"},children:["Error: ",d]});const f=e.mixes.filter(n=>n.favorite),w=e.mixes.filter(n=>!n.favorite),k=[...f,...w];return t.jsxs("div",{style:I,children:[t.jsx(R,{title:"Current Mix",children:u?t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:6},children:[t.jsx("div",{style:{fontWeight:600,fontSize:14},children:u.name}),t.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:[u.styles.length===0&&t.jsx("div",{style:{fontSize:12,color:"#666"},children:"No styles in this mix yet."}),u.styles.map(n=>{const r=e.styles.find(p=>p.id===n.style_id);return t.jsxs("div",{style:{border:`1px solid ${n.enabled?"var(--p-primary-color, #6c6)":"var(--p-surface-border, #444)"}`,borderRadius:6,padding:"6px 10px",background:"var(--p-surface-section, #1e1e1e)",opacity:n.enabled?1:.45,fontSize:12,display:"flex",flexDirection:"column",alignItems:"center",gap:4,minWidth:80},children:[t.jsx("span",{style:{fontWeight:600},children:(r==null?void 0:r.name)??"?"}),t.jsxs("span",{style:{color:"#aaa"},children:["×",n.weight.toFixed(2)]})]},n.style_id)})]})]}):t.jsx("div",{style:{fontSize:12,color:"#666"},children:"No mix active — select one from Mixes below."})}),t.jsx(R,{title:"Mixes",children:t.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[k.map(n=>t.jsx(V,{mix:n,styles:e.styles,isActive:n.id===e.current_mix_id,onActivate:()=>j(n.id),onUpdate:y,onDelete:()=>b(n.id)},n.id)),t.jsx("button",{title:"Add a new mix",onClick:c,style:{minWidth:80,minHeight:60,border:"1px dashed var(--p-surface-border, #555)",borderRadius:8,background:"transparent",color:"#666",cursor:"pointer",fontSize:22,alignSelf:"flex-start"},children:"+"})]})}),t.jsx(R,{title:"Styles",children:t.jsx(J,{styles:e.styles,onUpdate:h,onDelete:m,onAdd:v})})]})}const I={padding:"12px 12px",display:"flex",flexDirection:"column",gap:20,height:"100%",overflowY:"auto",color:"var(--p-text-color, #eee)",fontSize:13,boxSizing:"border-box"};export{Z as default}; +import{j as t}from"./main.js";import{r as l,b as P}from"./vendor-DPfS0z4g.js";const B={styles:[],mixes:[],current_mix_id:null},E="/immac_style_mixer/api/data";function $(){const[e,a]=l.useState(B),[d,o]=l.useState(!0),[u,v]=l.useState(null),h=l.useRef(null);l.useEffect(()=>{fetch(E).then(c=>{if(!c.ok)throw new Error(`HTTP ${c.status}`);return c.json()}).then(c=>a(c)).catch(c=>v(String(c))).finally(()=>o(!1))},[]);const m=l.useCallback(c=>{a(y=>{const b=typeof c=="function"?c(y):c;return h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{fetch(E,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(b)}).catch(j=>console.error("[ImmacStyleMixer] Save failed",j))},400),b})},[]);return{data:e,loading:d,error:u,update:m}}async function U(e){const a=new FormData;a.append("image",e),a.append("subfolder","immac_style_mixer/styles"),a.append("type","input");const d=await fetch("/upload/image",{method:"POST",body:a});if(!d.ok)throw new Error(`Upload failed: HTTP ${d.status}`);return(await d.json()).name}function M(e){return`/view?filename=${encodeURIComponent(e)}&subfolder=immac_style_mixer%2Fstyles&type=input`}async function L(e){const a=new FormData;a.append("image",e),a.append("subfolder","immac_style_mixer/mixes"),a.append("type","input");const d=await fetch("/upload/image",{method:"POST",body:a});if(!d.ok)throw new Error(`Upload failed: HTTP ${d.status}`);return(await d.json()).name}function F(e){return`/view?filename=${encodeURIComponent(e)}&subfolder=immac_style_mixer%2Fmixes&type=input`}function A({src:e,alt:a,onClose:d}){return l.useEffect(()=>{function o(u){u.key==="Escape"&&d()}return window.addEventListener("keydown",o),()=>window.removeEventListener("keydown",o)},[d]),P.createPortal(t.jsxs("div",{onClick:d,style:{position:"fixed",inset:0,zIndex:99999,background:"rgba(0,0,0,0.85)",display:"flex",alignItems:"center",justifyContent:"center",cursor:"zoom-out"},children:[t.jsx("img",{src:e,alt:a??"",onClick:o=>o.stopPropagation(),style:{maxWidth:"90vw",maxHeight:"90vh",objectFit:"contain",borderRadius:8,boxShadow:"0 8px 40px rgba(0,0,0,0.7)",cursor:"default"}}),t.jsx("button",{onClick:d,title:"Close",style:{position:"fixed",top:16,right:20,background:"none",border:"none",color:"#fff",fontSize:28,cursor:"pointer",lineHeight:1,opacity:.8},children:"✕"})]}),document.body)}function V({mix:e,styles:a,isActive:d,onActivate:o,onUpdate:u,onDelete:v}){const[h,m]=l.useState(!1),[c,y]=l.useState(e.name),[b,j]=l.useState(!1),[f,w]=l.useState(!1),k=l.useRef(null);async function n(i){if(i.type.startsWith("image/")){j(!0);try{const x=await L(i);u({...e,image_filename:x})}catch(x){console.error("[ImmacStyleMixer] Mix image upload failed",x)}finally{j(!1)}}}function r(){m(!1),c.trim()!==e.name&&u({...e,name:c.trim()||e.name})}function p(i,x){const S=e.styles.map((_,H)=>H===i?{..._,...x}:_);u({...e,styles:S})}function C(i){u({...e,styles:e.styles.filter((x,S)=>S!==i)})}function s(i){e.styles.some(x=>x.style_id===i)||u({...e,styles:[...e.styles,{style_id:i,weight:1,enabled:!0}]})}const g=a.filter(i=>!e.styles.some(x=>x.style_id===i.id));return t.jsxs("div",{style:{border:`2px solid ${d?"var(--p-primary-color, #6c6)":"var(--p-surface-border, #444)"}`,borderRadius:8,padding:10,background:"var(--p-surface-section, #1e1e1e)",display:"flex",flexDirection:"column",gap:8,minWidth:240,maxWidth:340,flexShrink:0},children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[t.jsx("input",{type:"radio",title:"Set as current mix",checked:d,onChange:o,style:{cursor:"pointer",flexShrink:0}}),h?t.jsx("input",{autoFocus:!0,value:c,onChange:i=>y(i.target.value),onBlur:r,onKeyDown:i=>{i.key==="Enter"&&r(),i.key==="Escape"&&m(!1)},style:z}):t.jsx("span",{title:"Double-click to rename",onDoubleClick:()=>{y(e.name),m(!0)},style:{fontWeight:600,flex:1,cursor:"text",fontSize:13},children:e.name}),t.jsx("button",{title:e.favorite?"Unfavorite":"Favorite",onClick:()=>u({...e,favorite:!e.favorite}),style:D,children:e.favorite?"★":"☆"}),t.jsx("button",{title:"Delete mix",onClick:v,style:{...D,color:"#e55"},children:"✕"})]}),t.jsxs("div",{style:{position:"relative",width:"100%",aspectRatio:"1"},children:[t.jsx("div",{title:"Click or drop an image to set mix cover",onClick:()=>{var i;return(i=k.current)==null?void 0:i.click()},onDragOver:i=>i.preventDefault(),onDrop:i=>{i.preventDefault();const x=i.dataTransfer.files[0];x&&n(x)},style:{width:"100%",height:"100%",borderRadius:6,border:"1px dashed var(--p-surface-border, #555)",overflow:"hidden",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",background:"var(--p-surface-ground, #141414)",fontSize:11,color:"#888",flexShrink:0},children:b?"Uploading…":e.image_filename?t.jsx("img",{src:F(e.image_filename),alt:e.name,style:{width:"100%",height:"100%",objectFit:"cover"}}):"+ cover image"}),!b&&e.image_filename&&t.jsx("button",{title:"View full size",onClick:i=>{i.stopPropagation(),w(!0)},style:K,children:t.jsx("i",{className:"pi pi-search-plus"})})]}),f&&e.image_filename&&t.jsx(A,{src:F(e.image_filename),alt:e.name,onClose:()=>w(!1)}),t.jsx("input",{ref:k,type:"file",accept:"image/*",style:{display:"none"},onChange:i=>{var S;const x=(S=i.target.files)==null?void 0:S[0];x&&n(x),i.target.value=""}}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:6,maxHeight:240,overflowY:"auto"},children:[e.styles.length===0&&t.jsx("div",{style:{fontSize:11,color:"#666"},children:"No styles added yet."}),e.styles.map((i,x)=>{const S=a.find(_=>_.id===i.style_id);return t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6},children:[t.jsx("button",{title:i.enabled?"Disable":"Enable",onClick:()=>p(x,{enabled:!i.enabled}),style:{...D,fontSize:11,padding:"2px 5px",border:"1px solid var(--p-surface-border, #555)",borderRadius:4,background:i.enabled?"var(--p-primary-color, #557755)":"transparent",color:i.enabled?"#fff":"#888",minWidth:32},children:i.enabled?"ON":"OFF"}),t.jsx("span",{style:{fontSize:12,flex:1,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:(S==null?void 0:S.name)??i.style_id}),t.jsx("input",{type:"number",min:0,max:2,step:.05,value:i.weight,onChange:_=>p(x,{weight:parseFloat(_.target.value)||0}),style:{...z,width:52,textAlign:"right"}}),t.jsx("button",{title:"Remove from mix",onClick:()=>C(x),style:{...D,color:"#e55",fontSize:13},children:"✕"})]},i.style_id)})]}),t.jsxs("select",{value:"",disabled:g.length===0,onChange:i=>{i.target.value&&s(i.target.value)},style:{...z,cursor:g.length===0?"not-allowed":"pointer",opacity:g.length===0?.45:1},title:g.length===0?"All library styles are already in this mix":"Add a style to this mix",children:[t.jsx("option",{value:"",children:g.length===0?"— all styles already added —":"+ add style…"}),g.map(i=>t.jsx("option",{value:i.id,children:i.name},i.id))]})]})}const D={background:"none",border:"none",cursor:"pointer",fontSize:16,padding:"0 2px",color:"inherit",lineHeight:1,flexShrink:0},K={position:"absolute",top:6,left:6,background:"rgba(255,255,255,0.92)",border:"none",borderRadius:6,cursor:"pointer",fontSize:13,padding:"3px 6px",lineHeight:1,color:"#222",boxShadow:"0 1px 4px rgba(0,0,0,0.25)"},z={background:"var(--p-surface-ground, #141414)",border:"1px solid var(--p-surface-border, #444)",borderRadius:4,color:"inherit",padding:"2px 4px",fontSize:12,boxSizing:"border-box"};function Y({style:e,onUpdate:a,onDelete:d}){const[o,u]=l.useState(!1),[v,h]=l.useState(!1),[m,c]=l.useState(e.name),[y,b]=l.useState(e.value),[j,f]=l.useState(!1),[w,k]=l.useState(!1),n=l.useRef(null);function r(){u(!1),m.trim()!==e.name&&a({...e,name:m.trim()||e.name})}function p(){h(!1),y!==e.value&&a({...e,value:y})}async function C(s){if(s.type.startsWith("image/")){f(!0);try{const g=await U(s);a({...e,image_filename:g})}catch(g){console.error("[ImmacStyleMixer] Image upload failed",g)}finally{f(!1)}}}return t.jsxs("div",{style:{border:"1px solid var(--p-surface-border, #444)",borderRadius:8,padding:8,width:180,flexShrink:0,background:"var(--p-surface-section, #1e1e1e)",display:"flex",flexDirection:"column",gap:6,position:"relative"},children:[t.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center"},children:[t.jsx("button",{title:e.favorite?"Unfavorite":"Favorite",onClick:()=>a({...e,favorite:!e.favorite}),style:N,children:e.favorite?"★":"☆"}),t.jsx("button",{title:"Delete style",onClick:d,style:{...N,color:"#e55"},children:"✕"})]}),t.jsxs("div",{style:{position:"relative",width:"100%",aspectRatio:"1"},children:[t.jsx("div",{title:"Click or drop to upload image",onClick:()=>{var s;return(s=n.current)==null?void 0:s.click()},onDragOver:s=>s.preventDefault(),onDrop:s=>{s.preventDefault();const g=s.dataTransfer.files[0];g&&C(g)},style:{width:"100%",height:"100%",borderRadius:6,border:"1px dashed var(--p-surface-border, #555)",overflow:"hidden",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",background:"var(--p-surface-ground, #141414)",fontSize:11,color:"#888",flexShrink:0},children:j?"Uploading…":e.image_filename?t.jsx("img",{src:M(e.image_filename),alt:e.name,style:{width:"100%",height:"100%",objectFit:"cover"}}):"+ image"}),!j&&e.image_filename&&t.jsx("button",{title:"View full size",onClick:s=>{s.stopPropagation(),k(!0)},style:G,children:t.jsx("i",{className:"pi pi-search-plus"})})]}),w&&e.image_filename&&t.jsx(A,{src:M(e.image_filename),alt:e.name,onClose:()=>k(!1)}),t.jsx("input",{ref:n,type:"file",accept:"image/*",style:{display:"none"},onChange:s=>{var i;const g=(i=s.target.files)==null?void 0:i[0];g&&C(g),s.target.value=""}}),o?t.jsx("input",{autoFocus:!0,value:m,onChange:s=>c(s.target.value),onBlur:r,onKeyDown:s=>{s.key==="Enter"&&r(),s.key==="Escape"&&u(!1)},style:T}):t.jsx("div",{title:"Click to rename",onDoubleClick:()=>{c(e.name),u(!0)},style:{fontWeight:600,fontSize:13,cursor:"text",wordBreak:"break-word"},children:e.name}),v?t.jsx("textarea",{autoFocus:!0,value:y,onChange:s=>b(s.target.value),onBlur:p,onKeyDown:s=>{s.key==="Escape"&&h(!1)},rows:3,style:{...T,resize:"vertical"}}):t.jsx("div",{title:"Click to edit prompt text",onDoubleClick:()=>{b(e.value),h(!0)},style:{fontSize:11,color:"#aaa",cursor:"text",wordBreak:"break-word",minHeight:32},children:e.value||t.jsx("span",{style:{color:"#555"},children:"double-click to add prompt…"})})]})}const N={background:"none",border:"none",cursor:"pointer",fontSize:16,padding:"0 2px",color:"inherit",lineHeight:1},G={position:"absolute",top:6,left:6,background:"rgba(255,255,255,0.92)",border:"none",borderRadius:6,cursor:"pointer",fontSize:13,padding:"3px 6px",lineHeight:1,color:"#222",boxShadow:"0 1px 4px rgba(0,0,0,0.25)"},T={width:"100%",boxSizing:"border-box",background:"var(--p-surface-ground, #141414)",border:"1px solid var(--p-primary-color, #6c6)",borderRadius:4,color:"inherit",padding:"2px 4px",fontSize:12};function J({styles:e,onUpdate:a,onDelete:d,onAdd:o}){const[u,v]=l.useState(""),[h,m]=l.useState(!1);function c(){const f=u.trim();f&&(o(f),v(""),m(!1))}const y=e.filter(f=>f.favorite),b=e.filter(f=>!f.favorite),j=[...y,...b];return t.jsx("div",{style:{display:"flex",flexDirection:"column",gap:10},children:t.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:10},children:[j.map(f=>t.jsx(Y,{style:f,onUpdate:a,onDelete:()=>d(f.id)},f.id)),h?t.jsxs("div",{style:{border:"1px dashed var(--p-primary-color, #6c6)",borderRadius:8,padding:10,width:180,display:"flex",flexDirection:"column",gap:8,background:"var(--p-surface-section, #1e1e1e)",flexShrink:0},children:[t.jsx("input",{autoFocus:!0,placeholder:"Style name…",value:u,onChange:f=>v(f.target.value),onKeyDown:f=>{f.key==="Enter"&&c(),f.key==="Escape"&&m(!1)},style:q}),t.jsxs("div",{style:{display:"flex",gap:6},children:[t.jsx("button",{onClick:c,style:W,children:"Add"}),t.jsx("button",{onClick:()=>{m(!1),v("")},style:{...W,background:"transparent",color:"#aaa"},children:"Cancel"})]})]}):t.jsx("button",{title:"Add a new style",onClick:()=>m(!0),style:{width:180,aspectRatio:"unset",minHeight:80,border:"1px dashed var(--p-surface-border, #555)",borderRadius:8,background:"transparent",color:"#666",cursor:"pointer",fontSize:24,flexShrink:0},children:"+"})]})})}const q={width:"100%",boxSizing:"border-box",background:"var(--p-surface-ground, #141414)",border:"1px solid var(--p-primary-color, #6c6)",borderRadius:4,color:"inherit",padding:"4px 6px",fontSize:13},W={flex:1,background:"var(--p-primary-color, #557755)",border:"none",borderRadius:4,color:"#fff",cursor:"pointer",padding:"4px 8px",fontSize:12};function O(){return crypto.randomUUID()}function R({title:e,children:a}){return t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8},children:[t.jsx("div",{style:{fontWeight:700,fontSize:12,textTransform:"uppercase",letterSpacing:"0.08em",color:"#888",borderBottom:"1px solid var(--p-surface-border, #333)",paddingBottom:4},children:e}),a]})}function Z(){const{data:e,loading:a,error:d,update:o}=$(),u=e.mixes.find(n=>n.id===e.current_mix_id)??null,v=l.useCallback(n=>{const r={id:O(),name:n,value:"",favorite:!1,image_filename:null};o(p=>({...p,styles:[...p.styles,r]}))},[o]),h=l.useCallback(n=>{o(r=>({...r,styles:r.styles.map(p=>p.id===n.id?n:p)}))},[o]),m=l.useCallback(n=>{o(r=>({...r,styles:r.styles.filter(p=>p.id!==n),mixes:r.mixes.map(p=>({...p,styles:p.styles.filter(C=>C.style_id!==n)}))}))},[o]),c=l.useCallback(()=>{const n={id:O(),name:`Mix ${e.mixes.length+1}`,favorite:!1,image_filename:null,styles:[]};o(r=>({...r,mixes:[...r.mixes,n]}))},[e.mixes.length,o]),y=l.useCallback(n=>{o(r=>({...r,mixes:r.mixes.map(p=>p.id===n.id?n:p)}))},[o]),b=l.useCallback(n=>{o(r=>({...r,mixes:r.mixes.filter(p=>p.id!==n),current_mix_id:r.current_mix_id===n?null:r.current_mix_id}))},[o]),j=l.useCallback(n=>{o(r=>({...r,current_mix_id:n}))},[o]);if(a)return t.jsx("div",{style:I,children:"Loading…"});if(d)return t.jsxs("div",{style:{...I,color:"#e55"},children:["Error: ",d]});const f=e.mixes.filter(n=>n.favorite),w=e.mixes.filter(n=>!n.favorite),k=[...f,...w];return t.jsxs("div",{style:I,children:[t.jsx(R,{title:"Current Mix",children:u?t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:6},children:[t.jsx("div",{style:{fontWeight:600,fontSize:14},children:u.name}),t.jsxs("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:[u.styles.length===0&&t.jsx("div",{style:{fontSize:12,color:"#666"},children:"No styles in this mix yet."}),u.styles.map(n=>{const r=e.styles.find(p=>p.id===n.style_id);return t.jsxs("div",{style:{border:`1px solid ${n.enabled?"var(--p-primary-color, #6c6)":"var(--p-surface-border, #444)"}`,borderRadius:6,padding:"6px 10px",background:"var(--p-surface-section, #1e1e1e)",opacity:n.enabled?1:.45,fontSize:12,display:"flex",flexDirection:"column",alignItems:"center",gap:4,minWidth:80},children:[t.jsx("span",{style:{fontWeight:600},children:(r==null?void 0:r.name)??"?"}),t.jsxs("span",{style:{color:"#aaa"},children:["×",n.weight.toFixed(2)]})]},n.style_id)})]})]}):t.jsx("div",{style:{fontSize:12,color:"#666"},children:"No mix active — select one from Mixes below."})}),t.jsx(R,{title:"Mixes",children:t.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[k.map(n=>t.jsx(V,{mix:n,styles:e.styles,isActive:n.id===e.current_mix_id,onActivate:()=>j(n.id),onUpdate:y,onDelete:()=>b(n.id)},n.id)),t.jsx("button",{title:"Add a new mix",onClick:c,style:{minWidth:80,minHeight:60,border:"1px dashed var(--p-surface-border, #555)",borderRadius:8,background:"transparent",color:"#666",cursor:"pointer",fontSize:22,alignSelf:"flex-start"},children:"+"})]})}),t.jsx(R,{title:"Styles",children:t.jsx(J,{styles:e.styles,onUpdate:h,onDelete:m,onAdd:v})})]})}const I={padding:"12px 12px",display:"flex",flexDirection:"column",gap:20,height:"100%",overflowY:"auto",color:"var(--p-text-color, #eee)",fontSize:13,boxSizing:"border-box"};export{Z as default}; diff --git a/dist/immac_style_mixer/main.js b/dist/immac_style_mixer/main.js index 78e8fb0..2148fea 100644 --- a/dist/immac_style_mixer/main.js +++ b/dist/immac_style_mixer/main.js @@ -1,4 +1,4 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["immac_style_mixer/StyleMixerPanel-VKyuy2q1.js","immac_style_mixer/vendor-DPfS0z4g.js"])))=>i.map(i=>d[i]); +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["immac_style_mixer/StyleMixerPanel-D2mbBoah.js","immac_style_mixer/vendor-DPfS0z4g.js"])))=>i.map(i=>d[i]); import{r as h,a as R,R as v}from"./vendor-DPfS0z4g.js";const g="modulepreload",I=function(r){return"/"+r},f={},P=function(e,o,n){let c=Promise.resolve();if(o&&o.length>0){document.getElementsByTagName("link");const t=document.querySelector("meta[property=csp-nonce]"),i=(t==null?void 0:t.nonce)||(t==null?void 0:t.getAttribute("nonce"));c=Promise.allSettled(o.map(a=>{if(a=I(a),a in f)return;f[a]=!0;const d=a.endsWith(".css"),w=d?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${a}"]${w}`))return;const s=document.createElement("link");if(s.rel=d?"stylesheet":g,d||(s.as="script"),s.crossOrigin="",s.href=a,i&&s.setAttribute("nonce",i),document.head.appendChild(s),d)return new Promise((E,S)=>{s.addEventListener("load",E),s.addEventListener("error",()=>S(new Error(`Unable to preload CSS for ${a}`)))})}))}function l(t){const i=new Event("vite:preloadError",{cancelable:!0});if(i.payload=t,window.dispatchEvent(i),!i.defaultPrevented)throw t}return c.then(t=>{for(const i of t||[])i.status==="rejected"&&l(i.reason);return e().catch(l)})};var x={exports:{}},u={};/** * @license React * react-jsx-runtime.production.min.js @@ -7,4 +7,4 @@ import{r as h,a as R,R as v}from"./vendor-DPfS0z4g.js";const g="modulepreload",I * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - */var b=h,j=Symbol.for("react.element"),k=Symbol.for("react.fragment"),O=Object.prototype.hasOwnProperty,L=b.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,C={key:!0,ref:!0,__self:!0,__source:!0};function _(r,e,o){var n,c={},l=null,t=null;o!==void 0&&(l=""+o),e.key!==void 0&&(l=""+e.key),e.ref!==void 0&&(t=e.ref);for(n in e)O.call(e,n)&&!C.hasOwnProperty(n)&&(c[n]=e[n]);if(r&&r.defaultProps)for(n in e=r.defaultProps,e)c[n]===void 0&&(c[n]=e[n]);return{$$typeof:j,type:r,key:l,ref:t,props:c,_owner:L.current}}u.Fragment=k;u.jsx=_;u.jsxs=_;x.exports=u;var m=x.exports,p={},y=R;p.createRoot=y.createRoot,p.hydrateRoot=y.hydrateRoot;const T=v.lazy(()=>P(()=>import("./StyleMixerPanel-VKyuy2q1.js"),__vite__mapDeps([0,1])));function U(){return new Promise(r=>{function e(){if(window.app){r();return}const o=setInterval(()=>{window.app&&(clearInterval(o),r())},50);setTimeout(()=>{clearInterval(o),console.error("[ImmacStyleMixer] Timeout waiting for ComfyUI app"),r()},5e3)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()})}async function M(){if(await U(),!window.app){console.error("[ImmacStyleMixer] ComfyUI app not available");return}window.app.extensionManager.registerSidebarTab({id:"immac-style-mixer",icon:"pi pi-palette",title:"Style Mixer",tooltip:"Immac Style Mixer",type:"custom",render:r=>{const e=document.createElement("div");e.id="immac-style-mixer-root",e.style.height="100%",r.appendChild(e),p.createRoot(e).render(m.jsx(v.StrictMode,{children:m.jsx(h.Suspense,{fallback:m.jsx("div",{style:{padding:"1rem"},children:"Loading…"}),children:m.jsx(T,{})})}))}}),window.app.registerExtension({name:"ImmacStyleMixer"})}M().catch(console.error);export{m as j}; + */var b=h,j=Symbol.for("react.element"),k=Symbol.for("react.fragment"),O=Object.prototype.hasOwnProperty,L=b.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,C={key:!0,ref:!0,__self:!0,__source:!0};function _(r,e,o){var n,c={},l=null,t=null;o!==void 0&&(l=""+o),e.key!==void 0&&(l=""+e.key),e.ref!==void 0&&(t=e.ref);for(n in e)O.call(e,n)&&!C.hasOwnProperty(n)&&(c[n]=e[n]);if(r&&r.defaultProps)for(n in e=r.defaultProps,e)c[n]===void 0&&(c[n]=e[n]);return{$$typeof:j,type:r,key:l,ref:t,props:c,_owner:L.current}}u.Fragment=k;u.jsx=_;u.jsxs=_;x.exports=u;var m=x.exports,p={},y=R;p.createRoot=y.createRoot,p.hydrateRoot=y.hydrateRoot;const T=v.lazy(()=>P(()=>import("./StyleMixerPanel-D2mbBoah.js"),__vite__mapDeps([0,1])));function U(){return new Promise(r=>{function e(){if(window.app){r();return}const o=setInterval(()=>{window.app&&(clearInterval(o),r())},50);setTimeout(()=>{clearInterval(o),console.error("[ImmacStyleMixer] Timeout waiting for ComfyUI app"),r()},5e3)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()})}async function M(){if(await U(),!window.app){console.error("[ImmacStyleMixer] ComfyUI app not available");return}window.app.extensionManager.registerSidebarTab({id:"immac-style-mixer",icon:"pi pi-palette",title:"Style Mixer",tooltip:"Immac Style Mixer",type:"custom",render:r=>{const e=document.createElement("div");e.id="immac-style-mixer-root",e.style.height="100%",r.appendChild(e),p.createRoot(e).render(m.jsx(v.StrictMode,{children:m.jsx(h.Suspense,{fallback:m.jsx("div",{style:{padding:"1rem"},children:"Loading…"}),children:m.jsx(T,{})})}))}}),window.app.registerExtension({name:"ImmacStyleMixer"})}M().catch(console.error);export{m as j}; diff --git a/ui/src/components/MixCard.tsx b/ui/src/components/MixCard.tsx index a076127..4c75708 100644 --- a/ui/src/components/MixCard.tsx +++ b/ui/src/components/MixCard.tsx @@ -110,7 +110,7 @@ export default function MixCard({ mix, styles, isActive, onActivate, onUpdate, o {/* Cover image */} -
+
fileRef.current?.click()} @@ -122,7 +122,7 @@ export default function MixCard({ mix, styles, isActive, onActivate, onUpdate, o }} style={{ width: '100%', - height: 90, + height: '100%', borderRadius: 6, border: '1px dashed var(--p-surface-border, #555)', overflow: 'hidden', @@ -134,7 +134,6 @@ export default function MixCard({ mix, styles, isActive, onActivate, onUpdate, o fontSize: 11, color: '#888', flexShrink: 0, - position: 'relative', }} > {uploading ? (