plugins: more functions in HFS.misc

Massimo Melina committed Jun 8, 2024 at 13:52 UTC d340ecabf3b4d922ca03a5b5d870206d11516f6e
5 files changed +19 -12
dev-plugins.md
+3 -3
@@ -125,8 +125,8 @@ Currently, these properties are supported:
125 - `label: string` what name to display next to the field. Default is based on `key`.
126 - `defaultValue: any` value to be used when nothing is set.
127 - `helperText: string` extra text printed next to the field.
128 -- `frontend: boolean` expose this setting on the frontend, so that javascript can access it as
129 - `HFS.getPluginConfig()[CONFIG_KEY]` but also css can access it as `var(--PLUGIN_NAME-CONFIG_KEY)`
128 +- `frontend: boolean` expose this setting on the frontend, so that javascript can access it
129 + using `HFS.getPluginConfig()[CONFIG_KEY]` but also css can access it as `var(--PLUGIN_NAME-CONFIG_KEY)`
130
131 Based on `type`, other properties are supported:
132 - `string`
@@ -358,7 +358,6 @@ This is a list of available frontend-events, with respective object parameter an
358 - `afterList` at the end of the files list
359 - `footer` at the bottom of the screen, even after the clipboard-bar (when visible)
360 - `unauthorized` displayed behind the login dialog accessing a protected folder
361 - - `htmlHead` inside the `<head>` element
361 - `userPanelAfterInfo` visible to logged-in users, after the click on the button with their username, between user-info and buttons
362
363 ## Back-end events
@@ -600,6 +599,7 @@ If you want to override a text regardless of the language, use the special langu
599 - middleware: ctx.stop()
600 - the old way of returning true is now deprecated
601 - exports.customHtml
602 + - more functions in HFS.misc
603 - 8.72 (v0.52.0)
604 - HFS.toast
605 - HFS.misc functions
frontend/src/misc.ts
+4 -2
@@ -5,7 +5,8 @@ import { Spinner } from './components'
5 import { newDialog, toast } from './dialog'
6 import { Icon } from './icons'
7 import { Dict, getHFS, Html, HTTP_MESSAGES, useBatch } from '@hfs/shared'
8 -import * as misc from '../../src/cross'
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'
12 import { t } from './i18n'
@@ -58,7 +59,8 @@ export function hfsEvent(name: string, params?:Dict) {
59 }
60
61 const tools = {
61 - misc, h, React, state, t, _, dialogLib, apiCall, useApi, reloadList, logout, Icon, hIcon, useBatch, fileShow, toast,
62 + h, React, state, t, _, dialogLib, apiCall, useApi, reloadList, logout, Icon, hIcon, useBatch, fileShow, toast,
63 + misc: { ...cross, ...shared },
64 watchState(k: string, cb: (v: any) => void) {
65 const up = k.split('upload.')[1]
66 return subscribeKey(up ? uploadState : state as any, up || k, cb, true)
shared/index.ts
+10 -6
@@ -121,12 +121,16 @@ export function focusSelector(selector: string, root: HTMLElement | Document=doc
121 }
122
123 export function loadScript(url: string, more={}) {
124 - const el = document.createElement('script')
125 - el.type = 'text/javascript'
126 - el.src = url
127 - for (const [k,v] of Object.entries(more))
128 - el.setAttribute(k, String(v))
129 - document.head.appendChild(el)
124 + return new Promise((resolve, reject) => {
125 + const el = document.createElement('script')
126 + el.type = 'text/javascript'
127 + el.src = url
128 + el.onload = resolve
129 + el.onerror = reject
130 + for (const [k,v] of Object.entries(more))
131 + el.setAttribute(k, String(v))
132 + document.head.appendChild(el)
133 + })
134 }
135
136 type DurationUnit = 'day' | 'hour' | 'minute' | 'second'
src/const.ts
+1 -1
@@ -7,7 +7,7 @@ import { mkdirSync } from 'fs'
7 import { basename, dirname, join } from 'path'
8 export * from './cross-const'
9
10 -export const API_VERSION = 8.85
10 +export const API_VERSION = 8.86
11 export const COMPATIBLE_API_VERSION = 1 // while changes in the api are not breaking, this number stays the same, otherwise it is made equal to API_VERSION
12 export const HFS_REPO = 'rejetto/hfs'
13
src/cross.ts
+1
@@ -433,6 +433,7 @@ export function matches(s: string, mask: string, emptyMaskReturns=false) {
433 return makeMatcher(mask, emptyMaskReturns)(s) // adding () will allow us to use the pipe at root level
434 }
435
436 +// if delimiter is specified, it is prefixed to symbols. If it contains a space, the part after the space is considered as suffix.
437 export function replace(s: string, symbols: Dict<string | Callback<string, string>>, delimiter='') {
438 const [open, close] = splitAt(' ', delimiter)
439 for (const [k, v] of Object.entries(symbols))