Skip to content

Commit

Permalink
fix bugs
Browse files Browse the repository at this point in the history
	modified:   index.html
	modified:   src/App.vue
	modified:   src/action/explorer.ts
	modified:   src/action/tree.ts
	new file:   src/init.ts
	modified:   src/module/alert.vue
	modified:   src/module/explorer.vue
	modified:   src/module/list.vue
	modified:   src/module/opener.vue
	modified:   src/module/tree.vue
	modified:   src/module/upload.vue
	modified:   src/opener/imager.vue
	modified:   src/opener/markdown.vue
	modified:   src/opener/vlite.vue
	modified:   src/opener/vplayer.vue
	modified:   src/script/cue.ts
	modified:   src/script/tree.ts
	deleted:    src/script/vsloader.js
	modified:   vite.config.ts
  • Loading branch information
imzlh committed Jul 20, 2024
1 parent 650adfe commit f9cd8d0
Show file tree
Hide file tree
Showing 19 changed files with 334 additions and 209 deletions.
8 changes: 1 addition & 7 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@
<link rel="icon" href="favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vList5</title>
<script defer type="module">
import { createApp } from 'vue';
import App from './src/App.vue';

// 挂载应用
createApp(App).mount(document.body);
</script>
<script src="./src/init.ts" type="module" defer></script>
</head>

<body tabindex="-1">
Expand Down
29 changes: 24 additions & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script setup lang="ts">
import { computed, onMounted, reactive, readonly, ref, watch, type Ref } from 'vue';
import type { CtxDispOpts, CtxMenuData } from './env';
import type { AlertOpts, CtxDispOpts, CtxMenuData } from './env';
import tabManager from './module/tabs.vue';
import Tree, { updated } from './module/tree.vue';
import Tree, { marked, markmap, updated } from './module/tree.vue';
import CtxMenu from './module/ctxmenu.vue';
import { APP_NAME, Global, TREE, getConfig, regConfig } from './utils';
import { APP_NAME, FS, Global, TREE, getConfig, regConfig, reloadTree, splitPath } from './utils';
import Opener from './module/opener.vue';
import Message from './module/message.vue';
import Chooser from './module/chooser.vue';
Expand Down Expand Up @@ -44,6 +44,14 @@
this.current --;
return this.elements.value[this.current] as HTMLElement;
},
_ensure(action: string):Promise<any>{
return new Promise(rs => Global('ui.alert').call({
"callback": res => res && rs(true),
"message": "真的要" + action + '吗?',
"title": "确认操作",
"type": "confirm"
} satisfies AlertOpts));
},
__handler(e: KeyboardEvent){
e.preventDefault();
Expand All @@ -60,6 +68,15 @@
this.elements.value[this.current].dispatchEvent(new MouseEvent('dblclick'));
break;
case 'Delete':
this._ensure('删除 ' + markmap.value.length + '个文件(夹)')
.then(() => {
const set = new Set(marked.value.map(item => splitPath(item).dir));
FS.delete(markmap.value);
reloadTree(Array.from(set));
});
break;
default:
break;
}
Expand Down Expand Up @@ -175,7 +192,9 @@
</svg>
{{ APP_NAME }}
</div>
<div class="files vlist" ref="list_ele" tabindex="-1" @contextmenu.prevent @focus="tree_active = true" @blur="tree_active = false">
<div class="files vlist" ref="list_ele" tabindex="-1"
@contextmenu.prevent @focus="tree_active = true" @blur="tree_active = false"
>
<Tree :data="TREE" :active="tree_active" />
</div>
</div>
Expand Down Expand Up @@ -323,7 +342,7 @@
left: 0;
width: 100vw;
height: 100vh;
z-index: 50;
z-index: 57;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/action/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ EXP_REG.register(() => ({
"title": "覆盖或合并提示",
"message": "这些文件将会被合并/覆盖\n\n" +
over.map(item => item.name + '\t' + (item.type == 'dir' ? '文件夹' : size2str(item.size))),
"callback": rs
"callback": res => res && rs(true)
} satisfies AlertOpts));
} catch { }

Expand Down
6 changes: 3 additions & 3 deletions src/action/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ TREE_REG.register(() => ({
"title": "覆盖或合并提示",
"message": "这些文件将会被合并/覆盖\n\n" +
over.map(item => item.name + '\t' + (item.type == 'dir' ? '文件夹' : size2str(item.size))),
"callback": rs
"callback": res => res && rs(true)
} satisfies AlertOpts));
} catch { }

