支持文件夹在右边打开,在新tab打开

pull/27/head
zanllp 2023-04-15 20:14:28 +08:00
parent 0d1c20bc16
commit f1de9f8400
24 changed files with 135 additions and 67 deletions

View File

@ -8,7 +8,7 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<script type="module" crossorigin src="/baidu_netdisk/fe-static/assets/index-6a893707.js"></script>
<script type="module" crossorigin src="/baidu_netdisk/fe-static/assets/index-3eae54c8.js"></script>
<link rel="stylesheet" href="/baidu_netdisk/fe-static/assets/index-1930f7ee.css">
</head>

View File

@ -246,8 +246,7 @@ def baidu_netdisk_api(_: Any, app: FastAPI):
if target == "local":
for path in req.file_paths:
try:
# 删除文件
os.remove(path)
shutil.rmtree(path)
except OSError as e:
# 处理删除失败的情况
raise HTTPException(400, detail=f"删除文件{path}时出错:{e}")

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{b as s}from"./index-fd27c05d.js";import{bL as t,aT as a}from"./index-6a893707.js";function c(e,o){return e&&e.length?t(e,s(o)):[]}const i=(e,o)=>(a.success({content:o??`已复制内容 "${e}" 到粘贴板`}),navigator.clipboard.writeText(e));export{i as c,c as u};
import{b as s}from"./index-80b56a21.js";import{bN as t,aT as a}from"./index-3eae54c8.js";function c(e,o){return e&&e.length?t(e,s(o)):[]}const i=(e,o)=>(a.success({content:o??`已复制内容 "${e}" 到粘贴板`}),navigator.clipboard.writeText(e));export{i as c,c as u};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{u as p}from"./useTaskListStore-a92be8d2.js";import{d as u,r as d,G as g,ah as f,ai as m,K as t,L as s,V as l,W as k,X as L,U as y,M as D,a0 as h}from"./index-6a893707.js";const v={class:"container"},x=u({__name:"logDetail",props:{logDetailId:null},setup(r){const n=r,c=p(),a=d(),o=g(()=>c.taskLogMap.get(n.logDetailId));return f(o,async()=>{await m();const e=a.value;e&&(e.scrollTop=e.scrollHeight)},{deep:!0}),(e,B)=>(t(),s("div",v,[l("ul",{class:"list",ref_key:"logListEl",ref:a},[(t(!0),s(k,null,L(D(o),(i,_)=>(t(),s("li",{key:_},[l("pre",null,y(i.log),1)]))),128))],512)]))}});const T=h(x,[["__scopeId","data-v-59148842"]]);export{T as default};
import{u as p}from"./useTaskListStore-0675db92.js";import{d as u,r as d,G as g,ah as f,ai as m,K as t,L as s,V as l,W as k,X as L,U as y,M as D,a0 as h}from"./index-3eae54c8.js";const v={class:"container"},x=u({__name:"logDetail",props:{logDetailId:null},setup(r){const n=r,c=p(),a=d(),o=g(()=>c.taskLogMap.get(n.logDetailId));return f(o,async()=>{await m();const e=a.value;e&&(e.scrollTop=e.scrollHeight)},{deep:!0}),(e,B)=>(t(),s("div",v,[l("ul",{class:"list",ref_key:"logListEl",ref:a},[(t(!0),s(k,null,L(D(o),(i,_)=>(t(),s("li",{key:_},[l("pre",null,y(i.log),1)]))),128))],512)]))}});const T=h(x,[["__scopeId","data-v-59148842"]]);export{T as default};

