@samitouri / QOSami-HFS / commits / 42a109bc

admin/options: "default tiles size" option

Massimo Melina committed Sep 18, 2023 at 14:57 UTC 42a109bc22214eeb475263e13dddef5b8fe137b9
7 files changed +23 -18
admin/src/OptionsPage.ts
+3 -2
@@ -5,7 +5,7 @@ import { createElement as h, Fragment, useEffect, useRef } from 'react';
5 import { apiCall, useApiEx } from './api'
6 import { state, useSnapState } from './state'
7 import { CardMembership, Refresh, Warning } from '@mui/icons-material'
8 -import { Dict, iconTooltip, InLink, LinkBtn, modifiedSx, REPO_URL, wait, wikiLink, with_ } from './misc'
8 +import { Dict, iconTooltip, InLink, LinkBtn, MAX_TILES_SIZE, modifiedSx, REPO_URL, wait, wikiLink, with_ } from './misc'
9 import { Form, BoolField, NumberField, SelectField, FieldProps, Field, StringField } from '@hfs/mui-grid-form';
10 import { ArrayField } from './ArrayField'
11 import FileField from './FileField'
@@ -147,7 +147,8 @@ export default function OptionsPage() {
147 { k: 'session_duration', comp: NumberField, sm: 3, min: 5, unit: "seconds", required: true },
148 { k: 'zip_calculate_size_for_seconds', comp: NumberField, sm: 3, label: "Calculate ZIP size for", unit: "seconds",
149 helperText: "If time is not enough, the browser will not show download percentage" },
150 - { k: 'update_to_beta', comp: BoolField, helperText: "Include betas in automatic updates" },
150 + { k: 'update_to_beta', comp: BoolField, md: 3, helperText: "Include betas in automatic updates" },
151 + { k: 'tiles_size', comp: NumberField, md: 3, min: 0, max: MAX_TILES_SIZE, label: "Default tiles size", helperText: "Zero for list mode" },
152 { k: 'admin_net', comp: NetmaskField, label: "Admin-panel accessible from", placeholder: "any address",
153 helperText: h(Fragment, {}, "IP address of browser machine. ", h(WildcardsSupported))
154 },
frontend/src/App.ts
+3 -3
@@ -13,14 +13,14 @@ import { Spinner } from "./components"
13 function App() {
14 useTheme()
15 const { ready } = useSnapshot(pageState) // wait for all plugins to be loaded
16 - const { messageOnly, tiles=0 } = useSnapState()
16 + const { messageOnly, tilesSize=0 } = useSnapState()
17 if (messageOnly)
18 return h('h1', { style: { textAlign: 'center'} }, messageOnly)
19 if (!ready)
20 return h(Spinner, { style: { margin: 'auto' } })
21 - const style = { '--tile-size': tiles }
21 + const style = { '--tiles-size': tilesSize }
22 return h(I18Nprovider, {},
23 - h('div', { className: tiles ? 'tiles-mode' : 'list-mode', style },
23 + h('div', { className: tilesSize ? 'tiles-mode' : 'list-mode', style },
24 h(BrowserRouter, {},
25 h(NavigationExtractor, {},
26 h(Routes, {},
frontend/src/index.scss
+4 -4
@@ -469,10 +469,10 @@ button label {
469 #root>.tiles-mode {
470 max-width: none;
471 margin: 0 1em;
472 - --tile-size: 5;
472 + --tiles-size: 5;
473 --name-lines: 3;
474 - --name-height: calc(4.7em + var(--tile-size) * .4em + 1.2em * var(--name-lines));
475 - --tile-width: calc(5em + 1em * var(--tile-size));
474 + --name-height: calc(4.7em + var(--tiles-size) * .4em + 1.2em * var(--name-lines));
475 + --tile-width: calc(5em + 1em * var(--tiles-size));
476
477 ul.dir {
478 display: grid;
@@ -501,7 +501,7 @@ button label {
501 a {
502 &:last-of-type { padding: 0; }
503 span { display: block; }
504 - .icon.icon { font-size: calc(1.2rem + .6rem * var(--tile-size)); }
504 + .icon.icon { font-size: calc(1.2rem + .6rem * var(--tiles-size)); }
505 img.icon {
506 width: auto;
507 height: 1em;
frontend/src/options.ts
+5 -5
@@ -4,7 +4,7 @@ import { newDialog } from './dialog'
4 import { state, useSnapState } from './state'
5 import { createElement as h } from 'react'
6 import { Checkbox, FlexV, Select } from './components'
7 -import { hIcon } from './misc'
7 +import { hIcon, MAX_TILES_SIZE } from './misc'
8 import { MenuLink } from './menu'
9 import { t } from './i18n'
10
@@ -56,13 +56,13 @@ export function showOptions (){
56 }, t`Numeric names`),
57
58 h('div', {},
59 - h('div', {}, t`Tiles mode:`, ' ', state.tiles || t`off`),
59 + h('div', {}, t`Tiles mode:`, ' ', state.tilesSize || t`off`),
60 h('input', {
61 type: 'range',
62 - min: 0, max: 10,
63 - value: snap.tiles || 0,
62 + min: 0, max: MAX_TILES_SIZE,
63 + value: snap.tilesSize || 0,
64 onChange(ev: any) {
65 - state.tiles = Number(ev.target.value)
65 + state.tilesSize = Number(ev.target.value)
66 }
67 }),
68 ),
frontend/src/state.ts
+4 -3
@@ -3,7 +3,7 @@
3 import _ from 'lodash'
4 import { proxy, useSnapshot } from 'valtio'
5 import { subscribeKey } from 'valtio/utils'
6 -import { hIcon } from './misc'
6 +import { getHFS, hIcon } from './misc'
7
8 export const state = proxy<{
9 stopSearch?: ()=>void,
@@ -30,8 +30,9 @@ export const state = proxy<{
30 can_upload?: boolean
31 can_delete?: boolean
32 accept?: string
33 - tiles?: number
33 + tilesSize: number
34 }>({
35 + tilesSize: getHFS().tilesSize || 0,
36 iconsReady: false,
37 username: '',
38 list: [],
@@ -53,7 +54,7 @@ export function useSnapState() {
54 }
55
56 const SETTINGS_KEY = 'hfs_settings'
56 -const SETTINGS_TO_STORE: (keyof typeof state)[] = ['sortBy', 'sortNumerics', 'invertOrder', 'foldersFirst', 'theme', 'tiles']
57 +const SETTINGS_TO_STORE: (keyof typeof state)[] = ['sortBy', 'sortNumerics', 'invertOrder', 'foldersFirst', 'theme', 'tilesSize']
58
59 loadSettings()
60 for (const k of SETTINGS_TO_STORE)
src/cross.ts
+1
@@ -7,6 +7,7 @@ export const WIKI_URL = REPO_URL + 'wiki/'
7 export const MINUTE = 60_000
8 export const HOUR = 60 * MINUTE
9 export const DAY = 24 * HOUR
10 +export const MAX_TILES_SIZE = 10
11
12 export type Dict<T=any> = Record<string, T>
13 export type Falsy = false | null | undefined | '' | 0
src/serveGuiFiles.ts
+3 -1
@@ -108,6 +108,7 @@ async function treatIndex(ctx: Koa.Context, filesUri: string, body: string) {
108 customHtml: _.omit(Object.fromEntries(customHtmlState.sections),
109 ['top','bottom']), // excluding sections we apply in this phase
110 fileMenuOnLink: fileMenuOnLink.get(),
111 + tilesSize: tilesSize.get(),
112 lang
113 }, null, 4)
114 .replace(/<(\/script)/g, '<"+"$1') /*avoid breaking our script container*/}
@@ -165,4 +166,5 @@ export function serveGuiFiles(proxyPort:string | undefined, uri:string) {
166 return serveProxied(proxyPort, uri) || serveStatic(uri)
167 }
168
168 -const fileMenuOnLink = defineConfig('file_menu_on_link', true)
\ No newline at end of file
169 +const fileMenuOnLink = defineConfig('file_menu_on_link', true)
170 +const tilesSize = defineConfig('tiles_size', 0)
\ No newline at end of file