file show: zoom-mode (in menu)
Massimo Melina committed
Jul 26, 2023 at 22:31 UTC
d696c4882b3cd703ae83bc5b35ee2b89f8931af7
9 files changed
+66
-22
frontend/fontello-config.json
+18
@@ -203,6 +203,24 @@
203
"css": "reload",
204
"code": 59416,
205
"src": "fontawesome"
206
+ },
207
+ {
208
+ "uid": "b013f6403e5ab0326614e68d1850fd6b",
209
+ "css": "zoom",
210
+ "code": 61618,
211
+ "src": "fontawesome"
212
+ },
213
+ {
214
+ "uid": "757afacc32d82967975cbb3b45cfb41b",
215
+ "css": "fullscreen",
216
+ "code": 61704,
217
+ "src": "fontawesome"
218
+ },
219
+ {
220
+ "uid": "9c1376672bb4f1ed616fdd78a23667e9",
221
+ "css": "comment",
222
+ "code": 61669,
223
+ "src": "fontawesome"
224
}
225
]
226
}
\ No newline at end of file
frontend/public/fontello.css
+5
-2
@@ -1,6 +1,6 @@
1
@font-face {
2
font-family: 'fontello';
3
- src: url('fontello.woff2?26713191') format('woff2');
3
+ src: url('fontello.woff2?44288867') format('woff2');
4
font-weight: normal;
5
font-style: normal;
6
}
@@ -10,7 +10,7 @@
10
@media screen and (-webkit-min-device-pixel-ratio:0) {
11
@font-face {
12
font-family: 'fontello';
13
- src: url('../font/fontello.svg?26713191#fontello') format('svg');
13
+ src: url('../font/fontello.svg?44288867#fontello') format('svg');
14
}
15
}
16
*/
@@ -78,7 +78,10 @@
78
.fa-download:before { content: '\f02e'; } /* '' */
79
.fa-upload:before { content: '\f02f'; } /* '' */
80
.fa-filter:before { content: '\f0b0'; } /* '' */
81
+.fa-zoom:before { content: '\f0b2'; } /* '' */
82
.fa-menu:before { content: '\f0c9'; } /* '' */
83
+.fa-comment:before { content: '\f0e5'; } /* '' */
84
+.fa-fullscreen:before { content: '\f108'; } /* '' */
85
.fa-quote:before { content: '\f10d'; } /* '' */
86
.fa-unlink:before { content: '\f127'; } /* '' */
87
.fa-archive:before { content: '\f1c6'; } /* '' */
frontend/public/fontello.woff2
Binary files a/frontend/public/fontello.woff2 and b/frontend/public/fontello.woff2 differ
frontend/src/components.ts
+1
-1
@@ -19,7 +19,7 @@ export function Spinner(props: any) {
19
return hIcon('spinner', { className:'spinner', ...props })
20
}
21
22
-export function Flex({ gap='.8em', center=false, vert=false, children=null, className=undefined, props={}, ...rest }) {
22
+export function Flex({ gap='.8em', center=false, vert=false, children=null, className='', props={}, ...rest }) {
23
return h('div', {
24
className,
25
style: {
frontend/src/icons.ts
+10
-6
@@ -3,7 +3,7 @@
3
import { state, useSnapState } from './state'
4
import { createElement as h, memo } from 'react'
5
6
-const SYS_ICONS: Record<string, string[]> = {
6
+const SYS_ICONS: Record<string, [string] | [string, string]> = {
7
login: ['👤','user'],
8
user: ['👤','user'],
9
filter: ['✂'],
@@ -33,6 +33,7 @@ const SYS_ICONS: Record<string, string[]> = {
33
list: ['☰','menu'],
34
play: ['▶'],
35
edit: ['✏️'],
36
+ zoom: ['↔'],
37
}
38
39
document.fonts.ready.then(async ()=> {
@@ -43,17 +44,20 @@ document.fonts.ready.then(async ()=> {
44
45
interface IconProps { name:string, className?:string, alt?:string, [rest:string]: any }
46
export const Icon = memo(({ name, alt, className='', ...props }: IconProps) => {
46
- const [emoji,clazz] = SYS_ICONS[name] || name.split(':')
47
+ if (!name) return null
48
+ const [emoji, clazz=name] = SYS_ICONS[name] || []
49
const { iconsReady } = useSnapState()
50
className += ' icon'
49
- const nameIsEmoji = name.length <= 2
50
- const nameIsFile = name.includes('.')
51
- className += nameIsEmoji ? ' emoji-icon' : nameIsFile ? ' file-icon' : iconsReady ? ' fa-'+(clazz||name) : ' emoji-icon'
51
+ const nameIsTheIcon = name.length === 1 ||
52
+ name.match(/^[\uD800-\uDFFF\u2600-\u27BF\u2B50-\u2BFF\u3030-\u303F\u3297\u3299\u00A9\u00AE\u200D\u20E3\uFE0F\u2190-\u21FF\u2300-\u23FF\u2400-\u243F\u25A0-\u25FF\u2600-\u26FF\u2700-\u27BF]*$/)
53
+ const nameIsFile = !nameIsTheIcon && name.includes('.')
54
+ const isFontIcon = iconsReady && clazz
55
+ className += nameIsFile ? ' file-icon' : isFontIcon ? ` fa-${clazz}` : ' emoji-icon'
56
return h('span',{
57
'aria-label': alt,
58
role: 'img',
59
...props,
60
...nameIsFile ? { style: { backgroundImage: `url(${JSON.stringify(name)})`, ...props?.style } } : undefined,
61
className,
58
- }, nameIsEmoji ? name : iconsReady ? null : (emoji||'#'))
62
+ }, nameIsTheIcon ? name : isFontIcon ? null : (emoji||'#'))
63
})
frontend/src/index.scss
+6
-3
@@ -566,10 +566,13 @@ button label {
566
flex: 1; position: relative; max-height: 100%;
567
overflow: hidden; // without this <video> can make me go beyond the screen limit
568
}
569
- .fullY {
569
+ .freeY, .fullWidth {
570
.main { overflow-y: auto; }
571
- .showing { max-height: initial }
572
- .showing-container { overflow: auto; }
571
+ .showing { max-height: initial; margin: auto; }
572
+ .showing-container { overflow: auto; align-items: flex-start;}
573
+ }
574
+ .fullWidth {
575
+ .showing-container, .showing { width: 100%; }
576
}
577
--nav-size: min(25vh, 15vw);
578
.nav {
frontend/src/show.ts
+19
-5
@@ -6,6 +6,13 @@ import { EntryDetails, useMidnight } from './BrowseFiles'
6
import { Flex, FlexV, iconBtn, Spinner } from './components'
7
import { openFileMenu } from './fileMenu'
8
import { useI18N } from './i18n'
9
+import md from '@hfs/admin/src/md'
10
+
11
+enum ZoomMode {
12
+ fullWidth,
13
+ freeY,
14
+ contain, // leave this as last
15
+}
16
17
export function fileShow(entry: DirEntry) {
18
const { close } = newDialog({
@@ -15,7 +22,7 @@ export function fileShow(entry: DirEntry) {
22
const [cur, setCur] = useState(entry)
23
const moving = useRef(0)
24
const lastGood = useRef(entry)
18
- const [fullY, setFullY] = useState(false)
25
+ const [mode, setMode] = useState(ZoomMode.contain)
26
useEventListener('keydown', ({ key }) => {
27
if (key === 'ArrowLeft')
28
return go(-1)
@@ -23,8 +30,8 @@ export function fileShow(entry: DirEntry) {
30
return go(+1)
31
if (key === 'd')
32
return location.href = cur.uri + '?dl'
26
- if (key === 'ArrowUp')
27
- return setFullY(x => !x)
33
+ if (key === 'z')
34
+ return switchZoomMode()
35
if (key === ' ') {
36
const sel = state.selected
37
if (sel[cur.uri])
@@ -41,13 +48,16 @@ export function fileShow(entry: DirEntry) {
48
useEffect(() => { containerRef.current?.scrollTo(0,0) }, [cur])
49
const {t} = useI18N()
50
return h(Fragment, {},
44
- h(FlexV, { gap: 0, alignItems: 'stretch', className: fullY ? 'fullY' : undefined, },
51
+ h(FlexV, { gap: 0, alignItems: 'stretch', className: ZoomMode[mode] },
52
h('div', { className: 'bar' },
53
h('div', { className: 'filename' }, cur.n),
54
h(EntryDetails, { entry: cur, midnight: useMidnight() }),
55
h(Flex, {},
56
useWindowSize().width > 1280 && iconBtn('?', () => window.open(WIKI_URL + 'File-show')),
50
- iconBtn('menu', ev => openFileMenu(cur, ev, ['open','delete'])),
57
+ iconBtn('menu', ev => openFileMenu(cur, ev, [
58
+ 'open','delete',
59
+ { icon: 'zoom', label: md(t`Switch _z_oom mode`), onClick: switchZoomMode },
60
+ ])),
61
iconBtn('close', close),
62
)
63
),
@@ -94,6 +104,10 @@ export function fileShow(entry: DirEntry) {
104
}
105
setCur(e)
106
}
107
+
108
+ function switchZoomMode() {
109
+ setMode(x => x ? x - 1 : ZoomMode.contain)
110
+ }
111
}
112
})
113
}
src/langs/hfs-lang-en.json
+3
-2
@@ -1,7 +1,7 @@
1
{
2
"author": "YOUR NAME HERE",
3
"version": 1.0,
4
- "hfs_version": "0.46.0",
4
+ "hfs_version": "0.47.0",
5
"translate": {
6
"Select": "Select",
7
"n_files": "{n,plural,one{# file} other{# files}}",
@@ -120,6 +120,7 @@
120
"off": "off",
121
"Operation successful": "Operation successful",
122
"Uploader": "Uploader",
123
- "Download counter": "Download counter"
123
+ "Download counter": "Download counter",
124
+ "Switch _z_oom mode": "Switch _z_oom mode"
125
}
126
}
src/langs/hfs-lang-it.json
+4
-3
@@ -1,7 +1,7 @@
1
{
2
"author": "Massimo Melina",
3
- "version": 1.6,
4
- "hfs_version": "0.46.0",
3
+ "version": 1.7,
4
+ "hfs_version": "0.47.0",
5
"translate": {
6
"Select": "Seleziona",
7
"n_files": "{n} file",
@@ -114,6 +114,7 @@
114
"off": "no",
115
"Operation successful": "Operazione riuscita",
116
"Uploader": "Upload da",
117
- "Download counter": "Download conteggiati"
117
+ "Download counter": "Download conteggiati",
118
+ "Switch _z_oom mode": "Cambia _z_oom"
119
}
120
}