3
vue/dist/assets/stackView-090df58b.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
import{i as Te,I as P,t as Re,f as Oe,C as Ne,a as je,r as ie,E as $e}from"./index-3eb7b787.js";import{d as K,u as te,G as q,_ as S,a as _,h as g,x as fe,P as ke,r as O,a2 as Ee,bG as Ve,b as _e,c as ne,B as ae,A as De,aj as U,ab as Ge,ah as Me,ai as J,y as He,f as Le,bH as Ue,bI as Ze,am as Be,af as Ye,H as qe,ae as ee,a6 as ge,D as Ke,i as Qe,bJ as oe,bK as We}from"./index-6a893707.js";import{i as Xe}from"./index-2c46e3b9.js";import{B as Je}from"./button-e3c54354.js";const et=K({compatConfig:{MODE:3},name:"AInputGroup",props:{prefixCls:String,size:{type:String},compact:{type:Boolean,default:void 0},onMouseenter:{type:Function},onMouseleave:{type:Function},onFocus:{type:Function},onBlur:{type:Function}},setup:function(e,t){var a=t.slots,c=te("input-group",e),p=c.prefixCls,f=c.direction,r=q(function(){var o,u=p.value;return o={},S(o,"".concat(u),!0),S(o,"".concat(u,"-lg"),e.size==="large"),S(o,"".concat(u,"-sm"),e.size==="small"),S(o,"".concat(u,"-compact"),e.compact),S(o,"".concat(u,"-rtl"),f.value==="rtl"),o});return function(){var o;return _("span",{class:r.value,onMouseenter:e.onMouseenter,onMouseleave:e.onMouseleave,onFocus:e.onFocus,onBlur:e.onBlur},[(o=a.default)===null||o===void 0?void 0:o.call(a)])}}});var le=/iPhone/i,me=/iPod/i,pe=/iPad/i,ue=/\bAndroid(?:.+)Mobile\b/i,he=/Android/i,Z=/\bAndroid(?:.+)SD4930UR\b/i,X=/\bAndroid(?:.+)(?:KF[A-Z]{2,4})\b/i,V=/Windows Phone/i,be=/\bWindows(?:.+)ARM\b/i,xe=/BlackBerry/i,ye=/BB10/i,Ce=/Opera Mini/i,ze=/\b(CriOS|Chrome)(?:.+)Mobile/i,Se=/Mobile(?:.+)Firefox\b/i;function i(l,e){return l.test(e)}function we(l){var e=l||(typeof navigator<"u"?navigator.userAgent:""),t=e.split("[FBAN");if(typeof t[1]<"u"){var a=t,c=fe(a,1);e=c[0]}if(t=e.split("Twitter"),typeof t[1]<"u"){var p=t,f=fe(p,1);e=f[0]}var r={apple:{phone:i(le,e)&&!i(V,e),ipod:i(me,e),tablet:!i(le,e)&&i(pe,e)&&!i(V,e),device:(i(le,e)||i(me,e)||i(pe,e))&&!i(V,e)},amazon:{phone:i(Z,e),tablet:!i(Z,e)&&i(X,e),device:i(Z,e)||i(X,e)},android:{phone:!i(V,e)&&i(Z,e)||!i(V,e)&&i(ue,e),tablet:!i(V,e)&&!i(Z,e)&&!i(ue,e)&&(i(X,e)||i(he,e)),device:!i(V,e)&&(i(Z,e)||i(X,e)||i(ue,e)||i(he,e))||i(/\bokhttp\b/i,e)},windows:{phone:i(V,e),tablet:i(be,e),device:i(V,e)||i(be,e)},other:{blackberry:i(xe,e),blackberry10:i(ye,e),opera:i(Ce,e),firefox:i(Se,e),chrome:i(ze,e),device:i(xe,e)||i(ye,e)||i(Ce,e)||i(Se,e)||i(ze,e)},any:null,phone:null,tablet:null};return r.any=r.apple.device||r.android.device||r.windows.device||r.other.device,r.phone=r.apple.phone||r.android.phone||r.windows.phone,r.tablet=r.apple.tablet||r.android.tablet||r.windows.tablet,r}var tt=g(g({},we()),{},{isMobile:we});const nt=tt;var at=["disabled","loading","addonAfter","suffix"];const rt=K({compatConfig:{MODE:3},name:"AInputSearch",inheritAttrs:!1,props:g(g({},Te()),{},{inputPrefixCls:String,enterButton:ke.any,onSearch:{type:Function}}),setup:function(e,t){var a=t.slots,c=t.attrs,p=t.expose,f=t.emit,r=O(),o=function(){var s;(s=r.value)===null||s===void 0||s.focus()},u=function(){var s;(s=r.value)===null||s===void 0||s.blur()};p({focus:o,blur:u});var y=function(s){f("update:value",s.target.value),s&&s.target&&s.type==="click"&&f("search",s.target.value,s),f("change",s)},h=function(s){var C;document.activeElement===((C=r.value)===null||C===void 0?void 0:C.input)&&s.preventDefault()},A=function(s){var C;f("search",(C=r.value)===null||C===void 0?void 0:C.stateValue,s),nt.tablet||r.value.focus()},I=te("input-search",e),T=I.prefixCls,$=I.getPrefixCls,N=I.direction,w=I.size,v=q(function(){return $("input",e.inputPrefixCls)});return function(){var m,s,C,M,E,B=e.disabled,j=e.loading,H=e.addonAfter,k=H===void 0?(m=a.addonAfter)===null||m===void 0?void 0:m.call(a):H,Q=e.suffix,W=Q===void 0?(s=a.suffix)===null||s===void 0?void 0:s.call(a):Q,re=Ee(e,at),b=e.enterButton,n=b===void 0?(C=(M=a.enterButton)===null||M===void 0?void 0:M.call(a))!==null&&C!==void 0?C:!1:b;n=n||n==="";var d=typeof n=="boolean"?_(Ve,null,null):null,x="".concat(T.value,"-button"),z=Array.isArray(n)?n[0]:n,R,L=z.type&&Xe(z.type)&&z.type.__ANT_BUTTON;if(L||z.tagName==="button")R=_e(z,g({onMousedown:h,onClick:A,key:"enterButton"},L?{class:x,size:w.value}:{}),!1);else{var D=d&&!n;R=_(Je,{class:x,type:n?"primary":void 0,size:w.value,disabled:B,key:"enterButton",onMousedown:h,onClick:A,loading:j,icon:D?d:null},{default:function(){return[D?null:d||n]}})}k&&(R=[R,k]);var G=ne(T.value,(E={},S(E,"".concat(T.value,"-rtl"),N.value==="rtl"),S(E,"".concat(T.value,"-").concat(w.value),!!w.value),S(E,"".concat(T.value,"-with-button"),!!n),E),c.class);return _(P,g(g(g({ref:r},ae(re,["onUpdate:value","onSearch","enterButton"])),c),{},{onPressEnter:A,size:w.value,prefixCls:v.value,addonAfter:R,suffix:W,onChange:y,class:G,disabled:B}),a)}}});var it=`
import{i as Te,I as P,t as Re,f as Oe,C as Ne,a as je,r as ie,E as $e}from"./index-ca5e55e8.js";import{d as K,u as te,G as q,_ as S,a as _,h as g,x as fe,P as ke,r as O,a2 as Ee,bI as Ve,b as _e,c as ne,B as ae,A as De,aj as U,ab as Ge,ah as Me,ai as J,y as He,f as Le,bJ as Ue,bK as Ze,am as Be,af as Ye,H as qe,ae as ee,a6 as ge,D as Ke,i as Qe,bL as oe,bM as We}from"./index-3eae54c8.js";import{i as Xe}from"./index-b363ae13.js";import{B as Je}from"./button-26bad4bf.js";const et=K({compatConfig:{MODE:3},name:"AInputGroup",props:{prefixCls:String,size:{type:String},compact:{type:Boolean,default:void 0},onMouseenter:{type:Function},onMouseleave:{type:Function},onFocus:{type:Function},onBlur:{type:Function}},setup:function(e,t){var a=t.slots,c=te("input-group",e),p=c.prefixCls,f=c.direction,r=q(function(){var o,u=p.value;return o={},S(o,"".concat(u),!0),S(o,"".concat(u,"-lg"),e.size==="large"),S(o,"".concat(u,"-sm"),e.size==="small"),S(o,"".concat(u,"-compact"),e.compact),S(o,"".concat(u,"-rtl"),f.value==="rtl"),o});return function(){var o;return _("span",{class:r.value,onMouseenter:e.onMouseenter,onMouseleave:e.onMouseleave,onFocus:e.onFocus,onBlur:e.onBlur},[(o=a.default)===null||o===void 0?void 0:o.call(a)])}}});var le=/iPhone/i,me=/iPod/i,pe=/iPad/i,ue=/\bAndroid(?:.+)Mobile\b/i,he=/Android/i,Z=/\bAndroid(?:.+)SD4930UR\b/i,X=/\bAndroid(?:.+)(?:KF[A-Z]{2,4})\b/i,V=/Windows Phone/i,be=/\bWindows(?:.+)ARM\b/i,xe=/BlackBerry/i,ye=/BB10/i,Ce=/Opera Mini/i,ze=/\b(CriOS|Chrome)(?:.+)Mobile/i,Se=/Mobile(?:.+)Firefox\b/i;function i(l,e){return l.test(e)}function we(l){var e=l||(typeof navigator<"u"?navigator.userAgent:""),t=e.split("[FBAN");if(typeof t[1]<"u"){var a=t,c=fe(a,1);e=c[0]}if(t=e.split("Twitter"),typeof t[1]<"u"){var p=t,f=fe(p,1);e=f[0]}var r={apple:{phone:i(le,e)&&!i(V,e),ipod:i(me,e),tablet:!i(le,e)&&i(pe,e)&&!i(V,e),device:(i(le,e)||i(me,e)||i(pe,e))&&!i(V,e)},amazon:{phone:i(Z,e),tablet:!i(Z,e)&&i(X,e),device:i(Z,e)||i(X,e)},android:{phone:!i(V,e)&&i(Z,e)||!i(V,e)&&i(ue,e),tablet:!i(V,e)&&!i(Z,e)&&!i(ue,e)&&(i(X,e)||i(he,e)),device:!i(V,e)&&(i(Z,e)||i(X,e)||i(ue,e)||i(he,e))||i(/\bokhttp\b/i,e)},windows:{phone:i(V,e),tablet:i(be,e),device:i(V,e)||i(be,e)},other:{blackberry:i(xe,e),blackberry10:i(ye,e),opera:i(Ce,e),firefox:i(Se,e),chrome:i(ze,e),device:i(xe,e)||i(ye,e)||i(Ce,e)||i(Se,e)||i(ze,e)},any:null,phone:null,tablet:null};return r.any=r.apple.device||r.android.device||r.windows.device||r.other.device,r.phone=r.apple.phone||r.android.phone||r.windows.phone,r.tablet=r.apple.tablet||r.android.tablet||r.windows.tablet,r}var tt=g(g({},we()),{},{isMobile:we});const nt=tt;var at=["disabled","loading","addonAfter","suffix"];const rt=K({compatConfig:{MODE:3},name:"AInputSearch",inheritAttrs:!1,props:g(g({},Te()),{},{inputPrefixCls:String,enterButton:ke.any,onSearch:{type:Function}}),setup:function(e,t){var a=t.slots,c=t.attrs,p=t.expose,f=t.emit,r=O(),o=function(){var s;(s=r.value)===null||s===void 0||s.focus()},u=function(){var s;(s=r.value)===null||s===void 0||s.blur()};p({focus:o,blur:u});var y=function(s){f("update:value",s.target.value),s&&s.target&&s.type==="click"&&f("search",s.target.value,s),f("change",s)},h=function(s){var C;document.activeElement===((C=r.value)===null||C===void 0?void 0:C.input)&&s.preventDefault()},A=function(s){var C;f("search",(C=r.value)===null||C===void 0?void 0:C.stateValue,s),nt.tablet||r.value.focus()},I=te("input-search",e),T=I.prefixCls,$=I.getPrefixCls,N=I.direction,w=I.size,v=q(function(){return $("input",e.inputPrefixCls)});return function(){var m,s,C,M,E,B=e.disabled,j=e.loading,H=e.addonAfter,k=H===void 0?(m=a.addonAfter)===null||m===void 0?void 0:m.call(a):H,Q=e.suffix,W=Q===void 0?(s=a.suffix)===null||s===void 0?void 0:s.call(a):Q,re=Ee(e,at),b=e.enterButton,n=b===void 0?(C=(M=a.enterButton)===null||M===void 0?void 0:M.call(a))!==null&&C!==void 0?C:!1:b;n=n||n==="";var d=typeof n=="boolean"?_(Ve,null,null):null,x="".concat(T.value,"-button"),z=Array.isArray(n)?n[0]:n,R,L=z.type&&Xe(z.type)&&z.type.__ANT_BUTTON;if(L||z.tagName==="button")R=_e(z,g({onMousedown:h,onClick:A,key:"enterButton"},L?{class:x,size:w.value}:{}),!1);else{var D=d&&!n;R=_(Je,{class:x,type:n?"primary":void 0,size:w.value,disabled:B,key:"enterButton",onMousedown:h,onClick:A,loading:j,icon:D?d:null},{default:function(){return[D?null:d||n]}})}k&&(R=[R,k]);var G=ne(T.value,(E={},S(E,"".concat(T.value,"-rtl"),N.value==="rtl"),S(E,"".concat(T.value,"-").concat(w.value),!!w.value),S(E,"".concat(T.value,"-with-button"),!!n),E),c.class);return _(P,g(g(g({ref:r},ae(re,["onUpdate:value","onSearch","enterButton"])),c),{},{onPressEnter:A,size:w.value,prefixCls:v.value,addonAfter:R,suffix:W,onChange:y,class:G,disabled:B}),a)}}});var it=`
min-height:0 !important;
max-height:none !important;
height:0 !important;

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{cM as r,r as e,J as t,aV as i,cN as d}from"./index-6a893707.js";const v=r("useTaskListStore",()=>{const a=e(new Map),n=t(new i),u=e(3),o=e([]),c=t([]),l=e(-1),s=e(null);return{checkBaiduyunInstalled:async()=>(s.value===null&&(s.value=d()),s.value),baiduyunInstalled:s,pollInterval:u,taskLogMap:a,queue:n,tasks:o,showDirAutoCompletedIdx:l,pendingBaiduyunTaskQueue:c}},{persist:{paths:["pollInterval","tasks"],key:"useTaskListStore-v0.0.1"}});export{v as u};
import{cM as r,r as e,J as t,aV as i,cN as d}from"./index-3eae54c8.js";const v=r("useTaskListStore",()=>{const a=e(new Map),n=t(new i),u=e(3),o=e([]),c=t([]),l=e(-1),s=e(null);return{checkBaiduyunInstalled:async()=>(s.value===null&&(s.value=d()),s.value),baiduyunInstalled:s,pollInterval:u,taskLogMap:a,queue:n,tasks:o,showDirAutoCompletedIdx:l,pendingBaiduyunTaskQueue:c}},{persist:{paths:["pollInterval","tasks"],key:"useTaskListStore-v0.0.1"}});export{v as u};

