Merge pull request #126 from zanllp/feature/auto-refresh-with-tree-view-and-index-check

Add auto-refresh with tree view and index check when returning to ext…
pull/132/head
zanllp 2023-05-12 02:16:40 +08:00 committed by GitHub
commit d67fcf9394
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 324 additions and 284 deletions

View File

@ -8,8 +8,8 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-e10b03a9.js"></script>
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-55967755.css">
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-edca4075.js"></script>
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-99766f9b.css">
</head>
<body>

View File

@ -303,6 +303,15 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
"expired_dirs": expired_dirs,
}
@app.get(db_pre+"/expired_dirs")
async def get_db_expired():
conn = DataBase.get_conn()
expired_dirs = Floder.get_expired_dirs(conn)
return {
"expired": len(expired_dirs) != 0,
"expired_dirs": expired_dirs,
}
@app.post(db_pre + "/update_image_data")
async def update_image_db_data():
try:

View File

@ -1 +1 @@
import{d as E,r as S,aX as L,x as Q,o as d,l as T,c as a,m as r,n as e,p as V,q as z,A as j,t as F,B as H,y as A,J as k,I as B,aM as J,L as X,Q as K}from"./index-e10b03a9.js";import{u as W,b as Y,f as Z,c as ee,d as se,e as le,i as te,j as ie,t as ae,L as ne,R as oe,k as re,S as ce}from"./fullScreenContextMenu-8784c740.js";import{g as de,M as ue}from"./db-20204a02.js";import"./index-85f87e21.js";import"./_baseIteratee-0f4d51fc.js";import"./button-955acb02.js";const me={class:"hint"},pe={key:1,class:"preview-switch"},ve=E({__name:"MatchedImageGrid",props:{tabIdx:null,paneIdx:null,selectedTagIds:null,id:null},setup(R){const u=R,l=S(),g=L();Q(()=>u.selectedTagIds,async()=>{var s;const{res:i}=g.pushAction(()=>de(u.selectedTagIds));l.value=await i,(s=m.value)==null||s.scrollToItem(0)},{immediate:!0});const m=S(),I={tabIdx:-1,target:"local",paneIdx:-1,walkMode:!1},{stackViewEl:$,multiSelectedIdxs:p,stack:G}=W().toRefs(),{itemSize:w,gridItems:N}=Y(I),{showMenuIdx:v}=Z();ee();const{showGenInfo:c,imageGenInfo:x,q:P,onContextMenuClick:O,onFileItemClick:U}=se(I,{openNext:J}),{previewIdx:n,previewing:C,onPreviewVisibleChange:q,previewImgMove:_,canPreview:y}=le(u,{scroller:m,files:l}),b=async(i,s,o)=>{G.value=[{curr:"",files:l.value}];const f=p.value.includes(o)?p.value:[o];await O(i,s,o),i.key==="deleteFiles"&&(l.value=l.value.filter((M,t)=>!f.includes(t)))};return(i,s)=>{const o=X,f=ue,M=ce;return d(),T("div",{class:"container",ref_key:"stackViewEl",ref:$},[a(M,{size:"large",spinning:!e(g).isIdle},{default:r(()=>[a(f,{visible:e(c),"onUpdate:visible":s[1]||(s[1]=t=>V(c)?c.value=t:null),width:"70vw","mask-closable":"",onOk:s[2]||(s[2]=t=>c.value=!1)},{cancelText:r(()=>[]),default:r(()=>[a(o,{active:"",loading:!e(P).isIdle},{default:r(()=>[z("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:s[0]||(s[0]=t=>e(j)(e(x)))},[z("div",me,F(i.$t("doubleClickToCopy")),1),H(" "+F(e(x)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),l.value?(d(),A(e(te),{key:0,ref_key:"scroller",ref:m,class:"file-list",items:l.value,"item-size":e(w).first,"key-field":"fullpath","item-secondary-size":e(w).second,gridItems:e(N)},{default:r(({item:t,index:h})=>[a(ie,{idx:h,file:t,"show-menu-idx":e(v),"onUpdate:showMenuIdx":s[3]||(s[3]=D=>V(v)?v.value=D:null),onFileItemClick:e(U),"full-screen-preview-image-url":l.value[e(n)]?e(ae)(l.value[e(n)]):"",selected:e(p).includes(h),onContextMenuClick:b,onPreviewVisibleChange:e(q)},null,8,["idx","file","show-menu-idx","onFileItemClick","full-screen-preview-image-url","selected","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):k("",!0),e(C)?(d(),T("div",pe,[a(e(ne),{onClick:s[4]||(s[4]=t=>e(_)("prev")),class:B({disable:!e(y)("prev")})},null,8,["class"]),a(e(oe),{onClick:s[5]||(s[5]=t=>e(_)("next")),class:B({disable:!e(y)("next")})},null,8,["class"])])):k("",!0)]),_:1},8,["spinning"]),e(C)&&l.value&&l.value[e(n)]?(d(),A(re,{key:0,file:l.value[e(n)],idx:e(n),onContextMenuClick:b},null,8,["file","idx"])):k("",!0)],512)}}});const Ce=K(ve,[["__scopeId","data-v-a04a415f"]]);export{Ce as default};
import{d as E,r as S,aX as L,x as Q,o as d,l as T,c as a,m as r,n as e,p as V,q as z,A as j,t as F,B as H,y as A,J as k,I as B,aM as J,L as X,Q as K}from"./index-edca4075.js";import{u as W,b as Y,f as Z,c as ee,d as se,e as le,i as te,j as ie,t as ae,L as ne,R as oe,k as re,S as ce}from"./fullScreenContextMenu-f4394da9.js";import{g as de,M as ue}from"./db-0ad5acd9.js";import"./index-011a6447.js";import"./_baseIteratee-8e08e621.js";import"./button-8244f7e4.js";const me={class:"hint"},pe={key:1,class:"preview-switch"},ve=E({__name:"MatchedImageGrid",props:{tabIdx:null,paneIdx:null,selectedTagIds:null,id:null},setup(R){const u=R,l=S(),g=L();Q(()=>u.selectedTagIds,async()=>{var s;const{res:i}=g.pushAction(()=>de(u.selectedTagIds));l.value=await i,(s=m.value)==null||s.scrollToItem(0)},{immediate:!0});const m=S(),I={tabIdx:-1,target:"local",paneIdx:-1,walkMode:!1},{stackViewEl:$,multiSelectedIdxs:p,stack:G}=W().toRefs(),{itemSize:w,gridItems:N}=Y(I),{showMenuIdx:v}=Z();ee();const{showGenInfo:c,imageGenInfo:x,q:P,onContextMenuClick:O,onFileItemClick:U}=se(I,{openNext:J}),{previewIdx:n,previewing:C,onPreviewVisibleChange:q,previewImgMove:_,canPreview:y}=le(u,{scroller:m,files:l}),b=async(i,s,o)=>{G.value=[{curr:"",files:l.value}];const f=p.value.includes(o)?p.value:[o];await O(i,s,o),i.key==="deleteFiles"&&(l.value=l.value.filter((M,t)=>!f.includes(t)))};return(i,s)=>{const o=X,f=ue,M=ce;return d(),T("div",{class:"container",ref_key:"stackViewEl",ref:$},[a(M,{size:"large",spinning:!e(g).isIdle},{default:r(()=>[a(f,{visible:e(c),"onUpdate:visible":s[1]||(s[1]=t=>V(c)?c.value=t:null),width:"70vw","mask-closable":"",onOk:s[2]||(s[2]=t=>c.value=!1)},{cancelText:r(()=>[]),default:r(()=>[a(o,{active:"",loading:!e(P).isIdle},{default:r(()=>[z("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:s[0]||(s[0]=t=>e(j)(e(x)))},[z("div",me,F(i.$t("doubleClickToCopy")),1),H(" "+F(e(x)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),l.value?(d(),A(e(te),{key:0,ref_key:"scroller",ref:m,class:"file-list",items:l.value,"item-size":e(w).first,"key-field":"fullpath","item-secondary-size":e(w).second,gridItems:e(N)},{default:r(({item:t,index:h})=>[a(ie,{idx:h,file:t,"show-menu-idx":e(v),"onUpdate:showMenuIdx":s[3]||(s[3]=D=>V(v)?v.value=D:null),onFileItemClick:e(U),"full-screen-preview-image-url":l.value[e(n)]?e(ae)(l.value[e(n)]):"",selected:e(p).includes(h),onContextMenuClick:b,onPreviewVisibleChange:e(q)},null,8,["idx","file","show-menu-idx","onFileItemClick","full-screen-preview-image-url","selected","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):k("",!0),e(C)?(d(),T("div",pe,[a(e(ne),{onClick:s[4]||(s[4]=t=>e(_)("prev")),class:B({disable:!e(y)("prev")})},null,8,["class"]),a(e(oe),{onClick:s[5]||(s[5]=t=>e(_)("next")),class:B({disable:!e(y)("next")})},null,8,["class"])])):k("",!0)]),_:1},8,["spinning"]),e(C)&&l.value&&l.value[e(n)]?(d(),A(re,{key:0,file:l.value[e(n)],idx:e(n),onContextMenuClick:b},null,8,["file","idx"])):k("",!0)],512)}}});const Ce=K(ve,[["__scopeId","data-v-a04a415f"]]);export{Ce as default};

1
vue/dist/assets/TagSearch-001cc62a.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
.container[data-v-2a184aeb]{height:var(--pane-max-height);overflow:auto;display:flex;flex-direction:column;align-items:stretch}.container .generate-idx-hint[data-v-2a184aeb]{margin:64px;padding:64px;font-size:2em;text-align:center;background-color:var(--zp-secondary-background);white-space:pre-line;line-height:2.5em;border-radius:16px}.container .remove[data-v-2a184aeb]{padding:4px;position:cursor;border-radius:2px}.container .remove[data-v-2a184aeb]:hover{background-color:var(--zp-secondary-background)}.container .select[data-v-2a184aeb]{padding:8px}.container .search-bar[data-v-2a184aeb]{padding:8px;display:flex}.container .list-container[data-v-2a184aeb]{background-color:var(--zp-secondary-background);overflow:scroll}.container .tag-list[data-v-2a184aeb]{list-style:none;margin:16px;border-radius:16px;background:var(--zp-primary-background);padding:8px}.container .tag-list .cat-name[data-v-2a184aeb]{position:sticky;top:0;padding:4px 16px;background:var(--zp-primary-background);border-left:4px solid var(--primary-color);margin:4px}.container .tag-list .tag[data-v-2a184aeb]{border:2px solid var(--zp-secondary);color:var(--zp-primary);border-radius:999px;padding:4px 16px;margin:4px;display:inline-block;cursor:pointer;max-width:256px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.container .tag-list .tag.selected[data-v-2a184aeb]{color:var(--primary-color);border:2px solid var(--primary-color)}

View File

@ -1 +0,0 @@
.container[data-v-c4b1e490]{height:var(--pane-max-height);overflow:auto;display:flex;flex-direction:column;align-items:stretch}.container .generate-idx-hint[data-v-c4b1e490]{margin:64px;padding:64px;font-size:2em;text-align:center;background-color:var(--zp-secondary-background);white-space:pre-line;line-height:2.5em;border-radius:16px}.container .remove[data-v-c4b1e490]{padding:4px;position:cursor;border-radius:2px}.container .remove[data-v-c4b1e490]:hover{background-color:var(--zp-secondary-background)}.container .select[data-v-c4b1e490]{padding:8px}.container .search-bar[data-v-c4b1e490]{padding:8px;display:flex}.container .list-container[data-v-c4b1e490]{background-color:var(--zp-secondary-background);overflow:scroll}.container .tag-list[data-v-c4b1e490]{list-style:none;margin:16px;border-radius:16px;background:var(--zp-primary-background);padding:8px}.container .tag-list .cat-name[data-v-c4b1e490]{position:sticky;top:0;padding:4px 16px;background:var(--zp-primary-background);border-left:4px solid var(--primary-color);margin:4px}.container .tag-list .tag[data-v-c4b1e490]{border:2px solid var(--zp-secondary);color:var(--zp-primary);border-radius:999px;padding:4px 16px;margin:4px;display:inline-block;cursor:pointer;max-width:256px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.container .tag-list .tag.selected[data-v-c4b1e490]{color:var(--primary-color);border:2px solid var(--primary-color)}

View File

@ -1 +0,0 @@
import{ap as J,ao as X,c2 as K,bR as W,d as Y,v as Z,aX as ee,U as M,r as $,V as ae,ac as te,o as c,l as g,J as b,s as B,q as S,c as C,n as d,S as se,y as T,m as A,B as I,t as _,C as V,I as ne,c6 as oe,z,b5 as re,c7 as le,bs as D,T as N,Q as ie}from"./index-e10b03a9.js";import{I as ue,_ as ce}from"./index-8eb4bcf4.js";import"./index-9ce39af0.js";import{c as E,u as de,e as pe,M as me,r as ge}from"./db-20204a02.js";import{b as ve}from"./_baseIteratee-0f4d51fc.js";import{B as F}from"./button-955acb02.js";function fe(s,n,t,l){for(var u=-1,a=s==null?0:s.length;++u<a;){var o=s[u];n(l,o,t(o),s)}return l}function _e(s){return function(n,t,l){for(var u=-1,a=Object(n),o=l(n),v=o.length;v--;){var k=o[s?v:++u];if(t(a[k],k,a)===!1)break}return n}}var ye=_e();const he=ye;function be(s,n){return s&&he(s,n,J)}function ke(s,n){return function(t,l){if(t==null)return t;if(!X(t))return s(t,l);for(var u=t.length,a=n?u:-1,o=Object(t);(n?a--:++a<u)&&l(o[a],a,o)!==!1;);return t}}var Ce=ke(be);const Ie=Ce;function we(s,n,t,l){return Ie(s,function(u,a,o){n(l,u,t(u),o)}),l}function xe(s,n){return function(t,l){var u=K(t)?fe:we,a=n?n():{};return u(t,s,ve(l),a)}}var $e=Object.prototype,Be=$e.hasOwnProperty,Se=xe(function(s,n,t){Be.call(s,t)?s[t].push(n):W(s,t,[n])});const Te=Se,Ae={class:"container"},Oe={class:"search-bar"},Me={key:0,class:"generate-idx-hint"},Ne={class:"list-container"},Pe={class:"cat-name"},Ve=["onClick"],ze=["onClickCapture"],De=Y({__name:"TagSearch",props:{tabIdx:null,paneIdx:null},setup(s){const n=s,t=Z(),l=ee(),u=M(()=>!l.isIdle),a=$(),o=$(new Set),v=M(()=>a.value?a.value.tags.slice().sort((e,r)=>r.count-e.count):[]),k=["custom","Model","lora","pos","size","Postprocess upscaler","Postprocess upscale by","Sampler"].reduce((e,r,m)=>(e[r]=m,e),{}),U=M(()=>Object.entries(Te(v.value,e=>e.type)).sort((e,r)=>k[e[0]]-k[r[0]])),q=ae();te(async()=>{a.value=await E(),a.value.img_count&&a.value.expired&&P()});const P=async()=>{l.pushAction(async()=>{await de(),a.value=await E()})},G=()=>{t.openTagSearchMatchedImageGridInRight(n.tabIdx,q,Array.from(o.value))},O=(e,r=!1)=>(r?`[${e.type}] `:"")+(e.display_name?`${e.display_name} : ${e.name}`:e.name),w=$(!1),y=$(""),R=async()=>{var r,m,f;if(!y.value){w.value=!1;return}const e=await l.pushAction(()=>pe({tag_name:y.value})).res;e.type!=="custom"&&D.error(N("existInOtherType")),(r=a.value)!=null&&r.tags.find(h=>h.id===e.id)?D.error(N("alreadyExists")):((m=a.value)==null||m.tags.push(e),(f=t.conf)==null||f.all_custom_tags.push(e)),y.value="",w.value=!1},j=e=>{me.confirm({title:N("confirmDelete"),async onOk(){var m,f,h,x;await ge({tag_id:e});const r=((m=a.value)==null?void 0:m.tags.findIndex(i=>i.id===e))??-1;(f=a.value)==null||f.tags.splice(r,1),(x=t.conf)==null||x.all_custom_tags.splice((h=t.conf)==null?void 0:h.all_custom_tags.findIndex(i=>i.id===e),1)}})};return(e,r)=>{const m=F,f=ue,h=F,x=ce;return c(),g("div",Ae,[b("",!0),a.value?(c(),g(B,{key:1},[S("div",null,[S("div",Oe,[C(d(se),{conv:{value:i=>i.id,text:O,optionText:i=>O(i,!0)},mode:"multiple",style:{width:"100%"},options:d(v),value:Array.from(o.value),disabled:!d(v).length,placeholder:"Select tags to match images","onUpdate:value":r[0]||(r[0]=i=>o.value=new Set(i))},null,8,["conv","options","value","disabled"]),a.value.expired||!a.value.img_count?(c(),T(m,{key:0,onClick:P,loading:!d(l).isIdle,type:"primary"},{default:A(()=>[I(_(a.value.img_count===0?e.$t("generateIndexHint"):e.$t("UpdateIndex")),1)]),_:1},8,["loading"])):(c(),T(m,{key:1,type:"primary",onClick:G,loading:!d(l).isIdle,disabled:!o.value.size},{default:A(()=>[I(_(e.$t("search")),1)]),_:1},8,["loading","disabled"]))])]),d(v).filter(i=>i.type!=="custom").length?b("",!0):(c(),g("p",Me,_(e.$t("needGenerateIdx")),1)),S("div",Ne,[(c(!0),g(B,null,V(d(U),([i,L])=>(c(),g("ul",{class:"tag-list",key:i},[S("h3",Pe,_(e.$t(i)),1),(c(!0),g(B,null,V(L,(p,Q)=>(c(),g("li",{key:p.id,class:ne(["tag",{selected:o.value.has(p.id)}]),onClick:H=>o.value.has(p.id)?o.value.delete(p.id):o.value.add(p.id)},[o.value.has(p.id)?(c(),T(d(oe),{key:0})):b("",!0),I(" "+_(O(p))+" ",1),i==="custom"&&Q!==0?(c(),g("span",{key:1,class:"remove",onClickCapture:z(H=>j(p.id),["stop"])},[C(d(re))],40,ze)):b("",!0)],10,Ve))),128)),i==="custom"?(c(),g("li",{key:0,class:"tag",onClick:r[2]||(r[2]=p=>w.value=!0)},[w.value?(c(),T(x,{key:0,compact:""},{default:A(()=>[C(f,{value:y.value,"onUpdate:value":r[1]||(r[1]=p=>y.value=p),style:{width:"128px"},loading:d(u),"allow-clear":"",size:"small"},null,8,["value","loading"]),C(h,{size:"small",type:"primary",onClickCapture:z(R,["stop"]),loading:d(u)},{default:A(()=>[I(_(y.value?e.$t("submit"):e.$t("cancel")),1)]),_:1},8,["onClickCapture","loading"])]),_:1})):(c(),g(B,{key:1},[C(d(le)),I(" "+_(e.$t("add")),1)],64))])):b("",!0)]))),128))])],64)):b("",!0)])}}});const je=ie(De,[["__scopeId","data-v-c4b1e490"]]);export{je as default};

View File

@ -1 +1 @@
import{cl as A,cm as P,ce as _,c4 as b,cn as m,bj as C,ap as w,aO as h,co as E,aQ as g,cp as R,aM as x,c2 as D}from"./index-e10b03a9.js";var G=A(Object.getPrototypeOf,Object);const J=G;function y(e,n){for(var r=0;r<n.length;r++){var t=n[r];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(e,P(t.key),t)}}function W(e,n,r){return n&&y(e.prototype,n),r&&y(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function X(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}function M(e){return function(n){return n==null?void 0:n[e]}}var F=function(){return _()&&window.document.documentElement},a,Y=function(){if(!F())return!1;if(a!==void 0)return a;var n=document.createElement("div");return n.style.display="flex",n.style.flexDirection="column",n.style.rowGap="1px",n.appendChild(document.createElement("div")),n.appendChild(document.createElement("div")),document.body.appendChild(n),a=n.scrollHeight===1,document.body.removeChild(n),a},I=1,L=2;function S(e,n,r,t){var i=r.length,o=i,s=!t;if(e==null)return!o;for(e=Object(e);i--;){var f=r[i];if(s&&f[2]?f[1]!==e[f[0]]:!(f[0]in e))return!1}for(;++i<o;){f=r[i];var u=f[0],l=e[u],c=f[1];if(s&&f[2]){if(l===void 0&&!(u in e))return!1}else{var d=new b;if(t)var p=t(l,c,u,e,n,d);if(!(p===void 0?m(c,l,I|L,t,d):p))return!1}}return!0}function O(e){return e===e&&!C(e)}function U(e){for(var n=w(e),r=n.length;r--;){var t=n[r],i=e[t];n[r]=[t,i,O(i)]}return n}function v(e,n){return function(r){return r==null?!1:r[e]===n&&(n!==void 0||e in Object(r))}}function K(e){var n=U(e);return n.length==1&&n[0][2]?v(n[0][0],n[0][1]):function(r){return r===e||S(r,e,n)}}function T(e,n,r){var t=e==null?void 0:h(e,n);return t===void 0?r:t}var $=1,N=2;function q(e,n){return E(e)&&O(n)?v(g(e),n):function(r){var t=T(r,e);return t===void 0&&t===n?R(r,e):m(n,t,$|N)}}function H(e){return function(n){return h(n,e)}}function Q(e){return E(e)?M(g(e)):H(e)}function Z(e){return typeof e=="function"?e:e==null?x:typeof e=="object"?D(e)?q(e[0],e[1]):K(e):Q(e)}export{W as _,X as a,Z as b,F as c,Y as d,J as g};
import{cn as A,co as P,cg as _,c6 as b,cp as m,bj as C,ap as w,aO as g,cq as h,aQ as E,cr as R,aM as x,c4 as D}from"./index-edca4075.js";var G=A(Object.getPrototypeOf,Object);const J=G;function y(e,n){for(var r=0;r<n.length;r++){var t=n[r];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(e,P(t.key),t)}}function W(e,n,r){return n&&y(e.prototype,n),r&&y(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function X(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")}function M(e){return function(n){return n==null?void 0:n[e]}}var F=function(){return _()&&window.document.documentElement},a,Y=function(){if(!F())return!1;if(a!==void 0)return a;var n=document.createElement("div");return n.style.display="flex",n.style.flexDirection="column",n.style.rowGap="1px",n.appendChild(document.createElement("div")),n.appendChild(document.createElement("div")),document.body.appendChild(n),a=n.scrollHeight===1,document.body.removeChild(n),a},I=1,L=2;function S(e,n,r,t){var i=r.length,o=i,s=!t;if(e==null)return!o;for(e=Object(e);i--;){var f=r[i];if(s&&f[2]?f[1]!==e[f[0]]:!(f[0]in e))return!1}for(;++i<o;){f=r[i];var u=f[0],l=e[u],c=f[1];if(s&&f[2]){if(l===void 0&&!(u in e))return!1}else{var d=new b;if(t)var p=t(l,c,u,e,n,d);if(!(p===void 0?m(c,l,I|L,t,d):p))return!1}}return!0}function O(e){return e===e&&!C(e)}function U(e){for(var n=w(e),r=n.length;r--;){var t=n[r],i=e[t];n[r]=[t,i,O(i)]}return n}function v(e,n){return function(r){return r==null?!1:r[e]===n&&(n!==void 0||e in Object(r))}}function K(e){var n=U(e);return n.length==1&&n[0][2]?v(n[0][0],n[0][1]):function(r){return r===e||S(r,e,n)}}function T(e,n,r){var t=e==null?void 0:g(e,n);return t===void 0?r:t}var $=1,q=2;function N(e,n){return h(e)&&O(n)?v(E(e),n):function(r){var t=T(r,e);return t===void 0&&t===n?R(r,e):m(n,t,$|q)}}function H(e){return function(n){return g(n,e)}}function Q(e){return h(e)?M(E(e)):H(e)}function Z(e){return typeof e=="function"?e:e==null?x:typeof e=="object"?D(e)?N(e[0],e[1]):K(e):Q(e)}export{W as _,X as a,Z as b,F as c,Y as d,J as g};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{c as y,R as F,d as L,v as B,T as w,U as D,o,l,q as s,t as r,J as h,n as d,z as k,s as v,C as g,m as M,B as N,V as I,W as V,X as j,Y as H,Z as P,Q as R}from"./index-e10b03a9.js";import{B as A}from"./button-955acb02.js";var E={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M688 312v-48c0-4.4-3.6-8-8-8H296c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8zm-392 88c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H296zm376 116c-119.3 0-216 96.7-216 216s96.7 216 216 216 216-96.7 216-216-96.7-216-216-216zm107.5 323.5C750.8 868.2 712.6 884 672 884s-78.8-15.8-107.5-44.5C535.8 810.8 520 772.6 520 732s15.8-78.8 44.5-107.5C593.2 595.8 631.4 580 672 580s78.8 15.8 107.5 44.5C808.2 653.2 824 691.4 824 732s-15.8 78.8-44.5 107.5zM761 656h-44.3c-2.6 0-5 1.2-6.5 3.3l-63.5 87.8-23.1-31.9a7.92 7.92 0 00-6.5-3.3H573c-6.5 0-10.3 7.4-6.5 12.7l73.8 102.1c3.2 4.4 9.7 4.4 12.9 0l114.2-158c3.9-5.3.1-12.7-6.4-12.7zM440 852H208V148h560v344c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V108c0-17.7-14.3-32-32-32H168c-17.7 0-32 14.3-32 32v784c0 17.7 14.3 32 32 32h272c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8z"}}]},name:"file-done",theme:"outlined"};const T=E;function S(a){for(var c=1;c<arguments.length;c++){var t=arguments[c]!=null?Object(arguments[c]):{},i=Object.keys(t);typeof Object.getOwnPropertySymbols=="function"&&(i=i.concat(Object.getOwnPropertySymbols(t).filter(function(u){return Object.getOwnPropertyDescriptor(t,u).enumerable}))),i.forEach(function(u){W(a,u,t[u])})}return a}function W(a,c,t){return c in a?Object.defineProperty(a,c,{value:t,enumerable:!0,configurable:!0,writable:!0}):a[c]=t,a}var C=function(c,t){var i=S({},c,t.attrs);return y(F,S({},i,{icon:T}),null)};C.displayName="FileDoneOutlined";C.inheritAttrs=!1;const Q=C,q=a=>(H("data-v-fd61e9cd"),a=a(),P(),a),G={class:"container"},J={class:"header"},U=q(()=>s("div",{"flex-placeholder":""},null,-1)),X={class:"last-record"},Y=["onClick"],Z=q(()=>s("a",{href:"https://github.com/zanllp/sd-webui-infinite-image-browsing/issues/90",target:"_blank",class:"last-record",style:{color:"unset"}},"FAQ / 常见问题",-1)),K={class:"content"},ee={key:0,class:"quick-start"},te={key:1,class:"quick-start"},se=["onClick"],ne={class:"quick-start__text line-clamp-1"},ae={class:"quick-start"},oe=["onClick"],le={class:"quick-start__text line-clamp-1"},ce={key:2,class:"quick-start"},re=["onClick"],ie={class:"quick-start__text line-clamp-1"},ue=L({__name:"emptyStartup",props:{tabIdx:null,paneIdx:null},setup(a){const c=a,t=B(),i={local:w("local"),"tag-search":w("imgSearch"),"global-setting":w("globalSettings")},u=(e,_,f=!1)=>{let p;switch(e){case"tag-search-matched-image-grid":return;case"global-setting":case"tag-search":case"empty":p={type:e,name:i[e],key:Date.now()+I()};break;case"local":p={type:e,name:i[e],key:Date.now()+I(),path:_,walkMode:f}}const n=t.tabList[c.tabIdx];n.panes.splice(c.paneIdx,1,p),n.key=p.key},m=D(()=>{var e;return(e=t.lastTabListRecord)==null?void 0:e[1]});console.log(m.value);const O=D(()=>t.autoCompletedDirList.filter(({key:e})=>e==="outdir_txt2img_samples"||e==="outdir_img2img_samples")),$=window.parent!==window,z=()=>window.parent.open("/infinite_image_browsing"),x=()=>{V(m.value),t.tabList=m.value.tabs.map(e=>j(e,!0)),t.tabList.forEach(e=>{e.panes.forEach(_=>{typeof _.name!="string"&&(_.name="")})})};return(e,_)=>{var p;const f=A;return o(),l("div",G,[s("div",J,[s("h1",null,r(e.$t("welcome")),1),U,$?(o(),l("div",{key:0,class:"last-record",onClick:z},[s("a",null,r(e.$t("openInNewWindow")),1)])):h("",!0),s("div",X,[(p=d(m))!=null&&p.tabs.length?(o(),l("a",{key:0,onClick:k(x,["prevent"])},r(e.$t("restoreLastRecord")),9,Y)):h("",!0)]),Z]),s("div",K,[d(O).length?(o(),l("div",ee,[s("h2",null,r(e.$t("walkMode")),1),s("ul",null,[(o(!0),l(v,null,g(d(O),n=>(o(),l("li",{key:n.dir,class:"quick-start__item"},[y(f,{onClick:b=>u("local",n.dir,!0),ghost:"",type:"primary",block:""},{default:M(()=>[N(r(n.zh),1)]),_:2},1032,["onClick"])]))),128))])])):h("",!0),d(t).autoCompletedDirList.length?(o(),l("div",te,[s("h2",null,r(e.$t("launchFromQuickMove")),1),s("ul",null,[(o(!0),l(v,null,g(d(t).autoCompletedDirList,n=>(o(),l("li",{key:n.key,class:"quick-start__item",onClick:k(b=>u("local",n.dir),["prevent"])},[s("span",ne,r(n.zh),1)],8,se))),128))])])):h("",!0),s("div",ae,[s("h2",null,r(e.$t("launch")),1),s("ul",null,[(o(!0),l(v,null,g(Object.keys(i),n=>(o(),l("li",{key:n,class:"quick-start__item",onClick:k(b=>u(n),["prevent"])},[s("span",le,r(i[n]),1)],8,oe))),128))])]),d(t).recent.length?(o(),l("div",ce,[s("h2",null,r(e.$t("recent")),1),s("ul",null,[(o(!0),l(v,null,g(d(t).recent,n=>(o(),l("li",{key:n.key,class:"quick-start__item",onClick:k(b=>u("local",n.path),["prevent"])},[y(d(Q),{class:"quick-start__icon"}),s("span",ie,r(n.path),1)],8,re))),128))])])):h("",!0)])])}}});const _e=R(ue,[["__scopeId","data-v-fd61e9cd"]]);export{_e as default};
import{c as y,R as F,d as L,v as B,T as w,U as D,o,l,q as s,t as r,J as h,n as d,z as k,s as v,C as g,m as M,B as N,V as I,W as V,X as j,Y as H,Z as P,Q as R}from"./index-edca4075.js";import{B as A}from"./button-8244f7e4.js";var E={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M688 312v-48c0-4.4-3.6-8-8-8H296c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8zm-392 88c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H296zm376 116c-119.3 0-216 96.7-216 216s96.7 216 216 216 216-96.7 216-216-96.7-216-216-216zm107.5 323.5C750.8 868.2 712.6 884 672 884s-78.8-15.8-107.5-44.5C535.8 810.8 520 772.6 520 732s15.8-78.8 44.5-107.5C593.2 595.8 631.4 580 672 580s78.8 15.8 107.5 44.5C808.2 653.2 824 691.4 824 732s-15.8 78.8-44.5 107.5zM761 656h-44.3c-2.6 0-5 1.2-6.5 3.3l-63.5 87.8-23.1-31.9a7.92 7.92 0 00-6.5-3.3H573c-6.5 0-10.3 7.4-6.5 12.7l73.8 102.1c3.2 4.4 9.7 4.4 12.9 0l114.2-158c3.9-5.3.1-12.7-6.4-12.7zM440 852H208V148h560v344c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V108c0-17.7-14.3-32-32-32H168c-17.7 0-32 14.3-32 32v784c0 17.7 14.3 32 32 32h272c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8z"}}]},name:"file-done",theme:"outlined"};const T=E;function S(a){for(var c=1;c<arguments.length;c++){var t=arguments[c]!=null?Object(arguments[c]):{},i=Object.keys(t);typeof Object.getOwnPropertySymbols=="function"&&(i=i.concat(Object.getOwnPropertySymbols(t).filter(function(u){return Object.getOwnPropertyDescriptor(t,u).enumerable}))),i.forEach(function(u){W(a,u,t[u])})}return a}function W(a,c,t){return c in a?Object.defineProperty(a,c,{value:t,enumerable:!0,configurable:!0,writable:!0}):a[c]=t,a}var C=function(c,t){var i=S({},c,t.attrs);return y(F,S({},i,{icon:T}),null)};C.displayName="FileDoneOutlined";C.inheritAttrs=!1;const Q=C,q=a=>(H("data-v-fd61e9cd"),a=a(),P(),a),G={class:"container"},J={class:"header"},U=q(()=>s("div",{"flex-placeholder":""},null,-1)),X={class:"last-record"},Y=["onClick"],Z=q(()=>s("a",{href:"https://github.com/zanllp/sd-webui-infinite-image-browsing/issues/90",target:"_blank",class:"last-record",style:{color:"unset"}},"FAQ / 常见问题",-1)),K={class:"content"},ee={key:0,class:"quick-start"},te={key:1,class:"quick-start"},se=["onClick"],ne={class:"quick-start__text line-clamp-1"},ae={class:"quick-start"},oe=["onClick"],le={class:"quick-start__text line-clamp-1"},ce={key:2,class:"quick-start"},re=["onClick"],ie={class:"quick-start__text line-clamp-1"},ue=L({__name:"emptyStartup",props:{tabIdx:null,paneIdx:null},setup(a){const c=a,t=B(),i={local:w("local"),"tag-search":w("imgSearch"),"global-setting":w("globalSettings")},u=(e,_,f=!1)=>{let p;switch(e){case"tag-search-matched-image-grid":return;case"global-setting":case"tag-search":case"empty":p={type:e,name:i[e],key:Date.now()+I()};break;case"local":p={type:e,name:i[e],key:Date.now()+I(),path:_,walkMode:f}}const n=t.tabList[c.tabIdx];n.panes.splice(c.paneIdx,1,p),n.key=p.key},m=D(()=>{var e;return(e=t.lastTabListRecord)==null?void 0:e[1]});console.log(m.value);const O=D(()=>t.autoCompletedDirList.filter(({key:e})=>e==="outdir_txt2img_samples"||e==="outdir_img2img_samples")),$=window.parent!==window,z=()=>window.parent.open("/infinite_image_browsing"),x=()=>{V(m.value),t.tabList=m.value.tabs.map(e=>j(e,!0)),t.tabList.forEach(e=>{e.panes.forEach(_=>{typeof _.name!="string"&&(_.name="")})})};return(e,_)=>{var p;const f=A;return o(),l("div",G,[s("div",J,[s("h1",null,r(e.$t("welcome")),1),U,$?(o(),l("div",{key:0,class:"last-record",onClick:z},[s("a",null,r(e.$t("openInNewWindow")),1)])):h("",!0),s("div",X,[(p=d(m))!=null&&p.tabs.length?(o(),l("a",{key:0,onClick:k(x,["prevent"])},r(e.$t("restoreLastRecord")),9,Y)):h("",!0)]),Z]),s("div",K,[d(O).length?(o(),l("div",ee,[s("h2",null,r(e.$t("walkMode")),1),s("ul",null,[(o(!0),l(v,null,g(d(O),n=>(o(),l("li",{key:n.dir,class:"quick-start__item"},[y(f,{onClick:b=>u("local",n.dir,!0),ghost:"",type:"primary",block:""},{default:M(()=>[N(r(n.zh),1)]),_:2},1032,["onClick"])]))),128))])])):h("",!0),d(t).autoCompletedDirList.length?(o(),l("div",te,[s("h2",null,r(e.$t("launchFromQuickMove")),1),s("ul",null,[(o(!0),l(v,null,g(d(t).autoCompletedDirList,n=>(o(),l("li",{key:n.key,class:"quick-start__item",onClick:k(b=>u("local",n.dir),["prevent"])},[s("span",ne,r(n.zh),1)],8,se))),128))])])):h("",!0),s("div",ae,[s("h2",null,r(e.$t("launch")),1),s("ul",null,[(o(!0),l(v,null,g(Object.keys(i),n=>(o(),l("li",{key:n,class:"quick-start__item",onClick:k(b=>u(n),["prevent"])},[s("span",le,r(i[n]),1)],8,oe))),128))])]),d(t).recent.length?(o(),l("div",ce,[s("h2",null,r(e.$t("recent")),1),s("ul",null,[(o(!0),l(v,null,g(d(t).recent,n=>(o(),l("li",{key:n.key,class:"quick-start__item",onClick:k(b=>u("local",n.path),["prevent"])},[y(d(Q),{class:"quick-start__icon"}),s("span",ie,r(n.path),1)],8,re))),128))])])):h("",!0)])])}}});const _e=R(ue,[["__scopeId","data-v-fd61e9cd"]]);export{_e as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
vue/dist/assets/index-4aeb0932.js vendored Normal file
View File

@ -0,0 +1 @@
import{aN as n,cd as c}from"./index-edca4075.js";import{g as a}from"./_baseIteratee-8e08e621.js";var i="[object Object]",s=Function.prototype,p=Object.prototype,e=s.toString,f=p.hasOwnProperty,b=e.call(Object);function l(o){if(!n(o)||c(o)!=i)return!1;var r=a(o);if(r===null)return!0;var t=f.call(r,"constructor")&&r.constructor;return typeof t=="function"&&t instanceof t&&e.call(t)==b}export{l as i};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
import{aN as n,cb as c}from"./index-e10b03a9.js";import{g as a}from"./_baseIteratee-0f4d51fc.js";var i="[object Object]",s=Function.prototype,p=Object.prototype,e=s.toString,b=p.hasOwnProperty,f=e.call(Object);function l(o){if(!n(o)||c(o)!=i)return!1;var r=a(o);if(r===null)return!0;var t=b.call(r,"constructor")&&r.constructor;return typeof t=="function"&&t instanceof t&&e.call(t)==f}export{l as i};

File diff suppressed because one or more lines are too long

169
vue/dist/assets/index-edca4075.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
vue/dist/index.html vendored
View File

@ -7,8 +7,8 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-e10b03a9.js"></script>
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-55967755.css">
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-edca4075.js"></script>
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-99766f9b.css">
</head>
<body>

View File

@ -21,6 +21,12 @@ export const getDbBasicInfo = async () => {
return resp.data as DataBaseBasicInfo
}
export const getExpiredDirs = async () => {
const resp = await axiosInst.get('/db/expired_dirs')
return resp.data as Pick<DataBaseBasicInfo, 'expired' | 'expired_dirs'>
}
export const updateImageData = async () => {
await axiosInst.post('/db/update_image_data', {}, { timeout: Infinity })
}

View File

@ -124,10 +124,14 @@ const zh = {
"walk-mode-move-message": "在walk模式下仅允许使用“快速移动”移动位置",
"long_loading": "已经连续加载超过5秒如果你认为不是网络问题的话请尝试关掉VPN或者添加启动参数 --no-gradio-queue。如果还是不行请提Issue。",
"manualExitFullScreen": "你删除了最后一张图片,也许需要你手动退出全屏预览",
"copied": "已复制!"
"copied": "已复制!",
"index.expired": "索引过期,正在自动更新",
"auto.refreshed": "自动刷新完成!"
}
const en: Record<keyof typeof zh, string> = {
"auto.refreshed": "Auto refresh completed!",
copied: "Copied!",
"index.expired": "Index expired, updating automatically",
"manualExitFullScreen": "You have deleted the last image and may need to manually exit full-screen preview",
"long_loading": "Loading has been continuing for more than 5 seconds. If you don't think it's a network issue, please try turning off your VPN or adding the startup parameter --no-gradio-queue. If it still doesn't work, please submit an issue.",
"walk-mode-move-message": "Moving position is only allowed using 'Quick Move' in walk mode",

View File

@ -4,11 +4,14 @@ import { Splitpanes, Pane } from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import { useGlobalStore, type TabPane } from '@/store/useGlobalStore'
import { defineAsyncComponent, watch, ref, nextTick } from 'vue'
import { key } from '@/util'
import { uniqueId } from 'lodash-es'
import { gradioApp, key, globalEvents, asyncCheck } from '@/util'
import { debounce, uniqueId } from 'lodash-es'
import edgeTrigger from './edgeTrigger.vue'
import { t } from '@/i18n'
import { ID } from 'vue3-ts-util'
import { tryOnMounted, useDocumentVisibility, type Fn } from '@vueuse/core'
const global = useGlobalStore()
const compMap: Record<TabPane['type'], ReturnType<typeof defineAsyncComponent>> = {
local: defineAsyncComponent(() => import('@/page/fileTransfer/stackView.vue')),
@ -70,29 +73,32 @@ watch(
},
{ immediate: true, deep: true }
)
const emitReturnToIIB = debounce(() => globalEvents.emit('return-to-iib'), 100)
tryOnMounted(async () => {
const par = window.parent as Window & { get_uiCurrentTabContent (): undefined | HTMLButtonElement, onUiTabChange (cb: Fn): void }
if (!await asyncCheck(() => par?.onUiTabChange, 200, 30_000)) {
console.log('watch tab change failed');
return
}
par.onUiTabChange(() => {
const el = par.get_uiCurrentTabContent()
if (el?.id.includes("infinite-image-browsing")) {
emitReturnToIIB()
}
})
})
watch(useDocumentVisibility(), v => v && emitReturnToIIB())
</script>
<template>
<div ref="container">
<splitpanes class="default-theme">
<pane v-for="(tab, tabIdx) in global.tabList" :key="key(tab)">
<edge-trigger :tabIdx="tabIdx">
<a-tabs
type="editable-card"
v-model:activeKey="tab.key"
@edit="(key, act) => onEdit(tabIdx, key, act)"
>
<a-tab-pane
v-for="(pane, paneIdx) in tab.panes"
:key="pane.key"
:tab="pane.name"
class="pane"
>
<component
:is="compMap[pane.type]"
:tabIdx="tabIdx"
:paneIdx="paneIdx"
v-bind="pane"
/>
<a-tabs type="editable-card" v-model:activeKey="tab.key" @edit="(key, act) => onEdit(tabIdx, key, act)">
<a-tab-pane v-for="(pane, paneIdx) in tab.panes" :key="pane.key" :tab="pane.name" class="pane">
<component :is="compMap[pane.type]" :tabIdx="tabIdx" :paneIdx="paneIdx" v-bind="pane" />
</a-tab-pane>
</a-tabs>
</edge-trigger>

View File

@ -6,15 +6,17 @@ import {
type DataBaseBasicInfo,
type Tag,
addCustomTag,
removeCustomTag
removeCustomTag,
getExpiredDirs
} from '@/api/db'
import { SearchSelect } from 'vue3-ts-util'
import { CheckOutlined, PlusOutlined, CloseOutlined } from '@/icon'
import { useGlobalStore } from '@/store/useGlobalStore'
import { groupBy, uniqueId } from 'lodash-es'
import { createReactiveQueue, type Dict } from '@/util'
import { createReactiveQueue, type Dict, useGlobalEventListen } from '@/util'
import { Modal, message } from 'ant-design-vue'
import { t } from '@/i18n'
import { makeAsyncFunctionSingle } from '@/util'
const props = defineProps<{ tabIdx: number; paneIdx: number }>()
const global = useGlobalStore()
@ -51,17 +53,21 @@ onMounted(async () => {
}
})
const onUpdateBtnClick = async () => {
queue.pushAction(async () => {
await updateImageData()
info.value = await getDbBasicInfo()
})
}
const onUpdateBtnClick = makeAsyncFunctionSingle(() => queue.pushAction(async () => {
await updateImageData()
info.value = await getDbBasicInfo()
return info.value
}).res)
const query = () => {
global.openTagSearchMatchedImageGridInRight(props.tabIdx, pairid, Array.from(selectedId.value))
}
useGlobalEventListen('return-to-iib', async () => {
const res = await queue.pushAction(getExpiredDirs).res
info.value!.expired = res.expired
})
const toTagDisplayName = (v: Tag, withType = false) =>
(withType ? `[${v.type}] ` : '') + (v.display_name ? `${v.display_name} : ${v.name}` : v.name)
const addInputing = ref(false)
@ -87,7 +93,7 @@ const onAddTagBtnSubmit = async () => {
const onTagRemoveClick = (tagId: number) => {
Modal.confirm({
title: t('confirmDelete'),
async onOk() {
async onOk () {
await removeCustomTag({ tag_id: tagId })
const idx = info.value?.tags.findIndex((v) => v.id === tagId) ?? -1
info.value?.tags.splice(idx, 1)
@ -105,35 +111,18 @@ const onTagRemoveClick = (tagId: number) => {
<template v-if="info">
<div>
<div class="search-bar">
<SearchSelect
:conv="{
value: (v) => v.id,
text: toTagDisplayName,
optionText: (v) => toTagDisplayName(v, true)
}"
mode="multiple"
style="width: 100%"
:options="tags"
:value="Array.from(selectedId)"
:disabled="!tags.length"
placeholder="Select tags to match images"
@update:value="(v) => (selectedId = new Set(v))"
/>
<AButton
@click="onUpdateBtnClick"
:loading="!queue.isIdle"
type="primary"
v-if="info.expired || !info.img_count"
>
{{ info.img_count === 0 ? $t('generateIndexHint') : $t('UpdateIndex') }}</AButton
>
<AButton
v-else
type="primary"
@click="query"
:loading="!queue.isIdle"
:disabled="!selectedId.size"
>{{ $t('search') }}
<SearchSelect :conv="{
value: (v) => v.id,
text: toTagDisplayName,
optionText: (v) => toTagDisplayName(v, true)
}" mode="multiple" style="width: 100%" :options="tags" :value="Array.from(selectedId)"
:disabled="!tags.length" placeholder="Select tags to match images"
@update:value="(v) => (selectedId = new Set(v))" />
<AButton @click="onUpdateBtnClick" :loading="!queue.isIdle" type="primary"
v-if="info.expired || !info.img_count">
{{ info.img_count === 0 ? $t('generateIndexHint') : $t('UpdateIndex') }}</AButton>
<AButton v-else type="primary" @click="query" :loading="!queue.isIdle" :disabled="!selectedId.size">{{
$t('search') }}
</AButton>
</div>
</div>
@ -144,43 +133,25 @@ const onTagRemoveClick = (tagId: number) => {
<div class="list-container">
<ul class="tag-list" v-for="[name, list] in classifyTags" :key="name">
<h3 class="cat-name">{{ $t(name) }}</h3>
<li
v-for="(tag, idx) in list"
:key="tag.id"
class="tag"
:class="{ selected: selectedId.has(tag.id) }"
@click="selectedId.has(tag.id) ? selectedId.delete(tag.id) : selectedId.add(tag.id)"
>
<li v-for="(tag, idx) in list" :key="tag.id" class="tag" :class="{ selected: selectedId.has(tag.id) }"
@click="selectedId.has(tag.id) ? selectedId.delete(tag.id) : selectedId.add(tag.id)">
<CheckOutlined v-if="selectedId.has(tag.id)" />
{{ toTagDisplayName(tag) }}
<span
v-if="name === 'custom' && idx !== 0"
class="remove"
@click.capture.stop="onTagRemoveClick(tag.id)"
>
<span v-if="name === 'custom' && idx !== 0" class="remove" @click.capture.stop="onTagRemoveClick(tag.id)">
<CloseOutlined />
</span>
</li>
<li v-if="name === 'custom'" class="tag" @click="addInputing = true">
<template v-if="addInputing">
<a-input-group compact>
<a-input
v-model:value="addTagName"
style="width: 128px"
:loading="loading"
allow-clear
size="small"
/>
<a-button
size="small"
type="primary"
@click.capture.stop="onAddTagBtnSubmit"
:loading="loading"
>{{ addTagName ? $t('submit') : $t('cancel') }}</a-button
>
<a-input v-model:value="addTagName" style="width: 128px" :loading="loading" allow-clear size="small" />
<a-button size="small" type="primary" @click.capture.stop="onAddTagBtnSubmit" :loading="loading">{{
addTagName ? $t('submit') : $t('cancel') }}</a-button>
</a-input-group>
</template>
<template v-else> <PlusOutlined /> {{ $t('add') }} </template>
<template v-else>
<PlusOutlined /> {{ $t('add') }}
</template>
</li>
</ul>
</div>
@ -210,6 +181,7 @@ const onTagRemoveClick = (tagId: number) => {
padding: 4px;
position: cursor;
border-radius: 2px;
&:hover {
background-color: var(--zp-secondary-background);
}

View File

@ -12,7 +12,7 @@ import {
typedEventEmitter,
ID
} from 'vue3-ts-util'
import { createReactiveQueue, gradioApp, isImageFile, copy2clipboardI18n } from '@/util'
import { createReactiveQueue, gradioApp, isImageFile, copy2clipboardI18n, useGlobalEventListen, makeAsyncFunctionSingle } from '@/util'
import { getTargetFolderFiles, type FileNodeInfo, deleteFiles, moveFiles } from '@/api/files'
import { sortFiles, sortMethodMap, SortMethod } from './fileSort'
import { cloneDeep, debounce, last, range, uniqBy, uniqueId } from 'lodash-es'
@ -388,7 +388,7 @@ export function useLocation (props: Props) {
}
}
const refresh = async () => {
const refresh = makeAsyncFunctionSingle(async () => {
try {
np.value?.start()
if (walkModePath.value) {
@ -406,9 +406,23 @@ export function useLocation (props: Props) {
} finally {
np.value?.done()
}
}
})
useGlobalEventListen('return-to-iib',makeAsyncFunctionSingle(async () => {
if (!props.walkMode) {
try {
np.value?.start()
const { files } = await getTargetFolderFiles(
'local',
stack.value.length === 1 ? '/' : currLocation.value
)
last(stack.value)!.files = files
message.success(t('auto.refreshed'))
} finally {
np.value?.done()
}
}
}))
useEventListen.value('refresh', refresh)

View File

@ -1,9 +1,9 @@
import { t } from '@/i18n'
import { message } from 'ant-design-vue'
import { reactive } from 'vue'
import { FetchQueue, idKey, type UniqueId } from 'vue3-ts-util'
import { FetchQueue, idKey, typedEventEmitter, type UniqueId } from 'vue3-ts-util'
export function gradioApp () {
export function gradioApp (): Window & Document {
try {
return (parent.window as any).gradioApp()
} catch (error) {
@ -11,7 +11,7 @@ export function gradioApp () {
}
const elems = parent.document.getElementsByTagName('gradio-app')
const gradioShadowRoot = elems.length == 0 ? null : elems[0].shadowRoot
return gradioShadowRoot ? gradioShadowRoot : document
return (gradioShadowRoot ? gradioShadowRoot : document) as any
}
export const asyncCheck = async <T> (getter: () => T, checkSize = 100, timeout = 1000) => {
@ -70,4 +70,33 @@ export const copy2clipboardI18n = async (text: string) => {
} catch (error) {
message.error("copy failed. maybe it's non-secure environment")
}
}
export const { useEventListen: useGlobalEventListen, eventEmitter: globalEvents } = typedEventEmitter<{
'return-to-iib'(): void
}>()
type AsyncFunction<T> = (...args: any[]) => Promise<T>;
export function makeAsyncFunctionSingle<T>(fn: AsyncFunction<T>): AsyncFunction<T> {
let promise: Promise<T> | null = null;
let isExecuting = false;
return async function (this: any, ...args: any[]): Promise<T> {
if (isExecuting) {
// 如果当前有其他调用正在执行,直接返回上一个 Promise 对象
return promise as Promise<T>;
}
isExecuting = true;
try {
// 执行异步函数并等待结果
promise = fn.apply(this, args);
const result = await promise;
return result;
} finally {
isExecuting = false;
}
};
}