order by creation-time #872

Massimo Melina committed Jan 19, 2025 at 14:12 UTC f2f8e8b1aa77fb1a3bd070d4cb55cc4551a02525
8 files changed +23 -26
frontend/src/BrowseFiles.ts
+3 -2
@@ -326,7 +326,8 @@ export function getEntryIcon(entry: DirEntry) {
326 }
327
328 export const EntryDetails = memo(({ entry, midnight }: { entry: DirEntry, midnight: Date }) => {
329 - const { t: time, s } = entry
329 + const { sort_by } = useSnapState()
330 + const time = sort_by === 'creation' ? entry.c : entry.t
331 const today = time && time > midnight
332 const shortTs = useWindowSize().width < 800
333 const {t} = useI18N()
@@ -334,7 +335,7 @@ export const EntryDetails = memo(({ entry, midnight }: { entry: DirEntry, midnig
335 return h('div', { className: 'entry-details' },
336 h(CustomCode, { name: 'additionalEntryDetails', entry }),
337 entry.cantOpen && hIcon(entry.cantOpen === DirEntry.FORBIDDEN ? 'lock' : 'password', { className: 'miss-perm', title: t(MISSING_PERM) }),
337 - h(EntrySize, { s }),
338 + h(EntrySize, { s: entry.s }),
339 time && h('span', {
340 className: 'entry-ts',
341 'aria-hidden': true,
frontend/src/fileMenu.ts
+1
@@ -77,6 +77,7 @@ export function openFileMenu(entry: DirEntry, ev: MouseEvent, addToMenu: (Falsy
77 typeof s === 'number' && { id: 'size', label: t`Size`,
78 value: h(Fragment, {}, formatBytes(s), h('small', {}, prefix(' (', s > getHFS().kb && s.toLocaleString(), ')')) ) },
79 entry.t && { id: 'timestamp', label: t`Timestamp`, value: entry.t.toLocaleString() },
80 + entry.c && { id: 'creation', label: t`Creation`, value: entry.c.toLocaleString() },
81 folder && {
82 id: 'folder',
83 label: t`Folder`,
frontend/src/state.ts
+8 -18
@@ -3,17 +3,7 @@
3 import _ from 'lodash'
4 import { proxy, useSnapshot } from 'valtio'
5 import { subscribeKey } from 'valtio/utils'
6 -import {
7 - Dict,
8 - FRONTEND_OPTIONS,
9 - getHFS,
10 - hfsEvent,
11 - hIcon,
12 - objSameKeys,
13 - pathEncode,
14 - StringifyProps,
15 - typedKeys
16 -} from './misc'
6 +import { Dict, FRONTEND_OPTIONS, getHFS, hfsEvent, hIcon, objSameKeys, pathEncode, typedKeys } from './misc'
7 import { DirEntry as ServerDirEntry } from '../../src/api.get_file_list'
8
9 export const state = proxy<typeof FRONTEND_OPTIONS & {
@@ -101,12 +91,12 @@ function storeSettings() {
91 localStorage.setItem(SETTINGS_KEY, JSON.stringify(_.pick(state, SETTINGS_TO_STORE)))
92 }
93
104 -export class DirEntry implements StringifyProps<ServerDirEntry> {
94 +export class DirEntry implements ServerDirEntry {
95 static FORBIDDEN = 'FORBIDDEN'
96 public readonly n: string
97 public readonly s?: number
108 - public readonly m?: string
109 - public readonly c?: string
98 + public readonly m?: Date
99 + public readonly c?: Date
100 public readonly p?: string
101 public readonly icon?: string | true
102 public readonly web?: true
@@ -118,7 +108,7 @@ export class DirEntry implements StringifyProps<ServerDirEntry> {
108 public readonly uri: string
109 public readonly ext: string = ''
110 public readonly isFolder: boolean
121 - public readonly t?:Date
111 + public readonly t?: Date
112 public readonly cantOpen?: true | typeof DirEntry.FORBIDDEN
113 public readonly key?: string
114
@@ -131,9 +121,9 @@ export class DirEntry implements StringifyProps<ServerDirEntry> {
121 const i = this.n.lastIndexOf('.') + 1
122 this.ext = i ? this.n.substring(i).toLowerCase() : ''
123 }
134 - const t = this.m || this.c
135 - if (t)
136 - this.t = new Date(t)
124 + this.c &&= new Date(this.c)
125 + this.m &&= new Date(this.m)
126 + this.t = this.m || this.c
127 this.name = this.isFolder ? this.n.slice(this.n.lastIndexOf('/', this.n.length - 2) + 1, -1)
128 : this.n.slice(this.n.lastIndexOf('/') + 1)
129 const x = this.isFolder && !this.web ? 'L' : 'R' // to open we need list for folders and read for files
frontend/src/useFetchList.ts
+3 -1
@@ -176,6 +176,7 @@ function sort(list: DirList) {
176 const bySize = sort_by === 'size'
177 const byExt = sort_by === 'extension'
178 const byTime = sort_by === 'time'
179 + const byCreation = sort_by === 'creation'
180 const invert = state.invert_order ? -1 : 1
181 return list.sort((a,b) =>
182 hfsEvent('sortCompare', { a, b }).find(Boolean)
@@ -183,7 +184,8 @@ function sort(list: DirList) {
184 || invert * (bySize ? compare(a.s||0, b.s||0)
185 : byExt ? localCompare(a.ext, b.ext)
186 : byTime ? compare(a.t, b.t)
186 - : 0
187 + : byCreation ? compare(a.c, b.c)
188 + : 0
189 )
190 || sort_numerics && (invert * compareNumerics(a.n, b.n))
191 || invert * localCompare(a.n, b.n) // fallback to name/path
src/api.get_file_list.ts
+1 -1
@@ -94,7 +94,7 @@ export const get_file_list: ApiHandler = async ({ uri='/', offset, limit, c, onl
94 --offset
95 continue
96 }
97 - if (!c) { // include c field?
97 + if (c === 'no') { // allow excluding c for smaller payload
98 if (!entry.m)
99 entry.m = entry.c
100 if (entry.c)
src/cross.ts
+1 -2
@@ -25,7 +25,7 @@ export const FRONTEND_OPTIONS = {
25 auto_play_seconds: 5,
26 disableTranslation: false,
27 }
28 -export const SORT_BY_OPTIONS = ['name', 'extension', 'size', 'time']
28 +export const SORT_BY_OPTIONS = ['name', 'extension', 'size', 'time', 'creation']
29 export const THEME_OPTIONS = { auto: '', light: 'light', dark: 'dark' }
30 export const CFG = constMap(['geo_enable', 'geo_allow', 'geo_list', 'geo_allow_unknown', 'dynamic_dns_url',
31 'log', 'error_log', 'log_rotation', 'dont_log_net', 'log_gui', 'log_api', 'log_ua', 'log_spam', 'track_ips',
@@ -38,7 +38,6 @@ type Truthy<T> = T extends false | '' | 0 | null | undefined | void ? never : T
38 export type Callback<IN=void, OUT=void> = (x:IN) => OUT
39 export type Promisable<T> = T | Promise<T>
40 export type Functionable<T> = T | ((...args: any[]) => T)
41 -export type StringifyProps<T> = { [P in keyof T]: Exclude<T[P], Date> extends T[P] ? string | Exclude<T[P], Date> : T[P] }
41 export interface VfsPerms {
42 can_see?: Who
43 can_read?: Who
src/langs/hfs-lang-en.json
+3 -1
@@ -179,6 +179,8 @@
179 "focus_hint": "By typing on your keyboard, you search and focus elements of the list.",
180 "copy_links": "Copy links",
181
182 - "Calculate": "Calculate"
182 + "Calculate": "Calculate",
183 + "Creation": "Creation",
184 + "creation": "creation"
185 }
186 }
src/langs/hfs-lang-it.json
+3 -1
@@ -171,6 +171,8 @@
171 "focus_hint": "Scrivendo sulla tastiera cerchi tra gli elementi della lista.",
172 "copy_links": "Copia i link",
173
174 - "Calculate": "Calcola"
174 + "Calculate": "Calcola",
175 + "Creation": "Creazione",
176 + "creation": "creazione"
177 }
178 }