Add access control to ensure data security

pull/234/head
zanllp 2023-06-10 18:28:03 +08:00
parent 684dcb63fa
commit 5f98c26b86
28 changed files with 140 additions and 57 deletions

View File

@ -1,5 +1,12 @@
# This attribute is used for authentication. If you input a key here, it will be validated for authentication purposes.
# It will be prompted to enter your key when you open the extension. If the authentication fails, all your requests will be rejected.
IIB_SECRET_KEY=
# Configuring the server-side language for this extension,
# including the tab title and most of the server-side error messages returned. Options are 'zh', 'en', or 'auto'.
# If you want to configure the language for the front-end pages, please set it on the extension's global settings page.
IIB_SERVER_LANG=auto
IIB_SERVER_LANG=auto
# Used for configuring whether to enable access control to the file system.
# If enabled, only access to the provided pre-set folders (including those provided by sd-webui and manually added to Quick Move) will be allowed.
# The optional choices are 'enable', 'disable', and 'auto'. The default value is 'auto',
# which will be determined based on the command-line parameters used to start sd-webui.
IIB_ACCESS_CONTROL=auto

View File

@ -15,7 +15,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-e0b49225.js"></script>
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-25d56352.js"></script>
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-8961c2b3.css">
</head>

View File

@ -11,16 +11,16 @@ from scripts.iib.tool import (
is_win,
cwd,
locale,
enable_access_control,
get_windows_drives,
get_sd_webui_conf,
get_valid_img_dirs,
get_created_date,
open_folder
)
from fastapi import FastAPI, HTTPException
from fastapi.staticfiles import StaticFiles
import asyncio
from typing import Any, List, Optional
from typing import Any, List, Optional, TypedDict
from pydantic import BaseModel
from fastapi.responses import FileResponse
from PIL import Image
@ -41,7 +41,8 @@ from scripts.iib.logger import logger
send_img_path = {"value": ""}
mem = {
"IIB_SECRET_KEY_HASH" : None
"IIB_SECRET_KEY_HASH" : None,
"EXTRA_PATHS": []
}
secret_key = os.getenv("IIB_SECRET_KEY")
if secret_key:
@ -61,6 +62,59 @@ async def get_token(request: Request):
def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
pre = "/infinite_image_browsing"
img_search_dirs = []
try:
img_search_dirs = get_valid_img_dirs(get_sd_webui_conf(**kwargs))
except:
pass
def update_extra_paths(conn: sqlite3.Connection):
r = ExtraPath.get_extra_paths(conn, "scanned")
mem["EXTRA_PATHS"] = [x.path for x in r]
def is_path_under_parents(path, parent_paths = img_search_dirs + mem["EXTRA_PATHS"]):
"""
Check if the given path is under one of the specified parent paths.
:param path: The path to check.
:param parent_paths: A list of parent paths.
:return: True if the path is under one of the parent paths, False otherwise.
"""
try:
path = os.path.normpath(path)
for parent_path in parent_paths:
if (
os.path.commonpath([path, parent_path])
== parent_path
):
return True
except:
pass
return False
def is_path_trusted(path: str):
if not enable_access_control:
return True
try:
parent_paths: List[str] = img_search_dirs + mem["EXTRA_PATHS"]
path = os.path.normpath(path)
for parent_path in parent_paths:
if (len(path) <= len(parent_path)):
if parent_path.startswith(path):
return True
else:
if path.startswith(parent_path):
return True
except:
pass
return False
def check_path_trust(path: str):
if not is_path_trusted(path):
raise HTTPException(status_code=403)
app.mount(
f"{pre}/fe-static",
StaticFiles(directory=f"{cwd}/vue/dist"),
@ -80,6 +134,7 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
conn = DataBase.get_conn()
all_custom_tags = Tag.get_all_custom_tag(conn)
extra_paths = ExtraPath.get_extra_paths(conn)
update_extra_paths(conn)
except Exception as e:
print(e)
return {
@ -90,6 +145,7 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
"sd_cwd": os.getcwd(),
"all_custom_tags": all_custom_tags,
"extra_paths": extra_paths,
"enable_access_control": enable_access_control
}
class DeleteFilesReq(BaseModel):
@ -99,6 +155,7 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
async def delete_files(req: DeleteFilesReq):
conn = DataBase.get_conn()
for path in req.file_paths:
check_path_trust(path)
try:
if os.path.isdir(path):
if len(os.listdir(path)):
@ -134,6 +191,7 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
async def move_files(req: MoveFilesReq):
conn = DataBase.get_conn()
for path in req.file_paths:
check_path_trust(path)
try:
shutil.move(path, req.dest)
img = DbImg.get(conn, os.path.normpath(path))
@ -146,10 +204,19 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
else f"移动文件 {path}{req.dest} 时出错:{e}"
)
raise HTTPException(400, detail=error_msg)
class FileInfoDict(TypedDict):
type: str
date: float
size: int
name: str
bytes: bytes
created_time: float
fullpath: str
@app.get(pre + "/files", dependencies=[Depends(get_token)])
async def get_target_floder_files(folder_path: str):
files = []
files: List[FileInfoDict] = []
try:
if is_win and folder_path == "/":
for item in get_windows_drives():
@ -159,6 +226,7 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
else:
if not os.path.exists(folder_path):
return {"files": []}
check_path_trust(folder_path)
folder_listing: List[os.DirEntry] = os.scandir(folder_path)
for item in folder_listing:
if not os.path.exists(item.path):
@ -196,10 +264,11 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
logger.error(e)
raise HTTPException(status_code=400, detail=str(e))
return {"files": files}
return {"files": [x for x in files if is_path_trusted(x['fullpath'])]}
@app.get(pre + "/image-thumbnail", dependencies=[Depends(get_token)])
async def thumbnail(path: str, t: str, size: str = "256x256"):
check_path_trust(path)
if not temp_path:
return
# 生成缓存文件的路径
@ -230,32 +299,12 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
headers={"Cache-Control": "max-age=31536000", "ETag": hash},
)
img_search_dirs = []
try:
img_search_dirs = get_valid_img_dirs(get_sd_webui_conf(**kwargs))
except:
pass
def need_cache(path, parent_paths=img_search_dirs):
"""
判断 path 是否是 parent_paths 中某个路径的子路径
"""
try:
for parent_path in parent_paths:
if (
os.path.commonpath([os.path.normpath(path), parent_path])
== parent_path
):
return True
except:
pass
return False
@app.get(pre + "/file", dependencies=[Depends(get_token)])
async def get_file(path: str, t: str, disposition: Optional[str] = None):
filename = path
import mimetypes
check_path_trust(path)
if not os.path.exists(filename):
raise HTTPException(status_code=404)
if not os.path.isfile(filename):
@ -265,7 +314,7 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
headers = {}
if disposition:
headers["Content-Disposition"] = f'attachment; filename="{disposition}"'
if need_cache(filename) and is_valid_image_path(filename): # 认为永远不变,不要协商缓存了试试
if is_path_under_parents(filename) and is_valid_image_path(filename): # 认为永远不变,不要协商缓存了试试
headers[
"Cache-Control"
] = "public, max-age=31536000" # 针对同样名字文件但实际上不同内容的文件要求必须传入创建时间来避免浏览器缓存
@ -318,6 +367,8 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
@app.post(pre + "/open_folder", dependencies=[Depends(get_token)])
def open_folder_using_explore(req: OpenFolderReq):
if not is_path_trusted(req.path):
raise HTTPException(status_code=403)
open_folder(*os.path.split(req.path))
db_pre = pre + "/db"
@ -344,9 +395,6 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
"expired_dirs": expired_dirs,
}
def get_extra_paths(conn: sqlite3.Connection):
r = ExtraPath.get_extra_paths(conn, "scanned")
return [x.path for x in r]
@app.post(db_pre + "/update_image_data", dependencies=[Depends(get_token)])
async def update_image_db_data():
@ -354,9 +402,10 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
DataBase._initing = True
conn = DataBase.get_conn()
img_count = DbImg.count(conn)
update_extra_paths()
dirs = (
img_search_dirs if img_count == 0 else Floder.get_expired_dirs(conn)
) + get_extra_paths(conn)
) + mem["EXTRA_PATHS"]
update_image_data(dirs)
finally:
DataBase._initing = False
@ -380,7 +429,8 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
async def get_img_selected_custom_tag(path: str):
path = os.path.normpath(path)
conn = DataBase.get_conn()
if not need_cache(path, img_search_dirs + get_extra_paths(conn)):
update_extra_paths(conn)
if not is_path_under_parents(path):
return []
img = DbImg.get(conn, path)
if not img:
@ -400,7 +450,8 @@ def infinite_image_browsing_api(_: Any, app: FastAPI, **kwargs):
async def toggle_custom_tag_to_img(req: ToggleCustomTagToImgReq):
conn = DataBase.get_conn()
path = os.path.normpath(req.img_path)
if not need_cache(path, img_search_dirs + get_extra_paths(conn)):
update_extra_paths(conn)
if not is_path_under_parents(path):
raise HTTPException(
400,
"当前文件不在搜索路径内,你可以将它添加到扫描路径再尝试。"

View File

@ -167,6 +167,20 @@ def get_temp_path():
temp_path = get_temp_path()
def get_enable_access_control():
ctrl = os.getenv("IIB_ACCESS_CONTROL")
if ctrl == "enable":
return True
if ctrl == "disable":
return False
try:
from modules.shared import cmd_opts
return cmd_opts.share or cmd_opts.ngrok or cmd_opts.listen or cmd_opts.server_name
except:
pass
return False
enable_access_control = get_enable_access_control()
def get_locale():
import locale

1
vue/components.d.ts vendored
View File

@ -9,6 +9,7 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
AAlert: typeof import('ant-design-vue/es')['Alert']
ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb']
ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem']
AButton: typeof import('ant-design-vue/es')['Button']

View File

@ -1 +1 @@
import{d as U,y as q,o as r,l as _,c as l,m as a,n as e,p as y,q as h,B as E,t as b,C as O,z as M,J as u,N as S,Q as D,v as L,V as Q}from"./index-e0b49225.js";import{i as j,j as J,t as H,L as K,R as W,k as X,S as Y}from"./fullScreenContextMenu-7f6a8d02.js";import{g as Z}from"./db-b8702e20.js";import{u as ee}from"./hook-36e46354.js";import"./index-f1c455a2.js";import"./_baseIteratee-21c606ba.js";const ie={class:"hint"},se={key:1,class:"preview-switch"},te=U({__name:"MatchedImageGrid",props:{tabIdx:{},paneIdx:{},selectedTagIds:{},id:{}},setup(V){const m=V,{queue:p,images:s,onContextMenuClickU:v,stackViewEl:z,previewIdx:n,previewing:f,onPreviewVisibleChange:T,previewImgMove:g,canPreview:k,itemSize:I,gridItems:B,showGenInfo:o,imageGenInfo:C,q:$,multiSelectedIdxs:G,onFileItemClick:N,scroller:w,showMenuIdx:d}=ee();return q(()=>m.selectedTagIds,async()=>{var i;const{res:c}=p.pushAction(()=>Z(m.selectedTagIds));s.value=await c,(i=w.value)==null||i.scrollToItem(0)},{immediate:!0}),(c,i)=>{const A=D,F=L,P=Y;return r(),_("div",{class:"container",ref_key:"stackViewEl",ref:z},[l(P,{size:"large",spinning:!e(p).isIdle},{default:a(()=>[l(F,{visible:e(o),"onUpdate:visible":i[1]||(i[1]=t=>y(o)?o.value=t:null),width:"70vw","mask-closable":"",onOk:i[2]||(i[2]=t=>o.value=!1)},{cancelText:a(()=>[]),default:a(()=>[l(A,{active:"",loading:!e($).isIdle},{default:a(()=>[h("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:i[0]||(i[0]=t=>e(E)(e(C)))},[h("div",ie,b(c.$t("doubleClickToCopy")),1),O(" "+b(e(C)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),e(s)?(r(),M(e(j),{key:0,ref_key:"scroller",ref:w,class:"file-list",items:e(s),"item-size":e(I).first,"key-field":"fullpath","item-secondary-size":e(I).second,gridItems:e(B)},{default:a(({item:t,index:x})=>[l(J,{idx:x,file:t,"show-menu-idx":e(d),"onUpdate:showMenuIdx":i[3]||(i[3]=R=>y(d)?d.value=R:null),onFileItemClick:e(N),"full-screen-preview-image-url":e(s)[e(n)]?e(H)(e(s)[e(n)]):"",selected:e(G).includes(x),onContextMenuClick:e(v),onPreviewVisibleChange:e(T)},null,8,["idx","file","show-menu-idx","onFileItemClick","full-screen-preview-image-url","selected","onContextMenuClick","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):u("",!0),e(f)?(r(),_("div",se,[l(e(K),{onClick:i[4]||(i[4]=t=>e(g)("prev")),class:S({disable:!e(k)("prev")})},null,8,["class"]),l(e(W),{onClick:i[5]||(i[5]=t=>e(g)("next")),class:S({disable:!e(k)("next")})},null,8,["class"])])):u("",!0)]),_:1},8,["spinning"]),e(f)&&e(s)&&e(s)[e(n)]?(r(),M(X,{key:0,file:e(s)[e(n)],idx:e(n),onContextMenuClick:e(v)},null,8,["file","idx","onContextMenuClick"])):u("",!0)],512)}}});const ce=Q(te,[["__scopeId","data-v-2a47e96e"]]);export{ce as default};
import{d as U,y as q,o as r,l as _,c as l,m as a,n as e,p as y,q as h,B as E,t as b,C as O,z as M,J as u,N as S,Q as D,v as L,V as Q}from"./index-25d56352.js";import{i as j,j as J,t as H,L as K,R as W,k as X,S as Y}from"./fullScreenContextMenu-419af06d.js";import{g as Z}from"./db-8aee7ac1.js";import{u as ee}from"./hook-74fcab4d.js";import"./index-a4f9859b.js";import"./_baseIteratee-29ccfc96.js";const ie={class:"hint"},se={key:1,class:"preview-switch"},te=U({__name:"MatchedImageGrid",props:{tabIdx:{},paneIdx:{},selectedTagIds:{},id:{}},setup(V){const m=V,{queue:p,images:s,onContextMenuClickU:v,stackViewEl:z,previewIdx:n,previewing:f,onPreviewVisibleChange:T,previewImgMove:g,canPreview:k,itemSize:I,gridItems:B,showGenInfo:o,imageGenInfo:C,q:$,multiSelectedIdxs:G,onFileItemClick:N,scroller:w,showMenuIdx:d}=ee();return q(()=>m.selectedTagIds,async()=>{var i;const{res:c}=p.pushAction(()=>Z(m.selectedTagIds));s.value=await c,(i=w.value)==null||i.scrollToItem(0)},{immediate:!0}),(c,i)=>{const A=D,F=L,P=Y;return r(),_("div",{class:"container",ref_key:"stackViewEl",ref:z},[l(P,{size:"large",spinning:!e(p).isIdle},{default:a(()=>[l(F,{visible:e(o),"onUpdate:visible":i[1]||(i[1]=t=>y(o)?o.value=t:null),width:"70vw","mask-closable":"",onOk:i[2]||(i[2]=t=>o.value=!1)},{cancelText:a(()=>[]),default:a(()=>[l(A,{active:"",loading:!e($).isIdle},{default:a(()=>[h("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:i[0]||(i[0]=t=>e(E)(e(C)))},[h("div",ie,b(c.$t("doubleClickToCopy")),1),O(" "+b(e(C)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),e(s)?(r(),M(e(j),{key:0,ref_key:"scroller",ref:w,class:"file-list",items:e(s),"item-size":e(I).first,"key-field":"fullpath","item-secondary-size":e(I).second,gridItems:e(B)},{default:a(({item:t,index:x})=>[l(J,{idx:x,file:t,"show-menu-idx":e(d),"onUpdate:showMenuIdx":i[3]||(i[3]=R=>y(d)?d.value=R:null),onFileItemClick:e(N),"full-screen-preview-image-url":e(s)[e(n)]?e(H)(e(s)[e(n)]):"",selected:e(G).includes(x),onContextMenuClick:e(v),onPreviewVisibleChange:e(T)},null,8,["idx","file","show-menu-idx","onFileItemClick","full-screen-preview-image-url","selected","onContextMenuClick","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):u("",!0),e(f)?(r(),_("div",se,[l(e(K),{onClick:i[4]||(i[4]=t=>e(g)("prev")),class:S({disable:!e(k)("prev")})},null,8,["class"]),l(e(W),{onClick:i[5]||(i[5]=t=>e(g)("next")),class:S({disable:!e(k)("next")})},null,8,["class"])])):u("",!0)]),_:1},8,["spinning"]),e(f)&&e(s)&&e(s)[e(n)]?(r(),M(X,{key:0,file:e(s)[e(n)],idx:e(n),onContextMenuClick:e(v)},null,8,["file","idx","onContextMenuClick"])):u("",!0)],512)}}});const ce=Q(te,[["__scopeId","data-v-2a47e96e"]]);export{ce as default};

View File

@ -0,0 +1 @@
import{d as Q,r as V,aw as j,bo as H,bp as J,o,l as k,c as r,n as e,bu as W,z as m,m as u,C as w,t as v,J as f,p as $,q as A,B as X,N as U,bs as Y,ae as Z,I as ee,U as se,Q as te,v as ie,V as ne}from"./index-25d56352.js";import{i as ae,j as le,t as oe,L as re,R as ue,k as de,S as ce}from"./fullScreenContextMenu-419af06d.js";/* empty css */import{a as D,b as pe,d as me,u as ve}from"./db-8aee7ac1.js";import{u as fe}from"./hook-74fcab4d.js";import"./index-a4f9859b.js";import"./_baseIteratee-29ccfc96.js";const ge={key:0,class:"search-bar"},ke={class:"hint"},we={key:1,class:"preview-switch"},ye=Q({__name:"SubstrSearch",setup(Ce){const{queue:l,images:n,onContextMenuClickU:y,stackViewEl:E,previewIdx:d,previewing:C,onPreviewVisibleChange:F,previewImgMove:b,canPreview:I,itemSize:_,gridItems:N,showGenInfo:c,imageGenInfo:x,q:R,multiSelectedIdxs:q,onFileItemClick:P,scroller:h,showMenuIdx:g}=fe(),p=V(""),t=V();j(async()=>{t.value=await D(),t.value.img_count&&t.value.expired&&S()});const S=H(()=>l.pushAction(async()=>(await ve(),t.value=await D(),t.value)).res),z=async()=>{var i;n.value=await l.pushAction(()=>me(p.value)).res,(i=h.value)==null||i.scrollToItem(0),n.value.length||Y.info(Z("fuzzy-search-noResults"))};return J("return-to-iib",async()=>{const i=await l.pushAction(pe).res;t.value.expired=i.expired}),(i,s)=>{const T=ee,M=se,G=te,K=ie,L=ce;return o(),k("div",{class:"container",ref_key:"stackViewEl",ref:E},[t.value?(o(),k("div",ge,[r(T,{value:p.value,"onUpdate:value":s[0]||(s[0]=a=>p.value=a),placeholder:i.$t("fuzzy-search-placeholder"),disabled:!e(l).isIdle,onKeydown:W(z,["enter"])},null,8,["value","placeholder","disabled","onKeydown"]),t.value.expired||!t.value.img_count?(o(),m(M,{key:0,onClick:e(S),loading:!e(l).isIdle,type:"primary"},{default:u(()=>[w(v(t.value.img_count===0?i.$t("generateIndexHint"):i.$t("UpdateIndex")),1)]),_:1},8,["onClick","loading"])):(o(),m(M,{key:1,type:"primary",onClick:z,loading:!e(l).isIdle,disabled:!p.value},{default:u(()=>[w(v(i.$t("search")),1)]),_:1},8,["loading","disabled"]))])):f("",!0),r(L,{size:"large",spinning:!e(l).isIdle},{default:u(()=>[r(K,{visible:e(c),"onUpdate:visible":s[2]||(s[2]=a=>$(c)?c.value=a:null),width:"70vw","mask-closable":"",onOk:s[3]||(s[3]=a=>c.value=!1)},{cancelText:u(()=>[]),default:u(()=>[r(G,{active:"",loading:!e(R).isIdle},{default:u(()=>[A("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:s[1]||(s[1]=a=>e(X)(e(x)))},[A("div",ke,v(i.$t("doubleClickToCopy")),1),w(" "+v(e(x)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),e(n)?(o(),m(e(ae),{key:0,ref_key:"scroller",ref:h,class:"file-list",items:e(n),"item-size":e(_).first,"key-field":"fullpath","item-secondary-size":e(_).second,gridItems:e(N)},{default:u(({item:a,index:B})=>[r(le,{idx:B,file:a,"show-menu-idx":e(g),"onUpdate:showMenuIdx":s[4]||(s[4]=O=>$(g)?g.value=O:null),onFileItemClick:e(P),"full-screen-preview-image-url":e(n)[e(d)]?e(oe)(e(n)[e(d)]):"",selected:e(q).includes(B),onContextMenuClick:e(y),onPreviewVisibleChange:e(F)},null,8,["idx","file","show-menu-idx","onFileItemClick","full-screen-preview-image-url","selected","onContextMenuClick","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):f("",!0),e(C)?(o(),k("div",we,[r(e(re),{onClick:s[5]||(s[5]=a=>e(b)("prev")),class:U({disable:!e(I)("prev")})},null,8,["class"]),r(e(ue),{onClick:s[6]||(s[6]=a=>e(b)("next")),class:U({disable:!e(I)("next")})},null,8,["class"])])):f("",!0)]),_:1},8,["spinning"]),e(C)&&e(n)&&e(n)[e(d)]?(o(),m(de,{key:1,file:e(n)[e(d)],idx:e(d),onContextMenuClick:e(y)},null,8,["file","idx","onContextMenuClick"])):f("",!0)],512)}}});const Me=ne(ye,[["__scopeId","data-v-837e8af1"]]);export{Me as default};

View File

@ -1 +0,0 @@
import{d as Q,r as V,ai as j,bh as H,bi as J,o,l as k,c as r,n as e,bo as X,z as m,m as u,C as w,t as v,J as f,p as $,q as A,B as W,N as U,bm as Y,X as Z,I as ee,U as se,Q as te,v as ie,V as ne}from"./index-e0b49225.js";import{i as ae,j as le,t as oe,L as re,R as ue,k as de,S as ce}from"./fullScreenContextMenu-7f6a8d02.js";/* empty css */import{a as D,b as pe,d as me,u as ve}from"./db-b8702e20.js";import{u as fe}from"./hook-36e46354.js";import"./index-f1c455a2.js";import"./_baseIteratee-21c606ba.js";const ge={key:0,class:"search-bar"},ke={class:"hint"},we={key:1,class:"preview-switch"},ye=Q({__name:"SubstrSearch",setup(Ce){const{queue:l,images:n,onContextMenuClickU:y,stackViewEl:E,previewIdx:d,previewing:C,onPreviewVisibleChange:F,previewImgMove:b,canPreview:I,itemSize:_,gridItems:N,showGenInfo:c,imageGenInfo:x,q:R,multiSelectedIdxs:q,onFileItemClick:P,scroller:h,showMenuIdx:g}=fe(),p=V(""),t=V();j(async()=>{t.value=await D(),t.value.img_count&&t.value.expired&&S()});const S=H(()=>l.pushAction(async()=>(await ve(),t.value=await D(),t.value)).res),z=async()=>{var i;n.value=await l.pushAction(()=>me(p.value)).res,(i=h.value)==null||i.scrollToItem(0),n.value.length||Y.info(Z("fuzzy-search-noResults"))};return J("return-to-iib",async()=>{const i=await l.pushAction(pe).res;t.value.expired=i.expired}),(i,s)=>{const T=ee,M=se,G=te,K=ie,L=ce;return o(),k("div",{class:"container",ref_key:"stackViewEl",ref:E},[t.value?(o(),k("div",ge,[r(T,{value:p.value,"onUpdate:value":s[0]||(s[0]=a=>p.value=a),placeholder:i.$t("fuzzy-search-placeholder"),disabled:!e(l).isIdle,onKeydown:X(z,["enter"])},null,8,["value","placeholder","disabled","onKeydown"]),t.value.expired||!t.value.img_count?(o(),m(M,{key:0,onClick:e(S),loading:!e(l).isIdle,type:"primary"},{default:u(()=>[w(v(t.value.img_count===0?i.$t("generateIndexHint"):i.$t("UpdateIndex")),1)]),_:1},8,["onClick","loading"])):(o(),m(M,{key:1,type:"primary",onClick:z,loading:!e(l).isIdle,disabled:!p.value},{default:u(()=>[w(v(i.$t("search")),1)]),_:1},8,["loading","disabled"]))])):f("",!0),r(L,{size:"large",spinning:!e(l).isIdle},{default:u(()=>[r(K,{visible:e(c),"onUpdate:visible":s[2]||(s[2]=a=>$(c)?c.value=a:null),width:"70vw","mask-closable":"",onOk:s[3]||(s[3]=a=>c.value=!1)},{cancelText:u(()=>[]),default:u(()=>[r(G,{active:"",loading:!e(R).isIdle},{default:u(()=>[A("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:s[1]||(s[1]=a=>e(W)(e(x)))},[A("div",ke,v(i.$t("doubleClickToCopy")),1),w(" "+v(e(x)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),e(n)?(o(),m(e(ae),{key:0,ref_key:"scroller",ref:h,class:"file-list",items:e(n),"item-size":e(_).first,"key-field":"fullpath","item-secondary-size":e(_).second,gridItems:e(N)},{default:u(({item:a,index:B})=>[r(le,{idx:B,file:a,"show-menu-idx":e(g),"onUpdate:showMenuIdx":s[4]||(s[4]=O=>$(g)?g.value=O:null),onFileItemClick:e(P),"full-screen-preview-image-url":e(n)[e(d)]?e(oe)(e(n)[e(d)]):"",selected:e(q).includes(B),onContextMenuClick:e(y),onPreviewVisibleChange:e(F)},null,8,["idx","file","show-menu-idx","onFileItemClick","full-screen-preview-image-url","selected","onContextMenuClick","onPreviewVisibleChange"])]),_:1},8,["items","item-size","item-secondary-size","gridItems"])):f("",!0),e(C)?(o(),k("div",we,[r(e(re),{onClick:s[5]||(s[5]=a=>e(b)("prev")),class:U({disable:!e(I)("prev")})},null,8,["class"]),r(e(ue),{onClick:s[6]||(s[6]=a=>e(b)("next")),class:U({disable:!e(I)("next")})},null,8,["class"])])):f("",!0)]),_:1},8,["spinning"]),e(C)&&e(n)&&e(n)[e(d)]?(o(),m(de,{key:1,file:e(n)[e(d)],idx:e(d),onContextMenuClick:e(y)},null,8,["file","idx","onContextMenuClick"])):f("",!0)],512)}}});const Me=ne(ye,[["__scopeId","data-v-837e8af1"]]);export{Me as default};

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
import{ck as _,cl as d,bH as c,aw as g,aV as E,cm as O,aX as P,cn as p,aT as y,be as C}from"./index-e0b49225.js";function I(n){return function(r){return r==null?void 0:r[n]}}var L=1,w=2;function D(n,r,e,i){var t=e.length,a=t,A=!i;if(n==null)return!a;for(n=Object(n);t--;){var f=e[t];if(A&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return!1}for(;++t<a;){f=e[t];var u=f[0],s=n[u],o=f[1];if(A&&f[2]){if(s===void 0&&!(u in n))return!1}else{var l=new _;if(i)var R=i(s,o,u,n,r,l);if(!(R===void 0?d(o,s,L|w,i,l):R))return!1}}return!0}function h(n){return n===n&&!c(n)}function G(n){for(var r=g(n),e=r.length;e--;){var i=r[e],t=n[i];r[e]=[i,t,h(t)]}return r}function M(n,r){return function(e){return e==null?!1:e[n]===r&&(r!==void 0||n in Object(e))}}function F(n){var r=G(n);return r.length==1&&r[0][2]?M(r[0][0],r[0][1]):function(e){return e===n||D(e,n,r)}}function m(n,r,e){var i=n==null?void 0:E(n,r);return i===void 0?e:i}var S=1,T=2;function b(n,r){return O(n)&&h(r)?M(P(n),r):function(e){var i=m(e,n);return i===void 0&&i===r?p(e,n):d(r,i,S|T)}}function x(n){return function(r){return E(r,n)}}function K(n){return O(n)?I(P(n)):x(n)}function U(n){return typeof n=="function"?n:n==null?y:typeof n=="object"?C(n)?b(n[0],n[1]):F(n):K(n)}export{U as b};

View File

@ -0,0 +1 @@
import{cq as _,cr as d,bN as c,aJ as g,b3 as E,cs as O,b5 as P,ct as p,b1 as y,bl as C}from"./index-25d56352.js";function I(n){return function(r){return r==null?void 0:r[n]}}var L=1,b=2;function D(n,r,e,t){var i=e.length,A=i,a=!t;if(n==null)return!A;for(n=Object(n);i--;){var f=e[i];if(a&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return!1}for(;++i<A;){f=e[i];var u=f[0],s=n[u],o=f[1];if(a&&f[2]){if(s===void 0&&!(u in n))return!1}else{var l=new _;if(t)var R=t(s,o,u,n,r,l);if(!(R===void 0?d(o,s,L|b,t,l):R))return!1}}return!0}function h(n){return n===n&&!c(n)}function G(n){for(var r=g(n),e=r.length;e--;){var t=r[e],i=n[t];r[e]=[t,i,h(i)]}return r}function M(n,r){return function(e){return e==null?!1:e[n]===r&&(r!==void 0||n in Object(e))}}function w(n){var r=G(n);return r.length==1&&r[0][2]?M(r[0][0],r[0][1]):function(e){return e===n||D(e,n,r)}}function F(n,r,e){var t=n==null?void 0:E(n,r);return t===void 0?e:t}var N=1,S=2;function m(n,r){return O(n)&&h(r)?M(P(n),r):function(e){var t=F(e,n);return t===void 0&&t===r?p(e,n):d(r,t,N|S)}}function q(n){return function(r){return E(r,n)}}function x(n){return O(n)?I(P(n)):q(n)}function T(n){return typeof n=="function"?n:n==null?y:typeof n=="object"?C(n)?m(n[0],n[1]):w(n):x(n)}export{T as b};

View File

@ -1 +1 @@
import{bN as t}from"./index-e0b49225.js";const o=async()=>(await t.get("/db/basic_info")).data,c=async()=>(await t.get("/db/expired_dirs")).data,r=async()=>{await t.post("/db/update_image_data",{},{timeout:1/0})},d=async a=>(await t.post("/db/match_images_by_tags",a)).data,g=async a=>(await t.post("/db/add_custom_tag",a)).data,p=async a=>(await t.post("/db/toggle_custom_tag_to_img",a)).data,i=async a=>{await t.post("/db/remove_custom_tag",a)},m=async a=>(await t.get("/db/img_selected_custom_tag",{params:{path:a}})).data,u=async a=>(await t.get("/db/search_by_substr",{params:{substr:a}})).data,e="/db/scanned_paths",_=async a=>{await t.post(e,{path:a})},b=async a=>{await t.delete(e,{data:{path:a}})};export{o as a,c as b,g as c,u as d,b as e,_ as f,d as g,m as h,i as r,p as t,r as u};
import{bT as t}from"./index-25d56352.js";const o=async()=>(await t.get("/db/basic_info")).data,c=async()=>(await t.get("/db/expired_dirs")).data,r=async()=>{await t.post("/db/update_image_data",{},{timeout:1/0})},d=async a=>(await t.post("/db/match_images_by_tags",a)).data,g=async a=>(await t.post("/db/add_custom_tag",a)).data,p=async a=>(await t.post("/db/toggle_custom_tag_to_img",a)).data,i=async a=>{await t.post("/db/remove_custom_tag",a)},m=async a=>(await t.get("/db/img_selected_custom_tag",{params:{path:a}})).data,u=async a=>(await t.get("/db/search_by_substr",{params:{substr:a}})).data,e="/db/scanned_paths",_=async a=>{await t.post(e,{path:a})},b=async a=>{await t.delete(e,{data:{path:a}})};export{o as a,c as b,g as c,u as d,b as e,_ as f,d as g,m as h,i as r,p as t,r as u};

View File

@ -1 +0,0 @@
.container[data-v-89e9fce3]{padding:20px;background-color:var(--zp-secondary-background);height:100%;overflow:auto}.header[data-v-89e9fce3]{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}.header h1[data-v-89e9fce3]{font-size:28px;font-weight:700;color:var(--zp-primary)}.last-record[data-v-89e9fce3]{margin-left:16px;font-size:14px;color:var(--zp-secondary)}.last-record a[data-v-89e9fce3]{text-decoration:none;color:var(--zp-secondary)}.last-record a[data-v-89e9fce3]:hover{color:var(--zp-primary)}.content[data-v-89e9fce3]{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));grid-gap:20px}.quick-start[data-v-89e9fce3]{background-color:var(--zp-primary-background);border-radius:8px;box-shadow:0 1px 2px #0000001a;padding:20px}.quick-start ul[data-v-89e9fce3]{list-style:none;padding:4px}.quick-start .item[data-v-89e9fce3]{margin-bottom:10px;padding:4px 8px;display:flex;align-items:center}.quick-start .item[data-v-89e9fce3]:hover{background:var(--zp-secondary-background);border-radius:4px;color:var(--primary-color);cursor:pointer}.quick-start .icon[data-v-89e9fce3]{margin-right:8px}.quick-start h2[data-v-89e9fce3]{margin-top:0;margin-bottom:20px;font-size:20px;font-weight:700;color:var(--zp-primary)}.text[data-v-89e9fce3]{flex:1;font-size:16px}

View File

@ -0,0 +1 @@
.ant-alert{box-sizing:border-box;margin:0;color:#000000d9;font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum";position:relative;display:flex;align-items:center;padding:8px 15px;word-wrap:break-word;border-radius:2px}.ant-alert-content{flex:1;min-width:0}.ant-alert-icon{margin-right:8px}.ant-alert-description{display:none;font-size:14px;line-height:22px}.ant-alert-success{background-color:#f6ffed;border:1px solid #b7eb8f}.ant-alert-success .ant-alert-icon{color:#52c41a}.ant-alert-info{background-color:#fff1e6;border:1px solid #f7ae83}.ant-alert-info .ant-alert-icon{color:#d03f0a}.ant-alert-warning{background-color:#fffbe6;border:1px solid #ffe58f}.ant-alert-warning .ant-alert-icon{color:#faad14}.ant-alert-error{background-color:#fff2f0;border:1px solid #ffccc7}.ant-alert-error .ant-alert-icon{color:#ff4d4f}.ant-alert-error .ant-alert-description>pre{margin:0;padding:0}.ant-alert-action{margin-left:8px}.ant-alert-close-icon{margin-left:8px;padding:0;overflow:hidden;font-size:12px;line-height:12px;background-color:transparent;border:none;outline:none;cursor:pointer}.ant-alert-close-icon .anticon-close{color:#00000073;transition:color .3s}.ant-alert-close-icon .anticon-close:hover{color:#000000bf}.ant-alert-close-text{color:#00000073;transition:color .3s}.ant-alert-close-text:hover{color:#000000bf}.ant-alert-with-description{align-items:flex-start;padding:15px 15px 15px 24px}.ant-alert-with-description.ant-alert-no-icon{padding:15px}.ant-alert-with-description .ant-alert-icon{margin-right:15px;font-size:24px}.ant-alert-with-description .ant-alert-message{display:block;margin-bottom:4px;color:#000000d9;font-size:16px}.ant-alert-message{color:#000000d9}.ant-alert-with-description .ant-alert-description{display:block}.ant-alert.ant-alert-motion-leave{overflow:hidden;opacity:1;transition:max-height .3s cubic-bezier(.78,.14,.15,.86),opacity .3s cubic-bezier(.78,.14,.15,.86),padding-top .3s cubic-bezier(.78,.14,.15,.86),padding-bottom .3s cubic-bezier(.78,.14,.15,.86),margin-bottom .3s cubic-bezier(.78,.14,.15,.86)}.ant-alert.ant-alert-motion-leave-active{max-height:0;margin-bottom:0!important;padding-top:0;padding-bottom:0;opacity:0}.ant-alert-banner{margin-bottom:0;border:0;border-radius:0}.ant-alert.ant-alert-rtl{direction:rtl}.ant-alert-rtl .ant-alert-icon{margin-right:auto;margin-left:8px}.ant-alert-rtl .ant-alert-action,.ant-alert-rtl .ant-alert-close-icon{margin-right:8px;margin-left:auto}.ant-alert-rtl.ant-alert-with-description{padding-right:24px;padding-left:15px}.ant-alert-rtl.ant-alert-with-description .ant-alert-icon{margin-right:auto;margin-left:15px}.container[data-v-41f9ac3e]{padding:20px;background-color:var(--zp-secondary-background);height:100%;overflow:auto}.header[data-v-41f9ac3e]{display:flex;justify-content:space-between;align-items:center}.header h1[data-v-41f9ac3e]{font-size:28px;font-weight:700;color:var(--zp-primary)}.last-record[data-v-41f9ac3e]{margin-left:16px;font-size:14px;color:var(--zp-secondary)}.last-record a[data-v-41f9ac3e]{text-decoration:none;color:var(--zp-secondary)}.last-record a[data-v-41f9ac3e]:hover{color:var(--zp-primary)}.content[data-v-41f9ac3e]{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));grid-gap:20px;margin-top:16px}.quick-start[data-v-41f9ac3e]{background-color:var(--zp-primary-background);border-radius:8px;box-shadow:0 1px 2px #0000001a;padding:20px}.quick-start ul[data-v-41f9ac3e]{list-style:none;padding:4px;max-height:70vh;overflow-y:auto}.quick-start .item[data-v-41f9ac3e]{margin-bottom:10px;padding:4px 8px;display:flex;align-items:center}.quick-start .item[data-v-41f9ac3e]:hover{background:var(--zp-secondary-background);border-radius:4px;color:var(--primary-color);cursor:pointer}.quick-start .icon[data-v-41f9ac3e]{margin-right:8px}.quick-start h2[data-v-41f9ac3e]{margin-top:0;margin-bottom:20px;font-size:20px;font-weight:700;color:var(--zp-primary)}.text[data-v-41f9ac3e]{flex:1;font-size:16px}

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
import{c as y,W as q,d as x,x as P,X as _,Y as O,o as l,l as c,q as t,t as i,s as m,E as g,m as F,C as N,J as p,n as h,A as w,Z as $,$ as V,a0 as B,U as H,a1 as j,a2 as L,V as A}from"./index-e0b49225.js";var R={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 W=R;function S(a){for(var o=1;o<arguments.length;o++){var s=arguments[o]!=null?Object(arguments[o]):{},r=Object.keys(s);typeof Object.getOwnPropertySymbols=="function"&&(r=r.concat(Object.getOwnPropertySymbols(s).filter(function(u){return Object.getOwnPropertyDescriptor(s,u).enumerable}))),r.forEach(function(u){E(a,u,s[u])})}return a}function E(a,o,s){return o in a?Object.defineProperty(a,o,{value:s,enumerable:!0,configurable:!0,writable:!0}):a[o]=s,a}var C=function(o,s){var r=S({},o,s.attrs);return y(q,S({},r,{icon:W}),null)};C.displayName="FileDoneOutlined";C.inheritAttrs=!1;const T=C,G=a=>(j("data-v-89e9fce3"),a=a(),L(),a),J={class:"container"},Q={class:"header"},U=G(()=>t("div",{"flex-placeholder":""},null,-1)),X={href:"https://github.com/zanllp/sd-webui-infinite-image-browsing/issues/131",target:"_blank",class:"last-record"},Y={href:"https://github.com/zanllp/sd-webui-infinite-image-browsing/issues/90",target:"_blank",class:"last-record"},Z={class:"content"},K={key:0,class:"quick-start"},ee={key:1,class:"quick-start"},te=["onClick"],se={class:"text line-clamp-1"},ne={class:"quick-start"},ae=["onClick"],le={class:"text line-clamp-1"},ce={class:"text line-clamp-1"},oe={class:"text line-clamp-1"},ie={key:2,class:"quick-start"},re=["onClick"],ue={class:"text line-clamp-1"},de=x({__name:"emptyStartup",props:{tabIdx:{},paneIdx:{}},setup(a){const o=a,s=P(),r={local:_("local"),"tag-search":_("imgSearch"),"fuzzy-search":_("fuzzy-search"),"global-setting":_("globalSettings")},u=(e,f,k=!1)=>{let d;switch(e){case"tag-search-matched-image-grid":return;case"global-setting":case"tag-search":case"fuzzy-search":case"empty":d={type:e,name:r[e],key:Date.now()+$()};break;case"local":d={type:e,name:r[e],key:Date.now()+$(),path:f,walkModePath:k?f:void 0}}const n=s.tabList[o.tabIdx];n.panes.splice(o.paneIdx,1,d),n.key=d.key},v=O(()=>{var e;return(e=s.tabListHistoryRecord)==null?void 0:e[1]}),z=O(()=>s.quickMovePaths.filter(({key:e})=>e==="outdir_txt2img_samples"||e==="outdir_img2img_samples")),I=window.parent!==window,D=()=>window.parent.open("/infinite_image_browsing"),M=()=>{V(v.value),s.tabList=B(v.value.tabs)};return(e,f)=>{var d;const k=H;return l(),c("div",J,[t("div",Q,[t("h1",null,i(e.$t("welcome")),1),U,t("a",X,i(e.$t("changlog")),1),t("a",Y,i(e.$t("faq")),1)]),t("div",Z,[z.value.length?(l(),c("div",K,[t("h2",null,i(e.$t("walkMode")),1),t("ul",null,[(l(!0),c(m,null,g(z.value,n=>(l(),c("li",{key:n.dir,class:"item"},[y(k,{onClick:b=>u("local",n.dir,!0),ghost:"",type:"primary",block:""},{default:F(()=>[N(i(n.zh),1)]),_:2},1032,["onClick"])]))),128))])])):p("",!0),h(s).quickMovePaths.length?(l(),c("div",ee,[t("h2",null,i(e.$t("launchFromQuickMove")),1),t("ul",null,[(l(!0),c(m,null,g(h(s).quickMovePaths,n=>(l(),c("li",{key:n.key,class:"item",onClick:w(b=>u("local",n.dir),["prevent"])},[t("span",se,i(n.zh),1)],8,te))),128))])])):p("",!0),t("div",ne,[t("h2",null,i(e.$t("launch")),1),t("ul",null,[(l(!0),c(m,null,g(Object.keys(r),n=>(l(),c("li",{key:n,class:"item",onClick:w(b=>u(n),["prevent"])},[t("span",le,i(r[n]),1)],8,ae))),128)),I?(l(),c("li",{key:0,class:"item",onClick:D},[t("span",ce,i(e.$t("openInNewWindow")),1)])):p("",!0),(d=v.value)!=null&&d.tabs.length?(l(),c("li",{key:1,class:"item",onClick:M},[t("span",oe,i(e.$t("restoreLastRecord")),1)])):p("",!0)])]),h(s).recent.length?(l(),c("div",ie,[t("h2",null,i(e.$t("recent")),1),t("ul",null,[(l(!0),c(m,null,g(h(s).recent,n=>(l(),c("li",{key:n.key,class:"item",onClick:w(b=>u("local",n.path),["prevent"])},[y(h(T),{class:"icon"}),t("span",ue,i(n.path),1)],8,re))),128))])])):p("",!0)])])}}});const he=A(de,[["__scopeId","data-v-89e9fce3"]]);export{he as default};

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
import{r as l,bg as F,aT as S}from"./index-e0b49225.js";import{u as y,b as q,f as P,c as z,d as E,e as G,l as Q}from"./fullScreenContextMenu-7f6a8d02.js";const V=()=>{const e=l(),c=F(),n=l(),t={tabIdx:-1,target:"local",paneIdx:-1,walkMode:!1},{stackViewEl:r,multiSelectedIdxs:u,stack:m}=y({images:e}).toRefs(),{itemSize:f,gridItems:v}=q(t),{showMenuIdx:p}=P();z();const{showGenInfo:I,imageGenInfo:d,q:w,onContextMenuClick:o,onFileItemClick:g}=E(t,{openNext:S}),{previewIdx:x,previewing:k,onPreviewVisibleChange:M,previewImgMove:h,canPreview:C}=G(t,{scroller:n,files:e}),b=async(a,s,i)=>{m.value=[{curr:"",files:e.value}],await o(a,s,i)};return Q("removeFiles",async({paths:a})=>{var s;e.value=(s=e.value)==null?void 0:s.filter(i=>!a.includes(i.fullpath))}),{scroller:n,queue:c,images:e,onContextMenuClickU:b,stackViewEl:r,previewIdx:x,previewing:k,onPreviewVisibleChange:M,previewImgMove:h,canPreview:C,itemSize:f,gridItems:v,showGenInfo:I,imageGenInfo:d,q:w,onContextMenuClick:o,onFileItemClick:g,showMenuIdx:p,multiSelectedIdxs:u}};export{V as u};

1
vue/dist/assets/hook-74fcab4d.js vendored Normal file
View File

@ -0,0 +1 @@
import{r as l,bn as F,b1 as S}from"./index-25d56352.js";import{u as y,b as q,f as P,c as z,d as E,e as G,l as Q}from"./fullScreenContextMenu-419af06d.js";const A=()=>{const e=l(),c=F(),i=l(),t={tabIdx:-1,target:"local",paneIdx:-1,walkMode:!1},{stackViewEl:r,multiSelectedIdxs:u,stack:m}=y({images:e}).toRefs(),{itemSize:f,gridItems:v}=q(t),{showMenuIdx:p}=P();z();const{showGenInfo:I,imageGenInfo:d,q:w,onContextMenuClick:o,onFileItemClick:g}=E(t,{openNext:S}),{previewIdx:x,previewing:k,onPreviewVisibleChange:M,previewImgMove:b,canPreview:h}=G(t,{scroller:i,files:e}),C=async(n,s,a)=>{m.value=[{curr:"",files:e.value}],await o(n,s,a)};return Q("removeFiles",async({paths:n})=>{var s;e.value=(s=e.value)==null?void 0:s.filter(a=>!n.includes(a.fullpath))}),{scroller:i,queue:c,images:e,onContextMenuClickU:C,stackViewEl:r,previewIdx:x,previewing:k,onPreviewVisibleChange:M,previewImgMove:b,canPreview:h,itemSize:f,gridItems:v,showGenInfo:I,imageGenInfo:d,q:w,onContextMenuClick:o,onFileItemClick:g,showMenuIdx:p,multiSelectedIdxs:u}};export{A as u};

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{cj as i}from"./index-e0b49225.js";var r=1/0,o=17976931348623157e292;function s(n){if(!n)return n===0?n:0;if(n=i(n),n===r||n===-r){var t=n<0?-1:1;return t*o}return n===n?n:0}function c(n){var t=n==null?0:n.length;return t?n[t-1]:void 0}export{c as l,s as t};
import{cp as i}from"./index-25d56352.js";var r=1/0,o=17976931348623157e292;function s(n){if(!n)return n===0?n:0;if(n=i(n),n===r||n===-r){var t=n<0?-1:1;return t*o}return n===n?n:0}function c(n){var t=n==null?0:n.length;return t?n[t-1]:void 0}export{c as l,s as t};

File diff suppressed because one or more lines are too long

2
vue/dist/index.html vendored
View File

@ -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-e0b49225.js"></script>
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-25d56352.js"></script>
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-8961c2b3.css">
</head>

View File

@ -66,6 +66,7 @@ export interface GlobalConf {
home: string
sd_cwd: string
extra_paths: { path: string }[]
enable_access_control: boolean
}
export const getGlobalSetting = async () => {

View File

@ -134,11 +134,13 @@ const zh = {
fullscreenRestriction: '受技术限制,当前拓展不允许删除打开全屏预览时的首张图片。',
clear: '清除',
toggleTagSelection: '切换 "{tag}" 标签选中',
changlog: '更新日志'
changlog: '更新日志',
accessControlModeTips: "为确保数据安全,您当前正以访问控制模式运行,仅能访问授权文件夹。您可以通过编辑.env文件来调整访问权限设置。"
}
const en: Record<keyof typeof zh, string> = {
//! MissingTranslations: "Mark missing translations like this""shortcutKey": "Keyboard Shortcuts",
//! MissingTranslations
accessControlModeTips: "To ensure data security, you are currently running in access control mode, which only allows access to authorized folders. You can adjust access permissions by editing the .env file.",
changlog: 'Change log',
clear: 'Clear',
toggleTagSelection: 'Toggle Selection of Tag "{tag}"',

View File

@ -3,7 +3,7 @@ import { useGlobalStore, type TabPane } from '@/store/useGlobalStore'
import { uniqueId } from 'lodash-es'
import { computed } from 'vue'
import { ok } from 'vue3-ts-util'
import { FileDoneOutlined } from '@/icon'
import { FileDoneOutlined, LockOutlined } from '@/icon'
import { t } from '@/i18n'
import { cloneDeep } from 'lodash-es'
@ -32,7 +32,7 @@ const openInCurrentTab = (type: TabPane['type'], path?: string, walkMode = false
name: compCnMap[type]!,
key: Date.now() + uniqueId(),
path,
walkModePath: walkMode ? path: undefined
walkModePath: walkMode ? path : undefined
}
}
const tab = global.tabList[props.tabIdx]
@ -56,7 +56,7 @@ const previewInNewWindow = () => window.parent.open('/infinite_image_browsing')
const restoreRecord = () => {
ok(lastRecord.value)
global.tabList = cloneDeep(lastRecord.value.tabs)
}
</script>
<template>
@ -69,6 +69,11 @@ const restoreRecord = () => {
<a href="https://github.com/zanllp/sd-webui-infinite-image-browsing/issues/90" target="_blank"
class="last-record">{{ $t('faq') }}</a>
</div>
<a-alert :message="$t('accessControlModeTips')" show-icon v-if="global.conf?.enable_access_control">
<template #icon>
<LockOutlined></LockOutlined>
</template>
</a-alert>
<div class="content">
<div class="quick-start" v-if="walkModeSupportedDir.length">
<h2>{{ $t('walkMode') }}</h2>
@ -128,7 +133,6 @@ const restoreRecord = () => {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.header h1 {
@ -156,6 +160,7 @@ const restoreRecord = () => {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-gap: 20px;
margin-top: 16px;
}
.quick-start {
@ -167,6 +172,8 @@ const restoreRecord = () => {
ul {
list-style: none;
padding: 4px;
max-height: 70vh;
overflow-y: auto;
}
.item {