Implemented support for batch tag addition and removal
parent
3feff6a1de
commit
9634d9f20d
|
|
@ -12,7 +12,7 @@ Promise.resolve().then(async () => {
|
|||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Infinite Image Browsing</title>
|
||||
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-3ef1f0fd.js"></script>
|
||||
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-0eb75c61.js"></script>
|
||||
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-896679b3.css">
|
||||
</head>
|
||||
|
||||
|
|
|
|||
|
|
@ -684,6 +684,50 @@ def infinite_image_browsing_api(app: FastAPI, **kwargs):
|
|||
conn.commit()
|
||||
return {"is_remove": is_remove}
|
||||
|
||||
class BatchUpdateImageReq(BaseModel):
|
||||
img_paths: List[str]
|
||||
action: str
|
||||
tag_id: int
|
||||
|
||||
@app.post(
|
||||
db_pre + "/batch_update_image_tag",
|
||||
dependencies=[Depends(verify_secret), Depends(write_permission_required)],
|
||||
)
|
||||
async def batch_update_image_tag(req: BatchUpdateImageReq):
|
||||
assert req.action in ["add", "remove"]
|
||||
conn = DataBase.get_conn()
|
||||
paths: List[str] = seq(req.img_paths).map(os.path.normpath).to_list()
|
||||
update_extra_paths(conn)
|
||||
for path in paths:
|
||||
if not is_path_under_parents(path):
|
||||
raise HTTPException(
|
||||
400,
|
||||
'当前文件不在搜索路径内,你可以将它添加到扫描路径再尝试。在右上角的"更多"里面'
|
||||
if locale == "zh"
|
||||
else 'The current file is not within the scan path. You can add it to the scan path and try again. In the top right corner, click on "More".',
|
||||
)
|
||||
img = DbImg.get(conn, path)
|
||||
if not img:
|
||||
if DbImg.count(conn):
|
||||
update_image_data([os.path.dirname(path)])
|
||||
img = DbImg.get(conn, path)
|
||||
else:
|
||||
raise HTTPException(
|
||||
400,
|
||||
"你需要先通过图像搜索页生成索引"
|
||||
if locale == "zh"
|
||||
else "You need to generate an index through the image search page first.",
|
||||
)
|
||||
try:
|
||||
for path in paths:
|
||||
img = DbImg.get(conn, path)
|
||||
if req.action == "add":
|
||||
ImageTag(img.id, req.tag_id).save_or_ignore(conn)
|
||||
else:
|
||||
ImageTag.remove(conn, img.id, req.tag_id)
|
||||
finally:
|
||||
conn.commit()
|
||||
|
||||
class AddCustomTagReq(BaseModel):
|
||||
tag_name: str
|
||||
|
||||
|
|
|
|||
|
|
@ -340,6 +340,14 @@ class ImageTag:
|
|||
"INSERT INTO image_tag (image_id, tag_id) VALUES (?, ?)",
|
||||
(self.image_id, self.tag_id),
|
||||
)
|
||||
|
||||
|
||||
def save_or_ignore(self, conn):
|
||||
with closing(conn.cursor()) as cur:
|
||||
cur.execute(
|
||||
"INSERT OR IGNORE INTO image_tag (image_id, tag_id) VALUES (?, ?)",
|
||||
(self.image_id, self.tag_id),
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_tags_for_image(
|
||||
|
|
|
|||
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 +1 @@
|
|||
import{d as t,o as a,m as r,c1 as n}from"./index-3ef1f0fd.js";const p=t({__name:"ImgSliPagePane",props:{paneIdx:{},tabIdx:{},left:{},right:{}},setup(o){return(e,s)=>(a(),r(n,{left:e.left,right:e.right},null,8,["left","right"]))}});export{p as default};
|
||||
import{d as t,o as a,m as r,c1 as n}from"./index-0eb75c61.js";const p=t({__name:"ImgSliPagePane",props:{paneIdx:{},tabIdx:{},left:{},right:{}},setup(o){return(e,s)=>(a(),r(n,{left:e.left,right:e.right},null,8,["left","right"]))}});export{p as default};
|
||||
|
|
@ -1 +1 @@
|
|||
import{d as X,l as j,ax as H,o as r,y as g,c as l,n as o,r as e,s as S,p as c,t as J,v as m,x as T,m as V,L as K,C as v,N as $,Q as Y,R as Z,V as ee,X as te}from"./index-3ef1f0fd.js";import{L as se,R as ie,f as ne,S as le}from"./fullScreenContextMenu-26d18b39.js";import{g as oe,F as ae}from"./FileItem-e04c8436.js";import{g as re}from"./db-e68559e0.js";import{c as de,u as ce}from"./hook-7545c20e.js";import{o as me}from"./functionalCallableComp-9eb5277a.js";const ue={class:"hint"},pe={key:1},ge={class:"no-res-hint"},ve={class:"hint"},fe={key:2,class:"preview-switch"},Ie=X({__name:"MatchedImageGrid",props:{tabIdx:{},paneIdx:{},selectedTagIds:{},id:{}},setup(D){const f=D,u=de(s=>re(f.selectedTagIds,s)),{queue:F,images:n,onContextMenuClickU:I,stackViewEl:z,previewIdx:a,previewing:k,onPreviewVisibleChange:B,previewImgMove:w,canPreview:C,itemSize:x,gridItems:R,showGenInfo:d,imageGenInfo:_,q:N,multiSelectedIdxs:G,onFileItemClick:A,scroller:h,showMenuIdx:p,onFileDragStart:E,onFileDragEnd:P,cellWidth:U,onScroll:y}=ce(u);return j(()=>f.selectedTagIds,async()=>{var s;await u.reset(),await H(),(s=h.value)==null||s.scrollToItem(0),y()},{immediate:!0}),(s,t)=>{const L=Y,O=Z,q=ee,Q=le;return r(),g("div",{class:"container",ref_key:"stackViewEl",ref:z},[l(Q,{size:"large",spinning:!e(F).isIdle},{default:o(()=>{var b;return[l(O,{visible:e(d),"onUpdate:visible":t[1]||(t[1]=i=>S(d)?d.value=i:null),width:"70vw","mask-closable":"",onOk:t[2]||(t[2]=i=>d.value=!1)},{cancelText:o(()=>[]),default:o(()=>[l(L,{active:"",loading:!e(N).isIdle},{default:o(()=>[c("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:t[0]||(t[0]=i=>e(J)(e(_)))},[c("div",ue,m(s.$t("doubleClickToCopy")),1),T(" "+m(e(_)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),(b=e(n))!=null&&b.length?(r(),V(e(oe),{key:0,ref_key:"scroller",ref:h,class:"file-list",items:e(n),"item-size":e(x).first,"key-field":"fullpath","item-secondary-size":e(x).second,gridItems:e(R),onScroll:e(y)},{default:o(({item:i,index:M})=>[l(ae,{idx:M,file:i,"cell-width":e(U),"show-menu-idx":e(p),"onUpdate:showMenuIdx":t[3]||(t[3]=W=>S(p)?p.value=W:null),onDragstart:e(E),onDragend:e(P),onFileItemClick:e(A),"full-screen-preview-image-url":e(n)[e(a)]?e(K)(e(n)[e(a)]):"",selected:e(G).includes(M),onContextMenuClick:e(I),onPreviewVisibleChange:e(B)},null,8,["idx","file","cell-width","show-menu-idx","onDragstart","onDragend","onFileItemClick","full-screen-preview-image-url","selected","onContextMenuClick","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems","onScroll"])):e(u).load&&s.selectedTagIds.and_tags.length===1?(r(),g("div",pe,[c("div",ge,[c("p",ve,m(s.$t("tagSearchNoResultsMessage")),1),l(q,{onClick:t[4]||(t[4]=i=>e(me)()),type:"primary"},{default:o(()=>[T(m(s.$t("rebuildImageIndex")),1)]),_:1})])])):v("",!0),e(k)?(r(),g("div",fe,[l(e(se),{onClick:t[5]||(t[5]=i=>e(w)("prev")),class:$({disable:!e(C)("prev")})},null,8,["class"]),l(e(ie),{onClick:t[6]||(t[6]=i=>e(w)("next")),class:$({disable:!e(C)("next")})},null,8,["class"])])):v("",!0)]}),_:1},8,["spinning"]),e(k)&&e(n)&&e(n)[e(a)]?(r(),V(ne,{key:0,file:e(n)[e(a)],idx:e(a),onContextMenuClick:e(I)},null,8,["file","idx","onContextMenuClick"])):v("",!0)],512)}}});const ye=te(Ie,[["__scopeId","data-v-e67ecd35"]]);export{ye as default};
|
||||
import{d as X,l as j,ax as H,o as r,y as g,c as l,n as o,r as e,s as S,p as c,t as J,v as m,x as T,m as V,L as K,C as v,N as $,Q as Y,R as Z,V as ee,X as te}from"./index-0eb75c61.js";import{L as se,R as ie,f as ne,S as le}from"./fullScreenContextMenu-13ffe73e.js";import{g as oe,F as ae}from"./FileItem-4396e62f.js";import{g as re}from"./db-aff0e762.js";import{c as de,u as ce}from"./hook-94549014.js";import{o as me}from"./functionalCallableComp-426c49a7.js";const ue={class:"hint"},pe={key:1},ge={class:"no-res-hint"},ve={class:"hint"},fe={key:2,class:"preview-switch"},Ie=X({__name:"MatchedImageGrid",props:{tabIdx:{},paneIdx:{},selectedTagIds:{},id:{}},setup(D){const f=D,u=de(s=>re(f.selectedTagIds,s)),{queue:F,images:n,onContextMenuClickU:I,stackViewEl:z,previewIdx:a,previewing:k,onPreviewVisibleChange:B,previewImgMove:w,canPreview:C,itemSize:x,gridItems:R,showGenInfo:d,imageGenInfo:_,q:N,multiSelectedIdxs:G,onFileItemClick:A,scroller:h,showMenuIdx:p,onFileDragStart:E,onFileDragEnd:P,cellWidth:U,onScroll:y}=ce(u);return j(()=>f.selectedTagIds,async()=>{var s;await u.reset(),await H(),(s=h.value)==null||s.scrollToItem(0),y()},{immediate:!0}),(s,t)=>{const L=Y,O=Z,q=ee,Q=le;return r(),g("div",{class:"container",ref_key:"stackViewEl",ref:z},[l(Q,{size:"large",spinning:!e(F).isIdle},{default:o(()=>{var b;return[l(O,{visible:e(d),"onUpdate:visible":t[1]||(t[1]=i=>S(d)?d.value=i:null),width:"70vw","mask-closable":"",onOk:t[2]||(t[2]=i=>d.value=!1)},{cancelText:o(()=>[]),default:o(()=>[l(L,{active:"",loading:!e(N).isIdle},{default:o(()=>[c("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:t[0]||(t[0]=i=>e(J)(e(_)))},[c("div",ue,m(s.$t("doubleClickToCopy")),1),T(" "+m(e(_)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),(b=e(n))!=null&&b.length?(r(),V(e(oe),{key:0,ref_key:"scroller",ref:h,class:"file-list",items:e(n),"item-size":e(x).first,"key-field":"fullpath","item-secondary-size":e(x).second,gridItems:e(R),onScroll:e(y)},{default:o(({item:i,index:M})=>[l(ae,{idx:M,file:i,"cell-width":e(U),"show-menu-idx":e(p),"onUpdate:showMenuIdx":t[3]||(t[3]=W=>S(p)?p.value=W:null),onDragstart:e(E),onDragend:e(P),onFileItemClick:e(A),"full-screen-preview-image-url":e(n)[e(a)]?e(K)(e(n)[e(a)]):"",selected:e(G).includes(M),onContextMenuClick:e(I),onPreviewVisibleChange:e(B)},null,8,["idx","file","cell-width","show-menu-idx","onDragstart","onDragend","onFileItemClick","full-screen-preview-image-url","selected","onContextMenuClick","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems","onScroll"])):e(u).load&&s.selectedTagIds.and_tags.length===1?(r(),g("div",pe,[c("div",ge,[c("p",ve,m(s.$t("tagSearchNoResultsMessage")),1),l(q,{onClick:t[4]||(t[4]=i=>e(me)()),type:"primary"},{default:o(()=>[T(m(s.$t("rebuildImageIndex")),1)]),_:1})])])):v("",!0),e(k)?(r(),g("div",fe,[l(e(se),{onClick:t[5]||(t[5]=i=>e(w)("prev")),class:$({disable:!e(C)("prev")})},null,8,["class"]),l(e(ie),{onClick:t[6]||(t[6]=i=>e(w)("next")),class:$({disable:!e(C)("next")})},null,8,["class"])])):v("",!0)]}),_:1},8,["spinning"]),e(k)&&e(n)&&e(n)[e(a)]?(r(),V(ne,{key:0,file:e(n)[e(a)],idx:e(a),onContextMenuClick:e(I)},null,8,["file","idx","onContextMenuClick"])):v("",!0)],512)}}});const ye=te(Ie,[["__scopeId","data-v-e67ecd35"]]);export{ye as default};
|
||||
|
|
@ -1 +1 @@
|
|||
import{d as se,$ as x,aw as ne,bQ as ae,bP as U,o as i,y as b,q as A,c as o,r as e,bT as le,p as m,N as y,m as g,n as r,x as I,v as f,C as w,s as T,t as ie,L as oe,ax as re,al as de,ai as ue,U as ce,V as pe,Q as ve,R as me,X as ge}from"./index-3ef1f0fd.js";import{L as fe,R as we,f as ke,S as xe}from"./fullScreenContextMenu-26d18b39.js";/* empty css */import{g as be,F as ye}from"./FileItem-e04c8436.js";import{b as K,c as Ie,f as N,u as Ce}from"./db-e68559e0.js";import{c as he,u as _e}from"./hook-7545c20e.js";import"./functionalCallableComp-9eb5277a.js";const Se="/infinite_image_browsing/fe-static/assets/regex-a447f877.svg",Me=["src"],$e={class:"hint"},ze={key:1,class:"preview-switch"},De=se({__name:"SubstrSearch",setup(Be){const p=x(!1),u=x(""),C=he(n=>p.value?N("",n,u.value):N(u.value,n)),{queue:d,images:l,onContextMenuClickU:h,stackViewEl:P,previewIdx:c,previewing:_,onPreviewVisibleChange:q,previewImgMove:S,canPreview:M,itemSize:$,gridItems:L,showGenInfo:v,imageGenInfo:z,q:G,multiSelectedIdxs:O,onFileItemClick:Q,scroller:D,showMenuIdx:k,onFileDragStart:H,onFileDragEnd:W,cellWidth:X,onScroll:B}=_e(C),s=x();ne(async()=>{s.value=await K(),s.value.img_count&&s.value.expired&&V()});const V=ae(()=>d.pushAction(async()=>(await Ce(),s.value=await K(),s.value)).res),E=async()=>{await C.reset({refetch:!0}),await re(),B(),D.value.scrollToItem(0),l.value.length||de.info(ue("fuzzy-search-noResults"))};U("returnToIIB",async()=>{const n=await d.pushAction(Ie).res;s.value.expired=n.expired}),U("searchIndexExpired",()=>s.value&&(s.value.expired=!0));const j=()=>{p.value=!p.value};return(n,t)=>{const J=ce,F=pe,Y=ve,Z=me,ee=xe;return i(),b("div",{class:"container",ref_key:"stackViewEl",ref:P},[s.value?(i(),b("div",{key:0,class:"search-bar",onKeydown:t[2]||(t[2]=A(()=>{},["stop"]))},[o(J,{value:u.value,"onUpdate:value":t[0]||(t[0]=a=>u.value=a),placeholder:n.$t("fuzzy-search-placeholder")+" "+n.$t("regexSearchEnabledHint"),disabled:!e(d).isIdle,onKeydown:le(E,["enter"]),"allow-clear":""},null,8,["value","placeholder","disabled","onKeydown"]),m("div",{class:y(["regex-icon",{selected:p.value}]),onKeydown:t[1]||(t[1]=A(()=>{},["stop"])),onClick:j,title:"Use Regular Expression"},[m("img",{src:e(Se)},null,8,Me)],34),s.value.expired||!s.value.img_count?(i(),g(F,{key:0,onClick:e(V),loading:!e(d).isIdle,type:"primary"},{default:r(()=>[I(f(s.value.img_count===0?n.$t("generateIndexHint"):n.$t("UpdateIndex")),1)]),_:1},8,["onClick","loading"])):(i(),g(F,{key:1,type:"primary",onClick:E,loading:!e(d).isIdle,disabled:!u.value},{default:r(()=>[I(f(n.$t("search")),1)]),_:1},8,["loading","disabled"]))],32)):w("",!0),o(ee,{size:"large",spinning:!e(d).isIdle},{default:r(()=>[o(Z,{visible:e(v),"onUpdate:visible":t[4]||(t[4]=a=>T(v)?v.value=a:null),width:"70vw","mask-closable":"",onOk:t[5]||(t[5]=a=>v.value=!1)},{cancelText:r(()=>[]),default:r(()=>[o(Y,{active:"",loading:!e(G).isIdle},{default:r(()=>[m("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:t[3]||(t[3]=a=>e(ie)(e(z)))},[m("div",$e,f(n.$t("doubleClickToCopy")),1),I(" "+f(e(z)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),e(l)?(i(),g(e(be),{key:0,ref_key:"scroller",ref:D,class:"file-list",items:e(l),"item-size":e($).first,"key-field":"fullpath","item-secondary-size":e($).second,gridItems:e(L),onScroll:e(B)},{default:r(({item:a,index:R})=>[o(ye,{idx:R,file:a,"show-menu-idx":e(k),"onUpdate:showMenuIdx":t[6]||(t[6]=te=>T(k)?k.value=te:null),onFileItemClick:e(Q),"full-screen-preview-image-url":e(l)[e(c)]?e(oe)(e(l)[e(c)]):"","cell-width":e(X),selected:e(O).includes(R),onContextMenuClick:e(h),onDragstart:e(H),onDragend:e(W),onPreviewVisibleChange:e(q)},null,8,["idx","file","show-menu-idx","onFileItemClick","full-screen-preview-image-url","cell-width","selected","onContextMenuClick","onDragstart","onDragend","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems","onScroll"])):w("",!0),e(_)?(i(),b("div",ze,[o(e(fe),{onClick:t[7]||(t[7]=a=>e(S)("prev")),class:y({disable:!e(M)("prev")})},null,8,["class"]),o(e(we),{onClick:t[8]||(t[8]=a=>e(S)("next")),class:y({disable:!e(M)("next")})},null,8,["class"])])):w("",!0)]),_:1},8,["spinning"]),e(_)&&e(l)&&e(l)[e(c)]?(i(),g(ke,{key:1,file:e(l)[e(c)],idx:e(c),onContextMenuClick:e(h)},null,8,["file","idx","onContextMenuClick"])):w("",!0)],512)}}});const Ke=ge(De,[["__scopeId","data-v-a1cb02be"]]);export{Ke as default};
|
||||
import{d as se,$ as x,aw as ne,bQ as ae,bP as U,o as i,y as b,q as A,c as o,r as e,bT as le,p as m,N as y,m as g,n as r,x as I,v as f,C as w,s as T,t as ie,L as oe,ax as re,al as de,ai as ue,U as ce,V as pe,Q as ve,R as me,X as ge}from"./index-0eb75c61.js";import{L as fe,R as we,f as ke,S as xe}from"./fullScreenContextMenu-13ffe73e.js";/* empty css */import{g as be,F as ye}from"./FileItem-4396e62f.js";import{b as K,c as Ie,f as N,u as Ce}from"./db-aff0e762.js";import{c as he,u as _e}from"./hook-94549014.js";import"./functionalCallableComp-426c49a7.js";const Se="/infinite_image_browsing/fe-static/assets/regex-a447f877.svg",Me=["src"],$e={class:"hint"},ze={key:1,class:"preview-switch"},De=se({__name:"SubstrSearch",setup(Be){const p=x(!1),u=x(""),C=he(n=>p.value?N("",n,u.value):N(u.value,n)),{queue:d,images:l,onContextMenuClickU:h,stackViewEl:P,previewIdx:c,previewing:_,onPreviewVisibleChange:q,previewImgMove:S,canPreview:M,itemSize:$,gridItems:L,showGenInfo:v,imageGenInfo:z,q:G,multiSelectedIdxs:O,onFileItemClick:Q,scroller:D,showMenuIdx:k,onFileDragStart:H,onFileDragEnd:W,cellWidth:X,onScroll:B}=_e(C),s=x();ne(async()=>{s.value=await K(),s.value.img_count&&s.value.expired&&V()});const V=ae(()=>d.pushAction(async()=>(await Ce(),s.value=await K(),s.value)).res),E=async()=>{await C.reset({refetch:!0}),await re(),B(),D.value.scrollToItem(0),l.value.length||de.info(ue("fuzzy-search-noResults"))};U("returnToIIB",async()=>{const n=await d.pushAction(Ie).res;s.value.expired=n.expired}),U("searchIndexExpired",()=>s.value&&(s.value.expired=!0));const j=()=>{p.value=!p.value};return(n,t)=>{const J=ce,F=pe,Y=ve,Z=me,ee=xe;return i(),b("div",{class:"container",ref_key:"stackViewEl",ref:P},[s.value?(i(),b("div",{key:0,class:"search-bar",onKeydown:t[2]||(t[2]=A(()=>{},["stop"]))},[o(J,{value:u.value,"onUpdate:value":t[0]||(t[0]=a=>u.value=a),placeholder:n.$t("fuzzy-search-placeholder")+" "+n.$t("regexSearchEnabledHint"),disabled:!e(d).isIdle,onKeydown:le(E,["enter"]),"allow-clear":""},null,8,["value","placeholder","disabled","onKeydown"]),m("div",{class:y(["regex-icon",{selected:p.value}]),onKeydown:t[1]||(t[1]=A(()=>{},["stop"])),onClick:j,title:"Use Regular Expression"},[m("img",{src:e(Se)},null,8,Me)],34),s.value.expired||!s.value.img_count?(i(),g(F,{key:0,onClick:e(V),loading:!e(d).isIdle,type:"primary"},{default:r(()=>[I(f(s.value.img_count===0?n.$t("generateIndexHint"):n.$t("UpdateIndex")),1)]),_:1},8,["onClick","loading"])):(i(),g(F,{key:1,type:"primary",onClick:E,loading:!e(d).isIdle,disabled:!u.value},{default:r(()=>[I(f(n.$t("search")),1)]),_:1},8,["loading","disabled"]))],32)):w("",!0),o(ee,{size:"large",spinning:!e(d).isIdle},{default:r(()=>[o(Z,{visible:e(v),"onUpdate:visible":t[4]||(t[4]=a=>T(v)?v.value=a:null),width:"70vw","mask-closable":"",onOk:t[5]||(t[5]=a=>v.value=!1)},{cancelText:r(()=>[]),default:r(()=>[o(Y,{active:"",loading:!e(G).isIdle},{default:r(()=>[m("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:t[3]||(t[3]=a=>e(ie)(e(z)))},[m("div",$e,f(n.$t("doubleClickToCopy")),1),I(" "+f(e(z)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),e(l)?(i(),g(e(be),{key:0,ref_key:"scroller",ref:D,class:"file-list",items:e(l),"item-size":e($).first,"key-field":"fullpath","item-secondary-size":e($).second,gridItems:e(L),onScroll:e(B)},{default:r(({item:a,index:R})=>[o(ye,{idx:R,file:a,"show-menu-idx":e(k),"onUpdate:showMenuIdx":t[6]||(t[6]=te=>T(k)?k.value=te:null),onFileItemClick:e(Q),"full-screen-preview-image-url":e(l)[e(c)]?e(oe)(e(l)[e(c)]):"","cell-width":e(X),selected:e(O).includes(R),onContextMenuClick:e(h),onDragstart:e(H),onDragend:e(W),onPreviewVisibleChange:e(q)},null,8,["idx","file","show-menu-idx","onFileItemClick","full-screen-preview-image-url","cell-width","selected","onContextMenuClick","onDragstart","onDragend","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems","onScroll"])):w("",!0),e(_)?(i(),b("div",ze,[o(e(fe),{onClick:t[7]||(t[7]=a=>e(S)("prev")),class:y({disable:!e(M)("prev")})},null,8,["class"]),o(e(we),{onClick:t[8]||(t[8]=a=>e(S)("next")),class:y({disable:!e(M)("next")})},null,8,["class"])])):w("",!0)]),_:1},8,["spinning"]),e(_)&&e(l)&&e(l)[e(c)]?(i(),g(ke,{key:1,file:e(l)[e(c)],idx:e(c),onContextMenuClick:e(h)},null,8,["file","idx","onContextMenuClick"])):w("",!0)],512)}}});const Ke=ge(De,[["__scopeId","data-v-a1cb02be"]]);export{Ke as default};
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
import{d as v,c2 as C,bO as I,o as i,y as _,p as f,c,n as r,x as h,v as d,r as e,m as F,L as x,c3 as z,c4 as B,V as $,X as R}from"./index-3ef1f0fd.js";import{u as S,b as V,k as E,F as A,g as L}from"./FileItem-e04c8436.js";import"./functionalCallableComp-9eb5277a.js";import"./db-e68559e0.js";const T={class:"actions-panel actions"},N={key:0,class:"file-list"},U={class:"hint"},H=v({__name:"batchDownload",props:{tabIdx:{},paneIdx:{},id:{}},setup(O){const{stackViewEl:w}=S().toRefs(),{itemSize:p,gridItems:k,cellWidth:b}=V(),l=E(),{selectdFiles:n}=C(l),u=I(),y=async t=>{const s=z(t);s&&l.addFiles(s.nodes)},D=async()=>{u.pushAction(async()=>{const t=await B.value.post("/zip",{paths:n.value.map(o=>o.fullpath)},{responseType:"blob"}),s=window.URL.createObjectURL(new Blob([t.data])),a=document.createElement("a");a.href=s,a.setAttribute("download",`iib_${new Date().toLocaleString()}.zip`),document.body.appendChild(a),a.click()})},g=t=>{n.value.splice(t,1)};return(t,s)=>{const a=$;return i(),_("div",{class:"container",ref_key:"stackViewEl",ref:w,onDrop:y},[f("div",T,[c(a,{onClick:s[0]||(s[0]=o=>e(l).selectdFiles=[])},{default:r(()=>[h(d(t.$t("clear")),1)]),_:1}),c(a,{onClick:D,type:"primary",loading:!e(u).isIdle},{default:r(()=>[h(d(t.$t("zipDownload")),1)]),_:1},8,["loading"])]),e(n).length?(i(),F(e(L),{key:1,ref:"scroller",class:"file-list",items:e(n).slice(),"item-size":e(p).first,"key-field":"fullpath","item-secondary-size":e(p).second,gridItems:e(k)},{default:r(({item:o,index:m})=>[c(A,{idx:m,file:o,"cell-width":e(b),"enable-close-icon":"",onCloseIconClick:j=>g(m),"full-screen-preview-image-url":e(x)(o),"enable-right-click-menu":!1},null,8,["idx","file","cell-width","onCloseIconClick","full-screen-preview-image-url"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):(i(),_("div",N,[f("p",U,d(t.$t("batchDownloaDDragAndDropHint")),1)]))],544)}}});const G=R(H,[["__scopeId","data-v-aab31da2"]]);export{G as default};
|
||||
import{d as v,c2 as C,bO as I,o as i,y as _,p as f,c,n as r,x as h,v as d,r as e,m as F,L as x,c3 as z,c4 as B,V as $,X as R}from"./index-0eb75c61.js";import{u as S,b as V,k as E,F as A,g as L}from"./FileItem-4396e62f.js";import"./functionalCallableComp-426c49a7.js";import"./db-aff0e762.js";const T={class:"actions-panel actions"},N={key:0,class:"file-list"},U={class:"hint"},H=v({__name:"batchDownload",props:{tabIdx:{},paneIdx:{},id:{}},setup(O){const{stackViewEl:w}=S().toRefs(),{itemSize:p,gridItems:k,cellWidth:b}=V(),l=E(),{selectdFiles:n}=C(l),u=I(),y=async t=>{const s=z(t);s&&l.addFiles(s.nodes)},D=async()=>{u.pushAction(async()=>{const t=await B.value.post("/zip",{paths:n.value.map(o=>o.fullpath)},{responseType:"blob"}),s=window.URL.createObjectURL(new Blob([t.data])),a=document.createElement("a");a.href=s,a.setAttribute("download",`iib_${new Date().toLocaleString()}.zip`),document.body.appendChild(a),a.click()})},g=t=>{n.value.splice(t,1)};return(t,s)=>{const a=$;return i(),_("div",{class:"container",ref_key:"stackViewEl",ref:w,onDrop:y},[f("div",T,[c(a,{onClick:s[0]||(s[0]=o=>e(l).selectdFiles=[])},{default:r(()=>[h(d(t.$t("clear")),1)]),_:1}),c(a,{onClick:D,type:"primary",loading:!e(u).isIdle},{default:r(()=>[h(d(t.$t("zipDownload")),1)]),_:1},8,["loading"])]),e(n).length?(i(),F(e(L),{key:1,ref:"scroller",class:"file-list",items:e(n).slice(),"item-size":e(p).first,"key-field":"fullpath","item-secondary-size":e(p).second,gridItems:e(k)},{default:r(({item:o,index:m})=>[c(A,{idx:m,file:o,"cell-width":e(b),"enable-close-icon":"",onCloseIconClick:j=>g(m),"full-screen-preview-image-url":e(x)(o),"enable-right-click-menu":!1},null,8,["idx","file","cell-width","onCloseIconClick","full-screen-preview-image-url"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):(i(),_("div",N,[f("p",U,d(t.$t("batchDownloaDDragAndDropHint")),1)]))],544)}}});const G=R(H,[["__scopeId","data-v-aab31da2"]]);export{G as default};
|
||||
|
|
@ -0,0 +1 @@
|
|||
import{c4 as t}from"./index-0eb75c61.js";const c=async()=>(await t.value.get("/db/basic_info")).data,d=async()=>(await t.value.get("/db/expired_dirs")).data,g=async()=>{await t.value.post("/db/update_image_data",{},{timeout:1/0})},u=async(a,s)=>(await t.value.post("/db/match_images_by_tags",{...a,cursor:s})).data,p=async a=>(await t.value.post("/db/add_custom_tag",a)).data,i=async a=>(await t.value.post("/db/toggle_custom_tag_to_img",a)).data,m=async a=>{await t.value.post("/db/remove_custom_tag",a)},b=async(a,s,e)=>(await t.value.get("/db/search_by_substr",{params:{substr:a,cursor:s,regexp:e}})).data,r="/db/extra_paths",_=async a=>{await t.value.post(r,a)},l=async a=>{await t.value.delete(r,{data:a})},y=async a=>(await t.value.post("/db/get_image_tags",{paths:a})).data,v=()=>t.value.post("/db/rebuild_index"),h=a=>t.value.post("/db/batch_update_image_tag",a);export{_ as a,c as b,d as c,p as d,m as e,b as f,u as g,y as h,h as i,v as j,l as r,i as t,g as u};
|
||||
|
|
@ -1 +0,0 @@
|
|||
import{c4 as t}from"./index-3ef1f0fd.js";const c=async()=>(await t.value.get("/db/basic_info")).data,d=async()=>(await t.value.get("/db/expired_dirs")).data,u=async()=>{await t.value.post("/db/update_image_data",{},{timeout:1/0})},g=async(a,s)=>(await t.value.post("/db/match_images_by_tags",{...a,cursor:s})).data,i=async a=>(await t.value.post("/db/add_custom_tag",a)).data,p=async a=>(await t.value.post("/db/toggle_custom_tag_to_img",a)).data,m=async a=>{await t.value.post("/db/remove_custom_tag",a)},b=async(a,s,e)=>(await t.value.get("/db/search_by_substr",{params:{substr:a,cursor:s,regexp:e}})).data,r="/db/extra_paths",_=async a=>{await t.value.post(r,a)},l=async a=>{await t.value.delete(r,{data:a})},y=async a=>(await t.value.post("/db/get_image_tags",{paths:a})).data,v=()=>t.value.post("/db/rebuild_index");export{_ as a,c as b,d as c,i as d,m as e,b as f,g,y as h,v as i,l as r,p as t,u};
|
||||
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 +1 @@
|
|||
import{bn as A,$ as g,bU as q,bV as x,ar as k,ao as D,bO as z,bd as G}from"./index-3ef1f0fd.js";import{u as N,b as O,f as Q,c as U,d as j,e as H,h as L}from"./FileItem-e04c8436.js";let T=0;const V=()=>++T,W=(r,l,{dataUpdateStrategy:c="replace"}={})=>{const s=A([""]),u=g(!1),t=g(),a=g(!1);let f=g(-1);const v=new Set,b=e=>{var n;c==="replace"?t.value=e:c==="merge"&&(k((Array.isArray(t.value)||typeof t.value>"u")&&Array.isArray(e),"数据更新策略为合并时仅可用于值为数组的情况"),t.value=[...(n=t==null?void 0:t.value)!==null&&n!==void 0?n:[],...e])},d=e=>x(void 0,void 0,void 0,function*(){if(a.value||u.value&&typeof e>"u")return!1;a.value=!0;const n=V();f.value=n;try{let o;if(typeof e=="number"){if(o=s[e],typeof o!="string")return!1}else o=s[s.length-1];const p=yield r(o);if(v.has(n))return v.delete(n),!1;b(l(p));const i=p.cursor;if((e===s.length-1||typeof e!="number")&&(u.value=!i.has_next,i.has_next)){const I=i.next_cursor||i.next;k(typeof I=="string"),s.push(I)}}finally{f.value===n&&(a.value=!1)}return!0}),h=()=>{v.add(f.value),a.value=!1},w=(e=!1)=>x(void 0,void 0,void 0,function*(){const{refetch:n,force:o}=typeof e=="object"?e:{refetch:e};o&&h(),k(!a.value),s.splice(0,s.length,""),a.value=!1,t.value=void 0,u.value=!1,n&&(yield d())}),m=()=>({next:()=>x(void 0,void 0,void 0,function*(){if(a.value)throw new Error("不允许同时迭代");return{done:!(yield d()),value:t.value}})});return q({abort:h,load:u,next:d,res:t,loading:a,cursorStack:s,reset:w,[Symbol.asyncIterator]:m,iter:{[Symbol.asyncIterator]:m}})},J=r=>A(W(r,l=>l.files,{dataUpdateStrategy:"merge"})),K=r=>{const l=A(new Set),c=D(()=>(r.res??[]).filter(y=>!l.has(y.fullpath))),s=z(),{stackViewEl:u,multiSelectedIdxs:t,stack:a,scroller:f}=N({images:c}).toRefs(),{itemSize:v,gridItems:b,cellWidth:d,onScroll:h}=O({fetchNext:()=>r.next()}),{showMenuIdx:w}=Q(),{onFileDragStart:m,onFileDragEnd:e}=U(),{showGenInfo:n,imageGenInfo:o,q:p,onContextMenuClick:i,onFileItemClick:I}=j({openNext:G}),{previewIdx:C,previewing:F,onPreviewVisibleChange:_,previewImgMove:E,canPreview:M}=H(),P=async(y,S,R)=>{a.value=[{curr:"",files:c.value}],await i(y,S,R)};return L("removeFiles",async({paths:y})=>{y.forEach(S=>l.add(S))}),{images:c,scroller:f,queue:s,iter:r,onContextMenuClickU:P,stackViewEl:u,previewIdx:C,previewing:F,onPreviewVisibleChange:_,previewImgMove:E,canPreview:M,itemSize:v,gridItems:b,showGenInfo:n,imageGenInfo:o,q:p,onContextMenuClick:i,onFileItemClick:I,showMenuIdx:w,multiSelectedIdxs:t,onFileDragStart:m,onFileDragEnd:e,cellWidth:d,onScroll:h}};export{J as c,K as u};
|
||||
import{bn as A,$ as g,bU as q,bV as x,ar as k,ao as D,bO as z,bd as G}from"./index-0eb75c61.js";import{u as N,b as O,f as Q,c as U,d as j,e as H,h as L}from"./FileItem-4396e62f.js";let T=0;const V=()=>++T,W=(r,l,{dataUpdateStrategy:c="replace"}={})=>{const s=A([""]),u=g(!1),t=g(),a=g(!1);let f=g(-1);const v=new Set,b=e=>{var n;c==="replace"?t.value=e:c==="merge"&&(k((Array.isArray(t.value)||typeof t.value>"u")&&Array.isArray(e),"数据更新策略为合并时仅可用于值为数组的情况"),t.value=[...(n=t==null?void 0:t.value)!==null&&n!==void 0?n:[],...e])},d=e=>x(void 0,void 0,void 0,function*(){if(a.value||u.value&&typeof e>"u")return!1;a.value=!0;const n=V();f.value=n;try{let o;if(typeof e=="number"){if(o=s[e],typeof o!="string")return!1}else o=s[s.length-1];const p=yield r(o);if(v.has(n))return v.delete(n),!1;b(l(p));const i=p.cursor;if((e===s.length-1||typeof e!="number")&&(u.value=!i.has_next,i.has_next)){const I=i.next_cursor||i.next;k(typeof I=="string"),s.push(I)}}finally{f.value===n&&(a.value=!1)}return!0}),h=()=>{v.add(f.value),a.value=!1},w=(e=!1)=>x(void 0,void 0,void 0,function*(){const{refetch:n,force:o}=typeof e=="object"?e:{refetch:e};o&&h(),k(!a.value),s.splice(0,s.length,""),a.value=!1,t.value=void 0,u.value=!1,n&&(yield d())}),m=()=>({next:()=>x(void 0,void 0,void 0,function*(){if(a.value)throw new Error("不允许同时迭代");return{done:!(yield d()),value:t.value}})});return q({abort:h,load:u,next:d,res:t,loading:a,cursorStack:s,reset:w,[Symbol.asyncIterator]:m,iter:{[Symbol.asyncIterator]:m}})},J=r=>A(W(r,l=>l.files,{dataUpdateStrategy:"merge"})),K=r=>{const l=A(new Set),c=D(()=>(r.res??[]).filter(y=>!l.has(y.fullpath))),s=z(),{stackViewEl:u,multiSelectedIdxs:t,stack:a,scroller:f}=N({images:c}).toRefs(),{itemSize:v,gridItems:b,cellWidth:d,onScroll:h}=O({fetchNext:()=>r.next()}),{showMenuIdx:w}=Q(),{onFileDragStart:m,onFileDragEnd:e}=U(),{showGenInfo:n,imageGenInfo:o,q:p,onContextMenuClick:i,onFileItemClick:I}=j({openNext:G}),{previewIdx:C,previewing:F,onPreviewVisibleChange:_,previewImgMove:E,canPreview:M}=H(),P=async(y,S,R)=>{a.value=[{curr:"",files:c.value}],await i(y,S,R)};return L("removeFiles",async({paths:y})=>{y.forEach(S=>l.add(S))}),{images:c,scroller:f,queue:s,iter:r,onContextMenuClickU:P,stackViewEl:u,previewIdx:C,previewing:F,onPreviewVisibleChange:_,previewImgMove:E,canPreview:M,itemSize:v,gridItems:b,showGenInfo:n,imageGenInfo:o,q:p,onContextMenuClick:i,onFileItemClick:I,showMenuIdx:w,multiSelectedIdxs:t,onFileDragStart:m,onFileDragEnd:e,cellWidth:d,onScroll:h}};export{J as c,K as u};
|
||||
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 +1 @@
|
|||
.ant-breadcrumb{box-sizing:border-box;margin:0;padding:0;color:#000000d9;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum";color:#00000073;font-size:14px}.ant-breadcrumb .anticon{font-size:14px}.ant-breadcrumb a{color:#00000073;transition:color .3s}.ant-breadcrumb a:hover{color:#de632f}.ant-breadcrumb>span:last-child{color:#000000d9}.ant-breadcrumb>span:last-child a{color:#000000d9}.ant-breadcrumb>span:last-child .ant-breadcrumb-separator{display:none}.ant-breadcrumb-separator{margin:0 8px;color:#00000073}.ant-breadcrumb-link>.anticon+span,.ant-breadcrumb-link>.anticon+a{margin-left:4px}.ant-breadcrumb-overlay-link>.anticon{margin-left:4px}.ant-breadcrumb-rtl{direction:rtl}.ant-breadcrumb-rtl:before{display:table;content:""}.ant-breadcrumb-rtl:after{display:table;clear:both;content:""}.ant-breadcrumb-rtl>span{float:right}.ant-breadcrumb-rtl .ant-breadcrumb-link>.anticon+span,.ant-breadcrumb-rtl .ant-breadcrumb-link>.anticon+a{margin-right:4px;margin-left:0}.ant-breadcrumb-rtl .ant-breadcrumb-overlay-link>.anticon{margin-right:4px;margin-left:0}.nprogress{pointer-events:none}.nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}.nprogress .peg{display:block;position:absolute;right:0px;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translate(0px,-4px);-ms-transform:rotate(3deg) translate(0px,-4px);transform:rotate(3deg) translateY(-4px)}.nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}.nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:solid 2px transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent .nprogress .spinner,.nprogress-custom-parent .nprogress .bar{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.preview-switch[data-v-3b7597ab]{position:fixed;top:0;bottom:0;left:0;right:0;display:flex;align-items:center;justify-content:space-between;z-index:11111;pointer-events:none}.preview-switch>*[data-v-3b7597ab]{color:#fff;margin:16px;font-size:4em;pointer-events:all;cursor:pointer}.preview-switch>*.disable[data-v-3b7597ab]{opacity:0;pointer-events:none;cursor:none}.breadcrumb[data-v-3b7597ab]{display:flex;align-items:center}.breadcrumb>*[data-v-3b7597ab]{margin-right:4px}.container[data-v-3b7597ab]{background:var(--zp-secondary-background);height:var(--pane-max-height)}.location-bar[data-v-3b7597ab]{padding:4px 16px;background:var(--zp-primary-background);border-bottom:1px solid var(--zp-border);display:flex;align-items:center;justify-content:space-between}.location-bar .actions[data-v-3b7597ab]{display:flex;align-items:center;flex-shrink:0}.location-bar a.opt[data-v-3b7597ab]{margin-left:8px}.view[data-v-3b7597ab]{padding:8px;height:calc(100vh - 48px)}.view .file-list[data-v-3b7597ab]{list-style:none;padding:8px;height:100%;overflow:auto}.hint[data-v-3b7597ab]{padding:4px;border:4px;background:var(--zp-secondary-background);border:1px solid var(--zp-border)}
|
||||
.ant-breadcrumb{box-sizing:border-box;margin:0;padding:0;color:#000000d9;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum";color:#00000073;font-size:14px}.ant-breadcrumb .anticon{font-size:14px}.ant-breadcrumb a{color:#00000073;transition:color .3s}.ant-breadcrumb a:hover{color:#de632f}.ant-breadcrumb>span:last-child{color:#000000d9}.ant-breadcrumb>span:last-child a{color:#000000d9}.ant-breadcrumb>span:last-child .ant-breadcrumb-separator{display:none}.ant-breadcrumb-separator{margin:0 8px;color:#00000073}.ant-breadcrumb-link>.anticon+span,.ant-breadcrumb-link>.anticon+a{margin-left:4px}.ant-breadcrumb-overlay-link>.anticon{margin-left:4px}.ant-breadcrumb-rtl{direction:rtl}.ant-breadcrumb-rtl:before{display:table;content:""}.ant-breadcrumb-rtl:after{display:table;clear:both;content:""}.ant-breadcrumb-rtl>span{float:right}.ant-breadcrumb-rtl .ant-breadcrumb-link>.anticon+span,.ant-breadcrumb-rtl .ant-breadcrumb-link>.anticon+a{margin-right:4px;margin-left:0}.ant-breadcrumb-rtl .ant-breadcrumb-overlay-link>.anticon{margin-right:4px;margin-left:0}.nprogress{pointer-events:none}.nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}.nprogress .peg{display:block;position:absolute;right:0px;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translate(0px,-4px);-ms-transform:rotate(3deg) translate(0px,-4px);transform:rotate(3deg) translateY(-4px)}.nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}.nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:solid 2px transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner .4s linear infinite;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent .nprogress .spinner,.nprogress-custom-parent .nprogress .bar{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.preview-switch[data-v-a0015da1]{position:fixed;top:0;bottom:0;left:0;right:0;display:flex;align-items:center;justify-content:space-between;z-index:11111;pointer-events:none}.preview-switch>*[data-v-a0015da1]{color:#fff;margin:16px;font-size:4em;pointer-events:all;cursor:pointer}.preview-switch>*.disable[data-v-a0015da1]{opacity:0;pointer-events:none;cursor:none}.breadcrumb[data-v-a0015da1]{display:flex;align-items:center}.breadcrumb>*[data-v-a0015da1]{margin-right:4px}.container[data-v-a0015da1]{background:var(--zp-secondary-background);height:var(--pane-max-height)}.location-bar[data-v-a0015da1]{padding:4px 16px;background:var(--zp-primary-background);border-bottom:1px solid var(--zp-border);display:flex;align-items:center;justify-content:space-between}.location-bar .actions[data-v-a0015da1]{display:flex;align-items:center;flex-shrink:0}.location-bar a.opt[data-v-a0015da1]{margin-left:8px}.view[data-v-a0015da1]{padding:8px;height:calc(100vh - 48px)}.view .file-list[data-v-a0015da1]{list-style:none;padding:8px;height:100%;overflow:auto}.hint[data-v-a0015da1]{padding:4px;border:4px;background:var(--zp-secondary-background);border:1px solid var(--zp-border)}
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Infinite Image Browsing</title>
|
||||
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-3ef1f0fd.js"></script>
|
||||
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-0eb75c61.js"></script>
|
||||
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-896679b3.css">
|
||||
</head>
|
||||
|
||||
|
|
|
|||
|
|
@ -105,4 +105,14 @@ export const batchGetTagsByPath = async (paths: string[]) => {
|
|||
return resp.data as Dict<Tag[]>
|
||||
}
|
||||
|
||||
export const rebuildImageIndex = () => axiosInst.value.post('/db/rebuild_index')
|
||||
export const rebuildImageIndex = () => axiosInst.value.post('/db/rebuild_index')
|
||||
|
||||
export interface BatchUpdateTagParams {
|
||||
img_paths: string[]
|
||||
action: 'add' | 'remove'
|
||||
tag_id: number
|
||||
}
|
||||
|
||||
export const batchUpdateImageTag = (data: BatchUpdateTagParams) => {
|
||||
return axiosInst.value.post('/db/batch_update_image_tag', data)
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ const props = defineProps<{
|
|||
idx: number,
|
||||
selectedTag: Tag[],
|
||||
disableDelete?: boolean
|
||||
isSelectedMutilFiles?: boolean
|
||||
}>()
|
||||
const emit = defineEmits<{
|
||||
(type: 'contextMenuClick', e: MenuInfo, file: FileNodeInfo, idx: number): void
|
||||
|
|
@ -49,7 +50,17 @@ const tags = computed(() => {
|
|||
<a-menu-item key="send2BatchDownload">{{ $t('sendToBatchDownload') }}</a-menu-item>
|
||||
<a-menu-item key="send2savedDir">{{ $t('send2savedDir') }}</a-menu-item>
|
||||
<a-menu-divider />
|
||||
<a-sub-menu key="toggle-tag" :title="$t('toggleTag')">
|
||||
<template v-if="isSelectedMutilFiles">
|
||||
<a-sub-menu key="batch-add-tag" :title="$t('batchAddTag')">
|
||||
<a-menu-item v-for="tag in tags" :key="`batch-add-tag-${tag.id}`">{{ tag.name }}
|
||||
</a-menu-item>
|
||||
</a-sub-menu>
|
||||
<a-sub-menu key="batch-remove-tag" :title="$t('batchRemoveTag')">
|
||||
<a-menu-item v-for="tag in tags" :key="`batch-remove-tag-${tag.id}`">{{ tag.name }}
|
||||
</a-menu-item>
|
||||
</a-sub-menu>
|
||||
</template>
|
||||
<a-sub-menu v-else key="toggle-tag" :title="$t('toggleTag')">
|
||||
<a-menu-item v-for="tag in tags" :key="`toggle-tag-${tag.id}`">{{ tag.name }} <star-filled
|
||||
v-if="tag.selected" /><star-outlined v-else />
|
||||
</a-menu-item>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ const props = withDefaults(
|
|||
fullScreenPreviewImageUrl?: string
|
||||
enableRightClickMenu?: boolean,
|
||||
enableCloseIcon?: boolean
|
||||
isSelectedMutilFiles?: boolean
|
||||
}>(),
|
||||
{ selected: false, enableRightClickMenu: true, enableCloseIcon: false }
|
||||
)
|
||||
|
|
@ -82,7 +83,8 @@ const taggleLikeTag = () => {
|
|||
</div>
|
||||
<template #overlay>
|
||||
<context-menu :file="file" :idx="idx" :selected-tag="customTags"
|
||||
@context-menu-click="(e, f, i) => emit('contextMenuClick', e, f, i)" />
|
||||
@context-menu-click="(e, f, i) => emit('contextMenuClick', e, f, i)"
|
||||
:is-selected-mutil-files="isSelectedMutilFiles" />
|
||||
</template>
|
||||
</a-dropdown>
|
||||
<a-dropdown v-if="file.type === 'file'">
|
||||
|
|
@ -144,7 +146,8 @@ const taggleLikeTag = () => {
|
|||
</li>
|
||||
<template #overlay>
|
||||
<context-menu :file="file" :idx="idx" :selected-tag="customTags" v-if="enableRightClickMenu"
|
||||
@context-menu-click="(e, f, i) => emit('contextMenuClick', e, f, i)" />
|
||||
@context-menu-click="(e, f, i) => emit('contextMenuClick', e, f, i)"
|
||||
:is-selected-mutil-files="isSelectedMutilFiles" />
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import type { IIBI18nMap } from '.'
|
||||
|
||||
export const en: IIBI18nMap = {
|
||||
batchAddTag: 'Batch Add Tag',
|
||||
batchRemoveTag: 'Batch Remove Tag',
|
||||
imageCompareTips:
|
||||
'When dragging files, this panel will also appear, so you don\'t need to open the "Image Comparison" feature separately.',
|
||||
dragToResizePanel: 'Drag to resize the panel',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
export const zhHans = {
|
||||
batchAddTag: '批量添加Tag',
|
||||
batchRemoveTag: '批量移除Tag',
|
||||
errorOccurred: '发生了个错误',
|
||||
useThumbnailPreview: '使用缩略图预览',
|
||||
gridThumbnailWidth: '网格缩略图宽度',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import type { IIBI18nMap } from '.'
|
||||
|
||||
export const zhHant: IIBI18nMap = {
|
||||
batchAddTag: '批量添加Tag',
|
||||
batchRemoveTag: '批量移除Tag',
|
||||
errorOccurred: '發生了個錯誤',
|
||||
useThumbnailPreview: '使用縮圖預覽',
|
||||
gridThumbnailWidth: '網格縮圖寬度',
|
||||
|
|
@ -199,5 +201,5 @@ export const zhHant: IIBI18nMap = {
|
|||
confirmRebuildImageIndex: '確認重建圖像索引?',
|
||||
rebuildImageIndex: '重新構建圖像索引',
|
||||
rebuildComplete: '重新構建完成',
|
||||
tagSearchNoResultsMessage: "看起來沒有匹配到任何結果,嘗試通過重新構建索引來去除無用的標籤?"
|
||||
tagSearchNoResultsMessage: '看起來沒有匹配到任何結果,嘗試通過重新構建索引來去除無用的標籤?'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import { Button, Checkbox, Modal, message } from 'ant-design-vue'
|
|||
import type { MenuInfo } from 'ant-design-vue/lib/menu/src/interface'
|
||||
import { t } from '@/i18n'
|
||||
import { DatabaseOutlined } from '@/icon'
|
||||
import { addExtraPath, removeExtraPath, toggleCustomTagToImg } from '@/api/db'
|
||||
import { addExtraPath, batchUpdateImageTag, removeExtraPath, toggleCustomTagToImg } from '@/api/db'
|
||||
import { FileTransferData, downloadFiles, getFileTransferDataFromDragEvent, isMediaFile, toRawFileUrl } from '@/util/file'
|
||||
import { getShortcutStrFromEvent } from '@/util/shortcut'
|
||||
import { openCreateFlodersModal, MultiSelectTips } from '@/components/functionalCallableComp'
|
||||
|
|
@ -894,13 +894,28 @@ export function useFileItemActions (
|
|||
spinning.value = false
|
||||
}
|
||||
}
|
||||
if (`${e.key}`.startsWith('toggle-tag-')) {
|
||||
const tagId = +`${e.key}`.split('toggle-tag-')[1]
|
||||
const key = `${e.key}`
|
||||
console.log(111, e, file, idx);
|
||||
|
||||
if (key.startsWith('toggle-tag-')) {
|
||||
const tagId = +key.split('toggle-tag-')[1]
|
||||
const { is_remove } = await toggleCustomTagToImg({ tag_id: tagId, img_path: file.fullpath })
|
||||
const tag = global.conf?.all_custom_tags.find((v) => v.id === tagId)?.name!
|
||||
tagStore.refreshTags([file.fullpath])
|
||||
await tagStore.refreshTags([file.fullpath])
|
||||
message.success(t(is_remove ? 'removedTagFromImage' : 'addedTagToImage', { tag }))
|
||||
return
|
||||
} else if (key.startsWith('batch-add-tag-') || key.startsWith('batch-remove-tag-')) {
|
||||
const tagId = +key.split('-tag-')[1]
|
||||
const action = key.includes('add') ? 'add' : 'remove'
|
||||
const paths = getSelectedImg().map(v => v.fullpath)
|
||||
await batchUpdateImageTag({
|
||||
tag_id: tagId,
|
||||
img_paths: paths,
|
||||
action
|
||||
})
|
||||
await tagStore.refreshTags(paths)
|
||||
message.success(t(action === 'add' ? 'addCompleted' : 'removeCompleted'))
|
||||
return
|
||||
}
|
||||
switch (e.key) {
|
||||
case 'previewInNewWindow':
|
||||
|
|
|
|||
|
|
@ -201,7 +201,8 @@ watch(
|
|||
:full-screen-preview-image-url="sortedFiles[previewIdx] ? toRawFileUrl(sortedFiles[previewIdx]) : ''"
|
||||
v-model:show-menu-idx="showMenuIdx" :selected="multiSelectedIdxs.includes(idx)" :cell-width="cellWidth"
|
||||
@file-item-click="onFileItemClick" @dragstart="onFileDragStart" @dragend="onFileDragEnd"
|
||||
@preview-visible-change="onPreviewVisibleChange" @context-menu-click="onContextMenuClick" />
|
||||
@preview-visible-change="onPreviewVisibleChange" @context-menu-click="onContextMenuClick"
|
||||
:is-selected-mutil-files="multiSelectedIdxs.length > 1" />
|
||||
</template>
|
||||
<template v-if="props.walkModePath" #after>
|
||||
<div style="padding: 16px 0 32px;">
|
||||
|
|
|
|||
Loading…
Reference in New Issue