Merge pull request #861 from zanllp/feature/audio-support
feat: add audio file playback support and improve TikTok viewpull/865/head
commit
3fbded3a63
|
|
@ -13,8 +13,8 @@ Promise.resolve().then(async () => {
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Infinite Image Browsing</title>
|
<title>Infinite Image Browsing</title>
|
||||||
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-88195b71.js"></script>
|
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-e20a7c5d.js"></script>
|
||||||
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-a44325c7.css">
|
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-66b0f04c.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ from scripts.iib.tool import (
|
||||||
is_dev,
|
is_dev,
|
||||||
get_modified_date,
|
get_modified_date,
|
||||||
is_image_file,
|
is_image_file,
|
||||||
|
is_audio_file,
|
||||||
case_insensitive_get,
|
case_insensitive_get,
|
||||||
get_img_geninfo_txt_path,
|
get_img_geninfo_txt_path,
|
||||||
parse_generation_parameters
|
parse_generation_parameters
|
||||||
|
|
@ -189,7 +190,16 @@ def build_single_img_idx(conn, file_path, is_rebuild, safe_save_img_tag):
|
||||||
type="size",
|
type="size",
|
||||||
)
|
)
|
||||||
safe_save_img_tag(ImageTag(img.id, size_tag.id))
|
safe_save_img_tag(ImageTag(img.id, size_tag.id))
|
||||||
media_type_tag = Tag.get_or_create(conn, "Image" if is_image_file(file_path) else "Video", 'Media Type')
|
# 确定媒体类型:Image / Video / Audio / Unknown
|
||||||
|
if is_image_file(file_path):
|
||||||
|
media_type_name = "Image"
|
||||||
|
elif is_audio_file(file_path):
|
||||||
|
media_type_name = "Audio"
|
||||||
|
elif get_video_type(file_path):
|
||||||
|
media_type_name = "Video"
|
||||||
|
else:
|
||||||
|
media_type_name = "Unknown"
|
||||||
|
media_type_tag = Tag.get_or_create(conn, media_type_name, 'Media Type')
|
||||||
safe_save_img_tag(ImageTag(img.id, media_type_tag.id))
|
safe_save_img_tag(ImageTag(img.id, media_type_tag.id))
|
||||||
keys = [
|
keys = [
|
||||||
"Model",
|
"Model",
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,9 @@ class SdWebUIParser:
|
||||||
meta={"final_width": width, "final_height": height}
|
meta={"final_width": width, "final_height": height}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
info += ", Source Identifier: Stable Diffusion web UI"
|
|
||||||
|
if "Source Identifier" not in info:
|
||||||
|
info += ", Source Identifier: Stable Diffusion web UI"
|
||||||
params = parse_generation_parameters(info)
|
params = parse_generation_parameters(info)
|
||||||
return ImageGenerationInfo(
|
return ImageGenerationInfo(
|
||||||
info,
|
info,
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,18 @@ def is_image_file(filename: str) -> bool:
|
||||||
def is_video_file(filename: str) -> bool:
|
def is_video_file(filename: str) -> bool:
|
||||||
return isinstance(get_video_type(filename), str) and is_video_simple(filename)
|
return isinstance(get_video_type(filename), str) and is_video_simple(filename)
|
||||||
|
|
||||||
|
def get_audio_type(file_path):
|
||||||
|
audio_extensions = ['.mp3', '.wav', '.ogg', '.flac', '.m4a', '.aac', '.wma']
|
||||||
|
file_extension = file_path[file_path.rfind('.'):].lower()
|
||||||
|
|
||||||
|
if file_extension in audio_extensions:
|
||||||
|
return file_extension[1:]
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def is_audio_file(filename: str) -> bool:
|
||||||
|
return isinstance(get_audio_type(filename), str)
|
||||||
|
|
||||||
def is_valid_media_path(path):
|
def is_valid_media_path(path):
|
||||||
"""
|
"""
|
||||||
判断给定的路径是否是图像文件
|
判断给定的路径是否是图像文件
|
||||||
|
|
@ -240,10 +252,10 @@ def is_valid_media_path(path):
|
||||||
return False
|
return False
|
||||||
if not os.path.isfile(abs_path): # 判断是否是文件
|
if not os.path.isfile(abs_path): # 判断是否是文件
|
||||||
return False
|
return False
|
||||||
return is_image_file(abs_path) or is_video_file(abs_path)
|
return is_image_file(abs_path) or is_video_file(abs_path) or is_audio_file(abs_path)
|
||||||
|
|
||||||
def is_media_file(file_path):
|
def is_media_file(file_path):
|
||||||
return is_image_file(file_path) or is_video_file(file_path)
|
return is_image_file(file_path) or is_video_file(file_path) or is_audio_file(file_path)
|
||||||
|
|
||||||
def create_zip_file(file_paths: List[str], zip_file_name: str, compress = False):
|
def create_zip_file(file_paths: List[str], zip_file_name: str, compress = False):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ declare module '@vue/runtime-core' {
|
||||||
ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem']
|
ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem']
|
||||||
AButton: typeof import('ant-design-vue/es')['Button']
|
AButton: typeof import('ant-design-vue/es')['Button']
|
||||||
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
||||||
|
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
|
||||||
ACol: typeof import('ant-design-vue/es')['Col']
|
ACol: typeof import('ant-design-vue/es')['Col']
|
||||||
ACollapse: typeof import('ant-design-vue/es')['Collapse']
|
ACollapse: typeof import('ant-design-vue/es')['Collapse']
|
||||||
ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
|
ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel']
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
import{d as E,bC as $,r as f,m as M,_ as T,a as c,an as W,h as m,c as v,P as z}from"./index-88195b71.js";var G=["prefixCls","name","id","type","disabled","readonly","tabindex","autofocus","value","required"],H={prefixCls:String,name:String,id:String,type:String,defaultChecked:{type:[Boolean,Number],default:void 0},checked:{type:[Boolean,Number],default:void 0},disabled:Boolean,tabindex:{type:[Number,String]},readonly:Boolean,autofocus:Boolean,value:z.any,required:Boolean};const L=E({compatConfig:{MODE:3},name:"Checkbox",inheritAttrs:!1,props:$(H,{prefixCls:"rc-checkbox",type:"checkbox",defaultChecked:!1}),emits:["click","change"],setup:function(a,d){var t=d.attrs,h=d.emit,g=d.expose,o=f(a.checked===void 0?a.defaultChecked:a.checked),i=f();M(function(){return a.checked},function(){o.value=a.checked}),g({focus:function(){var e;(e=i.value)===null||e===void 0||e.focus()},blur:function(){var e;(e=i.value)===null||e===void 0||e.blur()}});var l=f(),x=function(e){if(!a.disabled){a.checked===void 0&&(o.value=e.target.checked),e.shiftKey=l.value;var r={target:c(c({},a),{},{checked:e.target.checked}),stopPropagation:function(){e.stopPropagation()},preventDefault:function(){e.preventDefault()},nativeEvent:e};a.checked!==void 0&&(i.value.checked=!!a.checked),h("change",r),l.value=!1}},C=function(e){h("click",e),l.value=e.shiftKey};return function(){var n,e=a.prefixCls,r=a.name,s=a.id,p=a.type,b=a.disabled,K=a.readonly,P=a.tabindex,B=a.autofocus,S=a.value,N=a.required,_=T(a,G),q=t.class,D=t.onFocus,j=t.onBlur,w=t.onKeydown,A=t.onKeypress,F=t.onKeyup,y=c(c({},_),t),O=Object.keys(y).reduce(function(k,u){return(u.substr(0,5)==="aria-"||u.substr(0,5)==="data-"||u==="role")&&(k[u]=y[u]),k},{}),R=W(e,q,(n={},m(n,"".concat(e,"-checked"),o.value),m(n,"".concat(e,"-disabled"),b),n)),V=c(c({name:r,id:s,type:p,readonly:K,disabled:b,tabindex:P,class:"".concat(e,"-input"),checked:!!o.value,autofocus:B,value:S},O),{},{onChange:x,onClick:C,onFocus:D,onBlur:j,onKeydown:w,onKeypress:A,onKeyup:F,required:N});return v("span",{class:R},[v("input",c({ref:i},V),null),v("span",{class:"".concat(e,"-inner")},null)])}}});export{L as V};
|
import{d as E,bC as $,r as f,m as M,_ as T,a as c,an as W,h as m,c as v,P as z}from"./index-e20a7c5d.js";var G=["prefixCls","name","id","type","disabled","readonly","tabindex","autofocus","value","required"],H={prefixCls:String,name:String,id:String,type:String,defaultChecked:{type:[Boolean,Number],default:void 0},checked:{type:[Boolean,Number],default:void 0},disabled:Boolean,tabindex:{type:[Number,String]},readonly:Boolean,autofocus:Boolean,value:z.any,required:Boolean};const L=E({compatConfig:{MODE:3},name:"Checkbox",inheritAttrs:!1,props:$(H,{prefixCls:"rc-checkbox",type:"checkbox",defaultChecked:!1}),emits:["click","change"],setup:function(a,d){var t=d.attrs,h=d.emit,g=d.expose,o=f(a.checked===void 0?a.defaultChecked:a.checked),i=f();M(function(){return a.checked},function(){o.value=a.checked}),g({focus:function(){var e;(e=i.value)===null||e===void 0||e.focus()},blur:function(){var e;(e=i.value)===null||e===void 0||e.blur()}});var l=f(),x=function(e){if(!a.disabled){a.checked===void 0&&(o.value=e.target.checked),e.shiftKey=l.value;var r={target:c(c({},a),{},{checked:e.target.checked}),stopPropagation:function(){e.stopPropagation()},preventDefault:function(){e.preventDefault()},nativeEvent:e};a.checked!==void 0&&(i.value.checked=!!a.checked),h("change",r),l.value=!1}},C=function(e){h("click",e),l.value=e.shiftKey};return function(){var n,e=a.prefixCls,r=a.name,s=a.id,p=a.type,b=a.disabled,K=a.readonly,P=a.tabindex,B=a.autofocus,S=a.value,N=a.required,_=T(a,G),q=t.class,D=t.onFocus,j=t.onBlur,w=t.onKeydown,A=t.onKeypress,F=t.onKeyup,y=c(c({},_),t),O=Object.keys(y).reduce(function(k,u){return(u.substr(0,5)==="aria-"||u.substr(0,5)==="data-"||u==="role")&&(k[u]=y[u]),k},{}),R=W(e,q,(n={},m(n,"".concat(e,"-checked"),o.value),m(n,"".concat(e,"-disabled"),b),n)),V=c(c({name:r,id:s,type:p,readonly:K,disabled:b,tabindex:P,class:"".concat(e,"-input"),checked:!!o.value,autofocus:B,value:S},O),{},{onChange:x,onClick:C,onFocus:D,onBlur:j,onKeydown:w,onKeypress:A,onKeyup:F,required:N});return v("span",{class:R},[v("input",c({ref:i},V),null),v("span",{class:"".concat(e,"-inner")},null)])}}});export{L as V};
|
||||||
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 a,U as t,V as s,c as n,cD as _,a0 as o}from"./index-88195b71.js";const c={class:"img-sli-container"},i=a({__name:"ImgSliPagePane",props:{paneIdx:{},tabIdx:{},left:{},right:{}},setup(l){return(e,r)=>(t(),s("div",c,[n(_,{left:e.left,right:e.right},null,8,["left","right"])]))}});const d=o(i,[["__scopeId","data-v-ae3fb9a8"]]);export{d as default};
|
import{d as a,U as t,V as s,c as n,cD as _,a0 as o}from"./index-e20a7c5d.js";const c={class:"img-sli-container"},i=a({__name:"ImgSliPagePane",props:{paneIdx:{},tabIdx:{},left:{},right:{}},setup(l){return(e,r)=>(t(),s("div",c,[n(_,{left:e.left,right:e.right},null,8,["left","right"])]))}});const d=o(i,[["__scopeId","data-v-ae3fb9a8"]]);export{d 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 +1 @@
|
||||||
import{bU as i,b1 as t,dZ as f,bL as n}from"./index-88195b71.js";function u(e,s,r){if(!i(r))return!1;var a=typeof s;return(a=="number"?t(r)&&f(s,r.length):a=="string"&&s in r)?n(r[s],e):!1}export{u as i};
|
import{bU as i,b1 as t,e0 as f,bL as n}from"./index-e20a7c5d.js";function u(e,s,r){if(!i(r))return!1;var a=typeof s;return(a=="number"?t(r)&&f(s,r.length):a=="string"&&s in r)?n(r[s],e):!1}export{u as i};
|
||||||
|
|
@ -1 +1 @@
|
||||||
import{d as z,a1 as B,cE as $,cb as S,U as _,V as w,W as f,c as l,a3 as d,X as p,Y as c,a4 as s,a2 as A,af as E,cF as R,cG as y,z as V,B as x,ak as T,a0 as U}from"./index-88195b71.js";import{_ as N}from"./index-4a2d6de2.js";import{u as L,a as G,f as H,F as O,d as W}from"./FileItem-7ac27ad0.js";import"./numInput.vue_vue_type_style_index_0_scoped_55978858_lang-1a7f64c8.js";/* empty css */import"./_isIterateeCall-68480f5b.js";import"./index-a3d562b6.js";const j={class:"actions-panel actions"},q={class:"item"},P={key:0,class:"file-list"},Q={class:"hint"},X=z({__name:"batchDownload",props:{tabIdx:{},paneIdx:{},id:{}},setup(Y){const{stackViewEl:b}=L().toRefs(),{itemSize:h,gridItems:D,cellWidth:g}=G(),i=B(),m=H(),{selectdFiles:o}=$(m),r=S(),v=async e=>{const t=R(e);t&&m.addFiles(t.nodes)},C=async()=>{r.pushAction(async()=>{const e=await y.value.post("/zip",{paths:o.value.map(u=>u.fullpath),compress:i.batchDownloadCompress,pack_only:!1},{responseType:"blob"}),t=window.URL.createObjectURL(new Blob([e.data])),a=document.createElement("a");a.href=t,a.setAttribute("download",`iib_${new Date().toLocaleString()}.zip`),document.body.appendChild(a),a.click()})},I=async()=>{r.pushAction(async()=>{await y.value.post("/zip",{paths:o.value.map(e=>e.fullpath),compress:i.batchDownloadCompress,pack_only:!0},{responseType:"blob"}),V.success(x("success"))})},F=e=>{o.value.splice(e,1)};return(e,t)=>{const a=T,u=N;return _(),w("div",{class:"container",ref_key:"stackViewEl",ref:b,onDrop:v},[f("div",j,[l(a,{onClick:t[0]||(t[0]=n=>s(m).selectdFiles=[])},{default:d(()=>[p(c(e.$t("clear")),1)]),_:1}),f("div",q,[p(c(e.$t("compressFile"))+": ",1),l(u,{checked:s(i).batchDownloadCompress,"onUpdate:checked":t[1]||(t[1]=n=>s(i).batchDownloadCompress=n)},null,8,["checked"])]),l(a,{onClick:I,type:"primary",loading:!s(r).isIdle},{default:d(()=>[p(c(e.$t("packOnlyNotDownload")),1)]),_:1},8,["loading"]),l(a,{onClick:C,type:"primary",loading:!s(r).isIdle},{default:d(()=>[p(c(e.$t("zipDownload")),1)]),_:1},8,["loading"])]),s(o).length?(_(),A(s(W),{key:1,ref:"scroller",class:"file-list",items:s(o).slice(),"item-size":s(h).first,"key-field":"fullpath","item-secondary-size":s(h).second,gridItems:s(D)},{default:d(({item:n,index:k})=>[l(O,{idx:k,file:n,"cell-width":s(g),"enable-close-icon":"",onCloseIconClick:J=>F(k),"full-screen-preview-image-url":s(E)(n),"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"])):(_(),w("div",P,[f("p",Q,c(e.$t("batchDownloaDDragAndDropHint")),1)]))],544)}}});const oe=U(X,[["__scopeId","data-v-a2642a17"]]);export{oe as default};
|
import{d as z,a1 as B,cE as $,cb as S,U as _,V as w,W as f,c as l,a3 as d,X as p,Y as c,a4 as s,a2 as A,af as E,cF as R,cG as y,z as V,B as x,ak as T,a0 as U}from"./index-e20a7c5d.js";import{_ as N}from"./index-0b27168c.js";import{u as L,a as G,f as H,F as O,d as W}from"./FileItem-034eec0b.js";import"./numInput.vue_vue_type_style_index_0_scoped_55978858_lang-6616bb47.js";/* empty css */import"./_isIterateeCall-038c812a.js";import"./index-ac822435.js";const j={class:"actions-panel actions"},q={class:"item"},P={key:0,class:"file-list"},Q={class:"hint"},X=z({__name:"batchDownload",props:{tabIdx:{},paneIdx:{},id:{}},setup(Y){const{stackViewEl:b}=L().toRefs(),{itemSize:h,gridItems:D,cellWidth:g}=G(),i=B(),m=H(),{selectdFiles:o}=$(m),r=S(),v=async e=>{const t=R(e);t&&m.addFiles(t.nodes)},C=async()=>{r.pushAction(async()=>{const e=await y.value.post("/zip",{paths:o.value.map(u=>u.fullpath),compress:i.batchDownloadCompress,pack_only:!1},{responseType:"blob"}),t=window.URL.createObjectURL(new Blob([e.data])),a=document.createElement("a");a.href=t,a.setAttribute("download",`iib_${new Date().toLocaleString()}.zip`),document.body.appendChild(a),a.click()})},I=async()=>{r.pushAction(async()=>{await y.value.post("/zip",{paths:o.value.map(e=>e.fullpath),compress:i.batchDownloadCompress,pack_only:!0},{responseType:"blob"}),V.success(x("success"))})},F=e=>{o.value.splice(e,1)};return(e,t)=>{const a=T,u=N;return _(),w("div",{class:"container",ref_key:"stackViewEl",ref:b,onDrop:v},[f("div",j,[l(a,{onClick:t[0]||(t[0]=n=>s(m).selectdFiles=[])},{default:d(()=>[p(c(e.$t("clear")),1)]),_:1}),f("div",q,[p(c(e.$t("compressFile"))+": ",1),l(u,{checked:s(i).batchDownloadCompress,"onUpdate:checked":t[1]||(t[1]=n=>s(i).batchDownloadCompress=n)},null,8,["checked"])]),l(a,{onClick:I,type:"primary",loading:!s(r).isIdle},{default:d(()=>[p(c(e.$t("packOnlyNotDownload")),1)]),_:1},8,["loading"]),l(a,{onClick:C,type:"primary",loading:!s(r).isIdle},{default:d(()=>[p(c(e.$t("zipDownload")),1)]),_:1},8,["loading"])]),s(o).length?(_(),A(s(W),{key:1,ref:"scroller",class:"file-list",items:s(o).slice(),"item-size":s(h).first,"key-field":"fullpath","item-secondary-size":s(h).second,gridItems:s(D)},{default:d(({item:n,index:k})=>[l(O,{idx:k,file:n,"cell-width":s(g),"enable-close-icon":"",onCloseIconClick:J=>F(k),"full-screen-preview-image-url":s(E)(n),"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"])):(_(),w("div",P,[f("p",Q,c(e.$t("batchDownloaDDragAndDropHint")),1)]))],544)}}});const oe=U(X,[["__scopeId","data-v-a2642a17"]]);export{oe 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 +1 @@
|
||||||
import{u as w,a as y,F as k,d as x}from"./FileItem-7ac27ad0.js";import{d as F,a1 as h,c8 as b,r as D,bh as I,bl as C,U as V,V as E,c,a3 as z,a4 as e,af as S,cF as B,cH as R,a0 as A}from"./index-88195b71.js";import"./numInput.vue_vue_type_style_index_0_scoped_55978858_lang-1a7f64c8.js";/* empty css */import"./_isIterateeCall-68480f5b.js";import"./index-a3d562b6.js";const H=F({__name:"gridView",props:{tabIdx:{},paneIdx:{},id:{},removable:{type:Boolean},allowDragAndDrop:{type:Boolean},files:{},paneKey:{}},setup(p){const o=p,d=h(),{stackViewEl:m}=w().toRefs(),{itemSize:i,gridItems:u,cellWidth:f}=y(),g=b(),a=D(o.files??[]),_=async s=>{const l=B(s);o.allowDragAndDrop&&l&&(a.value=R([...a.value,...l.nodes]))},v=s=>{a.value.splice(s,1)};return I(()=>{d.pageFuncExportMap.set(o.paneKey,{getFiles:()=>C(a.value),setFiles:s=>a.value=s})}),(s,l)=>(V(),E("div",{class:"container",ref_key:"stackViewEl",ref:m,onDrop:_},[c(e(x),{ref:"scroller",class:"file-list",items:a.value.slice(),"item-size":e(i).first,"key-field":"fullpath","item-secondary-size":e(i).second,gridItems:e(u)},{default:z(({item:t,index:r})=>{var n;return[c(k,{idx:r,file:t,"cell-width":e(f),"enable-close-icon":o.removable,onCloseIconClick:K=>v(r),"full-screen-preview-image-url":e(S)(t),"extra-tags":(n=t==null?void 0:t.tags)==null?void 0:n.map(e(g).tagConvert),"enable-right-click-menu":!1},null,8,["idx","file","cell-width","enable-close-icon","onCloseIconClick","full-screen-preview-image-url","extra-tags"])]}),_:1},8,["items","item-size","item-secondary-size","gridItems"])],544))}});const N=A(H,[["__scopeId","data-v-f35f4802"]]);export{N as default};
|
import{u as w,a as y,F as k,d as x}from"./FileItem-034eec0b.js";import{d as F,a1 as h,c8 as b,r as D,bh as I,bl as C,U as V,V as E,c,a3 as z,a4 as e,af as S,cF as B,cH as R,a0 as A}from"./index-e20a7c5d.js";import"./numInput.vue_vue_type_style_index_0_scoped_55978858_lang-6616bb47.js";/* empty css */import"./_isIterateeCall-038c812a.js";import"./index-ac822435.js";const H=F({__name:"gridView",props:{tabIdx:{},paneIdx:{},id:{},removable:{type:Boolean},allowDragAndDrop:{type:Boolean},files:{},paneKey:{}},setup(p){const o=p,d=h(),{stackViewEl:m}=w().toRefs(),{itemSize:i,gridItems:u,cellWidth:f}=y(),g=b(),a=D(o.files??[]),_=async s=>{const l=B(s);o.allowDragAndDrop&&l&&(a.value=R([...a.value,...l.nodes]))},v=s=>{a.value.splice(s,1)};return I(()=>{d.pageFuncExportMap.set(o.paneKey,{getFiles:()=>C(a.value),setFiles:s=>a.value=s})}),(s,l)=>(V(),E("div",{class:"container",ref_key:"stackViewEl",ref:m,onDrop:_},[c(e(x),{ref:"scroller",class:"file-list",items:a.value.slice(),"item-size":e(i).first,"key-field":"fullpath","item-secondary-size":e(i).second,gridItems:e(u)},{default:z(({item:t,index:r})=>{var n;return[c(k,{idx:r,file:t,"cell-width":e(f),"enable-close-icon":o.removable,onCloseIconClick:K=>v(r),"full-screen-preview-image-url":e(S)(t),"extra-tags":(n=t==null?void 0:t.tags)==null?void 0:n.map(e(g).tagConvert),"enable-right-click-menu":!1},null,8,["idx","file","cell-width","enable-close-icon","onCloseIconClick","full-screen-preview-image-url","extra-tags"])]}),_:1},8,["items","item-size","item-secondary-size","gridItems"])],544))}});const N=A(H,[["__scopeId","data-v-f35f4802"]]);export{N as default};
|
||||||
|
|
@ -1 +1 @@
|
||||||
import{am as F,r as g,l as P,k as A,O as b,G as R,cb as q,cm as O,cr as z}from"./index-88195b71.js";import{u as L,a as Q,b as j,e as H}from"./FileItem-7ac27ad0.js";import{a as T,b as U,c as W}from"./MultiSelectKeep-59d164ab.js";import{u as B}from"./useGenInfoDiff-9898302d.js";let K=0;const V=()=>++K,X=(n,i,{dataUpdateStrategy:l="replace"}={})=>{const o=F([""]),c=g(!1),t=g(),a=g(!1);let f=g(-1);const v=new Set,w=e=>{var s;l==="replace"?t.value=e:l==="merge"&&(b((Array.isArray(t.value)||typeof t.value>"u")&&Array.isArray(e),"数据更新策略为合并时仅可用于值为数组的情况"),t.value=[...(s=t==null?void 0:t.value)!==null&&s!==void 0?s:[],...e])},d=e=>A(void 0,void 0,void 0,function*(){if(a.value||c.value&&typeof e>"u")return!1;a.value=!0;const s=V();f.value=s;try{let r;if(typeof e=="number"){if(r=o[e],typeof r!="string")return!1}else r=o[o.length-1];const h=yield n(r);if(v.has(s))return v.delete(s),!1;w(i(h));const u=h.cursor;if((e===o.length-1||typeof e!="number")&&(c.value=!u.has_next,u.has_next)){const m=u.next_cursor||u.next;b(typeof m=="string"),o.push(m)}}finally{f.value===s&&(a.value=!1)}return!0}),p=()=>{v.add(f.value),a.value=!1},x=(e=!1)=>A(void 0,void 0,void 0,function*(){const{refetch:s,force:r}=typeof e=="object"?e:{refetch:e};r&&p(),b(!a.value),o.splice(0,o.length,""),a.value=!1,t.value=void 0,c.value=!1,s&&(yield d())}),I=()=>({next:()=>A(void 0,void 0,void 0,function*(){if(a.value)throw new Error("不允许同时迭代");return{done:!(yield d()),value:t.value}})});return P({abort:p,load:c,next:d,res:t,loading:a,cursorStack:o,reset:x,[Symbol.asyncIterator]:I,iter:{[Symbol.asyncIterator]:I}})},se=n=>F(X(n,i=>i.files,{dataUpdateStrategy:"merge"})),ne=n=>{const i=F(new Set),l=R(()=>(n.res??[]).filter(y=>!i.has(y.fullpath))),o=q(),{stackViewEl:c,multiSelectedIdxs:t,stack:a,scroller:f,props:v}=L({images:l}).toRefs(),{itemSize:w,gridItems:d,cellWidth:p,onScroll:x}=Q({fetchNext:()=>n.next()}),{showMenuIdx:I}=j(),{onFileDragStart:e,onFileDragEnd:s}=T(),{showGenInfo:r,imageGenInfo:h,q:u,onContextMenuClick:m,onFileItemClick:C}=U({openNext:O}),{previewIdx:_,previewing:E,onPreviewVisibleChange:M,previewImgMove:D,canPreview:G}=W({loadNext:()=>n.next()}),J=async(y,S,N)=>{a.value=[{curr:"",files:l.value}],await m(y,S,N)};H("removeFiles",async({paths:y})=>{y.forEach(S=>i.add(S))});const k=()=>{z(l.value)};return{images:l,scroller:f,queue:o,iter:n,onContextMenuClickU:J,stackViewEl:c,previewIdx:_,previewing:E,onPreviewVisibleChange:M,previewImgMove:D,canPreview:G,itemSize:w,gridItems:d,showGenInfo:r,imageGenInfo:h,q:u,onContextMenuClick:m,onFileItemClick:C,showMenuIdx:I,multiSelectedIdxs:t,onFileDragStart:e,onFileDragEnd:s,cellWidth:p,onScroll:x,saveLoadedFileAsJson:k,saveAllFileAsJson:async()=>{for(;!n.load;)await n.next();k()},props:v,...B()}};export{se as c,ne as u};
|
import{am as F,r as g,l as P,k as A,O as b,G as R,cb as q,cm as O,cr as z}from"./index-e20a7c5d.js";import{u as L,a as Q,b as j,e as H}from"./FileItem-034eec0b.js";import{a as T,b as U,c as W}from"./MultiSelectKeep-601528da.js";import{u as B}from"./useGenInfoDiff-ce9027fb.js";let K=0;const V=()=>++K,X=(n,i,{dataUpdateStrategy:l="replace"}={})=>{const o=F([""]),c=g(!1),t=g(),a=g(!1);let f=g(-1);const v=new Set,w=e=>{var s;l==="replace"?t.value=e:l==="merge"&&(b((Array.isArray(t.value)||typeof t.value>"u")&&Array.isArray(e),"数据更新策略为合并时仅可用于值为数组的情况"),t.value=[...(s=t==null?void 0:t.value)!==null&&s!==void 0?s:[],...e])},d=e=>A(void 0,void 0,void 0,function*(){if(a.value||c.value&&typeof e>"u")return!1;a.value=!0;const s=V();f.value=s;try{let r;if(typeof e=="number"){if(r=o[e],typeof r!="string")return!1}else r=o[o.length-1];const h=yield n(r);if(v.has(s))return v.delete(s),!1;w(i(h));const u=h.cursor;if((e===o.length-1||typeof e!="number")&&(c.value=!u.has_next,u.has_next)){const m=u.next_cursor||u.next;b(typeof m=="string"),o.push(m)}}finally{f.value===s&&(a.value=!1)}return!0}),p=()=>{v.add(f.value),a.value=!1},x=(e=!1)=>A(void 0,void 0,void 0,function*(){const{refetch:s,force:r}=typeof e=="object"?e:{refetch:e};r&&p(),b(!a.value),o.splice(0,o.length,""),a.value=!1,t.value=void 0,c.value=!1,s&&(yield d())}),I=()=>({next:()=>A(void 0,void 0,void 0,function*(){if(a.value)throw new Error("不允许同时迭代");return{done:!(yield d()),value:t.value}})});return P({abort:p,load:c,next:d,res:t,loading:a,cursorStack:o,reset:x,[Symbol.asyncIterator]:I,iter:{[Symbol.asyncIterator]:I}})},se=n=>F(X(n,i=>i.files,{dataUpdateStrategy:"merge"})),ne=n=>{const i=F(new Set),l=R(()=>(n.res??[]).filter(y=>!i.has(y.fullpath))),o=q(),{stackViewEl:c,multiSelectedIdxs:t,stack:a,scroller:f,props:v}=L({images:l}).toRefs(),{itemSize:w,gridItems:d,cellWidth:p,onScroll:x}=Q({fetchNext:()=>n.next()}),{showMenuIdx:I}=j(),{onFileDragStart:e,onFileDragEnd:s}=T(),{showGenInfo:r,imageGenInfo:h,q:u,onContextMenuClick:m,onFileItemClick:C}=U({openNext:O}),{previewIdx:_,previewing:E,onPreviewVisibleChange:M,previewImgMove:D,canPreview:G}=W({loadNext:()=>n.next()}),J=async(y,S,N)=>{a.value=[{curr:"",files:l.value}],await m(y,S,N)};H("removeFiles",async({paths:y})=>{y.forEach(S=>i.add(S))});const k=()=>{z(l.value)};return{images:l,scroller:f,queue:o,iter:n,onContextMenuClickU:J,stackViewEl:c,previewIdx:_,previewing:E,onPreviewVisibleChange:M,previewImgMove:D,canPreview:G,itemSize:w,gridItems:d,showGenInfo:r,imageGenInfo:h,q:u,onContextMenuClick:m,onFileItemClick:C,showMenuIdx:I,multiSelectedIdxs:t,onFileDragStart:e,onFileDragEnd:s,cellWidth:p,onScroll:x,saveLoadedFileAsJson:k,saveAllFileAsJson:async()=>{for(;!n.load;)await n.next();k()},props:v,...B()}};export{se as c,ne as u};
|
||||||
|
|
@ -1 +1 @@
|
||||||
import{cv as j,ay as z,d as K,j as U,dg as $,w,r as b,G as S,m as A,u as D,o as E,az as G,h as d,c as s,a as C,aw as H,bf as L,g as _,dh as W,P as c,di as x}from"./index-88195b71.js";var R=z("small","default"),q=function(){return{id:String,prefixCls:String,size:c.oneOf(R),disabled:{type:Boolean,default:void 0},checkedChildren:c.any,unCheckedChildren:c.any,tabindex:c.oneOfType([c.string,c.number]),autofocus:{type:Boolean,default:void 0},loading:{type:Boolean,default:void 0},checked:c.oneOfType([c.string,c.number,c.looseBool]),checkedValue:c.oneOfType([c.string,c.number,c.looseBool]).def(!0),unCheckedValue:c.oneOfType([c.string,c.number,c.looseBool]).def(!1),onChange:{type:Function},onClick:{type:Function},onKeydown:{type:Function},onMouseup:{type:Function},"onUpdate:checked":{type:Function},onBlur:Function,onFocus:Function}},J=K({compatConfig:{MODE:3},name:"ASwitch",__ANT_SWITCH:!0,inheritAttrs:!1,props:q(),slots:["checkedChildren","unCheckedChildren"],setup:function(n,r){var o=r.attrs,y=r.slots,B=r.expose,l=r.emit,m=U();$(function(){w(!("defaultChecked"in o),"Switch","'defaultChecked' is deprecated, please use 'v-model:checked'"),w(!("value"in o),"Switch","`value` is not validate prop, do you mean `checked`?")});var h=b(n.checked!==void 0?n.checked:o.defaultChecked),f=S(function(){return h.value===n.checkedValue});A(function(){return n.checked},function(){h.value=n.checked});var v=D("switch",n),u=v.prefixCls,F=v.direction,T=v.size,i=b(),g=function(){var e;(e=i.value)===null||e===void 0||e.focus()},V=function(){var e;(e=i.value)===null||e===void 0||e.blur()};B({focus:g,blur:V}),E(function(){G(function(){n.autofocus&&!n.disabled&&i.value.focus()})});var k=function(e,t){n.disabled||(l("update:checked",e),l("change",e,t),m.onFieldChange())},I=function(e){l("blur",e)},N=function(e){g();var t=f.value?n.unCheckedValue:n.checkedValue;k(t,e),l("click",t,e)},M=function(e){e.keyCode===x.LEFT?k(n.unCheckedValue,e):e.keyCode===x.RIGHT&&k(n.checkedValue,e),l("keydown",e)},O=function(e){var t;(t=i.value)===null||t===void 0||t.blur(),l("mouseup",e)},P=S(function(){var a;return a={},d(a,"".concat(u.value,"-small"),T.value==="small"),d(a,"".concat(u.value,"-loading"),n.loading),d(a,"".concat(u.value,"-checked"),f.value),d(a,"".concat(u.value,"-disabled"),n.disabled),d(a,u.value,!0),d(a,"".concat(u.value,"-rtl"),F.value==="rtl"),a});return function(){var a;return s(W,{insertExtraNode:!0},{default:function(){return[s("button",C(C(C({},H(n,["prefixCls","checkedChildren","unCheckedChildren","checked","autofocus","checkedValue","unCheckedValue","id","onChange","onUpdate:checked"])),o),{},{id:(a=n.id)!==null&&a!==void 0?a:m.id.value,onKeydown:M,onClick:N,onBlur:I,onMouseup:O,type:"button",role:"switch","aria-checked":h.value,disabled:n.disabled||n.loading,class:[o.class,P.value],ref:i}),[s("div",{class:"".concat(u.value,"-handle")},[n.loading?s(L,{class:"".concat(u.value,"-loading-icon")},null):null]),s("span",{class:"".concat(u.value,"-inner")},[f.value?_(y,n,"checkedChildren"):_(y,n,"unCheckedChildren")])])]}})}}});const X=j(J);export{X as _};
|
import{cv as P,ay as z,d as K,j as U,di as $,w,r as b,G as S,m as A,u as D,o as E,az as G,h as d,c as s,a as C,aw as H,bf as L,g as _,dj as W,P as c,dk as x}from"./index-e20a7c5d.js";var R=z("small","default"),q=function(){return{id:String,prefixCls:String,size:c.oneOf(R),disabled:{type:Boolean,default:void 0},checkedChildren:c.any,unCheckedChildren:c.any,tabindex:c.oneOfType([c.string,c.number]),autofocus:{type:Boolean,default:void 0},loading:{type:Boolean,default:void 0},checked:c.oneOfType([c.string,c.number,c.looseBool]),checkedValue:c.oneOfType([c.string,c.number,c.looseBool]).def(!0),unCheckedValue:c.oneOfType([c.string,c.number,c.looseBool]).def(!1),onChange:{type:Function},onClick:{type:Function},onKeydown:{type:Function},onMouseup:{type:Function},"onUpdate:checked":{type:Function},onBlur:Function,onFocus:Function}},J=K({compatConfig:{MODE:3},name:"ASwitch",__ANT_SWITCH:!0,inheritAttrs:!1,props:q(),slots:["checkedChildren","unCheckedChildren"],setup:function(n,r){var o=r.attrs,y=r.slots,B=r.expose,l=r.emit,m=U();$(function(){w(!("defaultChecked"in o),"Switch","'defaultChecked' is deprecated, please use 'v-model:checked'"),w(!("value"in o),"Switch","`value` is not validate prop, do you mean `checked`?")});var h=b(n.checked!==void 0?n.checked:o.defaultChecked),f=S(function(){return h.value===n.checkedValue});A(function(){return n.checked},function(){h.value=n.checked});var v=D("switch",n),u=v.prefixCls,F=v.direction,T=v.size,i=b(),g=function(){var e;(e=i.value)===null||e===void 0||e.focus()},V=function(){var e;(e=i.value)===null||e===void 0||e.blur()};B({focus:g,blur:V}),E(function(){G(function(){n.autofocus&&!n.disabled&&i.value.focus()})});var k=function(e,t){n.disabled||(l("update:checked",e),l("change",e,t),m.onFieldChange())},I=function(e){l("blur",e)},N=function(e){g();var t=f.value?n.unCheckedValue:n.checkedValue;k(t,e),l("click",t,e)},M=function(e){e.keyCode===x.LEFT?k(n.unCheckedValue,e):e.keyCode===x.RIGHT&&k(n.checkedValue,e),l("keydown",e)},O=function(e){var t;(t=i.value)===null||t===void 0||t.blur(),l("mouseup",e)},j=S(function(){var a;return a={},d(a,"".concat(u.value,"-small"),T.value==="small"),d(a,"".concat(u.value,"-loading"),n.loading),d(a,"".concat(u.value,"-checked"),f.value),d(a,"".concat(u.value,"-disabled"),n.disabled),d(a,u.value,!0),d(a,"".concat(u.value,"-rtl"),F.value==="rtl"),a});return function(){var a;return s(W,{insertExtraNode:!0},{default:function(){return[s("button",C(C(C({},H(n,["prefixCls","checkedChildren","unCheckedChildren","checked","autofocus","checkedValue","unCheckedValue","id","onChange","onUpdate:checked"])),o),{},{id:(a=n.id)!==null&&a!==void 0?a:m.id.value,onKeydown:M,onClick:N,onBlur:I,onMouseup:O,type:"button",role:"switch","aria-checked":h.value,disabled:n.disabled||n.loading,class:[o.class,j.value],ref:i}),[s("div",{class:"".concat(u.value,"-handle")},[n.loading?s(L,{class:"".concat(u.value,"-loading-icon")},null):null]),s("span",{class:"".concat(u.value,"-inner")},[f.value?_(y,n,"checkedChildren"):_(y,n,"unCheckedChildren")])])]}})}}});const X=P(J);export{X as _};
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
||||||
import{r as F,o as P,cw as K,av as L,G as l,ax as T,ay as $,d as I,u as B,cx as _,b as y,bk as V,cy as A,an as E,h as c,c as M,a as G}from"./index-88195b71.js";const W=function(){var o=F(!1);return P(function(){o.value=K()}),o};var D=Symbol("rowContextKey"),k=function(r){T(D,r)},U=function(){return L(D,{gutter:l(function(){}),wrap:l(function(){}),supportFlexGap:l(function(){})})};$("top","middle","bottom","stretch");$("start","end","center","space-around","space-between");var q=function(){return{align:String,justify:String,prefixCls:String,gutter:{type:[Number,Array,Object],default:0},wrap:{type:Boolean,default:void 0}}},H=I({compatConfig:{MODE:3},name:"ARow",props:q(),setup:function(r,N){var m=N.slots,v=B("row",r),d=v.prefixCls,h=v.direction,j,x=F({xs:!0,sm:!0,md:!0,lg:!0,xl:!0,xxl:!0,xxxl:!0}),w=W();P(function(){j=_.subscribe(function(e){var t=r.gutter||0;(!Array.isArray(t)&&y(t)==="object"||Array.isArray(t)&&(y(t[0])==="object"||y(t[1])==="object"))&&(x.value=e)})}),V(function(){_.unsubscribe(j)});var S=l(function(){var e=[0,0],t=r.gutter,n=t===void 0?0:t,s=Array.isArray(n)?n:[n,0];return s.forEach(function(i,b){if(y(i)==="object")for(var a=0;a<A.length;a++){var p=A[a];if(x.value[p]&&i[p]!==void 0){e[b]=i[p];break}}else e[b]=i||0}),e});k({gutter:S,supportFlexGap:w,wrap:l(function(){return r.wrap})});var R=l(function(){var e;return E(d.value,(e={},c(e,"".concat(d.value,"-no-wrap"),r.wrap===!1),c(e,"".concat(d.value,"-").concat(r.justify),r.justify),c(e,"".concat(d.value,"-").concat(r.align),r.align),c(e,"".concat(d.value,"-rtl"),h.value==="rtl"),e))}),O=l(function(){var e=S.value,t={},n=e[0]>0?"".concat(e[0]/-2,"px"):void 0,s=e[1]>0?"".concat(e[1]/-2,"px"):void 0;return n&&(t.marginLeft=n,t.marginRight=n),w.value?t.rowGap="".concat(e[1],"px"):s&&(t.marginTop=s,t.marginBottom=s),t});return function(){var e;return M("div",{class:R.value,style:O.value},[(e=m.default)===null||e===void 0?void 0:e.call(m)])}}});const Y=H;function J(o){return typeof o=="number"?"".concat(o," ").concat(o," auto"):/^\d+(\.\d+)?(px|em|rem|%)$/.test(o)?"0 0 ".concat(o):o}var Q=function(){return{span:[String,Number],order:[String,Number],offset:[String,Number],push:[String,Number],pull:[String,Number],xs:{type:[String,Number,Object],default:void 0},sm:{type:[String,Number,Object],default:void 0},md:{type:[String,Number,Object],default:void 0},lg:{type:[String,Number,Object],default:void 0},xl:{type:[String,Number,Object],default:void 0},xxl:{type:[String,Number,Object],default:void 0},xxxl:{type:[String,Number,Object],default:void 0},prefixCls:String,flex:[String,Number]}};const Z=I({compatConfig:{MODE:3},name:"ACol",props:Q(),setup:function(r,N){var m=N.slots,v=U(),d=v.gutter,h=v.supportFlexGap,j=v.wrap,x=B("col",r),w=x.prefixCls,S=x.direction,R=l(function(){var e,t=r.span,n=r.order,s=r.offset,i=r.push,b=r.pull,a=w.value,p={};return["xs","sm","md","lg","xl","xxl","xxxl"].forEach(function(g){var f,u={},C=r[g];typeof C=="number"?u.span=C:y(C)==="object"&&(u=C||{}),p=G(G({},p),{},(f={},c(f,"".concat(a,"-").concat(g,"-").concat(u.span),u.span!==void 0),c(f,"".concat(a,"-").concat(g,"-order-").concat(u.order),u.order||u.order===0),c(f,"".concat(a,"-").concat(g,"-offset-").concat(u.offset),u.offset||u.offset===0),c(f,"".concat(a,"-").concat(g,"-push-").concat(u.push),u.push||u.push===0),c(f,"".concat(a,"-").concat(g,"-pull-").concat(u.pull),u.pull||u.pull===0),c(f,"".concat(a,"-rtl"),S.value==="rtl"),f))}),E(a,(e={},c(e,"".concat(a,"-").concat(t),t!==void 0),c(e,"".concat(a,"-order-").concat(n),n),c(e,"".concat(a,"-offset-").concat(s),s),c(e,"".concat(a,"-push-").concat(i),i),c(e,"".concat(a,"-pull-").concat(b),b),e),p)}),O=l(function(){var e=r.flex,t=d.value,n={};if(t&&t[0]>0){var s="".concat(t[0]/2,"px");n.paddingLeft=s,n.paddingRight=s}if(t&&t[1]>0&&!h.value){var i="".concat(t[1]/2,"px");n.paddingTop=i,n.paddingBottom=i}return e&&(n.flex=J(e),j.value===!1&&!n.minWidth&&(n.minWidth=0)),n});return function(){var e;return M("div",{class:R.value,style:O.value},[(e=m.default)===null||e===void 0?void 0:e.call(m)])}}});export{Z as C,Y as R};
|
import{r as F,o as P,cw as K,av as L,G as l,ax as T,ay as $,d as I,u as B,cx as _,b as y,bk as V,cy as A,an as E,h as c,c as M,a as G}from"./index-e20a7c5d.js";const W=function(){var o=F(!1);return P(function(){o.value=K()}),o};var D=Symbol("rowContextKey"),k=function(r){T(D,r)},U=function(){return L(D,{gutter:l(function(){}),wrap:l(function(){}),supportFlexGap:l(function(){})})};$("top","middle","bottom","stretch");$("start","end","center","space-around","space-between");var q=function(){return{align:String,justify:String,prefixCls:String,gutter:{type:[Number,Array,Object],default:0},wrap:{type:Boolean,default:void 0}}},H=I({compatConfig:{MODE:3},name:"ARow",props:q(),setup:function(r,N){var m=N.slots,v=B("row",r),d=v.prefixCls,h=v.direction,j,x=F({xs:!0,sm:!0,md:!0,lg:!0,xl:!0,xxl:!0,xxxl:!0}),w=W();P(function(){j=_.subscribe(function(e){var t=r.gutter||0;(!Array.isArray(t)&&y(t)==="object"||Array.isArray(t)&&(y(t[0])==="object"||y(t[1])==="object"))&&(x.value=e)})}),V(function(){_.unsubscribe(j)});var S=l(function(){var e=[0,0],t=r.gutter,n=t===void 0?0:t,s=Array.isArray(n)?n:[n,0];return s.forEach(function(i,b){if(y(i)==="object")for(var a=0;a<A.length;a++){var p=A[a];if(x.value[p]&&i[p]!==void 0){e[b]=i[p];break}}else e[b]=i||0}),e});k({gutter:S,supportFlexGap:w,wrap:l(function(){return r.wrap})});var R=l(function(){var e;return E(d.value,(e={},c(e,"".concat(d.value,"-no-wrap"),r.wrap===!1),c(e,"".concat(d.value,"-").concat(r.justify),r.justify),c(e,"".concat(d.value,"-").concat(r.align),r.align),c(e,"".concat(d.value,"-rtl"),h.value==="rtl"),e))}),O=l(function(){var e=S.value,t={},n=e[0]>0?"".concat(e[0]/-2,"px"):void 0,s=e[1]>0?"".concat(e[1]/-2,"px"):void 0;return n&&(t.marginLeft=n,t.marginRight=n),w.value?t.rowGap="".concat(e[1],"px"):s&&(t.marginTop=s,t.marginBottom=s),t});return function(){var e;return M("div",{class:R.value,style:O.value},[(e=m.default)===null||e===void 0?void 0:e.call(m)])}}});const Y=H;function J(o){return typeof o=="number"?"".concat(o," ").concat(o," auto"):/^\d+(\.\d+)?(px|em|rem|%)$/.test(o)?"0 0 ".concat(o):o}var Q=function(){return{span:[String,Number],order:[String,Number],offset:[String,Number],push:[String,Number],pull:[String,Number],xs:{type:[String,Number,Object],default:void 0},sm:{type:[String,Number,Object],default:void 0},md:{type:[String,Number,Object],default:void 0},lg:{type:[String,Number,Object],default:void 0},xl:{type:[String,Number,Object],default:void 0},xxl:{type:[String,Number,Object],default:void 0},xxxl:{type:[String,Number,Object],default:void 0},prefixCls:String,flex:[String,Number]}};const Z=I({compatConfig:{MODE:3},name:"ACol",props:Q(),setup:function(r,N){var m=N.slots,v=U(),d=v.gutter,h=v.supportFlexGap,j=v.wrap,x=B("col",r),w=x.prefixCls,S=x.direction,R=l(function(){var e,t=r.span,n=r.order,s=r.offset,i=r.push,b=r.pull,a=w.value,p={};return["xs","sm","md","lg","xl","xxl","xxxl"].forEach(function(g){var f,u={},C=r[g];typeof C=="number"?u.span=C:y(C)==="object"&&(u=C||{}),p=G(G({},p),{},(f={},c(f,"".concat(a,"-").concat(g,"-").concat(u.span),u.span!==void 0),c(f,"".concat(a,"-").concat(g,"-order-").concat(u.order),u.order||u.order===0),c(f,"".concat(a,"-").concat(g,"-offset-").concat(u.offset),u.offset||u.offset===0),c(f,"".concat(a,"-").concat(g,"-push-").concat(u.push),u.push||u.push===0),c(f,"".concat(a,"-").concat(g,"-pull-").concat(u.pull),u.pull||u.pull===0),c(f,"".concat(a,"-rtl"),S.value==="rtl"),f))}),E(a,(e={},c(e,"".concat(a,"-").concat(t),t!==void 0),c(e,"".concat(a,"-order-").concat(n),n),c(e,"".concat(a,"-offset-").concat(s),s),c(e,"".concat(a,"-push-").concat(i),i),c(e,"".concat(a,"-pull-").concat(b),b),e),p)}),O=l(function(){var e=r.flex,t=d.value,n={};if(t&&t[0]>0){var s="".concat(t[0]/2,"px");n.paddingLeft=s,n.paddingRight=s}if(t&&t[1]>0&&!h.value){var i="".concat(t[1]/2,"px");n.paddingTop=i,n.paddingBottom=i}return e&&(n.flex=J(e),j.value===!1&&!n.minWidth&&(n.minWidth=0)),n});return function(){var e;return M("div",{class:R.value,style:O.value},[(e=m.default)===null||e===void 0?void 0:e.call(m)])}}});export{Z as C,Y as R};
|
||||||
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 x,a1 as $,aK as g,cI as b,r as w,U as p,V as i,W as a,c as r,a3 as d,X as u,Y as n,Z as B,a8 as I,a4 as m,y as V,z as _,B as v,aj as W,ak as D,cJ as N,a0 as R}from"./index-88195b71.js";/* empty css */const F={class:"container"},K={class:"actions"},L={class:"uni-desc"},U={class:"snapshot"},j=x({__name:"index",props:{tabIdx:{},paneIdx:{},id:{},paneKey:{}},setup(q){const h=$(),t=g(),f=e=>{h.tabList=V(e.tabs)},k=b(async e=>{await N(`workspace_snapshot_${e.id}`),t.snapshots=t.snapshots.filter(c=>c.id!==e.id),_.success(v("deleteSuccess"))}),o=w(""),y=async()=>{if(!o.value){_.error(v("nameRequired"));return}const e=t.createSnapshot(o.value);await t.addSnapshot(e),_.success(v("saveCompleted"))};return(e,c)=>{const C=W,l=D;return p(),i("div",F,[a("div",K,[r(C,{value:o.value,"onUpdate:value":c[0]||(c[0]=s=>o.value=s),placeholder:e.$t("name"),style:{"max-width":"300px"}},null,8,["value","placeholder"]),r(l,{type:"primary",onClick:y},{default:d(()=>[u(n(e.$t("saveWorkspaceSnapshot")),1)]),_:1})]),a("p",L,n(e.$t("WorkspaceSnapshotDesc")),1),a("ul",U,[(p(!0),i(B,null,I(m(t).snapshots,s=>(p(),i("li",{key:s.id},[a("div",null,[a("span",null,n(s.name),1)]),a("div",null,[r(l,{onClick:S=>f(s)},{default:d(()=>[u(n(e.$t("restore")),1)]),_:2},1032,["onClick"]),r(l,{onClick:S=>m(k)(s)},{default:d(()=>[u(n(e.$t("remove")),1)]),_:2},1032,["onClick"])])]))),128))])])}}});const E=R(j,[["__scopeId","data-v-2c44013c"]]);export{E as default};
|
import{d as x,a1 as $,aK as g,cI as b,r as w,U as p,V as i,W as a,c as r,a3 as d,X as u,Y as n,Z as B,a8 as I,a4 as m,y as V,z as _,B as v,aj as W,ak as D,cJ as N,a0 as R}from"./index-e20a7c5d.js";/* empty css */const F={class:"container"},K={class:"actions"},L={class:"uni-desc"},U={class:"snapshot"},j=x({__name:"index",props:{tabIdx:{},paneIdx:{},id:{},paneKey:{}},setup(q){const h=$(),t=g(),f=e=>{h.tabList=V(e.tabs)},k=b(async e=>{await N(`workspace_snapshot_${e.id}`),t.snapshots=t.snapshots.filter(c=>c.id!==e.id),_.success(v("deleteSuccess"))}),o=w(""),y=async()=>{if(!o.value){_.error(v("nameRequired"));return}const e=t.createSnapshot(o.value);await t.addSnapshot(e),_.success(v("saveCompleted"))};return(e,c)=>{const C=W,l=D;return p(),i("div",F,[a("div",K,[r(C,{value:o.value,"onUpdate:value":c[0]||(c[0]=s=>o.value=s),placeholder:e.$t("name"),style:{"max-width":"300px"}},null,8,["value","placeholder"]),r(l,{type:"primary",onClick:y},{default:d(()=>[u(n(e.$t("saveWorkspaceSnapshot")),1)]),_:1})]),a("p",L,n(e.$t("WorkspaceSnapshotDesc")),1),a("ul",U,[(p(!0),i(B,null,I(m(t).snapshots,s=>(p(),i("li",{key:s.id},[a("div",null,[a("span",null,n(s.name),1)]),a("div",null,[r(l,{onClick:S=>f(s)},{default:d(()=>[u(n(e.$t("restore")),1)]),_:2},1032,["onClick"]),r(l,{onClick:S=>m(k)(s)},{default:d(()=>[u(n(e.$t("remove")),1)]),_:2},1032,["onClick"])])]))),128))])])}}});const E=R(j,[["__scopeId","data-v-2c44013c"]]);export{E as default};
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
||||||
import{d as w,bC as A,av as D,cz as j,az as k,n as B,cA as V,cB as y,e as $,c as a,_ as T,h as r,a as P,cC as M,P as b}from"./index-88195b71.js";var O=["class","style"],W=function(){return{prefixCls:String,spinning:{type:Boolean,default:void 0},size:String,wrapperClassName:String,tip:b.any,delay:Number,indicator:b.any}},p=null;function q(t,n){return!!t&&!!n&&!isNaN(Number(n))}function G(t){var n=t.indicator;p=typeof n=="function"?n:function(){return a(n,null,null)}}const H=w({compatConfig:{MODE:3},name:"ASpin",inheritAttrs:!1,props:A(W(),{size:"default",spinning:!0,wrapperClassName:""}),setup:function(){return{originalUpdateSpinning:null,configProvider:D("configProvider",j)}},data:function(){var n=this.spinning,e=this.delay,i=q(n,e);return{sSpinning:n&&!i}},created:function(){this.originalUpdateSpinning=this.updateSpinning,this.debouncifyUpdateSpinning(this.$props)},mounted:function(){this.updateSpinning()},updated:function(){var n=this;k(function(){n.debouncifyUpdateSpinning(),n.updateSpinning()})},beforeUnmount:function(){this.cancelExistingSpin()},methods:{debouncifyUpdateSpinning:function(n){var e=n||this.$props,i=e.delay;i&&(this.cancelExistingSpin(),this.updateSpinning=B(this.originalUpdateSpinning,i))},updateSpinning:function(){var n=this.spinning,e=this.sSpinning;e!==n&&(this.sSpinning=n)},cancelExistingSpin:function(){var n=this.updateSpinning;n&&n.cancel&&n.cancel()},renderIndicator:function(n){var e="".concat(n,"-dot"),i=V(this,"indicator");return i===null?null:(Array.isArray(i)&&(i=i.length===1?i[0]:i),y(i)?$(i,{class:e}):p&&y(p())?$(p(),{class:e}):a("span",{class:"".concat(e," ").concat(n,"-dot-spin")},[a("i",{class:"".concat(n,"-dot-item")},null),a("i",{class:"".concat(n,"-dot-item")},null),a("i",{class:"".concat(n,"-dot-item")},null),a("i",{class:"".concat(n,"-dot-item")},null)]))}},render:function(){var n,e,i,o=this.$props,f=o.size,x=o.prefixCls,h=o.tip,d=h===void 0?(n=(e=this.$slots).tip)===null||n===void 0?void 0:n.call(e):h,C=o.wrapperClassName,l=this.$attrs,v=l.class,N=l.style,_=T(l,O),S=this.configProvider,U=S.getPrefixCls,z=S.direction,s=U("spin",x),u=this.sSpinning,E=(i={},r(i,s,!0),r(i,"".concat(s,"-sm"),f==="small"),r(i,"".concat(s,"-lg"),f==="large"),r(i,"".concat(s,"-spinning"),u),r(i,"".concat(s,"-show-text"),!!d),r(i,"".concat(s,"-rtl"),z==="rtl"),r(i,v,!!v),i),m=a("div",P(P({},_),{},{style:N,class:E}),[this.renderIndicator(s),d?a("div",{class:"".concat(s,"-text")},[d]):null]),g=M(this);if(g&&g.length){var c,I=(c={},r(c,"".concat(s,"-container"),!0),r(c,"".concat(s,"-blur"),u),c);return a("div",{class:["".concat(s,"-nested-loading"),C]},[u&&a("div",{key:"loading"},[m]),a("div",{class:I,key:"container"},[g])])}return m}});export{H as S,G as s};
|
import{d as w,bC as A,av as D,cz as j,az as k,n as B,cA as V,cB as y,e as $,c as a,_ as T,h as r,a as P,cC as M,P as b}from"./index-e20a7c5d.js";var O=["class","style"],W=function(){return{prefixCls:String,spinning:{type:Boolean,default:void 0},size:String,wrapperClassName:String,tip:b.any,delay:Number,indicator:b.any}},p=null;function q(t,n){return!!t&&!!n&&!isNaN(Number(n))}function G(t){var n=t.indicator;p=typeof n=="function"?n:function(){return a(n,null,null)}}const H=w({compatConfig:{MODE:3},name:"ASpin",inheritAttrs:!1,props:A(W(),{size:"default",spinning:!0,wrapperClassName:""}),setup:function(){return{originalUpdateSpinning:null,configProvider:D("configProvider",j)}},data:function(){var n=this.spinning,e=this.delay,i=q(n,e);return{sSpinning:n&&!i}},created:function(){this.originalUpdateSpinning=this.updateSpinning,this.debouncifyUpdateSpinning(this.$props)},mounted:function(){this.updateSpinning()},updated:function(){var n=this;k(function(){n.debouncifyUpdateSpinning(),n.updateSpinning()})},beforeUnmount:function(){this.cancelExistingSpin()},methods:{debouncifyUpdateSpinning:function(n){var e=n||this.$props,i=e.delay;i&&(this.cancelExistingSpin(),this.updateSpinning=B(this.originalUpdateSpinning,i))},updateSpinning:function(){var n=this.spinning,e=this.sSpinning;e!==n&&(this.sSpinning=n)},cancelExistingSpin:function(){var n=this.updateSpinning;n&&n.cancel&&n.cancel()},renderIndicator:function(n){var e="".concat(n,"-dot"),i=V(this,"indicator");return i===null?null:(Array.isArray(i)&&(i=i.length===1?i[0]:i),y(i)?$(i,{class:e}):p&&y(p())?$(p(),{class:e}):a("span",{class:"".concat(e," ").concat(n,"-dot-spin")},[a("i",{class:"".concat(n,"-dot-item")},null),a("i",{class:"".concat(n,"-dot-item")},null),a("i",{class:"".concat(n,"-dot-item")},null),a("i",{class:"".concat(n,"-dot-item")},null)]))}},render:function(){var n,e,i,o=this.$props,f=o.size,x=o.prefixCls,h=o.tip,d=h===void 0?(n=(e=this.$slots).tip)===null||n===void 0?void 0:n.call(e):h,C=o.wrapperClassName,l=this.$attrs,v=l.class,N=l.style,_=T(l,O),S=this.configProvider,U=S.getPrefixCls,z=S.direction,s=U("spin",x),u=this.sSpinning,E=(i={},r(i,s,!0),r(i,"".concat(s,"-sm"),f==="small"),r(i,"".concat(s,"-lg"),f==="large"),r(i,"".concat(s,"-spinning"),u),r(i,"".concat(s,"-show-text"),!!d),r(i,"".concat(s,"-rtl"),z==="rtl"),r(i,v,!!v),i),m=a("div",P(P({},_),{},{style:N,class:E}),[this.renderIndicator(s),d?a("div",{class:"".concat(s,"-text")},[d]):null]),g=M(this);if(g&&g.length){var c,I=(c={},r(c,"".concat(s,"-container"),!0),r(c,"".concat(s,"-blur"),u),c);return a("div",{class:["".concat(s,"-nested-loading"),C]},[u&&a("div",{key:"loading"},[m]),a("div",{class:I,key:"container"},[g])])}return m}});export{H as S,G as s};
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{ck as e,cl as i,cm as r,cn as a,b1 as n}from"./index-88195b71.js";function o(s,t){return e(i(s,t,r),s+"")}function b(s){return a(s)&&n(s)}export{o as b,b as i};
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import{ck as e,cl as i,cm as r,cn as a,b1 as n}from"./index-e20a7c5d.js";function o(s,t){return e(i(s,t,r),s+"")}function b(s){return a(s)&&n(s)}export{o as b,b as i};
|
||||||
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 Z,a1 as ee,r as F,J as te,K as le,o as ie,U as v,V as N,c as i,a4 as e,W as g,a3 as n,X as k,Y as u,a5 as R,L as se,a6 as ae,af as oe,ag as $,$ as A,a2 as ne,z as w,B as re,cK as ce,cL as de,ak as ue,ai as me,T as fe,a0 as pe}from"./index-88195b71.js";import{u as ve,c as ge,a as ke,F as we,d as he}from"./FileItem-7ac27ad0.js";import{a as Ce,b as Se,c as _e,M as Ie,o as z,L as ye,R as xe,f as be}from"./MultiSelectKeep-59d164ab.js";import"./numInput.vue_vue_type_style_index_0_scoped_55978858_lang-1a7f64c8.js";/* empty css */import"./_isIterateeCall-68480f5b.js";import"./index-a3d562b6.js";import"./shortcut-2543ed2c.js";import"./Checkbox-4759a033.js";import"./index-4a2d6de2.js";const Ve={class:"refresh-button"},Me={class:"hint"},Te={key:0,class:"preview-switch"},Fe=Z({__name:"randomImage",props:{tabIdx:{},paneIdx:{},id:{},paneKey:{}},setup(Ne){const B=ee(),m=F(!1),l=F([]),r=l,h=te(`${le}randomImageSettingNotificationShown`,!1),K=()=>{h.value||(w.info({content:re("randomImageSettingNotification"),duration:6,key:"randomImageSetting"}),h.value=!0)},f=async()=>{try{m.value=!0;const s=await ce();s.length===0&&w.warn("No data, please generate index in image search page first"),l.value=s}finally{m.value=!1,_()}},C=()=>{if(l.value.length===0){w.warn("没有图片可以浏览");return}z(l.value,o.value||0)};ie(()=>{f(),setTimeout(()=>{K()},2e3)});const{stackViewEl:L,multiSelectedIdxs:p,stack:P,scroller:U}=ve({images:l}).toRefs(),{onClearAllSelected:D,onSelectAll:E,onReverseSelect:G}=ge();Ce();const{itemSize:S,gridItems:O,cellWidth:W,onScroll:_}=ke(),{showGenInfo:c,imageGenInfo:I,q,onContextMenuClick:H,onFileItemClick:J}=Se({openNext:de}),{previewIdx:o,previewing:y,onPreviewVisibleChange:Q,previewImgMove:x,canPreview:b}=_e(),V=async(s,t,d)=>{P.value=[{curr:"",files:l.value}],await H(s,t,d)};return(s,t)=>{var M;const d=ue,X=me,Y=fe;return v(),N("div",{class:"container",ref_key:"stackViewEl",ref:L},[i(Ie,{show:!!e(p).length||e(B).keepMultiSelect,onClearAllSelected:e(D),onSelectAll:e(E),onReverseSelect:e(G)},null,8,["show","onClearAllSelected","onSelectAll","onReverseSelect"]),g("div",Ve,[i(d,{onClick:f,onTouchstart:R(f,["prevent"]),type:"primary",loading:m.value,shape:"round"},{default:n(()=>[k(u(s.$t("shuffle")),1)]),_:1},8,["onTouchstart","loading"]),i(d,{onClick:C,onTouchstart:R(C,["prevent"]),type:"default",disabled:!((M=l.value)!=null&&M.length),shape:"round"},{default:n(()=>[k(u(s.$t("tiktokView")),1)]),_:1},8,["onTouchstart","disabled"])]),i(Y,{visible:e(c),"onUpdate:visible":t[1]||(t[1]=a=>ae(c)?c.value=a:null),width:"70vw","mask-closable":"",onOk:t[2]||(t[2]=a=>c.value=!1)},{cancelText:n(()=>[]),default:n(()=>[i(X,{active:"",loading:!e(q).isIdle},{default:n(()=>[g("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:t[0]||(t[0]=a=>e(se)(e(I)))},[g("div",Me,u(s.$t("doubleClickToCopy")),1),k(" "+u(e(I)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),i(e(he),{ref_key:"scroller",ref:U,class:"file-list",items:l.value.slice(),"item-size":e(S).first,"key-field":"fullpath","item-secondary-size":e(S).second,gridItems:e(O),onScroll:e(_)},{default:n(({item:a,index:T})=>[i(we,{idx:T,file:a,"cell-width":e(W),"full-screen-preview-image-url":e(r)[e(o)]?e(oe)(e(r)[e(o)]):"",onContextMenuClick:V,onPreviewVisibleChange:e(Q),"is-selected-mutil-files":e(p).length>1,selected:e(p).includes(T),onFileItemClick:e(J),onTiktokView:(Re,j)=>e(z)(l.value,j)},null,8,["idx","file","cell-width","full-screen-preview-image-url","onPreviewVisibleChange","is-selected-mutil-files","selected","onFileItemClick","onTiktokView"])]),_:1},8,["items","item-size","item-secondary-size","gridItems","onScroll"]),e(y)?(v(),N("div",Te,[i(e(ye),{onClick:t[3]||(t[3]=a=>e(x)("prev")),class:$({disable:!e(b)("prev")})},null,8,["class"]),i(e(xe),{onClick:t[4]||(t[4]=a=>e(x)("next")),class:$({disable:!e(b)("next")})},null,8,["class"])])):A("",!0),e(y)&&e(r)&&e(r)[e(o)]?(v(),ne(be,{key:1,file:e(r)[e(o)],idx:e(o),onContextMenuClick:V},null,8,["file","idx"])):A("",!0)],512)}}});const Ge=pe(Fe,[["__scopeId","data-v-49082269"]]);export{Ge as default};
|
import{d as Z,a1 as ee,r as F,J as te,K as le,o as ie,U as v,V as N,c as i,a4 as e,W as g,a3 as n,X as k,Y as u,a5 as R,L as se,a6 as ae,af as oe,ag as $,$ as A,a2 as ne,z as w,B as re,cK as ce,cL as de,ak as ue,ai as me,T as fe,a0 as pe}from"./index-e20a7c5d.js";import{u as ve,c as ge,a as ke,F as we,d as he}from"./FileItem-034eec0b.js";import{a as Ce,b as Se,c as _e,M as Ie,o as z,L as ye,R as xe,f as be}from"./MultiSelectKeep-601528da.js";import"./numInput.vue_vue_type_style_index_0_scoped_55978858_lang-6616bb47.js";/* empty css */import"./_isIterateeCall-038c812a.js";import"./index-ac822435.js";import"./shortcut-4952a1b1.js";import"./Checkbox-63e244a0.js";import"./index-0b27168c.js";const Ve={class:"refresh-button"},Me={class:"hint"},Te={key:0,class:"preview-switch"},Fe=Z({__name:"randomImage",props:{tabIdx:{},paneIdx:{},id:{},paneKey:{}},setup(Ne){const B=ee(),m=F(!1),l=F([]),r=l,h=te(`${le}randomImageSettingNotificationShown`,!1),K=()=>{h.value||(w.info({content:re("randomImageSettingNotification"),duration:6,key:"randomImageSetting"}),h.value=!0)},f=async()=>{try{m.value=!0;const s=await ce();s.length===0&&w.warn("No data, please generate index in image search page first"),l.value=s}finally{m.value=!1,_()}},C=()=>{if(l.value.length===0){w.warn("没有图片可以浏览");return}z(l.value,o.value||0)};ie(()=>{f(),setTimeout(()=>{K()},2e3)});const{stackViewEl:L,multiSelectedIdxs:p,stack:P,scroller:U}=ve({images:l}).toRefs(),{onClearAllSelected:D,onSelectAll:E,onReverseSelect:G}=ge();Ce();const{itemSize:S,gridItems:O,cellWidth:W,onScroll:_}=ke(),{showGenInfo:c,imageGenInfo:I,q,onContextMenuClick:H,onFileItemClick:J}=Se({openNext:de}),{previewIdx:o,previewing:y,onPreviewVisibleChange:Q,previewImgMove:x,canPreview:b}=_e(),V=async(s,t,d)=>{P.value=[{curr:"",files:l.value}],await H(s,t,d)};return(s,t)=>{var M;const d=ue,X=me,Y=fe;return v(),N("div",{class:"container",ref_key:"stackViewEl",ref:L},[i(Ie,{show:!!e(p).length||e(B).keepMultiSelect,onClearAllSelected:e(D),onSelectAll:e(E),onReverseSelect:e(G)},null,8,["show","onClearAllSelected","onSelectAll","onReverseSelect"]),g("div",Ve,[i(d,{onClick:f,onTouchstart:R(f,["prevent"]),type:"primary",loading:m.value,shape:"round"},{default:n(()=>[k(u(s.$t("shuffle")),1)]),_:1},8,["onTouchstart","loading"]),i(d,{onClick:C,onTouchstart:R(C,["prevent"]),type:"default",disabled:!((M=l.value)!=null&&M.length),shape:"round"},{default:n(()=>[k(u(s.$t("tiktokView")),1)]),_:1},8,["onTouchstart","disabled"])]),i(Y,{visible:e(c),"onUpdate:visible":t[1]||(t[1]=a=>ae(c)?c.value=a:null),width:"70vw","mask-closable":"",onOk:t[2]||(t[2]=a=>c.value=!1)},{cancelText:n(()=>[]),default:n(()=>[i(X,{active:"",loading:!e(q).isIdle},{default:n(()=>[g("div",{style:{width:"100%","word-break":"break-all","white-space":"pre-line","max-height":"70vh",overflow:"auto"},onDblclick:t[0]||(t[0]=a=>e(se)(e(I)))},[g("div",Me,u(s.$t("doubleClickToCopy")),1),k(" "+u(e(I)),1)],32)]),_:1},8,["loading"])]),_:1},8,["visible"]),i(e(he),{ref_key:"scroller",ref:U,class:"file-list",items:l.value.slice(),"item-size":e(S).first,"key-field":"fullpath","item-secondary-size":e(S).second,gridItems:e(O),onScroll:e(_)},{default:n(({item:a,index:T})=>[i(we,{idx:T,file:a,"cell-width":e(W),"full-screen-preview-image-url":e(r)[e(o)]?e(oe)(e(r)[e(o)]):"",onContextMenuClick:V,onPreviewVisibleChange:e(Q),"is-selected-mutil-files":e(p).length>1,selected:e(p).includes(T),onFileItemClick:e(J),onTiktokView:(Re,j)=>e(z)(l.value,j)},null,8,["idx","file","cell-width","full-screen-preview-image-url","onPreviewVisibleChange","is-selected-mutil-files","selected","onFileItemClick","onTiktokView"])]),_:1},8,["items","item-size","item-secondary-size","gridItems","onScroll"]),e(y)?(v(),N("div",Te,[i(e(ye),{onClick:t[3]||(t[3]=a=>e(x)("prev")),class:$({disable:!e(b)("prev")})},null,8,["class"]),i(e(xe),{onClick:t[4]||(t[4]=a=>e(x)("next")),class:$({disable:!e(b)("next")})},null,8,["class"])])):A("",!0),e(y)&&e(r)&&e(r)[e(o)]?(v(),ne(be,{key:1,file:e(r)[e(o)],idx:e(o),onContextMenuClick:V},null,8,["file","idx"])):A("",!0)],512)}}});const Ge=pe(Fe,[["__scopeId","data-v-49082269"]]);export{Ge as default};
|
||||||
|
|
@ -1 +1 @@
|
||||||
import{R as y,C as v}from"./index-c617e69f.js";import{cv as f,c as d,A as P,d as w,U as o,V as c,W as r,Z as S,a8 as V,aG as O,a3 as R,X as u,Y as p,a4 as b,ak as $,a0 as x,R as H,J as _,K as m}from"./index-88195b71.js";const A=f(y),E=f(v);var L={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M878.3 392.1L631.9 145.7c-6.5-6.5-15-9.7-23.5-9.7s-17 3.2-23.5 9.7L423.8 306.9c-12.2-1.4-24.5-2-36.8-2-73.2 0-146.4 24.1-206.5 72.3-15.4 12.3-16.6 35.4-2.7 49.4l181.7 181.7-215.4 215.2a15.8 15.8 0 00-4.6 9.8l-3.4 37.2c-.9 9.4 6.6 17.4 15.9 17.4.5 0 1 0 1.5-.1l37.2-3.4c3.7-.3 7.2-2 9.8-4.6l215.4-215.4 181.7 181.7c6.5 6.5 15 9.7 23.5 9.7 9.7 0 19.3-4.2 25.9-12.4 56.3-70.3 79.7-158.3 70.2-243.4l161.1-161.1c12.9-12.8 12.9-33.8 0-46.8z"}}]},name:"pushpin",theme:"filled"};const C=L;function h(t){for(var e=1;e<arguments.length;e++){var s=arguments[e]!=null?Object(arguments[e]):{},n=Object.keys(s);typeof Object.getOwnPropertySymbols=="function"&&(n=n.concat(Object.getOwnPropertySymbols(s).filter(function(i){return Object.getOwnPropertyDescriptor(s,i).enumerable}))),n.forEach(function(i){N(t,i,s[i])})}return t}function N(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}var l=function(e,s){var n=h({},e,s.attrs);return d(P,h({},n,{icon:C}),null)};l.displayName="PushpinFilled";l.inheritAttrs=!1;const z=l,F={class:"record-container"},k={style:{flex:"1"}},I={class:"rec-actions"},B=["onClick"],J=w({__name:"HistoryRecord",props:{records:{}},emits:["reuseRecord"],setup(t){return(e,s)=>{const n=$;return o(),c("div",null,[r("ul",F,[(o(!0),c(S,null,V(e.records.getRecords(),i=>(o(),c("li",{key:i.id,class:"record"},[r("div",k,[O(e.$slots,"default",{record:i},void 0,!0)]),r("div",I,[d(n,{onClick:g=>e.$emit("reuseRecord",i),type:"primary"},{default:R(()=>[u(p(e.$t("restore")),1)]),_:2},1032,["onClick"]),r("div",{class:"pin",onClick:g=>e.records.switchPin(i)},[d(b(z)),u(" "+p(e.records.isPinned(i)?e.$t("unpin"):e.$t("pin")),1)],8,B)])]))),128))])])}}});const q=x(J,[["__scopeId","data-v-834a248f"]]);class a{constructor(e=128,s=[],n=[]){this.maxLength=e,this.records=s,this.pinnedValues=n}isPinned(e){return this.pinnedValues.some(s=>s.id===e.id)}add(e){this.records.length>=this.maxLength&&this.records.pop(),this.records.unshift({...e,id:H()+Date.now(),time:new Date().toLocaleString()})}pin(e){const s=this.records.findIndex(n=>n.id===e.id);s!==-1&&this.records.splice(s,1),this.pinnedValues.push(e)}unpin(e){const s=this.pinnedValues.findIndex(n=>n.id===e.id);s!==-1&&this.pinnedValues.splice(s,1),this.records.unshift(e)}switchPin(e){this.isPinned(e)?this.unpin(e):this.pin(e)}getRecords(){return[...this.pinnedValues,...this.records]}getPinnedValues(){return this.pinnedValues}}const G=_(`${m}fuzzy-search-HistoryRecord`,new a,{serializer:{read:t=>{const e=JSON.parse(t);return new a(e.maxLength,e.records,e.pinnedValues)},write:JSON.stringify}}),M=_(`${m}tag-search-HistoryRecord`,new a,{serializer:{read:t=>{const e=JSON.parse(t);return new a(e.maxLength,e.records,e.pinnedValues)},write:JSON.stringify}});export{q as H,E as _,A as a,G as f,M as t};
|
import{R as y,C as v}from"./index-875d82be.js";import{cv as f,c as d,A as P,d as w,U as o,V as c,W as r,Z as S,a8 as V,aG as O,a3 as R,X as u,Y as p,a4 as b,ak as $,a0 as x,R as H,J as _,K as m}from"./index-e20a7c5d.js";const A=f(y),E=f(v);var L={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M878.3 392.1L631.9 145.7c-6.5-6.5-15-9.7-23.5-9.7s-17 3.2-23.5 9.7L423.8 306.9c-12.2-1.4-24.5-2-36.8-2-73.2 0-146.4 24.1-206.5 72.3-15.4 12.3-16.6 35.4-2.7 49.4l181.7 181.7-215.4 215.2a15.8 15.8 0 00-4.6 9.8l-3.4 37.2c-.9 9.4 6.6 17.4 15.9 17.4.5 0 1 0 1.5-.1l37.2-3.4c3.7-.3 7.2-2 9.8-4.6l215.4-215.4 181.7 181.7c6.5 6.5 15 9.7 23.5 9.7 9.7 0 19.3-4.2 25.9-12.4 56.3-70.3 79.7-158.3 70.2-243.4l161.1-161.1c12.9-12.8 12.9-33.8 0-46.8z"}}]},name:"pushpin",theme:"filled"};const C=L;function h(t){for(var e=1;e<arguments.length;e++){var s=arguments[e]!=null?Object(arguments[e]):{},n=Object.keys(s);typeof Object.getOwnPropertySymbols=="function"&&(n=n.concat(Object.getOwnPropertySymbols(s).filter(function(i){return Object.getOwnPropertyDescriptor(s,i).enumerable}))),n.forEach(function(i){N(t,i,s[i])})}return t}function N(t,e,s){return e in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}var l=function(e,s){var n=h({},e,s.attrs);return d(P,h({},n,{icon:C}),null)};l.displayName="PushpinFilled";l.inheritAttrs=!1;const z=l,F={class:"record-container"},k={style:{flex:"1"}},I={class:"rec-actions"},B=["onClick"],J=w({__name:"HistoryRecord",props:{records:{}},emits:["reuseRecord"],setup(t){return(e,s)=>{const n=$;return o(),c("div",null,[r("ul",F,[(o(!0),c(S,null,V(e.records.getRecords(),i=>(o(),c("li",{key:i.id,class:"record"},[r("div",k,[O(e.$slots,"default",{record:i},void 0,!0)]),r("div",I,[d(n,{onClick:g=>e.$emit("reuseRecord",i),type:"primary"},{default:R(()=>[u(p(e.$t("restore")),1)]),_:2},1032,["onClick"]),r("div",{class:"pin",onClick:g=>e.records.switchPin(i)},[d(b(z)),u(" "+p(e.records.isPinned(i)?e.$t("unpin"):e.$t("pin")),1)],8,B)])]))),128))])])}}});const q=x(J,[["__scopeId","data-v-834a248f"]]);class a{constructor(e=128,s=[],n=[]){this.maxLength=e,this.records=s,this.pinnedValues=n}isPinned(e){return this.pinnedValues.some(s=>s.id===e.id)}add(e){this.records.length>=this.maxLength&&this.records.pop(),this.records.unshift({...e,id:H()+Date.now(),time:new Date().toLocaleString()})}pin(e){const s=this.records.findIndex(n=>n.id===e.id);s!==-1&&this.records.splice(s,1),this.pinnedValues.push(e)}unpin(e){const s=this.pinnedValues.findIndex(n=>n.id===e.id);s!==-1&&this.pinnedValues.splice(s,1),this.records.unshift(e)}switchPin(e){this.isPinned(e)?this.unpin(e):this.pin(e)}getRecords(){return[...this.pinnedValues,...this.records]}getPinnedValues(){return this.pinnedValues}}const G=_(`${m}fuzzy-search-HistoryRecord`,new a,{serializer:{read:t=>{const e=JSON.parse(t);return new a(e.maxLength,e.records,e.pinnedValues)},write:JSON.stringify}}),M=_(`${m}tag-search-HistoryRecord`,new a,{serializer:{read:t=>{const e=JSON.parse(t);return new a(e.maxLength,e.records,e.pinnedValues)},write:JSON.stringify}});export{q as H,E as _,A as a,G as f,M as t};
|
||||||
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{u as G,g as d}from"./FileItem-7ac27ad0.js";import{r as b,t as j,cs as m,ct as y,cu as D}from"./index-88195b71.js";const r=new Map,A=()=>{const{useEventListen:k,sortedFiles:s,getViewableAreaFiles:w}=G().toRefs(),c=b(d.defaultChangeIndchecked),u=b(d.defaultSeedChangeChecked),g=async()=>{if(await j(100),!c.value)return;const o=w.value().filter(e=>m(e.fullpath)&&!e.gen_info_obj);if(!o.length)return;const t=await y(o.map(e=>e.fullpath).filter(e=>!r.has(e)));o.forEach(e=>{const i=t[e.fullpath]||r.get(e.fullpath)||"";r.set(e.fullpath,i),e.gen_info_obj=D(i),e.gen_info_raw=i})};k.value("viewableAreaFilesChange",g);const F=o=>{const t=s.value;return[o,u.value,t[o-1],t[o],t[o+1]]};function I(o,t,e,i){const a={diff:{},empty:!0,ownFile:"",otherFile:""};if(t+e<0||t+e>=s.value.length||s.value[t]==null||!("gen_info_obj"in s.value[t])||!("gen_info_obj"in s.value[t+e]))return a;const l=o,f=s.value[t+e].gen_info_obj;if(f==null)return a;const h=["hashes","resources"];a.diff={},a.ownFile=i.name,a.otherFile=s.value[t+e].name,a.empty=!1,u.value||h.push("seed");for(const n in l)if(!h.includes(n)){if(!(n in f)){a.diff[n]="+";continue}if(l[n]!=f[n])if(n.includes("rompt")&&l[n]!=""&&f[n]!=""){const p=l[n].split(","),C=f[n].split(",");let _=0;for(const v in p)p[v]!=C[v]&&_++;a.diff[n]=_}else a.diff[n]=[l[n],f[n]]}return a}return{getGenDiff:I,changeIndchecked:c,seedChangeChecked:u,getRawGenParams:()=>g(),getGenDiffWatchDep:F}};export{A as u};
|
import{u as G,g as d}from"./FileItem-034eec0b.js";import{r as b,t as j,cs as m,ct as y,cu as D}from"./index-e20a7c5d.js";const r=new Map,A=()=>{const{useEventListen:k,sortedFiles:s,getViewableAreaFiles:w}=G().toRefs(),c=b(d.defaultChangeIndchecked),u=b(d.defaultSeedChangeChecked),g=async()=>{if(await j(100),!c.value)return;const o=w.value().filter(e=>m(e.fullpath)&&!e.gen_info_obj);if(!o.length)return;const t=await y(o.map(e=>e.fullpath).filter(e=>!r.has(e)));o.forEach(e=>{const i=t[e.fullpath]||r.get(e.fullpath)||"";r.set(e.fullpath,i),e.gen_info_obj=D(i),e.gen_info_raw=i})};k.value("viewableAreaFilesChange",g);const F=o=>{const t=s.value;return[o,u.value,t[o-1],t[o],t[o+1]]};function I(o,t,e,i){const a={diff:{},empty:!0,ownFile:"",otherFile:""};if(t+e<0||t+e>=s.value.length||s.value[t]==null||!("gen_info_obj"in s.value[t])||!("gen_info_obj"in s.value[t+e]))return a;const l=o,f=s.value[t+e].gen_info_obj;if(f==null)return a;const h=["hashes","resources"];a.diff={},a.ownFile=i.name,a.otherFile=s.value[t+e].name,a.empty=!1,u.value||h.push("seed");for(const n in l)if(!h.includes(n)){if(!(n in f)){a.diff[n]="+";continue}if(l[n]!=f[n])if(n.includes("rompt")&&l[n]!=""&&f[n]!=""){const p=l[n].split(","),C=f[n].split(",");let _=0;for(const v in p)p[v]!=C[v]&&_++;a.diff[n]=_}else a.diff[n]=[l[n],f[n]]}return a}return{getGenDiff:I,changeIndchecked:c,seedChangeChecked:u,getRawGenParams:()=>g(),getGenDiffWatchDep:F}};export{A as u};
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Infinite Image Browsing</title>
|
<title>Infinite Image Browsing</title>
|
||||||
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-88195b71.js"></script>
|
<script type="module" crossorigin src="/infinite_image_browsing/fe-static/assets/index-e20a7c5d.js"></script>
|
||||||
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-a44325c7.css">
|
<link rel="stylesheet" href="/infinite_image_browsing/fe-static/assets/index-66b0f04c.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { FileOutlined, FolderOpenOutlined, EllipsisOutlined, HeartOutlined, Hear
|
||||||
import { useGlobalStore } from '@/store/useGlobalStore'
|
import { useGlobalStore } from '@/store/useGlobalStore'
|
||||||
import { fallbackImage, ok } from 'vue3-ts-util'
|
import { fallbackImage, ok } from 'vue3-ts-util'
|
||||||
import type { FileNodeInfo } from '@/api/files'
|
import type { FileNodeInfo } from '@/api/files'
|
||||||
import { isImageFile, isVideoFile } from '@/util'
|
import { isImageFile, isVideoFile, isAudioFile } from '@/util'
|
||||||
import { toImageThumbnailUrl, toVideoCoverUrl, toRawFileUrl } from '@/util/file'
|
import { toImageThumbnailUrl, toVideoCoverUrl, toRawFileUrl } from '@/util/file'
|
||||||
import type { MenuInfo } from 'ant-design-vue/lib/menu/src/interface'
|
import type { MenuInfo } from 'ant-design-vue/lib/menu/src/interface'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
|
|
@ -12,7 +12,7 @@ import ChangeIndicator from './ChangeIndicator.vue'
|
||||||
import { useTagStore } from '@/store/useTagStore'
|
import { useTagStore } from '@/store/useTagStore'
|
||||||
import { CloseCircleOutlined, StarFilled, StarOutlined } from '@/icon'
|
import { CloseCircleOutlined, StarFilled, StarOutlined } from '@/icon'
|
||||||
import { Tag } from '@/api/db'
|
import { Tag } from '@/api/db'
|
||||||
import { openVideoModal } from './functionalCallableComp'
|
import { openVideoModal, openAudioModal } from './functionalCallableComp'
|
||||||
import type { GenDiffInfo } from '@/api/files'
|
import type { GenDiffInfo } from '@/api/files'
|
||||||
import { play } from '@/icon'
|
import { play } from '@/icon'
|
||||||
import { Top4MediaInfo } from '@/api'
|
import { Top4MediaInfo } from '@/api'
|
||||||
|
|
@ -100,6 +100,9 @@ const minShowDetailWidth = 160
|
||||||
const handleFileClick = (event: MouseEvent) => {
|
const handleFileClick = (event: MouseEvent) => {
|
||||||
// 检查magic switch是否开启且是图片文件(视频有自己的处理逻辑)
|
// 检查magic switch是否开启且是图片文件(视频有自己的处理逻辑)
|
||||||
if (global.magicSwitchTiktokView && props.file.type === 'file' && isImageFile(props.file.name)) {
|
if (global.magicSwitchTiktokView && props.file.type === 'file' && isImageFile(props.file.name)) {
|
||||||
|
// 阻止事件传播,防止 a-image 组件也触发预览
|
||||||
|
event.stopPropagation()
|
||||||
|
event.preventDefault()
|
||||||
// 直接触发TikTok视图
|
// 直接触发TikTok视图
|
||||||
emit('tiktokView', props.file, props.idx)
|
emit('tiktokView', props.file, props.idx)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -125,6 +128,21 @@ const handleVideoClick = () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理音频点击事件
|
||||||
|
const handleAudioClick = () => {
|
||||||
|
if (global.magicSwitchTiktokView) {
|
||||||
|
// 直接触发TikTok视图
|
||||||
|
emit('tiktokView', props.file, props.idx)
|
||||||
|
} else {
|
||||||
|
// 正常打开音频模态框
|
||||||
|
openAudioModal(
|
||||||
|
props.file,
|
||||||
|
(id) => emit('contextMenuClick', { key: `toggle-tag-${id}` } as any, props.file, props.idx),
|
||||||
|
() => emit('tiktokView', props.file, props.idx)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<a-dropdown :trigger="['contextmenu']" :visible="!global.longPressOpenContextMenu ? undefined : typeof idx === 'number' && showMenuIdx === idx
|
<a-dropdown :trigger="['contextmenu']" :visible="!global.longPressOpenContextMenu ? undefined : typeof idx === 'number' && showMenuIdx === idx
|
||||||
|
|
@ -196,6 +214,15 @@ const handleVideoClick = () => {
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div :class="`idx-${idx} item-content audio`" v-else-if="isAudioFile(file.name)"
|
||||||
|
@click="handleAudioClick">
|
||||||
|
<div class="audio-icon">🎵</div>
|
||||||
|
<div class="tags-container" v-if="customTags && cellWidth > minShowDetailWidth">
|
||||||
|
<a-tag v-for="tag in customTags" :key="tag.id" :color="tagStore.getColor(tag)">
|
||||||
|
{{ tag.name }}
|
||||||
|
</a-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div v-else class="preview-icon-wrap">
|
<div v-else class="preview-icon-wrap">
|
||||||
<file-outlined class="icon center" v-if="file.type === 'file'" />
|
<file-outlined class="icon center" v-if="file.type === 'file'" />
|
||||||
<div v-else-if="coverFiles?.length && cellWidth > 160" class="dir-cover-container">
|
<div v-else-if="coverFiles?.length && cellWidth > 160" class="dir-cover-container">
|
||||||
|
|
@ -249,6 +276,22 @@ const handleVideoClick = () => {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.audio {
|
||||||
|
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
width: v-bind('$props.cellWidth + "px"');
|
||||||
|
height: v-bind('$props.cellWidth + "px"');
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.audio-icon {
|
||||||
|
font-size: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.play-icon {
|
.play-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import * as Path from '@/util/path'
|
||||||
import { FileNodeInfo, mkdirs } from '@/api/files'
|
import { FileNodeInfo, mkdirs } from '@/api/files'
|
||||||
import { setTargetFrameAsCover } from '@/api'
|
import { setTargetFrameAsCover } from '@/api'
|
||||||
import { t } from '@/i18n'
|
import { t } from '@/i18n'
|
||||||
import { downloadFiles, globalEvents, toRawFileUrl, toStreamVideoUrl } from '@/util'
|
import { downloadFiles, globalEvents, toRawFileUrl, toStreamVideoUrl, toStreamAudioUrl } from '@/util'
|
||||||
import { DownloadOutlined } from '@/icon'
|
import { DownloadOutlined } from '@/icon'
|
||||||
import { isStandalone } from '@/util/env'
|
import { isStandalone } from '@/util/env'
|
||||||
import { addCustomTag, getDbBasicInfo, rebuildImageIndex, renameFile } from '@/api/db'
|
import { addCustomTag, getDbBasicInfo, rebuildImageIndex, renameFile } from '@/api/db'
|
||||||
|
|
@ -141,6 +141,91 @@ export const openVideoModal = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const openAudioModal = (
|
||||||
|
file: FileNodeInfo,
|
||||||
|
onTagClick?: (id: string| number) => void,
|
||||||
|
onTiktokView?: () => void
|
||||||
|
) => {
|
||||||
|
const tagStore = useTagStore()
|
||||||
|
const global = useGlobalStore()
|
||||||
|
const isSelected = (id: string | number) => {
|
||||||
|
return !!tagStore.tagMap.get(file.fullpath)?.some(v => v.id === id)
|
||||||
|
}
|
||||||
|
const tagBaseStyle: StyleValue = {
|
||||||
|
margin: '2px',
|
||||||
|
padding: '2px 16px',
|
||||||
|
'border-radius': '4px',
|
||||||
|
display: 'inline-block',
|
||||||
|
cursor: 'pointer',
|
||||||
|
'font-weight': 'bold',
|
||||||
|
transition: '.5s all ease',
|
||||||
|
'user-select': 'none',
|
||||||
|
}
|
||||||
|
|
||||||
|
const modal = Modal.confirm({
|
||||||
|
width: '60vw',
|
||||||
|
title: file.name,
|
||||||
|
icon: null,
|
||||||
|
content: () => (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
flexDirection: 'column'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '80px',
|
||||||
|
marginBottom: '16px'
|
||||||
|
}}>🎵</div>
|
||||||
|
<audio style={{ width: '100%', maxWidth: '500px' }} src={toStreamAudioUrl(file)} controls autoplay></audio>
|
||||||
|
<div style={{ marginTop: '16px' }}>
|
||||||
|
<div onClick={openAddNewTagModal} style={{
|
||||||
|
background: 'var(--zp-primary-background)',
|
||||||
|
color: 'var(--zp-luminous)',
|
||||||
|
border: '2px solid var(--zp-luminous)',
|
||||||
|
...tagBaseStyle
|
||||||
|
}}>
|
||||||
|
{ t('addNewCustomTag') }
|
||||||
|
</div>
|
||||||
|
{global.conf!.all_custom_tags.map((tag) =>
|
||||||
|
<div key={tag.id} onClick={() => onTagClick?.(tag.id)} style={{
|
||||||
|
background: isSelected(tag.id) ? tagStore.getColor(tag) : 'var(--zp-primary-background)',
|
||||||
|
color: !isSelected(tag.id) ? tagStore.getColor(tag) : 'white',
|
||||||
|
border: `2px solid ${tagStore.getColor(tag)}`,
|
||||||
|
...tagBaseStyle
|
||||||
|
}}>
|
||||||
|
{ tag.name }
|
||||||
|
</div>)}
|
||||||
|
</div>
|
||||||
|
<div class="actions" style={{ marginTop: '16px' }}>
|
||||||
|
<Button onClick={() => downloadFiles([toRawFileUrl(file, true)])}>
|
||||||
|
{{
|
||||||
|
icon: <DownloadOutlined/>,
|
||||||
|
default: t('download')
|
||||||
|
}}
|
||||||
|
</Button>
|
||||||
|
{onTiktokView && (
|
||||||
|
<Button onClick={onTiktokViewWrapper} type="primary">
|
||||||
|
{{
|
||||||
|
default: t('tiktokView')
|
||||||
|
}}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
maskClosable: true,
|
||||||
|
wrapClassName: 'hidden-antd-btns-modal'
|
||||||
|
})
|
||||||
|
function onTiktokViewWrapper() {
|
||||||
|
onTiktokView?.()
|
||||||
|
closeImageFullscreenPreview()
|
||||||
|
modal.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const openRebuildImageIndexModal = () => {
|
export const openRebuildImageIndexModal = () => {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: t('confirmRebuildImageIndex'),
|
title: t('confirmRebuildImageIndex'),
|
||||||
|
|
|
||||||
|
|
@ -145,5 +145,8 @@ export const de: Partial<IIBI18nMap> = {
|
||||||
all: 'Alle',
|
all: 'Alle',
|
||||||
video: 'Video',
|
video: 'Video',
|
||||||
randomSort: 'Zufällig sortieren',
|
randomSort: 'Zufällig sortieren',
|
||||||
sortByDate: 'Nach Datum sortieren'
|
sortByDate: 'Nach Datum sortieren',
|
||||||
|
fileTypeFilter: 'Dateityp-Filter',
|
||||||
|
allFiles: 'Alle Dateien',
|
||||||
|
audio: 'Audio'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -317,6 +317,9 @@ You can specify which snapshot to restore to when starting IIB in the global set
|
||||||
searchResults: 'Search Results',
|
searchResults: 'Search Results',
|
||||||
imgSearch: 'Image Search',
|
imgSearch: 'Image Search',
|
||||||
onlyFoldersAndImages: 'Only show folders/images/videos',
|
onlyFoldersAndImages: 'Only show folders/images/videos',
|
||||||
|
fileTypeFilter: 'File Type Filter',
|
||||||
|
allFiles: 'All Files',
|
||||||
|
audio: 'Audio',
|
||||||
send2savedDir: 'Send to saved folder',
|
send2savedDir: 'Send to saved folder',
|
||||||
regexSearchEnabledHint:
|
regexSearchEnabledHint:
|
||||||
'(You can also enable regex search by clicking the regex icon on the right)',
|
'(You can also enable regex search by clicking the regex icon on the right)',
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,9 @@ export const zhHans = {
|
||||||
searchResults: '搜索结果',
|
searchResults: '搜索结果',
|
||||||
imgSearch: '图像搜索',
|
imgSearch: '图像搜索',
|
||||||
onlyFoldersAndImages: '只显示文件夹/图像/视频',
|
onlyFoldersAndImages: '只显示文件夹/图像/视频',
|
||||||
|
fileTypeFilter: '文件类型过滤',
|
||||||
|
allFiles: '所有文件',
|
||||||
|
audio: '音频',
|
||||||
send2savedDir: '发送到保存的文件夹',
|
send2savedDir: '发送到保存的文件夹',
|
||||||
unknownSavedDir: '找不到保存的文件夹(配置文件中的outdir_save字段)',
|
unknownSavedDir: '找不到保存的文件夹(配置文件中的outdir_save字段)',
|
||||||
Model: '模型',
|
Model: '模型',
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,9 @@ export const zhHant: Partial<IIBI18nMap> = {
|
||||||
searchResults: '搜尋結果',
|
searchResults: '搜尋結果',
|
||||||
imgSearch: '圖片搜尋',
|
imgSearch: '圖片搜尋',
|
||||||
onlyFoldersAndImages: '只顯示文件夾/圖片/視頻',
|
onlyFoldersAndImages: '只顯示文件夾/圖片/視頻',
|
||||||
|
fileTypeFilter: '文件類型過濾',
|
||||||
|
allFiles: '所有文件',
|
||||||
|
audio: '音頻',
|
||||||
send2savedDir: '發送到儲存的文件夾',
|
send2savedDir: '發送到儲存的文件夾',
|
||||||
unknownSavedDir: '找不到儲存的文件夾(配置文件中的outdir_save欄位)',
|
unknownSavedDir: '找不到儲存的文件夾(配置文件中的outdir_save欄位)',
|
||||||
Model: '模型',
|
Model: '模型',
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import { ref, computed, onMounted, onUnmounted, nextTick, watch } from 'vue'
|
||||||
import { useTiktokStore, type TiktokMediaItem } from '@/store/useTiktokStore'
|
import { useTiktokStore, type TiktokMediaItem } from '@/store/useTiktokStore'
|
||||||
import { useTagStore } from '@/store/useTagStore'
|
import { useTagStore } from '@/store/useTagStore'
|
||||||
import { useGlobalStore } from '@/store/useGlobalStore'
|
import { useGlobalStore } from '@/store/useGlobalStore'
|
||||||
import { useLocalStorage } from '@vueuse/core'
|
import { useLocalStorage, onLongPress } from '@vueuse/core'
|
||||||
import { isVideoFile } from '@/util'
|
import { isVideoFile, isAudioFile } from '@/util'
|
||||||
import { openAddNewTagModal } from '@/components/functionalCallableComp'
|
import { openAddNewTagModal } from '@/components/functionalCallableComp'
|
||||||
import { toggleCustomTagToImg } from '@/api/db'
|
import { toggleCustomTagToImg } from '@/api/db'
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
|
|
@ -86,6 +86,7 @@ const getAnimationDelay = (isTriggerByTouch: boolean) => {
|
||||||
const containerRef = ref<HTMLElement>()
|
const containerRef = ref<HTMLElement>()
|
||||||
const viewportRef = ref<HTMLElement>()
|
const viewportRef = ref<HTMLElement>()
|
||||||
const videoRefs = ref<(HTMLVideoElement | null)[]>([null, null, null]) // 视频元素引用
|
const videoRefs = ref<(HTMLVideoElement | null)[]>([null, null, null]) // 视频元素引用
|
||||||
|
const audioRefs = ref<(HTMLAudioElement | null)[]>([null, null, null]) // 音频元素引用
|
||||||
|
|
||||||
// 3位buffer状态管理
|
// 3位buffer状态管理
|
||||||
const bufferItems = ref<(TiktokMediaItem | null)[]>([null, null, null]) // [prev, current, next]
|
const bufferItems = ref<(TiktokMediaItem | null)[]>([null, null, null]) // [prev, current, next]
|
||||||
|
|
@ -99,6 +100,14 @@ const dragOffset = ref(0) // 拖拽偏移量
|
||||||
// TAG 相关状态
|
// TAG 相关状态
|
||||||
const showTags = ref(false)
|
const showTags = ref(false)
|
||||||
|
|
||||||
|
// 控件可见性状态(长按切换)
|
||||||
|
const controlsVisible = ref(true)
|
||||||
|
|
||||||
|
// 长按切换控件可见性
|
||||||
|
const toggleControlsVisibility = () => {
|
||||||
|
controlsVisible.value = !controlsVisible.value
|
||||||
|
}
|
||||||
|
|
||||||
// 计算属性
|
// 计算属性
|
||||||
const currentItem = computed(() => bufferItems.value[1]) // 中间位置是当前显示的项目
|
const currentItem = computed(() => bufferItems.value[1]) // 中间位置是当前显示的项目
|
||||||
|
|
||||||
|
|
@ -173,9 +182,25 @@ const handleVideoEnded = (index: number) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理音频播放结束事件
|
||||||
|
const handleAudioEnded = (index: number) => {
|
||||||
|
// 只处理当前显示的音频(index === 1)
|
||||||
|
if (index === 1 && autoPlayMode.value !== 'off' && !isAnimating.value) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (tiktokStore.hasNext) {
|
||||||
|
goToNext()
|
||||||
|
} else {
|
||||||
|
// 到达最后一个时跳回第一个
|
||||||
|
goToFirst()
|
||||||
|
}
|
||||||
|
}, 500) // 延迟500ms后切换,避免过于突兀
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 控制视频播放
|
// 控制视频播放
|
||||||
const controlVideoPlayback = async () => {
|
const controlVideoPlayback = async () => {
|
||||||
await delay(30)
|
await delay(30)
|
||||||
|
// 控制视频
|
||||||
for (let index = 0; index < videoRefs.value.length; index++) {
|
for (let index = 0; index < videoRefs.value.length; index++) {
|
||||||
const video = videoRefs.value[index]
|
const video = videoRefs.value[index]
|
||||||
if (!video) continue
|
if (!video) continue
|
||||||
|
|
@ -200,6 +225,32 @@ const controlVideoPlayback = async () => {
|
||||||
console.warn(`视频播放控制失败 (index: ${index}):`, err)
|
console.warn(`视频播放控制失败 (index: ${index}):`, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 控制音频
|
||||||
|
for (let index = 0; index < audioRefs.value.length; index++) {
|
||||||
|
const audio = audioRefs.value[index]
|
||||||
|
if (!audio) continue
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (index === 1) {
|
||||||
|
// 当前显示的音频:自动播放
|
||||||
|
audio.currentTime = 0 // 重置到开头
|
||||||
|
audio.muted = isMuted.value // 根据用户偏好设置静音状态
|
||||||
|
|
||||||
|
// 添加音频结束事件监听
|
||||||
|
audio.onended = () => handleAudioEnded(index)
|
||||||
|
|
||||||
|
await audio.play()
|
||||||
|
} else {
|
||||||
|
// 非当前显示的音频:暂停并重置
|
||||||
|
audio.pause()
|
||||||
|
audio.currentTime = 0
|
||||||
|
audio.onended = null // 清除事件监听
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(`音频播放控制失败 (index: ${index}):`, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新buffer内容
|
// 更新buffer内容
|
||||||
|
|
@ -589,6 +640,12 @@ const toggleMute = () => {
|
||||||
if (currentVideo) {
|
if (currentVideo) {
|
||||||
currentVideo.muted = isMuted.value
|
currentVideo.muted = isMuted.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 立即应用到当前播放的音频
|
||||||
|
const currentAudio = audioRefs.value[1]
|
||||||
|
if (currentAudio) {
|
||||||
|
currentAudio.muted = isMuted.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听全屏状态变化
|
// 监听全屏状态变化
|
||||||
|
|
@ -596,15 +653,30 @@ const handleFullscreenChange = () => {
|
||||||
tiktokStore.isFullscreen = !!document.fullscreenElement
|
tiktokStore.isFullscreen = !!document.fullscreenElement
|
||||||
}
|
}
|
||||||
const videoPreloadList = ref([] as HTMLVideoElement[])
|
const videoPreloadList = ref([] as HTMLVideoElement[])
|
||||||
|
const audioPreloadList = ref([] as HTMLAudioElement[])
|
||||||
|
|
||||||
const recVideo = (video?: HTMLVideoElement) => {
|
const recVideo = (video?: HTMLVideoElement) => {
|
||||||
if (!video) return
|
if (!video) return
|
||||||
video.src = ''
|
|
||||||
video.pause()
|
video.pause()
|
||||||
|
video.src = ''
|
||||||
video.muted = true
|
video.muted = true
|
||||||
|
video.load() // 强制释放资源
|
||||||
if (video.parentNode) {
|
if (video.parentNode) {
|
||||||
video.parentNode.removeChild(video)
|
video.parentNode.removeChild(video)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const recAudio = (audio?: HTMLAudioElement) => {
|
||||||
|
if (!audio) return
|
||||||
|
audio.pause()
|
||||||
|
audio.src = ''
|
||||||
|
audio.muted = true
|
||||||
|
audio.load() // 强制释放资源
|
||||||
|
if (audio.parentNode) {
|
||||||
|
audio.parentNode.removeChild(audio)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
watch(videoPreloadList, (newList) => {
|
watch(videoPreloadList, (newList) => {
|
||||||
// 清理已加载的视频元素
|
// 清理已加载的视频元素
|
||||||
while (newList.length > 5) {
|
while (newList.length > 5) {
|
||||||
|
|
@ -613,11 +685,22 @@ watch(videoPreloadList, (newList) => {
|
||||||
recVideo(video)
|
recVideo(video)
|
||||||
}
|
}
|
||||||
}, { deep: true })
|
}, { deep: true })
|
||||||
|
|
||||||
|
watch(audioPreloadList, (newList) => {
|
||||||
|
// 清理已加载的音频元素
|
||||||
|
while (newList.length > 5) {
|
||||||
|
const audio = newList.shift()
|
||||||
|
if (!audio) continue
|
||||||
|
recAudio(audio)
|
||||||
|
}
|
||||||
|
}, { deep: true })
|
||||||
watch(() => tiktokStore.visible === false || tiktokStore.mediaList.length === 0, (isClose) => {
|
watch(() => tiktokStore.visible === false || tiktokStore.mediaList.length === 0, (isClose) => {
|
||||||
if (isClose) return
|
if (isClose) return
|
||||||
// 组件隐藏时清理预加载列表
|
// 组件隐藏时清理预加载列表
|
||||||
videoPreloadList.value.forEach(recVideo)
|
videoPreloadList.value.forEach(recVideo)
|
||||||
videoPreloadList.value = []
|
videoPreloadList.value = []
|
||||||
|
audioPreloadList.value.forEach(recAudio)
|
||||||
|
audioPreloadList.value = []
|
||||||
|
|
||||||
autoPlayMode.value = 'off' // 重置自动轮播模式
|
autoPlayMode.value = 'off' // 重置自动轮播模式
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
@ -631,6 +714,11 @@ const preloadMedia = () => {
|
||||||
video.preload = 'metadata'
|
video.preload = 'metadata'
|
||||||
video.src = item.url
|
video.src = item.url
|
||||||
videoPreloadList.value.push(video)
|
videoPreloadList.value.push(video)
|
||||||
|
} else if (isAudioFile(item.url)) {
|
||||||
|
const audio = document.createElement('audio')
|
||||||
|
audio.preload = 'metadata'
|
||||||
|
audio.src = item.url
|
||||||
|
audioPreloadList.value.push(audio)
|
||||||
} else {
|
} else {
|
||||||
const img = new Image()
|
const img = new Image()
|
||||||
img.src = item.url
|
img.src = item.url
|
||||||
|
|
@ -650,6 +738,13 @@ const loadCurrentItemTags = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 长按切换控件可见性
|
||||||
|
onLongPress(
|
||||||
|
viewportRef,
|
||||||
|
toggleControlsVisibility,
|
||||||
|
{ delay: 500 }
|
||||||
|
)
|
||||||
|
|
||||||
// 生命周期
|
// 生命周期
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener('keydown', handleKeydown)
|
document.addEventListener('keydown', handleKeydown)
|
||||||
|
|
@ -668,6 +763,17 @@ onUnmounted(() => {
|
||||||
videoRefs.value.forEach(video => {
|
videoRefs.value.forEach(video => {
|
||||||
recVideo(video!)
|
recVideo(video!)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 清理:停止所有音频播放
|
||||||
|
audioRefs.value.forEach(audio => {
|
||||||
|
recAudio(audio!)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 清理预加载列表
|
||||||
|
videoPreloadList.value.forEach(recVideo)
|
||||||
|
videoPreloadList.value = []
|
||||||
|
audioPreloadList.value.forEach(recAudio)
|
||||||
|
audioPreloadList.value = []
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听当前项变化
|
// 监听当前项变化
|
||||||
|
|
@ -687,12 +793,28 @@ watch(() => tiktokStore.mediaList, () => {
|
||||||
// 监听组件可见性变化
|
// 监听组件可见性变化
|
||||||
watch(() => tiktokStore.visible, (visible) => {
|
watch(() => tiktokStore.visible, (visible) => {
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
// 组件隐藏时停止所有视频
|
// 组件隐藏时停止并清理所有视频
|
||||||
videoRefs.value.forEach(video => {
|
videoRefs.value.forEach(video => {
|
||||||
if (video) {
|
if (video) {
|
||||||
video.pause()
|
video.pause()
|
||||||
|
video.src = ''
|
||||||
|
video.load()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
videoRefs.value = [null, null, null]
|
||||||
|
|
||||||
|
// 组件隐藏时停止并清理所有音频
|
||||||
|
audioRefs.value.forEach(audio => {
|
||||||
|
if (audio) {
|
||||||
|
audio.pause()
|
||||||
|
audio.src = ''
|
||||||
|
audio.load()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
audioRefs.value = [null, null, null]
|
||||||
|
|
||||||
|
// 清空缓冲区
|
||||||
|
bufferItems.value = [null, null, null]
|
||||||
|
|
||||||
// 清除自动轮播计时器
|
// 清除自动轮播计时器
|
||||||
clearAutoPlayTimer()
|
clearAutoPlayTimer()
|
||||||
|
|
@ -702,20 +824,28 @@ watch(() => tiktokStore.visible, (visible) => {
|
||||||
exitFullscreen()
|
exitFullscreen()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 组件显示时重新控制视频播放
|
// 组件显示时重置控件可见性
|
||||||
|
controlsVisible.value = true
|
||||||
|
|
||||||
|
// 组件显示时重新更新缓冲区并控制播放
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
controlVideoPlayback()
|
updateBuffer()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听静音状态变化,同步所有视频
|
// 监听静音状态变化,同步所有视频和音频
|
||||||
watch(() => isMuted.value, (muted) => {
|
watch(() => isMuted.value, (muted) => {
|
||||||
videoRefs.value.forEach(video => {
|
videoRefs.value.forEach(video => {
|
||||||
if (video) {
|
if (video) {
|
||||||
video.muted = muted
|
video.muted = muted
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
audioRefs.value.forEach(audio => {
|
||||||
|
if (audio) {
|
||||||
|
audio.muted = muted
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听自动轮播模式变化
|
// 监听自动轮播模式变化
|
||||||
|
|
@ -752,6 +882,21 @@ watch(() => autoPlayMode.value, () => {
|
||||||
:controls="index === 1" :loop="index === 1 && autoPlayMode === 'off'" playsinline preload="metadata"
|
:controls="index === 1" :loop="index === 1 && autoPlayMode === 'off'" playsinline preload="metadata"
|
||||||
:key="item.url" :ref="(el) => { if (el) videoRefs[index] = el as HTMLVideoElement }" />
|
:key="item.url" :ref="(el) => { if (el) videoRefs[index] = el as HTMLVideoElement }" />
|
||||||
|
|
||||||
|
<!-- 音频 -->
|
||||||
|
<div v-else-if="isAudioFile(item.url) && tiktokStore.visible" class="tiktok-media tiktok-audio-container">
|
||||||
|
<div class="audio-icon">🎵</div>
|
||||||
|
<div class="audio-filename">{{ item.name || item.url.split('/').pop() }}</div>
|
||||||
|
<audio
|
||||||
|
class="tiktok-audio"
|
||||||
|
:src="item.url"
|
||||||
|
:controls="index === 1"
|
||||||
|
:loop="index === 1 && autoPlayMode === 'off'"
|
||||||
|
preload="metadata"
|
||||||
|
:key="item.url"
|
||||||
|
:ref="(el) => { if (el) audioRefs[index] = el as HTMLAudioElement }"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 图片 -->
|
<!-- 图片 -->
|
||||||
<img v-else class="tiktok-media" :src="item.url" />
|
<img v-else class="tiktok-media" :src="item.url" />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -759,7 +904,7 @@ watch(() => autoPlayMode.value, () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 控制按钮区域 -->
|
<!-- 控制按钮区域 -->
|
||||||
<div class="tiktok-controls">
|
<div v-show="controlsVisible" class="tiktok-controls">
|
||||||
<!-- 关闭按钮 -->
|
<!-- 关闭按钮 -->
|
||||||
<button class="control-btn close-btn" @click="tiktokStore.closeView" :title="$t('close')">
|
<button class="control-btn close-btn" @click="tiktokStore.closeView" :title="$t('close')">
|
||||||
<CloseOutlined />
|
<CloseOutlined />
|
||||||
|
|
@ -799,7 +944,7 @@ watch(() => autoPlayMode.value, () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 导航指示器 -->
|
<!-- 导航指示器 -->
|
||||||
<div v-if="globalStore.showTiktokNavigator" class="tiktok-navigation">
|
<div v-show="controlsVisible" v-if="globalStore.showTiktokNavigator" class="tiktok-navigation">
|
||||||
<!-- 上一个指示器 -->
|
<!-- 上一个指示器 -->
|
||||||
<div v-if="tiktokStore.hasPrev" class="nav-indicator nav-prev" @touchstart.prevent="goToPrev(false)"
|
<div v-if="tiktokStore.hasPrev" class="nav-indicator nav-prev" @touchstart.prevent="goToPrev(false)"
|
||||||
@click="goToPrev(false)">
|
@click="goToPrev(false)">
|
||||||
|
|
@ -813,16 +958,25 @@ watch(() => autoPlayMode.value, () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 进度指示器 -->
|
<!-- 底部渐变遮罩和文件名 -->
|
||||||
<div class="tiktok-progress">
|
<div v-show="controlsVisible" class="tiktok-bottom-overlay">
|
||||||
<div class="progress-bar">
|
<div class="filename-display" v-if="currentItem?.name">
|
||||||
<div class="progress-fill" :style="{
|
{{ currentItem.name }}
|
||||||
width: `${((tiktokStore.currentIndex + 1) / tiktokStore.mediaList.length) * 100}%`
|
</div>
|
||||||
}" />
|
</div>
|
||||||
|
|
||||||
|
<!-- 进度指示器 -->
|
||||||
|
<div v-show="controlsVisible" class="tiktok-progress">
|
||||||
|
<div class="progress-bar-row">
|
||||||
|
<div class="progress-bar">
|
||||||
|
<div class="progress-fill" :style="{
|
||||||
|
width: `${((tiktokStore.currentIndex + 1) / tiktokStore.mediaList.length) * 100}%`
|
||||||
|
}" />
|
||||||
|
</div>
|
||||||
|
<span class="progress-text">
|
||||||
|
{{ tiktokStore.currentIndex + 1 }} / {{ tiktokStore.mediaList.length }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="progress-text">
|
|
||||||
{{ tiktokStore.currentIndex + 1 }} / {{ tiktokStore.mediaList.length }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- TAG 面板 -->
|
<!-- TAG 面板 -->
|
||||||
|
|
@ -946,6 +1100,7 @@ watch(() => autoPlayMode.value, () => {
|
||||||
.media-content {
|
.media-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100% - 32px);
|
height: calc(100% - 32px);
|
||||||
|
margin-bottom: 32px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
@ -1094,18 +1249,51 @@ watch(() => autoPlayMode.value, () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 底部渐变遮罩 - 抖音风格 */
|
||||||
|
.tiktok-bottom-overlay {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 200px;
|
||||||
|
background: linear-gradient(to top, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.4) 40%, rgba(0, 0, 0, 0) 100%);
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 8;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding: 0 20px 20px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filename-display {
|
||||||
|
color: white;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: left;
|
||||||
|
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
.tiktok-progress {
|
.tiktok-progress {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 5px;
|
bottom: 5px;
|
||||||
left: 20px;
|
left: 20px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
gap: 12px;
|
align-items: stretch;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.progress-bar-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 4px;
|
height: 4px;
|
||||||
|
|
@ -1127,6 +1315,123 @@ watch(() => autoPlayMode.value, () => {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 音频容器样式 */
|
||||||
|
.tiktok-audio-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
background: linear-gradient(135deg, #0a0a1a 0%, #0d1525 50%, #0a1628 100%);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
/* 星空背景层 */
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 星星层1 - 小星星 */
|
||||||
|
&::before {
|
||||||
|
background-image:
|
||||||
|
radial-gradient(1px 1px at 20px 30px, white, transparent),
|
||||||
|
radial-gradient(1px 1px at 40px 70px, rgba(255,255,255,0.8), transparent),
|
||||||
|
radial-gradient(1px 1px at 50px 160px, rgba(255,255,255,0.6), transparent),
|
||||||
|
radial-gradient(1px 1px at 90px 40px, white, transparent),
|
||||||
|
radial-gradient(1px 1px at 130px 80px, rgba(255,255,255,0.7), transparent),
|
||||||
|
radial-gradient(1px 1px at 160px 120px, white, transparent),
|
||||||
|
radial-gradient(1.5px 1.5px at 200px 50px, rgba(255,255,255,0.9), transparent),
|
||||||
|
radial-gradient(1px 1px at 220px 150px, rgba(255,255,255,0.5), transparent),
|
||||||
|
radial-gradient(1.5px 1.5px at 280px 90px, white, transparent),
|
||||||
|
radial-gradient(1px 1px at 320px 20px, rgba(255,255,255,0.8), transparent),
|
||||||
|
radial-gradient(1px 1px at 350px 180px, rgba(255,255,255,0.6), transparent),
|
||||||
|
radial-gradient(1.5px 1.5px at 400px 60px, white, transparent),
|
||||||
|
radial-gradient(1px 1px at 450px 130px, rgba(255,255,255,0.7), transparent),
|
||||||
|
radial-gradient(1px 1px at 500px 40px, rgba(255,255,255,0.9), transparent),
|
||||||
|
radial-gradient(1.5px 1.5px at 80px 200px, white, transparent),
|
||||||
|
radial-gradient(1px 1px at 180px 220px, rgba(255,255,255,0.6), transparent),
|
||||||
|
radial-gradient(1px 1px at 300px 250px, rgba(255,255,255,0.8), transparent),
|
||||||
|
radial-gradient(1.5px 1.5px at 420px 200px, white, transparent);
|
||||||
|
background-repeat: repeat;
|
||||||
|
background-size: 550px 300px;
|
||||||
|
animation: starfield-move 60s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 星星层2 - 亮星星,不同速度 */
|
||||||
|
&::after {
|
||||||
|
background-image:
|
||||||
|
radial-gradient(2px 2px at 100px 50px, rgba(255,255,255,0.9), transparent),
|
||||||
|
radial-gradient(2px 2px at 250px 120px, white, transparent),
|
||||||
|
radial-gradient(2.5px 2.5px at 380px 80px, rgba(200,220,255,0.9), transparent),
|
||||||
|
radial-gradient(2px 2px at 150px 180px, rgba(255,255,255,0.8), transparent),
|
||||||
|
radial-gradient(2.5px 2.5px at 450px 150px, rgba(220,200,255,0.9), transparent),
|
||||||
|
radial-gradient(2px 2px at 50px 250px, white, transparent),
|
||||||
|
radial-gradient(2px 2px at 320px 220px, rgba(255,255,255,0.85), transparent);
|
||||||
|
background-repeat: repeat;
|
||||||
|
background-size: 600px 350px;
|
||||||
|
animation: starfield-move 90s linear infinite reverse;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-icon {
|
||||||
|
font-size: 120px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
animation: pulse 2s ease-in-out infinite;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
text-shadow: 0 0 40px rgba(100, 150, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-filename {
|
||||||
|
color: white;
|
||||||
|
font-size: 18px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
max-width: 80%;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiktok-audio {
|
||||||
|
width: 80%;
|
||||||
|
max-width: 1400px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes starfield-move {
|
||||||
|
from {
|
||||||
|
transform: translateY(0) translateX(0);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateY(-300px) translateX(-550px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tiktok-tags-panel {
|
.tiktok-tags-panel {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import { type FileNodeInfo } from '@/api/files'
|
||||||
import { sortFiles } from '../fileSort'
|
import { sortFiles } from '../fileSort'
|
||||||
import { last, range } from 'lodash-es'
|
import { last, range } from 'lodash-es'
|
||||||
import * as Path from '@/util/path'
|
import * as Path from '@/util/path'
|
||||||
import { isMediaFile } from '@/util/file'
|
import { isImageFile, isVideoFile, isAudioFile } from '@/util/file'
|
||||||
import { useTagStore } from '@/store/useTagStore'
|
import { useTagStore } from '@/store/useTagStore'
|
||||||
import { useBatchDownloadStore } from '@/store/useBatchDownloadStore'
|
import { useBatchDownloadStore } from '@/store/useBatchDownloadStore'
|
||||||
import { Walker } from '../walker'
|
import { Walker } from '../walker'
|
||||||
|
|
@ -88,10 +88,25 @@ export const { useHookShareState } = createTypedShareStateHook(
|
||||||
}
|
}
|
||||||
const files = currPage.value?.files ?? []
|
const files = currPage.value?.files ?? []
|
||||||
const method = sortMethod.value
|
const method = sortMethod.value
|
||||||
const filter = (files: FileNodeInfo[]) =>
|
const filter = (files: FileNodeInfo[]) => {
|
||||||
global.onlyFoldersAndImages
|
const filterTypes = global.fileTypeFilter
|
||||||
? files.filter((file) => file.type === 'dir' || isMediaFile(file.name))
|
// 如果选择了 'all',显示所有文件
|
||||||
: files
|
if (filterTypes.includes('all')) {
|
||||||
|
return files
|
||||||
|
}
|
||||||
|
// 如果没有选择任何类型,显示所有文件
|
||||||
|
if (filterTypes.length === 0) {
|
||||||
|
return files
|
||||||
|
}
|
||||||
|
// 根据选择的类型过滤
|
||||||
|
return files.filter((file) => {
|
||||||
|
if (file.type === 'dir') return true // 始终显示文件夹
|
||||||
|
if (filterTypes.includes('image') && isImageFile(file.name)) return true
|
||||||
|
if (filterTypes.includes('video') && isVideoFile(file.name)) return true
|
||||||
|
if (filterTypes.includes('audio') && isAudioFile(file.name)) return true
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
return sortFiles(filter(files), method).filter(v => !deletedFiles.has(v.fullpath))
|
return sortFiles(filter(files), method).filter(v => !deletedFiles.has(v.fullpath))
|
||||||
})
|
})
|
||||||
const multiSelectedIdxs = ref([] as number[])
|
const multiSelectedIdxs = ref([] as number[])
|
||||||
|
|
|
||||||
|
|
@ -140,8 +140,13 @@ const disableMaximize = useLocalStorage(prefix+'disable_maximize', false)
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<h2 style="margin-top: 0;">{{ t('other') }}</h2>
|
<h2 style="margin-top: 0;">{{ t('other') }}</h2>
|
||||||
<a-form-item :label="$t('onlyFoldersAndImages')">
|
<a-form-item :label="$t('fileTypeFilter')">
|
||||||
<a-switch v-model:checked="globalStore.onlyFoldersAndImages" />
|
<a-checkbox-group v-model:value="globalStore.fileTypeFilter">
|
||||||
|
<a-checkbox value="all">{{ $t('allFiles') }}</a-checkbox>
|
||||||
|
<a-checkbox value="image">{{ $t('image') }}</a-checkbox>
|
||||||
|
<a-checkbox value="video">{{ $t('video') }}</a-checkbox>
|
||||||
|
<a-checkbox value="audio">{{ $t('audio') }}</a-checkbox>
|
||||||
|
</a-checkbox-group>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<!--在生成信息面板显示逗号-->
|
<!--在生成信息面板显示逗号-->
|
||||||
<a-form-item :label="$t('showCommaInGenInfoPanel')">
|
<a-form-item :label="$t('showCommaInGenInfoPanel')">
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,7 @@ export const presistKeys = [
|
||||||
'gridThumbnailResolution',
|
'gridThumbnailResolution',
|
||||||
'longPressOpenContextMenu',
|
'longPressOpenContextMenu',
|
||||||
'onlyFoldersAndImages',
|
'onlyFoldersAndImages',
|
||||||
|
'fileTypeFilter',
|
||||||
'shortcut',
|
'shortcut',
|
||||||
'ignoredConfirmActions',
|
'ignoredConfirmActions',
|
||||||
'previewBgOpacity',
|
'previewBgOpacity',
|
||||||
|
|
@ -369,7 +370,8 @@ export const useGlobalStore = defineStore(
|
||||||
gridThumbnailResolution,
|
gridThumbnailResolution,
|
||||||
longPressOpenContextMenu,
|
longPressOpenContextMenu,
|
||||||
openTagSearchMatchedImageGridInRight,
|
openTagSearchMatchedImageGridInRight,
|
||||||
onlyFoldersAndImages: ref(true),
|
onlyFoldersAndImages: ref(true), // 保留用于向后兼容
|
||||||
|
fileTypeFilter: ref<('image' | 'video' | 'audio' | 'all')[]>(['image', 'video', 'audio']), // 新的多选过滤
|
||||||
keepMultiSelect: ref(false),
|
keepMultiSelect: ref(false),
|
||||||
fullscreenPreviewInitialUrl: ref(''),
|
fullscreenPreviewInitialUrl: ref(''),
|
||||||
shortcut,
|
shortcut,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { ref, computed } from 'vue'
|
||||||
|
|
||||||
export interface TiktokMediaItem {
|
export interface TiktokMediaItem {
|
||||||
url: string
|
url: string
|
||||||
type: 'image' | 'video'
|
type: 'image' | 'video' | 'audio'
|
||||||
id: string
|
id: string
|
||||||
[key: string]: any // 允许额外的属性
|
[key: string]: any // 允许额外的属性
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,19 @@ export function isVideoFile (filename: string): boolean {
|
||||||
return extension !== undefined && exts.includes(`.${extension}`)
|
return extension !== undefined && exts.includes(`.${extension}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isMediaFile = (file: string) => isImageFile(file) || isVideoFile(file)
|
export function isAudioFile (filename: string): boolean {
|
||||||
|
if (typeof filename !== 'string') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const exts = ['.mp3', '.wav', '.ogg', '.flac', '.m4a', '.aac', '.wma']
|
||||||
|
const extension = filename.split('.').pop()?.toLowerCase()
|
||||||
|
return extension !== undefined && exts.includes(`.${extension}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const toStreamAudioUrl = (file: FileNodeInfo) =>
|
||||||
|
`${apiBase.value}/stream_video?path=${encode(file.fullpath)}`
|
||||||
|
|
||||||
|
export const isMediaFile = (file: string) => isImageFile(file) || isVideoFile(file) || isAudioFile(file)
|
||||||
|
|
||||||
export function downloadFiles (urls: string[]) {
|
export function downloadFiles (urls: string[]) {
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,34 @@
|
||||||
import type { FileNodeInfo } from '@/api/files'
|
import type { FileNodeInfo } from '@/api/files'
|
||||||
import type { TiktokMediaItem } from '@/store/useTiktokStore'
|
import type { TiktokMediaItem } from '@/store/useTiktokStore'
|
||||||
import { useTiktokStore } from '@/store/useTiktokStore'
|
import { useTiktokStore } from '@/store/useTiktokStore'
|
||||||
import { isVideoFile, isImageFile } from '@/util'
|
import { isVideoFile, isImageFile, isAudioFile } from '@/util'
|
||||||
import { toRawFileUrl, toStreamVideoUrl } from '@/util/file'
|
import { toRawFileUrl, toStreamVideoUrl, toStreamAudioUrl } from '@/util/file'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 FileNodeInfo 转换为 TiktokMediaItem
|
* 将 FileNodeInfo 转换为 TiktokMediaItem
|
||||||
*/
|
*/
|
||||||
export const fileToTiktokItem = (file: FileNodeInfo): TiktokMediaItem => {
|
export const fileToTiktokItem = (file: FileNodeInfo): TiktokMediaItem => {
|
||||||
const isVideo = isVideoFile(file.name)
|
const isVideo = isVideoFile(file.name)
|
||||||
|
const isAudio = isAudioFile(file.name)
|
||||||
|
|
||||||
|
let url: string
|
||||||
|
let type: 'image' | 'video' | 'audio'
|
||||||
|
|
||||||
|
if (isVideo) {
|
||||||
|
url = toStreamVideoUrl(file)
|
||||||
|
type = 'video'
|
||||||
|
} else if (isAudio) {
|
||||||
|
url = toStreamAudioUrl(file)
|
||||||
|
type = 'audio'
|
||||||
|
} else {
|
||||||
|
url = toRawFileUrl(file)
|
||||||
|
type = 'image'
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: file.fullpath,
|
id: file.fullpath,
|
||||||
url: isVideo ? toStreamVideoUrl(file) : toRawFileUrl(file),
|
url,
|
||||||
type: isVideo ? 'video' : 'image',
|
type,
|
||||||
// 保留原始文件信息以供后续使用
|
// 保留原始文件信息以供后续使用
|
||||||
originalFile: file,
|
originalFile: file,
|
||||||
name: file.name,
|
name: file.name,
|
||||||
|
|
@ -26,7 +41,7 @@ export const fileToTiktokItem = (file: FileNodeInfo): TiktokMediaItem => {
|
||||||
*/
|
*/
|
||||||
export const filesToTiktokItems = (files: FileNodeInfo[]): TiktokMediaItem[] => {
|
export const filesToTiktokItems = (files: FileNodeInfo[]): TiktokMediaItem[] => {
|
||||||
return files
|
return files
|
||||||
.filter(file => file.type === 'file' && (isImageFile(file.name) || isVideoFile(file.name)))
|
.filter(file => file.type === 'file' && (isImageFile(file.name) || isVideoFile(file.name) || isAudioFile(file.name)))
|
||||||
.map(fileToTiktokItem)
|
.map(fileToTiktokItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,11 +49,19 @@ export const filesToTiktokItems = (files: FileNodeInfo[]): TiktokMediaItem[] =>
|
||||||
* 从 URL 列表直接创建 TiktokMediaItem 数组
|
* 从 URL 列表直接创建 TiktokMediaItem 数组
|
||||||
*/
|
*/
|
||||||
export const urlsToTiktokItems = (urls: string[]): TiktokMediaItem[] => {
|
export const urlsToTiktokItems = (urls: string[]): TiktokMediaItem[] => {
|
||||||
return urls.map((url) => ({
|
return urls.map((url) => {
|
||||||
id: url,
|
let type: 'image' | 'video' | 'audio' = 'image'
|
||||||
url: url,
|
if (isVideoFile(url)) {
|
||||||
type: isVideoFile(url) ? 'video' : 'image'
|
type = 'video'
|
||||||
}))
|
} else if (isAudioFile(url)) {
|
||||||
|
type = 'audio'
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
id: url,
|
||||||
|
url: url,
|
||||||
|
type
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue