import type { Document } from '@/repositories/Document'; import { fetchFile } from '@/repositories/Document' import { formatSize, formatUnixDate } from '@/utils'; import { defineStore } from 'pinia'; import { localeIncludes } from 'locale-includes' type FileData = { id: string, mtime: number, size: number, dir: DirectoryData}; type DirectoryData = { [filename: string]: FileData; }; export type FileStructure = {id: string, mtime: number, size: number, dir: DirectoryData}; type User = { isOpenLoginModal: boolean, isLoggedIn : boolean, } export type DocumentStore = { root: FileStructure, document: Document[], loading: boolean, uploadingDocuments: Array<{key: number, name: string, progress: number}>, uploadCount: number, wsWatch: WebSocket | undefined, wsUpload: WebSocket | undefined, selectedDocuments: Document[], user: User, error: string, } export const useDocumentStore = defineStore({ id: 'documents', state: (): DocumentStore => ({ root: {} as FileStructure, document: [] as Document[], loading: true as boolean, uploadingDocuments: [], uploadCount: 0 as number, wsWatch: undefined, wsUpload: undefined, selectedDocuments: [] as Document[], error: '' as string, user: { isLoggedIn: false, isOpenLoginModal: false } as User }), actions: { updateTable(matched: DirectoryData) { // Transform data const dataMapped = [] for (const [name, attr] of Object.entries(matched)) { const {id, size, mtime, dir} = attr const element: Document = { name, key: id, size, sizedisp: formatSize(size), mtime, modified: formatUnixDate(mtime), type: dir === undefined ? 'folder-file' : 'folder', } dataMapped.push(element) } // Pre sort directory entries folders first then files, names in natural ordering dataMapped.sort((a, b) => a.type === b.type ? a.name.localeCompare(b.name) : a.type === "folder" ? -1 : 1) this.document = dataMapped this.loading = false; }, setFilter(filter: string){ function traverseDir(data: FileStructure, path: string){ if (data.dir === undefined) return for (const [name, attr] of Object.entries(data.dir)) { const fullname = `${path}/${name}` if (localeIncludes(name, filter, {usage: "search", sensitivity: "base"})) { matched[fullname.slice(1)] = attr // No initial slash on name } traverseDir(attr, fullname) } } this.loading = true const matched = {} traverseDir(this.root, "") this.updateTable(matched) }, setActualDocument(location: string){ location = decodeURIComponent(location) this.loading = true let data = this.root const actualDirArr = [] try { // Navigate to target folder for (const dirname of location.split('/').slice(1)) { if (!dirname) continue actualDirArr.push(dirname) data = data.dir[dirname] } } catch (error) { console.error("Cannot show requested folder", location, actualDirArr.join('/'), error) } if (data.dir === undefined) { // Target folder not available this.document = [] this.loading = false // ??? return } 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){ for (const d of this.uploadingDocuments) { if(d.key === key) d.progress = progress } }, pushUploadingDocuments(name: string){ this.uploadCount++; const document = { key: this.uploadCount, name: name, progress: 0 } this.uploadingDocuments.push(document) return document }, deleteUploadingDocument(key: number){ 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() { for (const d of this.document) { if ("mtime" in d) d.modified = formatUnixDate(d.mtime) } }, }, getters: { mainDocument(): 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{ return this.user.isLoggedIn } }, });