diff --git a/frontend/src/components/FileExplorer.vue b/frontend/src/components/FileExplorer.vue
index f490e4e..89bd9c6 100644
--- a/frontend/src/components/FileExplorer.vue
+++ b/frontend/src/components/FileExplorer.vue
@@ -5,9 +5,9 @@
|
- Name |
- Modified |
- Size |
+ Name |
+ Modified |
+ Size |
@@ -21,7 +21,7 @@
-
+
|
@@ -84,9 +84,10 @@ import { useMainStore } from '@/stores/main'
import { Doc } from '@/repositories/Document'
import FileRenameInput from './FileRenameInput.vue'
import { connect, controlUrl } from '@/repositories/WS'
-import { collator, formatSize } from '@/utils'
+import { formatSize } from '@/utils'
import { useRouter } from 'vue-router'
import ContextMenu from '@imengyu/vue3-context-menu'
+import type { SortOrder } from '@/utils/docsort'
const props = defineProps<{
path: Array
@@ -121,12 +122,6 @@ const rename = (doc: Doc, newName: string) => {
}
doc.name = newName // We should get an update from watch but this is quicker
}
-const sortedDocuments = computed(() => sorted(props.documents))
-const showFolderBreadcrumb = (i: number) => {
- const docs = sortedDocuments.value
- const docloc = docs[i].loc
- return i === 0 ? docloc !== loc.value : docloc !== docs[i - 1].loc
-}
defineExpose({
newFolder() {
const now = Math.floor(Date.now() / 1000)
@@ -144,8 +139,8 @@ defineExpose({
allSelected.value = !allSelected.value
},
toggleSortColumn(column: number) {
- const columns = ['', 'name', 'modified', 'size', '']
- toggleSort(columns[column])
+ const order = ['', 'name', 'modified', 'size', ''][column]
+ if (order) store.toggleSort(order as SortOrder)
},
isCursor() {
return cursor.value !== null && editing.value === null
@@ -165,25 +160,25 @@ defineExpose({
},
cursorMove(d: number, select = false) {
// Move cursor up or down (keyboard navigation)
- const documents = sortedDocuments.value
- if (documents.length === 0) {
+ const docs = props.documents
+ if (docs.length === 0) {
cursor.value = null
return
}
- const N = documents.length
+ const N = docs.length
const mod = (a: number, b: number) => ((a % b) + b) % b
const increment = (i: number, d: number) => mod(i + d, N + 1)
const index =
- cursor.value !== null ? documents.indexOf(cursor.value) : documents.length
+ cursor.value !== null ? docs.indexOf(cursor.value) : docs.length
const moveto = increment(index, d)
- cursor.value = documents[moveto] ?? null
+ cursor.value = docs[moveto] ?? null
const tr = cursor.value ? document.getElementById(`file-${cursor.value.key}`) : null
if (select) {
// Go forwards, possibly wrapping over the end; the last entry is not toggled
let [begin, end] = d > 0 ? [index, moveto] : [moveto, index]
for (let p = begin; p !== end; p = increment(p, 1)) {
if (p === N) continue
- const key = documents[p].key
+ const key = docs[p].key
if (store.selected.has(key)) store.selected.delete(key)
else store.selected.add(key)
}
@@ -254,22 +249,10 @@ const mkdir = (doc: Doc, name: string) => {
doc.name = name
doc.key = crypto.randomUUID()
}
-
-// Column sort
-const toggleSort = (name: string) => {
- sort.value = sort.value === name ? '' : name
-}
-const sort = ref('')
-const sortCompare = {
- name: (a: Doc, b: Doc) => collator.compare(a.name, b.name),
- modified: (a: Doc, b: Doc) => b.mtime - a.mtime,
- size: (a: Doc, b: Doc) => b.size - a.size
-}
-const sorted = (documents: Doc[]) => {
- const cmp = sortCompare[sort.value as keyof typeof sortCompare]
- const sorted = [...documents]
- if (cmp) sorted.sort(cmp)
- return sorted
+const showFolderBreadcrumb = (i: number) => {
+ const docs = props.documents
+ const docloc = docs[i].loc
+ return i === 0 ? docloc !== loc.value : docloc !== docs[i - 1].loc
}
const selectionIndeterminate = computed({
get: () => {
diff --git a/frontend/src/stores/main.ts b/frontend/src/stores/main.ts
index 158a5fd..bcdb5a2 100644
--- a/frontend/src/stores/main.ts
+++ b/frontend/src/stores/main.ts
@@ -5,6 +5,7 @@ import { collator } from '@/utils'
import { logoutUser } from '@/repositories/User'
import { watchConnect } from '@/repositories/WS'
import { shallowRef } from 'vue'
+import { sorted, type SortOrder } from '@/utils/docsort'
type User = {
username: string
@@ -18,10 +19,15 @@ export const useMainStore = defineStore({
state: () => ({
document: shallowRef([]),
selected: new Set(),
+ query: '' as string,
fileExplorer: null as any,
error: '' as string,
connected: false,
server: {} as Record,
+ prefs: {
+ sortListing: '' as SortOrder,
+ sortFiltered: '' as SortOrder,
+ },
user: {
username: '',
privileged: false,
@@ -29,6 +35,9 @@ export const useMainStore = defineStore({
isOpenLoginModal: false
} as User
}),
+ persist: {
+ paths: ['prefs'],
+ },
actions: {
updateRoot(root: FileEntry[]) {
const docs = []
@@ -63,22 +72,16 @@ export const useMainStore = defineStore({
this.$reset()
localStorage.clear()
history.go() // Reload page
- }
+ },
+ toggleSort(name: SortOrder) {
+ if (this.query) this.prefs.sortFiltered = this.prefs.sortFiltered === name ? '' : name
+ else this.prefs.sortListing = this.prefs.sortListing === name ? '' : name
+ },
},
getters: {
- isUserLogged(): boolean {
- return this.user.isLoggedIn
- },
- recentDocuments(): Doc[] {
- const ret = [...this.document]
- ret.sort((a, b) => b.mtime - a.mtime)
- return ret
- },
- largeDocuments(): Doc[] {
- const ret = [...this.document]
- ret.sort((a, b) => b.size - a.size)
- return ret
- },
+ sortOrder(): SortOrder { return this.query ? this.prefs.sortFiltered : this.prefs.sortListing },
+ isUserLogged(): boolean { return this.user.isLoggedIn },
+ recentDocuments(): Doc[] { return sorted(this.document, 'modified') },
selectedFiles(): SelectedItems {
const selected = this.selected
const found = new Set()
diff --git a/frontend/src/utils/docsort.ts b/frontend/src/utils/docsort.ts
new file mode 100644
index 0000000..016db06
--- /dev/null
+++ b/frontend/src/utils/docsort.ts
@@ -0,0 +1,15 @@
+import { Doc } from '@/repositories/Document'
+import { collator } from '@/utils'
+
+export const ordering = {
+ name: (a: Doc, b: Doc) => collator.compare(a.name, b.name),
+ modified: (a: Doc, b: Doc) => b.mtime - a.mtime,
+ size: (a: Doc, b: Doc) => b.size - a.size
+}
+export type SortOrder = keyof typeof ordering | ''
+export const sorted = (documents: Doc[], order: SortOrder) => {
+ if (!order) return documents
+ const sorted = [...documents]
+ sorted.sort(ordering[order])
+ return sorted
+}
diff --git a/frontend/src/views/ExplorerView.vue b/frontend/src/views/ExplorerView.vue
index a57976c..78f6021 100644
--- a/frontend/src/views/ExplorerView.vue
+++ b/frontend/src/views/ExplorerView.vue
@@ -13,6 +13,7 @@ import { watchEffect, ref, computed } from 'vue'
import { useMainStore } from '@/stores/main'
import Router from '@/router/index'
import { needleFormat, localeIncludes, collator } from '@/utils';
+import { sorted } from '@/utils/docsort';
const store = useMainStore()
const fileExplorer = ref()
@@ -24,7 +25,10 @@ const documents = computed(() => {
const loc = props.path.join('/')
const query = props.query
// List the current location
- if (!query) return store.document.filter(doc => doc.loc === loc)
+ if (!query) return sorted(
+ store.document.filter(doc => doc.loc === loc),
+ store.prefs.sortListing,
+ )
// Find up to 100 newest documents that match the search
const needle = needleFormat(query)
let limit = 100
@@ -35,8 +39,11 @@ const documents = computed(() => {
if (--limit === 0) break
}
}
- // Organize by folder, by relevance
const locsub = loc + '/'
+ // Custom sort override in effect?
+ const order = store.prefs.sortFiltered
+ if (order) return sorted(docs, order)
+ // Sort by relevance - current folder, then subfolders, then others
docs.sort((a, b) => (
// @ts-ignore
(b.loc === loc) - (a.loc === loc) ||
@@ -54,5 +61,6 @@ const documents = computed(() => {
watchEffect(() => {
store.fileExplorer = fileExplorer.value
+ store.query = props.query
})