dev: responsive mobile detection
Massimo Melina committed
Mar 26, 2024 at 18:11 UTC
c97b15d5f385488760e10347c6aa0674ae0cc634
3 files changed
+12
-7
admin/src/AccountForm.ts
+3
-3
@@ -5,12 +5,11 @@ import { BoolField, Form, MultiSelectField, NumberField } from '@hfs/mui-grid-fo
5
import { Alert } from '@mui/material'
6
import { apiCall } from './api'
7
import { alertDialog, toast, useDialogBarColors } from './dialog'
8
-import { isEqualLax, wantArray } from './misc'
8
+import { isEqualLax, useIsMobile, wantArray } from './misc'
9
import { IconBtn, modifiedProps } from './mui'
10
import { Account } from './AccountsPage'
11
import { createVerifierAndSalt, SRPParameters, SRPRoutines } from 'tssrp6a'
12
import { AutoDelete, Delete } from '@mui/icons-material'
13
-import { isMobile } from './misc'
13
import { state, useSnapState } from './state'
14
import VfsPathField from './VfsPathField'
15
import { DateTimeField } from './DateTimeField'
@@ -20,10 +19,11 @@ export default function AccountForm({ account, done, groups, addToBar, reload }:
19
const { username } = useSnapState()
20
const [values, setValues] = useState<Account & { password?: string, password2?: string }>(account)
21
const [belongsOptions, setBelongOptions] = useState<string[]>([])
22
+ const isMobile = useIsMobile()
23
useEffect(() => {
24
setValues(account)
25
setBelongOptions(groups.filter(x => x !== account.username ))
26
- if (!isMobile())
26
+ if (!isMobile)
27
ref.current?.querySelector('input')?.focus()
28
}, [JSON.stringify(account)]) //eslint-disable-line
29
const add = !account.username
frontend/src/upload.ts
+4
-3
@@ -2,7 +2,7 @@
2
3
import { createElement as h, DragEvent, Fragment, useMemo, CSSProperties } from 'react'
4
import { Flex, FlexV, iconBtn, Select } from './components'
5
-import { basename, closeDialog, formatBytes, formatPerc, hIcon, isMobile, newDialog, prefix, selectFiles, working,
5
+import { basename, closeDialog, formatBytes, formatPerc, hIcon, useIsMobile, newDialog, prefix, selectFiles, working,
6
HTTP_CONFLICT, HTTP_PAYLOAD_TOO_LARGE, formatSpeed, dirname, getHFS, onlyTruthy, with_ } from './misc'
7
import _ from 'lodash'
8
import { proxy, ref, subscribe, useSnapshot } from 'valtio'
@@ -110,6 +110,7 @@ export function showUpload() {
110
const inQ = _.sumBy(qs, q => q.entries.length) - (uploadState.uploading ? 1 : 0)
111
const queueStr = inQ && t('in_queue', { n: inQ }, "{n} in queue")
112
const size = formatBytes(adding.reduce((a, x) => a + x.file.size, 0))
113
+ const isMobile = useIsMobile()
114
115
return h(FlexV, { gap: '.5em', props: acceptDropFiles(more => uploadState.adding.push(...more.map(f => ({ file: ref(f) })))) },
116
h(FlexV, { className: 'upload-toolbar' },
@@ -120,7 +121,7 @@ export function showUpload() {
121
className: 'upload-files',
122
onClick: () => pickFiles({ accept: normalizeAccept(props?.accept) })
123
}, t`Pick files`),
123
- !isMobile() && h('button', {
124
+ !isMobile && h('button', {
125
className: 'upload-folder',
126
onClick: () => pickFiles({ folder: true })
127
}, t`Pick folder`),
@@ -137,7 +138,7 @@ export function showUpload() {
138
])
139
}),
140
),
140
- !isMobile() && h(Flex, { gap: 4 }, hIcon('info'), t('upload_dd_hint', "You can upload files doing drag&drop on the files list")),
141
+ !isMobile && h(Flex, { gap: 4 }, hIcon('info'), t('upload_dd_hint', "You can upload files doing drag&drop on the files list")),
142
adding.length > 0 && h(Flex, { center: true, flexWrap: 'wrap' },
143
h('button', {
144
className: 'upload-send',
shared/react.ts
+5
-1
@@ -2,7 +2,7 @@
2
3
import { createElement as h, Fragment, KeyboardEvent, ReactElement, ReactNode,
4
useCallback, useEffect, useRef, useState } from 'react'
5
-import { useIsMounted, useWindowSize } from 'usehooks-ts'
5
+import { useIsMounted, useWindowSize, useMediaQuery } from 'usehooks-ts'
6
import { Falsy } from '.'
7
8
export function useStateMounted<T>(init: T) {
@@ -99,6 +99,10 @@ export function KeepInScreen({ margin, ...props }: any) {
99
return h('div', { ref, style: { maxHeight, overflow: 'auto' }, ...props })
100
}
101
102
+export function useIsMobile() {
103
+ return useMediaQuery('(pointer:coarse)')
104
+}
105
+
106
export function AriaOnly({ children }: { children?: ReactNode }) {
107
return children ? h('div', { className: 'ariaOnly' }, children) : null
108
}