better code
Massimo Melina committed
Dec 7, 2023 at 17:55 UTC
110ac4c2dea7ff28f8ad25c5b8acd4edf9a6018f
8 files changed
+30
-33
admin/src/InternetPage.ts
+1
-1
@@ -1,6 +1,6 @@
1
import { createElement as h, ReactNode, useEffect, useMemo, useState } from 'react'
2
import { Alert, Box, Button, Card, CardContent, CircularProgress, Divider, LinearProgress, Link } from '@mui/material'
3
-import { CardMembership, HomeWorkTwoTone, Lock, Public, PublicTwoTone, RestartAlt, RouterTwoTone, Send, Storage,
3
+import { CardMembership, HomeWorkTwoTone, Lock, Public, PublicTwoTone, RouterTwoTone, Send, Storage,
4
SvgIconComponent } from '@mui/icons-material'
5
import { apiCall, useApiEx } from './api'
6
import { closeDialog, DAY, formatTimestamp, wait, wantArray, with_ } from '@hfs/shared'
admin/src/OptionsPage.ts
+3
-3
@@ -95,8 +95,8 @@ export default function OptionsPage() {
95
return { sm: 6 }
96
},
97
fields: [
98
- { k: 'port', comp: ServerPort, md: 4, label:"HTTP port", status: status?.http||true, suggestedPort: 80 },
99
- { k: 'https_port', comp: ServerPort, md: 4, label: "HTTPS port", status: status?.https||true, suggestedPort: 443,
98
+ { k: 'port', comp: PortField, md: 4, label:"HTTP port", status: status?.http||true, suggestedPort: 80 },
99
+ { k: 'https_port', comp: PortField, md: 4, label: "HTTPS port", status: status?.https||true, suggestedPort: 443,
100
onChange(v: number) {
101
if (v >= 0 && !httpsEnabled && !values.cert)
102
suggestMakingCert().then()
@@ -265,7 +265,7 @@ export function isKeyError(error: any) {
265
return /private key/.test(error)
266
}
267
268
-function ServerPort({ label, value, onChange, setApi, status, suggestedPort=1, error, helperText }: FieldProps<number | null>) {
268
+function PortField({ label, value, onChange, setApi, status, suggestedPort=1, error, helperText }: FieldProps<number | null>) {
269
const lastCustom = useRef(suggestedPort)
270
if (value! > 0)
271
lastCustom.current = value!
admin/src/VfsMenuBar.ts
+9
-15
@@ -8,7 +8,6 @@ import addFiles, { addLink, addVirtual } from './addFiles'
8
import MenuButton from './MenuButton'
9
import { Btn, reloadBtn } from './misc'
10
import { apiCall, useApi } from './api'
11
-import { confirmDialog } from './dialog'
11
12
export default function VfsMenuBar({ status }: any) {
13
const { data: integrated, reload } = useApi(status?.platform === 'win32' && 'windows_integrated')
@@ -40,7 +39,15 @@ export default function VfsMenuBar({ status }: any) {
39
doneMessage: true,
40
...(!integrated?.is ? {
41
children: "System integration",
43
- onClick: () => windowsIntegration().then(reload),
42
+ onClick: () => apiCall('windows_integration').then(reload),
43
+ confirm: h(Box, {}, "We are going to add a command in the right-click of Windows File Manager",
44
+ h('img', { src: 'win-shell.png', style: {
45
+ display: 'block',
46
+ width: 'min(30em, 80vw)',
47
+ marginTop: '1em',
48
+ } }),
49
+ h(Alert, { severity: 'info' }, "It will also automatically copy the URL, ready to paste!"),
50
+ )
51
} : {
52
confirm: true,
53
children: "Remove integration",
@@ -49,16 +56,3 @@ export default function VfsMenuBar({ status }: any) {
56
}),
57
)
58
}
52
-
53
-async function windowsIntegration() {
54
- const msg = h(Box, {}, "We are going to add a command in the right-click of Windows File Manager",
55
- h('img', { src: 'win-shell.png', style: {
56
- display: 'block',
57
- width: 'min(30em, 80vw)',
58
- marginTop: '1em',
59
- } }),
60
- h(Alert, { severity: 'info' }, "It will also automatically copy the URL, ready to paste!"),
61
- )
62
- return await confirmDialog(msg)
63
- && apiCall('windows_integration')
64
-}
admin/src/mui.ts
+1
-1
@@ -130,7 +130,7 @@ interface BtnProps extends Omit<LoadingButtonProps,'disabled'|'title'|'onClick'>
130
disabled?: boolean | string
131
progress?: boolean | number
132
link?: string
133
- confirm?: boolean | string
133
+ confirm?: boolean | ReactNode
134
labelFrom?: Breakpoint
135
doneMessage?: boolean | string // displayed only if the result of onClick !== false
136
tooltipProps?: TooltipProps
shared/api.ts
+11
-6
@@ -84,12 +84,15 @@ export function useApi<T=any>(cmd: string | Falsy, params?: object, options: Api
84
loadingRef.current?.abort()
85
setData(undefined)
86
setError(undefined)
87
- if (!cmd) return
87
let aborted = false
88
let req: undefined | ReturnType<typeof apiCall>
89
const wholePromise = wait(0) // postpone a bit, so that if it is aborted immediately, it is never really fired (happens mostly in dev mode)
91
- .then(() => aborted ? undefined : req = apiCall<T>(cmd, params, options))
92
- .then(res => aborted || setData(res), err => aborted || setError(err) || setData(undefined))
90
+ .then(() => !cmd || aborted ? undefined : req = apiCall<T>(cmd, params, options))
91
+ .then(res => aborted || setData(res), err => {
92
+ if (aborted) return
93
+ setError(err)
94
+ setData(undefined)
95
+ })
96
.finally(() => loadingRef.current = reloadingRef.current = undefined)
97
loadingRef.current = Object.assign(wholePromise, {
98
abort() {
@@ -99,9 +102,11 @@ export function useApi<T=any>(cmd: string | Falsy, params?: object, options: Api
102
})
103
reloadingRef.current?.resolve(wholePromise)
104
}, [cmd, JSON.stringify(params), forcer]) //eslint-disable-line -- json-ize to detect deep changes
102
- const reload = useCallback(() => loadingRef.current
103
- || setForcer(v => v+1) || (reloadingRef.current = pendingPromise()),
104
- [setForcer])
105
+ const reload = useCallback(() => {
106
+ if (loadingRef.current) return
107
+ setForcer(v => v + 1)
108
+ reloadingRef.current = pendingPromise()
109
+ }, [setForcer])
110
return { data, setData, error, reload, loading: Boolean(loadingRef.current || reloadingRef.current) }
111
}
112
src/const.ts
+4
@@ -7,6 +7,10 @@ import { mkdirSync } from 'fs'
7
import { basename, dirname, join } from 'path'
8
export * from './cross-const'
9
10
+export const API_VERSION = 8.6
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
+
14
export const argv = minimist(process.argv.slice(2))
15
export const DEV = process.env.DEV || argv.dev ? 'DEV' : ''
16
export const ORIGINAL_CWD = process.cwd()
src/cross-const.ts
-6
@@ -1,9 +1,3 @@
1
-
2
-export const API_VERSION = 8.4
3
-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
4
-
5
-export const HFS_REPO = 'rejetto/hfs'
6
-
1
export const SPECIAL_URI = '/~/'
2
export const FRONTEND_URI = SPECIAL_URI + 'frontend/'
3
export const ADMIN_URI = SPECIAL_URI + 'admin/'
src/vfs.ts
+1
-1
@@ -154,7 +154,7 @@ export function getNodeName(node: VfsNode) {
154
if (!source)
155
return '' // should happen only for root
156
if (source === '/')
157
- return 'root'
157
+ return 'root' // better name than
158
if (/^[a-zA-Z]:\\?$/.test(source))
159
return source.slice(0, 2) // exclude trailing slash
160
const base = basename(source)