Expand Down Expand Up @@ -347,9 +347,9 @@ TREE_REG.register(() => ({
const info = splitPath(ordered[i]);
ordered[i].status = 1;
obj[ordered[i].path] = info.dir + (i + 1).toString().padStart(3, '0') + '.' + info.ext;
if (reload.includes(info.dir)) reload.push(info.dir);
if (!reload.includes(info.dir)) reload.push(info.dir);
}
FS.rename(obj).then(() => void reloadTree(reload))
FS.rename(obj).then(() => reloadTree(reload))
.catch((e: Error) => Global('ui.message').call({
"type": "error",
"title": "文件资源管理器",
Expand Down
123 changes: 123 additions & 0 deletions src/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { createApp, ref, type Ref } from 'vue';
import App from './App.vue';

/**
* vList5 Entry Script(Main Interface)
* Copyright (c) 2024 izGroup
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @version 5.5
* @license MIT
* @copyright izGroup
* @author iz
* @link https://hi.imzlh.top/2024/06/16.cgi
*/

interface Touch{
x: number,
y: number,
mx: number,
my: number,
el: HTMLElement,
time: number,
prevent: boolean,
lastClick: Ref<number | undefined>
}

// 触摸管理
let touch: undefined | Touch;
document.documentElement.addEventListener('contextmenu', el => el.preventDefault());
document.documentElement.addEventListener('touchmove', ev => {
if(!touch) return;

if(touch.prevent) ev.preventDefault();

touch.mx = ev.touches[0].clientX,
touch.my = ev.touches[0].clientY;
touch.el.dispatchEvent(new PointerEvent('pointermove', {
"clientX": ev.touches[0].clientX,
"clientY": ev.touches[0].clientY,
"cancelable": false
}));
});
document.documentElement.addEventListener('touchend', ev => {
if(!touch) return;
if(touch.prevent) ev.preventDefault();

const click = ref(0);

touch.el.dispatchEvent(new MouseEvent('pointerup', {
"clientX": touch.mx,
"clientY": touch.my,
"cancelable": false
}));

if(Math.abs(touch.mx - touch.x) > 10 || Math.abs(touch.my - touch.y) > 10) return;

const now = new Date().getTime();
if(now - touch.time > 500){
touch.el.dispatchEvent(new MouseEvent('contextmenu', {
"clientX": touch.mx,
"clientY": touch.my,
"cancelable": true
}));
}else{
touch.el.dispatchEvent(new MouseEvent('click', {
"clientX": touch.mx,
"clientY": touch.my,
"cancelable": true
}));
if(touch.lastClick.value && now - touch.lastClick.value < 600)
touch.el.dispatchEvent(new MouseEvent('dblclick', {
"clientX": touch.mx,
"clientY": touch.my,
"cancelable": true
})),touch.lastClick.value = undefined;
else
touch.lastClick.value = now;
}
touch = undefined;
})

// 挂载应用
const app = createApp(App);
app.directive('touch', {
mounted(el: HTMLElement, direct){
const clickRef = ref();

el.addEventListener('touchstart',ev =>
touch = {
x: ev.touches[0].clientX,
y: ev.touches[0].clientY,
mx: ev.touches[0].clientX,
my: ev.touches[0].clientY,
el,
time: new Date().getTime(),
prevent: !!direct.arg?.includes('prevent'),
lastClick: clickRef
}
);
},
unmounted(){
touch = undefined
}
});

app.mount(document.body);
40 changes: 30 additions & 10 deletions src/module/alert.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,64 @@
<script setup lang="ts">
import { Global } from '@/utils';
import type { AlertOpts } from '@/env';
import { ref, shallowRef } from 'vue';
import { ref, shallowRef, type Directive } from 'vue';
const item = shallowRef<AlertOpts>(),
dataref = ref();
dataref = ref(),
core = ref<HTMLElement>(),
vFocus = {
mounted(el: HTMLElement, dat){
if(dat.value)
el.focus();
}
} satisfies Directive,
vBtn = {
mounted:(el: HTMLElement) =>
el.addEventListener('keydown', key =>
key.code == 'Enter' && (key.preventDefault(), el.click())
)
} satisfies Directive;
function call(role: string) {
if (role == 'close') item.value = undefined;
else if (role == 'submit') item.value?.callback(dataref.value), item.value = undefined;
}
Global('ui.alert').data = (d: AlertOpts) => {
item.value = d; dataref.value = '';
item.value = d; dataref.value = '';core.value && core.value.focus();
};
</script>

<template>
<div :type="item.type" class="sys-alert" v-if="item">
<div :type="item.type" class="sys-alert" v-if="item" ref="core">
<div class="basic">
<h3 v-if="item.title">{{ item.title }}</h3>
<span>{{ item.message }}</span>

<input type="text" v-model="dataref" v-if="item.type == 'prompt'">
<input type="text" v-model="dataref" v-if="item.type == 'prompt'" v-focus
@keydown="$event.key == 'Enter' && (item.callback(dataref.value), item = undefined)"
>
</div>
<div class="btns">
<div style="flex-grow: 1;"></div>
<template v-if="item.button">
<button v-for="btn in item.button" :style="{ backgroundColor: btn.color }"
@click="call(btn.role);btn.click && btn.click(dataref)">
@click="call(btn.role);btn.click && btn.click(dataref)"
>
{{ btn.content }}
</button>
</template>
<template v-else>
<button style="background-color: #e5e5e5"
@click="item.type == 'confirm' && item.callback(dataref = false);item = undefined">
<button style="background-color: #e5e5e5" v-focus="item.type != 'prompt'"
@click="item.type == 'confirm' && item.callback(dataref = false); item = undefined"
v-btn
>
取消
</button>
<button style="color: white;" @click="item.type == 'confirm' && (dataref = false); item.callback(dataref); item = undefined;
">
<button style="color: white;"
@click="item.type == 'confirm' && (dataref = true);item.callback(dataref); item = undefined;"
v-btn
>
确定
</button>
</template>
Expand Down
13 changes: 9 additions & 4 deletions src/module/explorer.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

<script setup lang="ts">
import type { FileOrDir, vDir } from '@/env';
import { computed, reactive, ref, watch, type Ref } from 'vue';
import { computed, nextTick, reactive, ref, watch, type Ref } from 'vue';
import List from './list.vue';
import { FACTION, UI, FS, Global, getConfig, getTree, loadPath, loadTree, openFile, regConfig, reloadTree, splitPath, type iDir, type iMixed, list_marked as marked, list_markmap as markmap } from '@/utils';
Expand Down Expand Up @@ -129,15 +129,16 @@
</script>

<script lang="ts">
nextTick(() =>
regConfig('explorer', [
{
"type": "number",
"default": 60,
"default": UI.app_width.value - UI.fontSize.value * 15,
"key": "ui.filebar_size",
"name": "路径框大小",
"step": 1
}
]);
]));
</script>

<template>
Expand Down Expand Up @@ -326,11 +327,15 @@
box-sizing: border-box;
display: flex;
gap: 0.35rem;
padding: 2.5rem 0.35rem 0.35rem 0.35rem;
padding: 0 0.35rem 0.35rem 0.35rem;
align-items: center;
position: relative;
flex-wrap: wrap;
@media screen and (min-width: 30rem) {
padding-top: 2.5rem;
}
> .btn {
padding: .35rem;
border-radius: .25rem;
Expand Down
6 changes: 3 additions & 3 deletions src/module/list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
return [ ..._prop.list ].sort((a, b) => b.ctime - a.ctime)
if(layout.orderBy == 'size')
return _prop.list.filter(item => item.type == 'dir')
.concat((_prop.list.filter(item => item.type == 'file') as Array<vFile>).sort((a, b) => a.size - b.size))
.concat((_prop.list.filter(item => item.type == 'file') as Array<vFile>).sort((a, b) => a.size - b.size) as any)
if(layout.orderBy == 'size_rev')
return (_prop.list.filter(item => item.type == 'file') as Array<vFile>).sort((a, b) => b.size - a.size)
.concat(_prop.list.filter(item => item.type == 'dir') as any);
Expand Down Expand Up @@ -198,14 +198,14 @@
<div class="fd-list" :data-empty="list.length == 0" :style="{
overflowY: select.enable ? 'hidden' : 'auto',
paddingRight: select.enable ? '.2rem' : '0'
}" v-bind="$attrs" ref="data">
}" v-bind="$attrs" ref="data" @contextmenu.prevent.stop="event('ctxroot', $event)">
<!-- 默认输出 -->
<div v-if="list.length == 0" style="width: auto;background-color: transparent;">
此文件夹为空
</div>
<!-- 列表 -->
<div class="view" v-else-if="_prop.mode == 'view'" tabindex="-1"
@pointerdown.stop.prevent="init_select" @click.prevent.stop="clear_selected()" @contextmenu.prevent.stop="event('ctxroot', $event)"
@pointerdown.stop.prevent="init_select" @click.prevent.stop="clear_selected()"
>
<template v-for="(fd,i) of flist" :key="fd.path">
<div :type="fd.type" ref="list_element" class="item" tabindex="2" @pointerdown.stop @pointermove.prevent
Expand Down
2 changes: 1 addition & 1 deletion src/module/opener.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
position: fixed;
top: -100vh;
left: 50%;
width: 40vw;
width: 100vw;
max-width: 20rem;
border-radius: .5rem;
background-color: rgb(240 244 253 / 80%);
Expand Down
Loading

0 comments on commit f9cd8d0

Please sign in to comment.