diff --git a/cista-front/components.d.ts b/cista-front/components.d.ts index b912e16..084f445 100644 --- a/cista-front/components.d.ts +++ b/cista-front/components.d.ts @@ -12,6 +12,7 @@ declare module 'vue' { FileRenameInput: typeof import('./src/components/FileRenameInput.vue')['default'] FileViewer: typeof import('./src/components/FileViewer.vue')['default'] HeaderMain: typeof import('./src/components/HeaderMain.vue')['default'] + HeaderSelected: typeof import('./src/components/HeaderSelected.vue')['default'] LoginModal: typeof import('./src/components/LoginModal.vue')['default'] ModalDialog: typeof import('./src/components/ModalDialog.vue')['default'] NotificationLoading: typeof import('./src/components/NotificationLoading.vue')['default'] diff --git a/cista-front/src/App.vue b/cista-front/src/App.vue index 56f2021..bc2a22f 100644 --- a/cista-front/src/App.vue +++ b/cista-front/src/App.vue @@ -52,7 +52,7 @@ let vert = 0 let vertInterval: any = null const globalShortcutHandler = (event: KeyboardEvent) => { if (event.repeat) return - console.log("key pressed", event) + //console.log("key pressed", event) const c = documentStore.fileExplorer.isCursor const keyup = event.type === "keyup" // For up/down implement custom fast repeat diff --git a/cista-front/src/assets/main.css b/cista-front/src/assets/main.css index 5d82565..83dddc5 100644 --- a/cista-front/src/assets/main.css +++ b/cista-front/src/assets/main.css @@ -30,6 +30,12 @@ html { font-size: 1.5rem; } + header .buttons:has(input[type=search]) > div { + display: none; + } + header .buttons > div:has(input[type=search]) { + display: inherit; + } } @media screen and (min-width: 1400px) and (--webkit-min-device-pixel-ratio: 3) { html { diff --git a/cista-front/src/components/BreadCrumb.vue b/cista-front/src/components/BreadCrumb.vue index d9655a3..058e670 100644 --- a/cista-front/src/components/BreadCrumb.vue +++ b/cista-front/src/components/BreadCrumb.vue @@ -82,7 +82,9 @@ const props = withDefaults( } .breadcrumb svg { /* FIXME: Custom positioning to align it well; needs proper solution */ - transform: translate(0.3rem, -0.3rem) scale(80%); + padding-left: .6rem; + width: 1.3rem; + height: 1.3rem; fill: var(--breadcrumb-color); transition: fill var(--breadcrumb-transtime); } diff --git a/cista-front/src/components/HeaderMain.vue b/cista-front/src/components/HeaderMain.vue index 15323f2..88e5a84 100644 --- a/cista-front/src/components/HeaderMain.vue +++ b/cista-front/src/components/HeaderMain.vue @@ -1,16 +1,18 @@ + + diff --git a/cista-front/src/components/SvgButton.vue b/cista-front/src/components/SvgButton.vue index 4c3d05c..c11454d 100644 --- a/cista-front/src/components/SvgButton.vue +++ b/cista-front/src/components/SvgButton.vue @@ -22,7 +22,9 @@ button { color: #ccc; cursor: pointer; transition: all 0.2s ease; - padding: 0.5rem; + padding: 0.2rem; + width: 3rem; + height: 3rem; } button:hover, button:focus { color: #fff; @@ -31,8 +33,6 @@ button:hover, button:focus { svg { fill: #ccc; transform: fill 0.2s ease; - width: 1rem; - height: 1rem; } button:hover svg, button:focus svg { fill: #fff; diff --git a/cista-front/src/repositories/Document.ts b/cista-front/src/repositories/Document.ts index 31d84c9..98d0adb 100644 --- a/cista-front/src/repositories/Document.ts +++ b/cista-front/src/repositories/Document.ts @@ -53,6 +53,19 @@ export type UpdateEntry = { dir?: DirList } +// Helper structure for selections +export interface SelectedItems { + selected: Set + missing: Set + rootdir: DirList + entries: Record + fullpath: Record + relpath: Record + url: Record + ids: FUID[] +} + + export const url_document_watch_ws = '/api/watch' export const url_document_upload_ws = '/api/upload' export const url_document_get = '/files' diff --git a/cista-front/src/stores/documents.ts b/cista-front/src/stores/documents.ts index a5d7956..76cd485 100644 --- a/cista-front/src/stores/documents.ts +++ b/cista-front/src/stores/documents.ts @@ -3,7 +3,8 @@ import type { DirEntry, FileEntry, FUID, - DirList + DirList, + SelectedItems, } from '@/repositories/Document' import { formatSize, formatUnixDate } from '@/utils' import { defineStore } from 'pinia' @@ -162,6 +163,50 @@ export const useDocumentStore = defineStore({ }, isUserLogged(): boolean { return this.user.isLoggedIn + }, + selectedFiles(): SelectedItems { + function traverseDir(data: DirEntry | FileEntry, path: string, relpath: string) { + if (!('dir' in data)) return + for (const [name, attr] of Object.entries(data.dir)) { + const fullname = path ? `${path}/${name}` : name + // Is this the file we are looking for? Ignore if nested within another selection. + let r = relpath + if (selected.has(attr.id) && !relpath) { + ret.selected.add(attr.id) + ret.rootdir[name] = attr + r = name + } else if (relpath) { + r = `${relpath}/${name}` + } + if (r) { + ret.entries[attr.id] = attr + ret.fullpath[attr.id] = fullname + ret.relpath[attr.id] = r + ret.ids.push(attr.id) + if (!("dir" in attr)) ret.url[attr.id] = `/files/${fullname}` + } + traverseDir(attr, fullname, r) + } + } + const selected = this.selected + const ret: SelectedItems = { + selected: new Set(), + missing: new Set(), + rootdir: {} as DirList, + entries: {} as Record, + fullpath: {} as Record, + relpath: {} as Record, + url: {} as Record, + ids: [] as FUID[] + } + traverseDir(this.root, '', '') + // What did we not select? + for (const id of selected) { + if (!ret.selected.has(id)) ret.missing.add(id) + } + // Sorted array of FUIDs for easy traversal + ret.ids.sort((a, b) => ret.relpath[a].localeCompare(ret.relpath[b] , undefined, {numeric: true, sensitivity: 'base'})) + return ret } } }) diff --git a/cista-front/src/views/ExplorerView.vue b/cista-front/src/views/ExplorerView.vue index 27d8cff..2f03b8d 100644 --- a/cista-front/src/views/ExplorerView.vue +++ b/cista-front/src/views/ExplorerView.vue @@ -1,17 +1,10 @@ - -