Removing stuff, refactoring for simplicity
This commit is contained in:
parent
7e5901a2cf
commit
831b2716f7
1
cista-front/components.d.ts
vendored
1
cista-front/components.d.ts
vendored
|
@ -22,7 +22,6 @@ declare module 'vue' {
|
||||||
AProgress: typeof import('ant-design-vue/es')['Progress']
|
AProgress: typeof import('ant-design-vue/es')['Progress']
|
||||||
ARow: typeof import('ant-design-vue/es')['Row']
|
ARow: typeof import('ant-design-vue/es')['Row']
|
||||||
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
ATooltip: typeof import('ant-design-vue/es')['Tooltip']
|
||||||
FileCarousel: typeof import('./src/components/FileCarousel.vue')['default']
|
|
||||||
FileExplorer: typeof import('./src/components/FileExplorer.vue')['default']
|
FileExplorer: typeof import('./src/components/FileExplorer.vue')['default']
|
||||||
FileRenameInput: typeof import('./src/components/FileRenameInput.vue')['default']
|
FileRenameInput: typeof import('./src/components/FileRenameInput.vue')['default']
|
||||||
FileViewer: typeof import('./src/components/FileViewer.vue')['default']
|
FileViewer: typeof import('./src/components/FileViewer.vue')['default']
|
||||||
|
|
|
@ -1,137 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="carousel" ref="fileCarousel">
|
|
||||||
<a-page-header :style="{ visibility: idle ? 'hidden' : 'visible' }">
|
|
||||||
<template #extra>
|
|
||||||
<a-button type="text" class="action-button" :onclick="toggle" :icon="h(isFullscreen? FullscreenExitOutlined: FullscreenOutlined)" />
|
|
||||||
<a-button type="text" class="action-button" :onclick="redirectBack" :icon="h(CloseOutlined)" />
|
|
||||||
</template>
|
|
||||||
</a-page-header>
|
|
||||||
<a-row class="slider">
|
|
||||||
<a-col :span="2" class="centered-vertically">
|
|
||||||
<div class="custom-slick-arrow slick-arrow slick-prev centered" @click="next(-1)" style="left: 10px; z-index: 1">
|
|
||||||
<LeftOutlined v-show="!idle" />
|
|
||||||
</div>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="20" class="centered">
|
|
||||||
<FileViewer v-if="!documentStore.loading" :visibleImg="visible" @visibleImg="setVisible" :type="fileType"></FileViewer>
|
|
||||||
</a-col>
|
|
||||||
<a-col :span="2" class="centered-vertically right">
|
|
||||||
<div class="custom-slick-arrow slick-arrow slick-prev centered" @click="next(1)" style="right: 10px">
|
|
||||||
<RightOutlined v-show="!idle" />
|
|
||||||
</div>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { h, ref, watchEffect } from 'vue'
|
|
||||||
import { useDocumentStore } from '@/stores/documents'
|
|
||||||
import { useIdle, useFullscreen } from '@vueuse/core'
|
|
||||||
import { LeftOutlined, RightOutlined, FullscreenOutlined, FullscreenExitOutlined, CloseOutlined } from '@ant-design/icons-vue';
|
|
||||||
import { getFileType } from '@/utils'
|
|
||||||
import Router from '@/router/index';
|
|
||||||
import FileViewer from './FileViewer.vue';
|
|
||||||
|
|
||||||
const fileCarousel = ref<HTMLElement | null>(null)
|
|
||||||
const { isFullscreen, toggle } = useFullscreen(fileCarousel)
|
|
||||||
const visible = ref<boolean>(false);
|
|
||||||
const documentStore = useDocumentStore()
|
|
||||||
const fileType = ref<string| undefined>(undefined);
|
|
||||||
watchEffect(() => {
|
|
||||||
if(documentStore.mainDocument[0] && documentStore.mainDocument[0].type === 'file'){
|
|
||||||
const fileExt = documentStore.mainDocument[0].ext
|
|
||||||
fileType.value = getFileType(fileExt)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
function setVisible(value: boolean) {
|
|
||||||
visible.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { idle } = useIdle(2000)
|
|
||||||
|
|
||||||
function redirectBack() {
|
|
||||||
const currentPath = Router.currentRoute.value.path;
|
|
||||||
const pathParts = currentPath.split('/').filter(part => part); // Remove empty parts
|
|
||||||
// Ensure there's always at least one part in the path
|
|
||||||
if (pathParts.length <= 1) {
|
|
||||||
// If it's empty, set it to the base URL
|
|
||||||
pathParts[0] = '/';
|
|
||||||
} else {
|
|
||||||
pathParts.pop();
|
|
||||||
}
|
|
||||||
const newPath = pathParts.join('/');
|
|
||||||
Router.push(newPath);
|
|
||||||
}
|
|
||||||
function next(direction: number){
|
|
||||||
const path = decodeURIComponent(new String(Router.currentRoute.value.path) as string)
|
|
||||||
const name = documentStore.getNextDocumentInRoute(direction, path)
|
|
||||||
let nextFileLocation : string[] | string = path.split('/')
|
|
||||||
nextFileLocation.pop()
|
|
||||||
nextFileLocation.push(name)
|
|
||||||
nextFileLocation = nextFileLocation.join('/')
|
|
||||||
Router.push(nextFileLocation)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
<style scoped>
|
|
||||||
:deep(.slick-arrow.custom-slick-arrow) {
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
font-size: 60px;
|
|
||||||
color: var(--primary-color);
|
|
||||||
transition: ease-in all 0.3s;
|
|
||||||
opacity: 0.3;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.slick-arrow.custom-slick-arrow:before) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.slick-arrow.custom-slick-arrow:hover) {
|
|
||||||
color: var(--primary-color);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider {
|
|
||||||
height: 80vh;
|
|
||||||
background-color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.centered {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.centered-vertically {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
flex-direction: row-reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-button {
|
|
||||||
padding: 0;
|
|
||||||
font-size: 1.5em;
|
|
||||||
opacity: 0.5;
|
|
||||||
color: var(--secondary-color);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: var(--blue-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-page-header {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.carousel{
|
|
||||||
margin: 0;
|
|
||||||
height: inherit;
|
|
||||||
background-color: var(--table-background);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,12 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<main>
|
<main>
|
||||||
<context-holder />
|
<table v-if="documentStore.mainDocument.length">
|
||||||
<!-- <h2 v-if="!documentStore.loading && documentStore.error"> {{ documentStore.error }} </h2> -->
|
|
||||||
<div class="carousel-container" v-if="!documentStore.loading && documentStore.mainDocument[0] && documentStore.mainDocument[0].type === 'file'">
|
|
||||||
<FileCarousel></FileCarousel>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table v-else-if="!documentStore.loading && documentStore.mainDocument">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="selection"><input type="checkbox" v-model="allSelected" :indeterminate="selectionIndeterminate"></th>
|
<th class="selection"><input type="checkbox" v-model="allSelected" :indeterminate="selectionIndeterminate"></th>
|
||||||
|
@ -17,7 +11,9 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="doc of sorted(documentStore.mainDocument as FolderDocument[])" :key="doc.key" :class="doc.type === 'folder' ? 'folder' : 'file'">
|
<tr v-for="doc of sorted(documentStore.mainDocument as FolderDocument[])" :key="doc.key" :class="doc.type === 'folder' ? 'folder' : 'file'">
|
||||||
<td class="selection"><input type="checkbox" v-model="doc.selected"></td>
|
<td class="selection">
|
||||||
|
<input type="checkbox" :checked="doc.key in documentStore.selected" @change="documentStore.selected.add(doc.key)">
|
||||||
|
</td>
|
||||||
<td class="name">
|
<td class="name">
|
||||||
<template v-if="editing === doc"><FileRenameInput :doc="doc" :rename="rename" :exit="() => { editing = null}"/></template>
|
<template v-if="editing === doc"><FileRenameInput :doc="doc" :rename="rename" :exit="() => { editing = null}"/></template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
@ -39,7 +35,6 @@ import { ref, computed } from 'vue'
|
||||||
import { useDocumentStore } from '@/stores/documents'
|
import { useDocumentStore } from '@/stores/documents'
|
||||||
import Router from '@/router/index';
|
import Router from '@/router/index';
|
||||||
import type { Document, FolderDocument } from '@/repositories/Document';
|
import type { Document, FolderDocument } from '@/repositories/Document';
|
||||||
import FileCarousel from './FileCarousel.vue';
|
|
||||||
import FileRenameInput from './FileRenameInput.vue'
|
import FileRenameInput from './FileRenameInput.vue'
|
||||||
import createWebSocket from '@/repositories/WS';
|
import createWebSocket from '@/repositories/WS';
|
||||||
|
|
||||||
|
@ -93,17 +88,21 @@ const sorted = (documents: FolderDocument[]) => {
|
||||||
}
|
}
|
||||||
const selectionIndeterminate = computed({
|
const selectionIndeterminate = computed({
|
||||||
get: () => {
|
get: () => {
|
||||||
return documentStore.mainDocument && documentStore.mainDocument.length > 0 && documentStore.mainDocument.some((doc: Document) => doc.selected) && !allSelected.value
|
return documentStore.mainDocument && documentStore.mainDocument.length > 0 && documentStore.mainDocument.some((doc: Document) => doc.key in documentStore.selected) && !allSelected.value
|
||||||
},
|
},
|
||||||
set: (value: boolean) => {}
|
set: (value: boolean) => {}
|
||||||
})
|
})
|
||||||
const allSelected = computed({
|
const allSelected = computed({
|
||||||
get: () => {
|
get: () => {
|
||||||
return documentStore.mainDocument && documentStore.mainDocument.length > 0 && documentStore.mainDocument.every((doc: Document) => doc.selected)
|
return documentStore.mainDocument && documentStore.mainDocument.length > 0 && documentStore.mainDocument.every((doc: Document) => doc.key in documentStore.selected)
|
||||||
},
|
},
|
||||||
set: (value: boolean) => {
|
set: (value: boolean) => {
|
||||||
if (documentStore.mainDocument) {
|
for (const doc of documentStore.mainDocument) {
|
||||||
documentStore.mainDocument.forEach((doc: Document) => doc.selected = value)
|
if (value) {
|
||||||
|
documentStore.selected.add(doc.key)
|
||||||
|
} else {
|
||||||
|
documentStore.selected.delete(doc.key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -48,11 +48,7 @@ function about() {
|
||||||
console.log("About ...")
|
console.log("About ...")
|
||||||
}
|
}
|
||||||
function deleteHandler(){
|
function deleteHandler(){
|
||||||
if(documentStore.selectedDocuments){
|
console.log("Delete ...")
|
||||||
documentStore.selectedDocuments.forEach(document => {
|
|
||||||
documentStore.deleteDocument(document)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
function share(){
|
function share(){
|
||||||
console.log("Share ...")
|
console.log("Share ...")
|
||||||
|
@ -80,7 +76,7 @@ function download(){
|
||||||
<a-button @click="createFolderHandler" type="text" class="action-button" :icon="h(FolderFilled)" />
|
<a-button @click="createFolderHandler" type="text" class="action-button" :icon="h(FolderFilled)" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<!-- TODO ADD CONDITIONAL RENDER -->
|
<!-- TODO ADD CONDITIONAL RENDER -->
|
||||||
<template v-if="documentStore.selectedDocuments && documentStore.selectedDocuments.length > 0">
|
<template v-if="documentStore.selected.size > 0">
|
||||||
<a-tooltip title="Share">
|
<a-tooltip title="Share">
|
||||||
<a-button type="text" @click="share" class="action-button" :icon="h(LinkOutlined)" />
|
<a-button type="text" @click="share" class="action-button" :icon="h(LinkOutlined)" />
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
|
|
|
@ -1,28 +1,22 @@
|
||||||
import type { FileStructure, DocumentStore } from '@/stores/documents'
|
import type { DocumentStore } from '@/stores/documents'
|
||||||
import { useDocumentStore } from '@/stores/documents'
|
import { useDocumentStore } from '@/stores/documents'
|
||||||
import { getFileExtension } from '@/utils'
|
|
||||||
import Client from '@/repositories/Client'
|
|
||||||
|
|
||||||
|
export type FUID = string;
|
||||||
|
|
||||||
type BaseDocument = {
|
type BaseDocument = {
|
||||||
name: string
|
name: string
|
||||||
key?: number | string
|
key: FUID
|
||||||
selected?: boolean
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FolderDocument = BaseDocument & {
|
export type FolderDocument = BaseDocument & {
|
||||||
type: 'folder' | 'folder-file';
|
type: 'folder' | 'file'
|
||||||
size: number;
|
size: number
|
||||||
sizedisp: string;
|
sizedisp: string
|
||||||
mtime: number;
|
mtime: number
|
||||||
modified: string;
|
modified: string
|
||||||
};
|
};
|
||||||
|
|
||||||
export type FileDocument = BaseDocument & {
|
export type Document = FolderDocument
|
||||||
type: 'file';
|
|
||||||
ext: string;
|
|
||||||
data: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type errorEvent = {
|
export type errorEvent = {
|
||||||
error: {
|
error: {
|
||||||
|
@ -32,8 +26,31 @@ export type errorEvent = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Document = FolderDocument | FileDocument;
|
// Raw types the backend /api/watch sends us
|
||||||
|
|
||||||
|
export type FileEntry = {
|
||||||
|
id: FUID
|
||||||
|
size: number
|
||||||
|
mtime: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DirEntry = {
|
||||||
|
id: FUID
|
||||||
|
size: number
|
||||||
|
mtime: number
|
||||||
|
dir: DirList
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DirList = Record<string, FileEntry | DirEntry>
|
||||||
|
|
||||||
|
export type UpdateEntry = {
|
||||||
|
name: string
|
||||||
|
deleted?: boolean
|
||||||
|
id?: FUID
|
||||||
|
size?: number
|
||||||
|
mtime?: number
|
||||||
|
dir?: DirList
|
||||||
|
}
|
||||||
|
|
||||||
export const url_document_watch_ws = '/api/watch'
|
export const url_document_watch_ws = '/api/watch'
|
||||||
export const url_document_upload_ws = '/api/upload'
|
export const url_document_upload_ws = '/api/upload'
|
||||||
|
@ -60,18 +77,27 @@ export class DocumentHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleRootMessage({ root }: { root: FileStructure }) {
|
private handleRootMessage({ root }: { root: DirEntry }) {
|
||||||
if (this.store && this.store.root) {
|
if (this.store && this.store.root) {
|
||||||
this.store.user.isLoggedIn = true;
|
this.store.user.isLoggedIn = true;
|
||||||
this.store.root = root;
|
this.store.root = root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private handleUpdateMessage(updateData: { update: UpdateEntry[] }) {
|
||||||
private handleUpdateMessage(updateData: { update: FileStructure[] }) {
|
let node: DirEntry = this.store.root;
|
||||||
const root = updateData.update[0]
|
for (const elem of updateData.update) {
|
||||||
if(root) {
|
if (elem.deleted) {
|
||||||
this.store.user.isLoggedIn = true;
|
delete node.dir[elem.name]
|
||||||
this.store.root = root
|
break // Deleted elements can't have further children
|
||||||
|
}
|
||||||
|
if (elem.name !== undefined) {
|
||||||
|
// @ts-ignore
|
||||||
|
node = node.dir[elem.name] ||= {}
|
||||||
|
}
|
||||||
|
if (elem.id !== undefined) node.id = elem.id
|
||||||
|
if (elem.size !== undefined) node.size = elem.size
|
||||||
|
if (elem.mtime !== undefined) node.mtime = elem.mtime
|
||||||
|
if (elem.dir !== undefined) node.dir = elem.dir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private handleError(msg: errorEvent){
|
private handleError(msg: errorEvent){
|
||||||
|
@ -103,13 +129,3 @@ export class DocumentUploadHandler {
|
||||||
console.log('Written message', msg.written)
|
console.log('Written message', msg.written)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export async function fetchFile(path: string): Promise<FileDocument>{
|
|
||||||
const file = await Client.get(url_document_get + path)
|
|
||||||
const name = path.substring(1 , path.length)
|
|
||||||
return {
|
|
||||||
name,
|
|
||||||
data: file.data,
|
|
||||||
type: 'file',
|
|
||||||
ext: getFileExtension(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import type { Document } from '@/repositories/Document';
|
import type { Document, DirEntry, FileEntry, FUID, DirList } from '@/repositories/Document'
|
||||||
import { fetchFile } from '@/repositories/Document'
|
import { formatSize, formatUnixDate } from '@/utils'
|
||||||
import { formatSize, formatUnixDate } from '@/utils';
|
import { defineStore } from 'pinia'
|
||||||
import { defineStore } from 'pinia';
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { localeIncludes } from 'locale-includes'
|
import { localeIncludes } from 'locale-includes'
|
||||||
|
|
||||||
|
@ -9,21 +8,20 @@ type FileData = { id: string, mtime: number, size: number, dir: DirectoryData};
|
||||||
type DirectoryData = {
|
type DirectoryData = {
|
||||||
[filename: string]: FileData;
|
[filename: string]: FileData;
|
||||||
};
|
};
|
||||||
export type FileStructure = {id: string, mtime: number, size: number, dir: DirectoryData};
|
|
||||||
type User = {
|
type User = {
|
||||||
isOpenLoginModal: boolean,
|
isOpenLoginModal: boolean,
|
||||||
isLoggedIn : boolean,
|
isLoggedIn : boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DocumentStore = {
|
export type DocumentStore = {
|
||||||
root: FileStructure,
|
root: DirEntry,
|
||||||
document: Document[],
|
document: Document[],
|
||||||
|
selected: Set<FUID>,
|
||||||
loading: boolean,
|
loading: boolean,
|
||||||
uploadingDocuments: Array<{key: number, name: string, progress: number}>,
|
uploadingDocuments: Array<{key: number, name: string, progress: number}>,
|
||||||
uploadCount: number,
|
uploadCount: number,
|
||||||
wsWatch: WebSocket | undefined,
|
wsWatch: WebSocket | undefined,
|
||||||
wsUpload: WebSocket | undefined,
|
wsUpload: WebSocket | undefined,
|
||||||
selectedDocuments: Document[],
|
|
||||||
user: User,
|
user: User,
|
||||||
error: string,
|
error: string,
|
||||||
}
|
}
|
||||||
|
@ -31,24 +29,24 @@ export type DocumentStore = {
|
||||||
export const useDocumentStore = defineStore({
|
export const useDocumentStore = defineStore({
|
||||||
id: 'documents',
|
id: 'documents',
|
||||||
state: (): DocumentStore => ({
|
state: (): DocumentStore => ({
|
||||||
root: {} as FileStructure,
|
root: {} as DirEntry,
|
||||||
document: [] as Document[],
|
document: [] as Document[],
|
||||||
|
selected: new Set<FUID>(),
|
||||||
loading: true as boolean,
|
loading: true as boolean,
|
||||||
uploadingDocuments: [],
|
uploadingDocuments: [],
|
||||||
uploadCount: 0 as number,
|
uploadCount: 0 as number,
|
||||||
wsWatch: undefined,
|
wsWatch: undefined,
|
||||||
wsUpload: undefined,
|
wsUpload: undefined,
|
||||||
selectedDocuments: [] as Document[],
|
|
||||||
error: '' as string,
|
error: '' as string,
|
||||||
user: { isLoggedIn: false, isOpenLoginModal: false } as User
|
user: { isLoggedIn: false, isOpenLoginModal: false } as User
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
updateTable(matched: DirectoryData) {
|
updateTable(matched: DirList) {
|
||||||
// Transform data
|
// Transform data
|
||||||
const dataMapped = []
|
const dataMapped = []
|
||||||
for (const [name, attr] of Object.entries(matched)) {
|
for (const [name, attr] of Object.entries(matched)) {
|
||||||
const {id, size, mtime, dir} = attr
|
const {id, size, mtime} = attr
|
||||||
const element: Document = {
|
const element: Document = {
|
||||||
name,
|
name,
|
||||||
key: id,
|
key: id,
|
||||||
|
@ -56,7 +54,7 @@ export const useDocumentStore = defineStore({
|
||||||
sizedisp: formatSize(size),
|
sizedisp: formatSize(size),
|
||||||
mtime,
|
mtime,
|
||||||
modified: formatUnixDate(mtime),
|
modified: formatUnixDate(mtime),
|
||||||
type: dir === undefined ? 'folder-file' : 'folder',
|
type: "dir" in attr ? 'folder' : 'file',
|
||||||
}
|
}
|
||||||
dataMapped.push(element)
|
dataMapped.push(element)
|
||||||
}
|
}
|
||||||
|
@ -66,8 +64,8 @@ export const useDocumentStore = defineStore({
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
setFilter(filter: string){
|
setFilter(filter: string){
|
||||||
function traverseDir(data: FileStructure, path: string){
|
function traverseDir(data: DirEntry | FileEntry, path: string){
|
||||||
if (data.dir === undefined) return
|
if (!("dir" in data)) return
|
||||||
for (const [name, attr] of Object.entries(data.dir)) {
|
for (const [name, attr] of Object.entries(data.dir)) {
|
||||||
const fullname = `${path}/${name}`
|
const fullname = `${path}/${name}`
|
||||||
if (localeIncludes(name, filter, {usage: "search", sensitivity: "base"})) {
|
if (localeIncludes(name, filter, {usage: "search", sensitivity: "base"})) {
|
||||||
|
@ -84,39 +82,26 @@ export const useDocumentStore = defineStore({
|
||||||
setActualDocument(location: string){
|
setActualDocument(location: string){
|
||||||
location = decodeURIComponent(location)
|
location = decodeURIComponent(location)
|
||||||
this.loading = true
|
this.loading = true
|
||||||
let data = this.root
|
let data: FileEntry | DirEntry = this.root
|
||||||
const actualDirArr = []
|
const actualDirArr = []
|
||||||
try {
|
try {
|
||||||
// Navigate to target folder
|
// Navigate to target folder
|
||||||
for (const dirname of location.split('/').slice(1)) {
|
for (const dirname of location.split('/').slice(1)) {
|
||||||
if (!dirname) continue
|
if (!dirname) continue
|
||||||
|
if (!("dir" in data)) throw Error("Target folder not available")
|
||||||
actualDirArr.push(dirname)
|
actualDirArr.push(dirname)
|
||||||
data = data.dir[dirname]
|
data = data.dir[dirname]
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Cannot show requested folder", location, actualDirArr.join('/'), error)
|
console.error("Cannot show requested folder", location, actualDirArr.join('/'), error)
|
||||||
}
|
}
|
||||||
if (data.dir === undefined) {
|
if (!("dir" in data)) {
|
||||||
// Target folder not available
|
// Target folder not available
|
||||||
this.document = []
|
this.document = []
|
||||||
this.loading = false // ???
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.updateTable(data.dir)
|
this.updateTable(data.dir)
|
||||||
},
|
},
|
||||||
async setActualDocumentFile(path: string){
|
|
||||||
this.loading = true;
|
|
||||||
const file = await fetchFile(path)
|
|
||||||
this.document = [file];
|
|
||||||
this.loading = false;
|
|
||||||
},
|
|
||||||
setSelectedDocuments(document: Document[]){
|
|
||||||
this.selectedDocuments = document
|
|
||||||
},
|
|
||||||
deleteDocument(document: Document){
|
|
||||||
this.document = this.document.filter(e => document.key !== e.key)
|
|
||||||
this.selectedDocuments = this.selectedDocuments.filter(e => document.key !== e.key)
|
|
||||||
},
|
|
||||||
updateUploadingDocuments(key: number, progress: number){
|
updateUploadingDocuments(key: number, progress: number){
|
||||||
for (const d of this.uploadingDocuments) {
|
for (const d of this.uploadingDocuments) {
|
||||||
if(d.key === key) d.progress = progress
|
if(d.key === key) d.progress = progress
|
||||||
|
@ -135,39 +120,6 @@ export const useDocumentStore = defineStore({
|
||||||
deleteUploadingDocument(key: number){
|
deleteUploadingDocument(key: number){
|
||||||
this.uploadingDocuments = this.uploadingDocuments.filter((e)=> e.key !== key)
|
this.uploadingDocuments = this.uploadingDocuments.filter((e)=> e.key !== key)
|
||||||
},
|
},
|
||||||
getNextDocumentInRoute(direction: number, path: string){
|
|
||||||
const locations = path.split('/').slice(1)
|
|
||||||
locations.pop()
|
|
||||||
let data = this.root
|
|
||||||
const actualDirArr = []
|
|
||||||
// Get data target location
|
|
||||||
locations.forEach(location => {
|
|
||||||
// location = decodeURIComponent(location)
|
|
||||||
if(data && data.dir){
|
|
||||||
for (const key in data.dir) {
|
|
||||||
if(key === location) data = data.dir[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
//Store in a temporary array
|
|
||||||
for (const key in data.dir) {
|
|
||||||
actualDirArr.push({
|
|
||||||
name: key,
|
|
||||||
content: data.dir[key]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const actualFileName = decodeURIComponent(this.mainDocument[0].name).split('/').pop()
|
|
||||||
let index = actualDirArr.findIndex(e => e.name === actualFileName)
|
|
||||||
|
|
||||||
if(index < 1 && direction === -1 ){
|
|
||||||
index = actualDirArr.length -1
|
|
||||||
}else if(index >= actualDirArr.length - 1 && direction === 1){
|
|
||||||
index = 0
|
|
||||||
}else {
|
|
||||||
index = index + direction
|
|
||||||
}
|
|
||||||
return actualDirArr[index].name
|
|
||||||
},
|
|
||||||
updateModified() {
|
updateModified() {
|
||||||
for (const d of this.document) {
|
for (const d of this.document) {
|
||||||
if ("mtime" in d) d.modified = formatUnixDate(d.mtime)
|
if ("mtime" in d) d.modified = formatUnixDate(d.mtime)
|
||||||
|
@ -178,12 +130,6 @@ export const useDocumentStore = defineStore({
|
||||||
mainDocument(): Document[] {
|
mainDocument(): Document[] {
|
||||||
return this.document;
|
return this.document;
|
||||||
},
|
},
|
||||||
rootSize(): number | undefined {
|
|
||||||
if(this.root) return this.root.size
|
|
||||||
},
|
|
||||||
rootMain(): DirectoryData | undefined {
|
|
||||||
if(this.root) return this.root.dir
|
|
||||||
},
|
|
||||||
isUserLogged(): boolean{
|
isUserLogged(): boolean{
|
||||||
return this.user.isLoggedIn
|
return this.user.isLoggedIn
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,9 @@ export function determineFileType(inputString: string): "file" | "folder" {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatSize(size: number) {
|
export function formatSize(size: number) {
|
||||||
|
if (size === 0) return 'empty'
|
||||||
for (const unit of [null, 'kB', 'MB', 'GB', 'TB', 'PB', 'EB']) {
|
for (const unit of [null, 'kB', 'MB', 'GB', 'TB', 'PB', 'EB']) {
|
||||||
if (size < 1e5) return size.toLocaleString().replace(',', '\u202F') + (unit ? `\u202F${unit}` : '')
|
if (size < 1e4) return size.toLocaleString().replace(',', '\u202F') + (unit ? `\u202F${unit}` : '')
|
||||||
size = Math.round(size / 1000)
|
size = Math.round(size / 1000)
|
||||||
}
|
}
|
||||||
return "huge"
|
return "huge"
|
||||||
|
|
|
@ -24,7 +24,7 @@ watchEffect(async () => {
|
||||||
if(!file){
|
if(!file){
|
||||||
documentStore.setActualDocument(path.toString())
|
documentStore.setActualDocument(path.toString())
|
||||||
}else {
|
}else {
|
||||||
documentStore.setActualDocumentFile(path)
|
//documentStore.setActualDocumentFile(path)
|
||||||
}
|
}
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
documentStore.loading = false
|
documentStore.loading = false
|
||||||
|
@ -33,4 +33,4 @@ watchEffect(async () => {
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -5,8 +5,8 @@
|
||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<title>Vite Vasanko</title>
|
<title>Vite Vasanko</title>
|
||||||
<script type="module" crossorigin src="/assets/index-0332a49a.js"></script>
|
<script type="module" crossorigin src="/assets/index-b757d1a1.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index-2503e4fd.css">
|
<link rel="stylesheet" href="/assets/index-1cbf2643.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user