file show: arrow up for full-height mode
Massimo Melina committed
Jul 26, 2023 at 16:54 UTC
195b7bac2bc850de4f1be67c9cbbf43e35245e93
4 files changed
+36
-20
frontend/src/components.ts
+2
-1
@@ -19,8 +19,9 @@ 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, props={}, ...rest }) {
22
+export function Flex({ gap='.8em', center=false, vert=false, children=null, className=undefined, props={}, ...rest }) {
23
return h('div', {
24
+ className,
25
style: {
26
display: 'flex',
27
gap,
frontend/src/index.scss
+10
@@ -556,11 +556,21 @@ button label {
556
height: 100%;
557
width: 100%;
558
}
559
+ .showing-container { max-height: 100%; }
560
.showing {
561
max-width: calc(100% - var(--nav-size)*2); // avoid overlapping of controls and nav buttons
562
max-height: 100%;
563
}
564
img.showing { max-width: 100% } // we are ok with overlapping for simple images
565
+ .main {
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 {
570
+ .main { overflow-y: auto; }
571
+ .showing { max-height: initial }
572
+ .showing-container { overflow: auto; }
573
+ }
574
--nav-size: min(25vh, 15vw);
575
.nav {
576
position: absolute;
frontend/src/show.ts
+22
-17
@@ -1,5 +1,5 @@
1
import { DirEntry, ext2type, state } from './state'
2
-import { createElement as h, Fragment, useRef, useState } from 'react'
2
+import { createElement as h, Fragment, useEffect, useRef, useState } from 'react'
3
import { hfsEvent, hIcon, newDialog, restartAnimation, WIKI_URL } from './misc'
4
import { useEventListener, useWindowSize } from 'usehooks-ts'
5
import { EntryDetails, useMidnight } from './BrowseFiles'
@@ -15,6 +15,7 @@ export function fileShow(entry: DirEntry) {
15
const [cur, setCur] = useState(entry)
16
const moving = useRef(0)
17
const lastGood = useRef(entry)
18
+ const [fullY, setFullY] = useState(false)
19
useEventListener('keydown', ({ key }) => {
20
if (key === 'ArrowLeft')
21
return go(-1)
@@ -22,6 +23,8 @@ export function fileShow(entry: DirEntry) {
23
return go(+1)
24
if (key === 'ArrowDown')
25
return location.href = cur.uri + '?dl'
26
+ if (key === 'ArrowUp')
27
+ return setFullY(x => !x)
28
if (key === ' ') {
29
const sel = state.selected
30
if (sel[cur.uri])
@@ -34,9 +37,11 @@ export function fileShow(entry: DirEntry) {
37
})
38
const [loading, setLoading] = useState(false)
39
const [failed, setFailed] = useState<false | string>(false)
40
+ const containerRef = useRef<HTMLDivElement>()
41
+ useEffect(() => { containerRef.current?.scrollTo(0,0) }, [cur])
42
const {t} = useI18N()
43
return h(Fragment, {},
39
- h(FlexV, { gap: 0, alignItems: 'stretch' },
44
+ h(FlexV, { gap: 0, alignItems: 'stretch', className: fullY ? 'fullY' : undefined, },
45
h('div', { className: 'bar' },
46
h('div', { className: 'filename' }, cur.n),
47
h(EntryDetails, { entry: cur, midnight: useMidnight() }),
@@ -46,26 +51,26 @@ export function fileShow(entry: DirEntry) {
51
iconBtn('close', close),
52
)
53
),
49
- h(FlexV, { flex: 1, center: true, position: 'relative', maxHeight: '100%',
50
- overflow: 'hidden' // without this <video> can make me go beyond the screen limit
51
- },
54
+ h(FlexV, { center: true, className: 'main' },
55
loading && h(Spinner, { style: { position: 'absolute', fontSize: '20vh', opacity: .5 } }),
56
failed === cur.n ? h(FlexV, { alignItems: 'center', textAlign: 'center' },
57
hIcon('error', { style: { fontSize: '20vh' } }),
58
h('div', {}, cur.name),
59
t`Loading failed`
57
- ) : h(getShowType(cur) || Fragment, {
58
- src: cur.uri,
59
- className: 'showing',
60
- onLoad: () => {
61
- lastGood.current = cur
62
- setLoading(false)
63
- },
64
- onError: () => {
65
- go()
66
- setFailed(cur.n)
67
- }
68
- }),
60
+ ) : h('div', { className: 'showing-container', ref: containerRef },
61
+ h(getShowType(cur) || Fragment, {
62
+ src: cur.uri,
63
+ className: 'showing',
64
+ onLoad: () => {
65
+ lastGood.current = cur
66
+ setLoading(false)
67
+ },
68
+ onError: () => {
69
+ go()
70
+ setFailed(cur.n)
71
+ }
72
+ })
73
+ ),
74
hIcon('❮', { className: 'nav', style: { left: 0 }, onClick: () => go(-1) }),
75
hIcon('❯', { className: 'nav', style: { right: 0 }, onClick: () => go(+1) }),
76
),
frontend/src/upload.ts
+2
-2
@@ -1,6 +1,6 @@
1
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3
-import { createElement as h, Fragment, useMemo, useState } from 'react'
3
+import { createElement as h, DragEvent, Fragment, useMemo, useState } from 'react'
4
import { Checkbox, Flex, FlexV, iconBtn } from './components'
5
import {
6
closeDialog,
@@ -102,7 +102,7 @@ export function showUpload() {
102
const size = formatBytes(files.reduce((a, f) => a + f.size, 0))
103
104
return h(FlexV, { gap: 0, props: acceptDropFiles(x => setFiles([ ...files, ...x ])) },
105
- h(FlexV, { props: { className: 'upload-toolbar' } },
105
+ h(FlexV, { className: 'upload-toolbar' },
106
!can_upload ? t('no_upload_here', "No upload permission for the current folder")
107
: h(FlexV, { margin: '0 0 1em' },
108
h(Flex, { justifyContent: 'center', flexWrap: 'wrap', alignItems: 'center' },