plugins: HFS.DirEntry

Massimo Melina committed Sep 8, 2024 at 23:23 UTC eec81149fc70564e52eebe94d9f7bbad88eee771
3 files changed +22 -24
dev-plugins.md
+16 -12
@@ -270,7 +270,10 @@ The HFS objects contains many properties:
270 - `loadScript(uri: string): Promise` load a js file. If uri is relative, it is based on the plugin's public folder.
271 - `customRestCall(name: string, parameters?: object): Promise<any>` call backend functions exported with `customRest`.
272 - `userBelongsTo(groupOrUsername: string): boolean` returns true if logged in account belongs to the specified group name.
273 - Returns true if the specified name is the one of the logged in account.
273 + Returns true if the specified name is the one of the logged in account.
274 +- `DirEntry: class_constructor(n :string, otherProps?: DirEntry)` this is the class of the objects inside `HFS.state.list`;
275 + in case you need to add to the list, do it by instantiating this class. E.g. `new HFS.DirEntry(name)`
276 +- `fileShow(entry: DirEntry, options?: { startPlaying: true )` open file-show on the specified entry.
277
278 The following properties are accessible only immediately at top-level; don't call it later in a callback.
279 - `getPluginConfig()` returns object of all config keys that are declared frontend-accessible by this plugin.
@@ -306,9 +309,9 @@ This is a list of available frontend-events, with respective object parameter an
309
310 - `additionalEntryDetails`
311 - you receive each entry of the list, and optionally produce HTML code that will be added in the `entry-details` container.
309 - - parameter `{ entry: Entry }`
312 + - parameter `{ entry: DirEntry }`
313
311 - The `Entry` type is an object with the following properties:
314 + The `DirEntry` type is an object with the following properties:
315 - `name: string` name of the entry.
316 - `ext: string` just the extension part of the name, dot excluded and lowercase.
317 - `isFolder: boolean` true if it's a folder.
@@ -320,21 +323,21 @@ This is a list of available frontend-events, with respective object parameter an
323 - `m?: Date` modified-time.
324 - `p?: string` permissions missing
325 - `cantOpen: boolean` true if current user has no permission to open this entry
323 - - `getNext/getPrevious: ()=>Entry` return next/previous Entry in list
324 - - `getNextFiltered/getPreviousFiltered: ()=>Entry` as above, but considers the filtered-list instead
326 + - `getNext/getPrevious: ()=>DirEntry` return next/previous DirEntry in list
327 + - `getNextFiltered/getPreviousFiltered: ()=>DirEntry` as above, but considers the filtered-list instead
328 - `getDefaultIcon: ()=>ReactElement` produces the default icon for this entry
329 - output `Html`
330 - `entry`
331 - you receive each entry of the list, and optionally produce HTML code that will completely replace the entry row/slot.
329 - - parameter `{ entry: Entry }` (refer above for Entry object)
332 + - parameter `{ entry: DirEntry }` (refer above for DirEntry object)
333 - output `Html | null` return null if you want to hide this entry
334 - `afterEntryName`
335 - you receive each entry of the list, and optionally produce HTML code that will be added after the name of the entry.
333 - - parameter `{ entry: Entry }` (refer above for Entry object)
336 + - parameter `{ entry: DirEntry }` (refer above for DirEntry object)
337 - output `Html`
338 - `entryIcon`
339 - you receive an entry of the list and optionally produce HTML that will be used in place of the standard icon.
337 - - parameter `{ entry: Entry }` (refer above for Entry object)
340 + - parameter `{ entry: DirEntry }` (refer above for DirEntry object)
341 - output `Html`
342 - `beforeHeader` & `afterHeader`
343 - use this to produce content that should go right before/after the `header` part
@@ -345,7 +348,7 @@ This is a list of available frontend-events, with respective object parameter an
348 - `fileMenu`
349 - add or manipulate entries of the menu. If you return something, that will be added to the menu.
350 You can also delete or replace the content of the `menu` array.
348 - - parameter `{ entry: Entry, menu: FileMenuEntry[], props: FileMenuProp[] }`
351 + - parameter `{ entry: DirEntry, menu: FileMenuEntry[], props: FileMenuProp[] }`
352 - output `undefined | FileMenuEntry | FileMenuEntry[]`
353 ```typescript
354 interface FileMenuEntry {
@@ -370,11 +373,11 @@ This is a list of available frontend-events, with respective object parameter an
373 or if you like lodash, you can simply `HFS._.remove(menu, { id: 'show' })`
374 - `fileShow`
375 - you receive an entry of the list, and optionally produce React Component for visualization.
373 - - parameter `{ entry: Entry }` (refer above for Entry object)
376 + - parameter `{ entry: DirEntry }` (refer above for DirEntry object)
377 - output `ReactComponent`
378 - `showPlay`
379 - emitted on each file played inside file-show. Use setCover if you want to customize the background picture.
377 - - parameter `{ entry: Entry, setCover(uri: string), meta: { title, album, artist, year } }`
380 + - parameter `{ entry: DirEntry, setCover(uri: string), meta: { title, album, artist, year } }`
381 - `menuZip`
382 - parameter `{ def: ReactNode }`
383 - output `Html`
@@ -388,7 +391,7 @@ This is a list of available frontend-events, with respective object parameter an
391 - you can decide the order of entries by comparing two entries.
392 Return a negative value if entry `a` must appear before `b`, or positive if you want the opposite.
393 Return zero or any falsy value if you want to leave the order to what the user decided in his options.
391 - - parameter `{ a: Entry, b: Entry }`
394 + - parameter `{ a: DirEntry, b: DirEntry }`
395 - output `number | undefined`
396 - All of the following have no parameters and you are supposed to output `Html` that will be displayed in the described place:
397 - `afterMenuBar` between menu-bar and breadcrumbs
@@ -646,6 +649,7 @@ If you want to override a text regardless of the language, use the special langu
649 - config.type: vfs_path
650 - frontend event: sortCompare
651 - HFS.userBelongsTo
652 + - HFS.DirEntry
653 - 8.891 (v0.53.0)
654 - api.openDb
655 - frontend event: menuZip
frontend/src/misc.ts
+5 -11
@@ -8,7 +8,7 @@ import { Callback, Dict, domOn, getHFS, Html, HTTP_MESSAGES, useBatch } from '@h
8 import * as cross from '../../src/cross'
9 import * as shared from '@hfs/shared'
10 import { apiCall, getNotifications, useApi } from '@hfs/shared/api'
11 -import { state, useSnapState } from './state'
11 +import { DirEntry, state, useSnapState } from './state'
12 import { t } from './i18n'
13 import * as dialogLib from './dialog'
14 import _ from 'lodash'
@@ -61,24 +61,18 @@ export function hfsEvent(name: string, params?:Dict) {
61 })
62 }
63
64 -const tools = {
64 +Object.assign(getHFS(), {
65 h, React, state, t, _, dialogLib, apiCall, useApi, reloadList, logout, Icon, hIcon, iconBtn, useBatch, fileShow,
66 - toast, domOn,
66 + toast, domOn, getNotifications, debounceAsync, useSnapState, DirEntry,
67 misc: { ...cross, ...shared },
68 + emit: hfsEvent,
69 watchState(k: string, cb: (v: any) => void) {
70 const up = k.split('upload.')[1]
71 return subscribeKey(up ? uploadState : state as any, up || k, cb, true)
72 },
73 customRestCall(name: string, ...rest: any[]) {
74 return apiCall(cross.PLUGIN_CUSTOM_REST_PREFIX + name, ...rest)
74 - }
75 -}
76 -Object.assign(getHFS(), {
77 - ...tools,
78 - emit: hfsEvent,
79 - getNotifications,
80 - debounceAsync,
81 - useSnapState,
75 + },
76 html: (html: string) => h(Html, {}, html),
77 onEvent(name: string, cb: (params:any, extra: { output: any[], preventDefault: Callback }, output: any[]) => any) {
78 const key = 'hfs.' + name
src/serveGuiAndSharedFiles.ts
+1 -1
@@ -106,7 +106,7 @@ export const serveGuiAndSharedFiles: Koa.Middleware = async (ctx, next) => {
106 : !statusCodeForMissingPerm(node, 'can_read', ctx) ? serveFileNode(ctx, node) // all good
107 : ctx.status !== HTTP_UNAUTHORIZED ? null // all errors don't need extra handling, except unauthorized
108 : detectBasicAgent(ctx) ? (ctx.set('WWW-Authenticate', 'Basic'), sendErrorPage(ctx))
109 - : (ctx.state.serveApp = true) && serveFrontendFiles(ctx, next) // this is necessary to support standard urls with credentials, as chrome125 will send provided credentials only after attempt a GET without them, and after this error
109 + : ctx.query.dl === undefined && (ctx.state.serveApp = true) && serveFrontendFiles(ctx, next)
110 if (!path.endsWith('/'))
111 return ctx.redirect(ctx.state.revProxyPath + ctx.originalUrl.replace(/(\?|$)/, '/$1')) // keep query-string, if any
112 if (statusCodeForMissingPerm(node, 'can_list', ctx)) {