expose entry.uri to plugins
Massimo Melina committed
Apr 2, 2023 at 13:01 UTC
d63021ff7a983a86b675952ea5ef0366cbc14448
4 files changed
+34
-24
dev-plugins.md
+6
-1
@@ -175,7 +175,9 @@ This is a list of available frontend-events, with respective object parameter an
175
- parameter `{ entry: Entry }`
176
177
The `Entry` type is an object with the following properties:
178
- - `n: string` name of the entry, including relative path in some cases.
178
+ - `name: string` name of the entry.
179
+ - `n: string` name of the entry, including relative path when searched in sub-folders.
180
+ - `uri: string` relative url of the entry.
181
- `s?: number` size of the entry, in bytes. It may be missing, for example for folders.
182
- `t?: Date` generic timestamp, combination of creation-time and modified-time.
183
- `c?: Date` creation-time.
@@ -222,6 +224,9 @@ HFS will scan through them in inverted alphabetical order searching for a compat
224
225
## API version history
226
227
+- 8 (v0.43.0)
228
+ - entry.name & .uri
229
+ - tools.dialogLib
230
- 7 (v0.42.0)
231
- event.fileMenu
232
- HFS.SPECIAL_URI, PLUGINS_PUB_URI, FRONTEND_URI,
frontend/src/BrowseFiles.ts
+13
-20
@@ -16,7 +16,7 @@ import { Checkbox, CustomCode, Spinner } from './components'
16
import { Head } from './Head'
17
import { state, useSnapState } from './state'
18
import { alertDialog } from './dialog'
19
-import useFetchList, { usePath } from './useFetchList'
19
+import useFetchList, { pathDecode, usePath } from './useFetchList'
20
import { useAuthorized } from './login'
21
import { acceptDropFiles, enqueue } from './upload'
22
import _ from 'lodash'
@@ -24,7 +24,7 @@ import { t, useI18N } from './i18n'
24
import { deleteFiles } from './menu'
25
26
export interface DirEntry { n:string, s?:number, m?:string, c?:string,
27
- ext:string, isFolder:boolean, t?:Date } // we memoize these value for speed
27
+ name: string, uri: string, ext:string, isFolder:boolean, t?:Date } // we memoize these value for speed
28
export type DirList = DirEntry[]
29
30
export function BrowseFiles() {
@@ -177,12 +177,10 @@ function useMidnight() {
177
const PAGE_SEPARATOR_CLASS = 'page-separator'
178
179
const Entry = memo((entry: DirEntry & { midnight: Date, separator?: string }) => {
180
- let { n: relativePath, isFolder, separator } = entry
180
+ const { name, uri, isFolder, separator } = entry
181
const base = usePath()
182
const { showFilter, selected, can_delete } = useSnapState()
183
- const href = fixUrl(relativePath)
184
- const containerDir = isFolder ? '' : relativePath.substring(0, relativePath.lastIndexOf('/')+1)
185
- const name = relativePath.substring(containerDir.length)
183
+ const containerDir = isFolder ? '' : uri.substring(0, uri.lastIndexOf('/')+1)
184
let className = isFolder ? 'folder' : 'file'
185
if (separator)
186
className += ' ' + PAGE_SEPARATOR_CLASS
@@ -190,18 +188,18 @@ const Entry = memo((entry: DirEntry & { midnight: Date, separator?: string }) =>
188
const menuOnLink = getHFS().fileMenuOnLink
189
return h('li', { className, label: separator },
190
showFilter && h(Checkbox, {
193
- value: selected[relativePath],
191
+ value: selected[uri],
192
onChange(v){
193
if (v)
196
- return state.selected[relativePath] = true
197
- delete state.selected[relativePath]
194
+ return state.selected[uri] = true
195
+ delete state.selected[uri]
196
},
197
}),
200
- isFolder ? h(Link, { to: base + href }, ico, relativePath.slice(0,-1))
198
+ isFolder ? h(Link, { to: base + uri }, ico, entry.n.slice(0,-1))
199
: h(Fragment, {},
202
- containerDir && h(Link, { to: base+fixUrl(containerDir), className:'container-folder' }, ico, containerDir ),
200
+ containerDir && h(Link, { to: base + containerDir, className:'container-folder' }, ico, pathDecode(containerDir) ),
201
h('a', {
204
- href,
202
+ href: uri,
203
onClick(ev: MouseEvent) {
204
if (menuOnLink)
205
openFileMenu(ev)
@@ -220,9 +218,9 @@ const Entry = memo((entry: DirEntry & { midnight: Date, separator?: string }) =>
218
if (ev.altKey || ev.ctrlKey || ev.metaKey) return
219
ev.preventDefault()
220
const menu = [
223
- menuOnLink && { label: t('file_open', "Open"), href, target: '_blank', icon: 'play' },
224
- { label: t`Download`, href: href + '?dl', icon: 'download' },
225
- can_delete && { label: t`Delete`, icon: 'trash', onClick: () => deleteFiles([href], base) }
221
+ menuOnLink && { label: t('file_open', "Open"), href: uri, target: '_blank', icon: 'play' },
222
+ { label: t`Download`, href: uri + '?dl', icon: 'download' },
223
+ can_delete && { label: t`Delete`, icon: 'trash', onClick: () => deleteFiles([uri], base) }
224
]
225
const res = hfsEvent('fileMenu', { entry })
226
if (res)
@@ -255,11 +253,6 @@ const Entry = memo((entry: DirEntry & { midnight: Date, separator?: string }) =>
253
}
254
})
255
258
-function fixUrl(s:string) {
259
- return s.replace(/[#%]/g, encodeURIComponent)
260
-}
261
-
262
-
256
const EntryProps = memo((entry: DirEntry & { midnight: Date }) => {
257
const { t: time, s } = entry
258
const today = time && time > entry.midnight
frontend/src/useFetchList.ts
+14
-2
@@ -18,6 +18,14 @@ export function usePath() {
18
return useLocation().pathname
19
}
20
21
+export function pathEncode(s: string) {
22
+ return encodeURI(s).replace(/#/g, encodeURIComponent)
23
+}
24
+
25
+export function pathDecode(s: string) {
26
+ return decodeURI(s).replace(/%23/g, '#')
27
+}
28
+
29
export default function useFetchList() {
30
const snap = useSnapState()
31
const desiredPath = usePath()
@@ -103,8 +111,12 @@ export default function useFetchList() {
111
}
112
state.can_upload ??= false
113
state.can_delete ??= false
106
- if (entry.add)
107
- buffer.push(entry.add)
114
+ const { add } = entry
115
+ if (add) {
116
+ add.uri = pathEncode(add.n)
117
+ add.name = add.n.slice(add.n.lastIndexOf('/')+1)
118
+ buffer.push(add)
119
+ }
120
}
121
if (src?.readyState === src?.CLOSED)
122
return state.stopSearch?.()
src/const.ts
+1
-1
@@ -17,7 +17,7 @@ export const VERSION = pkg.version
17
export const DAY = 86_400_000
18
export const SESSION_DURATION = DAY
19
20
-export const API_VERSION = 7 // fileMenu event
20
+export const API_VERSION = 8 // entry.uri
21
export const COMPATIBLE_API_VERSION = 1 // while changes in the api are not breaking, this number stays the same, otherwise is made equal to API_VERSION
22
23
export const SPECIAL_URI = '/~/'