2
vue/dist/index.html vendored
View File

@ -7,7 +7,7 @@
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<script type="module" crossorigin src="/baidu_netdisk/fe-static/assets/index-6a893707.js"></script>
<script type="module" crossorigin src="/baidu_netdisk/fe-static/assets/index-3eae54c8.js"></script>
<link rel="stylesheet" href="/baidu_netdisk/fe-static/assets/index-1930f7ee.css">
</head>

View File

@ -60,8 +60,8 @@ const messages = {
"downloadDirectly": "直接下载(大文件的话谨慎)",
"copySourceFilePreviewLink": "复制源文件预览链接",
"viewGenerationInfo": "查看生成信息(prompt等)",
"sendTot2i": "发送到文生图",
"sendToi2i": "发送到图生图",
"sendToTxt2img": "发送到文生图",
"sendToImg2img": "发送到图生图",
"sendToInpaint": "发送到局部重绘",
"sendToExtraFeatures": "发送到附加功能",
"loadNextPage": "加载下一页",
@ -91,7 +91,10 @@ const messages = {
"workingFolder": "工作文件夹",
lang: "语言",
'langChangeReload': '重新加载: 一些变化可能需要在重新加载后生效',
hypernetworks: '超网络模型'
hypernetworks: '超网络模型',
openOnTheRight: "在右边打开",
openInNewTab: '在新标签打开',
loginPrompt: '这个功能要求你先使用BDUSS登录到百度云盘。'
},
"en": {
"errorOccurred": "An error occurred",
@ -139,7 +142,7 @@ const messages = {
"login": "Login",
"doubleClickToCopy": "Double-click to copy",
"root": "Root",
"drive": "Drive",
"drive": " drive",
"refresh": "Refresh",
"quickMove": "Quick move",
"more": "More",
@ -182,7 +185,10 @@ const messages = {
"workingFolder": "Working folder",
lang: "Language",
'langChangeReload': 'Reload: Some changes may require a reload to take effect',
hypernetworks: 'hypernetworks'
hypernetworks: 'hypernetworks',
openOnTheRight: "Open on the right",
openInNewTab: 'Open in a new tab',
loginPrompt: 'This feature requires you to log in to Baidu Cloud Drive using your BDUSS.'
}
}

View File

@ -24,6 +24,6 @@ watch(dark, async (dark) => {
darkStyle.setAttribute('antd-dark', '')
head.appendChild(darkStyle)
} else {
Array.from(head.querySelectorAll('style[antd-dark]')).forEach(e => e.remove()) // for dev
Array.from(head.querySelectorAll('style[antd-dark]')).forEach(e => e.remove())
}
}, { immediate: true })

View File

@ -5,11 +5,11 @@ import { ref, computed, watch, onMounted, h, reactive } from 'vue'
import { downloadBaiduyun, genInfoCompleted, getImageGenerationInfo, setImgPath } from '@/api'
import { isAxiosError } from 'axios'
import { useWatchDocument, type SearchSelectConv, ok, createTypedShareStateHook, copy2clipboard, delay, FetchQueue, typedEventEmitter } from 'vue3-ts-util'
import { useWatchDocument, type SearchSelectConv, ok, createTypedShareStateHook, copy2clipboard, delay, FetchQueue, typedEventEmitter, ID } from 'vue3-ts-util'
import { gradioApp, isImageFile } from '@/util'
import { getTargetFolderFiles, type FileNodeInfo, deleteFiles, moveFiles } from '@/api/files'
import { sortFiles, sortMethodMap, SortMethod } from './fileSort'
import { cloneDeep, debounce, last, range, uniqBy } from 'lodash-es'
import { cloneDeep, debounce, last, range, uniqBy, uniqueId } from 'lodash-es'
import path from 'path-browserify'
import type Progress from 'nprogress'
// @ts-ignore
@ -21,6 +21,8 @@ import { loginByBduss } from '@/api/user'
import { t } from '@/i18n'
import { locale } from '@/i18n'
export const stackCache = new Map<string, Page[]>()
const global = useGlobalStore()
export const toRawFileUrl = (file: FileNodeInfo, download = false) => `/baidu_netdisk/file?filename=${encodeURIComponent(file.fullpath)}${download ? `&disposition=${encodeURIComponent(file.name)}` : ''}`
export const toImageThumbnailUrl = (file: FileNodeInfo, size: string) => `/baidu_netdisk/image-thumbnail?path=${encodeURIComponent(file.fullpath)}&size=${size}`
@ -145,7 +147,7 @@ export const useBaiduyun = () => {
}
}
interface Page {
export interface Page {
files: FileNodeInfo[]
walkFiles?: FileNodeInfo[][] // 使用walk时各个文件夹之间分散排序避免创建时间不同的带来的干扰
curr: string
@ -265,11 +267,13 @@ export function useLocation (props: Props) {
if (props.target === 'netdisk' && installedBaiduyun.value) {
return
}
const resp = await getTargetFolderFiles(props.target, '/')
stack.value.push({
files: resp.files,
curr: '/'
})
if (!stack.value.length) { // 有传入stack时直接使用传入的
const resp = await getTargetFolderFiles(props.target, '/')
stack.value.push({
files: resp.files,
curr: '/'
})
}
np.value = new NProgress()
np.value!.configure({ parent: stackViewEl.value as any })
if (props.path && props.path !== '/') {
@ -340,7 +344,7 @@ export function useLocation (props: Props) {
}
const to = async (dir: string, refreshIfCurrPage = true) => {
const backup = cloneDeep(stack.value)
const backup = stack.value.slice()
try {
if (!/^((\w:)|\/)/.test(dir)) {
// 相对路径
@ -655,6 +659,7 @@ export function useFileItemActions (props: Props, { openNext }: { openNext: (fil
const onContextMenuClick = async (e: MenuInfo, file: FileNodeInfo, idx: number) => {
const url = toRawFileUrl(file)
const path = currLocation.value
const copyImgTo = async (tab: ["txt2img", "img2img", "inpaint", "extras"][number]) => {
if (spinning.value) {
return
@ -682,6 +687,40 @@ export function useFileItemActions (props: Props, { openNext }: { openNext: (fil
case 'send2img2img': return copyImgTo('img2img')
case 'send2inpaint': return copyImgTo('inpaint')
case 'send2extras': return copyImgTo('extras')
case 'openInNewTab': {
stackCache.set(path, stack.value)
const tab = global.tabList[props.tabIdx]
const pane: FileTransferTabPane = {
type: props.target,
target: props.target,
key: uniqueId(),
path: file.fullpath,
name: props.target === 'local' ? t('local') : t('cloud'),
stackKey: path
}
tab.panes.push(pane)
tab.key = pane.key
break
}
case 'openOnTheRight': {
stackCache.set(path, stack.value)
let tab = global.tabList[props.tabIdx + 1]
if (!tab) {
tab = ID({ panes: [], key: '' })
global.tabList[props.tabIdx + 1] = tab
}
const pane: FileTransferTabPane = {
type: props.target,
target: props.target,
key: uniqueId(),
path: file.fullpath,
name: props.target === 'local' ? t('local') : t('cloud'),
stackKey: path
}
tab.panes.push(pane)
tab.key = pane.key
break
}
case 'viewGenInfo': {
showGenInfo.value = true
imageGenInfo.value = await q.pushAction(() => getImageGenerationInfo(file.fullpath)).res
@ -696,6 +735,7 @@ export function useFileItemActions (props: Props, { openNext }: { openNext: (fil
}
Modal.confirm({
title: t('confirmDelete'),
maskClosable: true,
content: h('ol', { style: 'max-height:50vh;overflow:auto;' }, selectedFiles.map(v => v.fullpath.split(/[/\\]/).pop()).map(v => h('li', v))),
async onOk () {
const paths = selectedFiles.map(v => v.fullpath)

View File

@ -2,7 +2,7 @@
import { FileOutlined, FolderOpenOutlined, DownOutlined, LeftCircleOutlined, RightCircleOutlined } from '@/icon'
import { sortMethodMap } from './fileSort'
import { useGlobalStore } from '@/store/useGlobalStore'
import { useFileTransfer, useFilesDisplay, useHookShareState, useLocation, usePreview, type ViewMode, useFileItemActions, toImageThumbnailUrl, toRawFileUrl } from './hook'
import { useFileTransfer, useFilesDisplay, useHookShareState, useLocation, usePreview, type ViewMode, useFileItemActions, toImageThumbnailUrl, toRawFileUrl, stackCache } from './hook'
import { copy2clipboard, SearchSelect, fallbackImage } from 'vue3-ts-util'
import 'multi-nprogress/nprogress.css'
@ -12,6 +12,8 @@ import { isImageFile } from '@/util'
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
import { watch } from 'vue'
import { toRaw } from 'vue'
import { cloneDeep } from 'lodash-es'
const global = useGlobalStore()
@ -19,20 +21,20 @@ const props = defineProps<{
target: 'local' | 'netdisk',
tabIdx: number,
paneIdx: number,
/**
* 初始打开路径
*/
path?: string,
walkMode?: boolean,
/**
* 页面栈,跳过不必要的api请求
*/
stackKey?: string
}>()
const { installBaiduyunBin, installedBaiduyun, failedHint, baiduyunLoading,
scroller, walkModePath, stackViewEl, props: _props, bduss, onLoginBtnClick, multiSelectedIdxs,
spinning
} = useHookShareState().toRefs()
watch(() => props, () => {
_props.value = props
if (props.walkMode) {
walkModePath.value = props.path
}
}, { immediate: true })
const { currLocation, currPage, refresh, copyLocation, back, openNext, stack, to } = useLocation(props)
const { gridItems, sortMethodConv, moreActionsDropdownShow,
sortedFiles, sortMethod, viewMode, viewModeMap, itemSize,
@ -42,6 +44,17 @@ const { onDrop, onFileDragStart } = useFileTransfer(props)
const { onFileItemClick, onContextMenuClick, showGenInfo, imageGenInfo, q } = useFileItemActions(props, { openNext })
const { previewIdx, onPreviewVisibleChange, previewing, previewImgMove, canPreview } = usePreview(props)
watch(() => props, () => {
_props.value = props
if (props.walkMode) {
walkModePath.value = props.path
}
const stackC = stackCache.get(props.stackKey ?? '')
if (stackC) {
stack.value = stackC.slice() //
}
}, { immediate: true })
</script>
<template>
@ -192,6 +205,10 @@ const { previewIdx, onPreviewVisibleChange, previewing, previewImgMove, canPrevi
<template #overlay>
<a-menu @click="onContextMenuClick($event, file, idx)">
<a-menu-item key="deleteFiles">{{ $t('deleteSelected') }}</a-menu-item>
<template v-if="file.type === 'dir'">
<a-menu-item key="openInNewTab">{{ $t('openInNewTab') }}</a-menu-item>
<a-menu-item key="openOnTheRight">{{ $t('openOnTheRight') }}</a-menu-item>
</template>
<template v-if="file.type === 'file' && props.target === 'local'">
<a-menu-item key="previewInNewWindow">{{ $t('previewInNewWindow') }}</a-menu-item>
<a-menu-item key="download">{{ $t('downloadDirectly') }}</a-menu-item>
@ -399,6 +416,7 @@ const { previewIdx, onPreviewVisibleChange, previewing, previewImgMove, canPrevi
}
}
}
.hint {
padding: 4px;
border: 4px;

View File

@ -4,6 +4,7 @@ import { i18n, t } from '@/i18n'
import { getPreferredLang } from '@/i18n'
import type { getAutoCompletedTagList } from '@/page/taskRecord/autoComplete'
import type { ReturnTypeAsync } from '@/util'
import { message } from 'ant-design-vue'
import { uniqueId } from 'lodash-es'
import { defineStore } from 'pinia'
import { watch } from 'vue'
@ -11,6 +12,7 @@ import { nextTick } from 'vue'
import { ref } from 'vue'
import { typedEventEmitter, type UniqueId, ID } from 'vue3-ts-util'
interface OtherTabPane {
type: 'auto-upload' | 'task-record' | 'empty' | 'log-detail' | 'global-setting'
name: string
@ -32,6 +34,7 @@ export interface FileTransferTabPane {
readonly key: string
path?: string
walkMode?: boolean
stackKey?: string
}
export type TabPane = FileTransferTabPane | OtherTabPane | LogDetailTabPane
@ -41,6 +44,7 @@ export interface Tab extends UniqueId {
key: string
}
export const useGlobalStore = defineStore('useGlobalStore', () => {
const conf = ref<GlobalConf>()
const user = ref<UserInfo>()
@ -92,7 +96,8 @@ export const useGlobalStore = defineStore('useGlobalStore', () => {
const openBaiduYunIfNotLogged = (tabIdx: number, paneIdx: number) => {
if (!user.value) {
const pane: FileTransferTabPane = { key: uniqueId(), type: 'netdisk', target: 'netdisk', name: t('login') }
message.info(t('loginPrompt'))
const pane: FileTransferTabPane = { key: uniqueId(), type: 'netdisk', target: 'netdisk', name: t('baiduCloud') + ' ' + t('login') }
tabList.value[tabIdx].panes[paneIdx] = pane
tabList.value[tabIdx].key = pane.key
}