diff --git a/src/contexts/UIPreferencesContext.tsx b/src/contexts/UIPreferencesContext.tsx index 1bec49b..6354e62 100644 --- a/src/contexts/UIPreferencesContext.tsx +++ b/src/contexts/UIPreferencesContext.tsx @@ -1,31 +1,35 @@ -import React, { ReactNode, useEffect, useState } from 'react'; +import React, { ReactNode, useCallback, useEffect, useState } from 'react'; import axios from 'axios'; export const PAGE_SIZES = [10, 20, 30, 40, 50, 100]; export const UIPreferencesContext = React.createContext({} as UIPreferences); -const DEFAULT_PREFERENCES = { pageSize: PAGE_SIZES[0], bytesStringBase2: false, defaultSnapshotViewAll: false, theme: getDefaultTheme() } as SerializedUIPreferences; +const DEFAULT_PREFERENCES = { pageSize: PAGE_SIZES[0], bytesStringBase2: false, defaultSnapshotViewAll: false, theme: getDefaultTheme(), preferWebDav: false, fontSize: "fs-6" } as SerializedUIPreferences; const PREFERENCES_URL = '/api/v1/ui-preferences'; export type Theme = "light" | "dark" | "pastel" | "ocean"; export type PageSize = 10 | 20 | 30 | 40 | 50 | 100; +export type fontSize = "fs-6" | "fs-5" | "fs-4"; export interface UIPreferences { get pageSize(): PageSize get theme(): Theme get bytesStringBase2(): boolean get defaultSnapshotViewAll(): boolean + get fontSize(): fontSize setTheme: (theme: Theme) => void setPageSize: (pageSize: number) => void setByteStringBase: (bytesStringBase2: String) => void setDefaultSnapshotViewAll: (defaultSnapshotView: boolean) => void + setFontSize: (size: String) => void } interface SerializedUIPreferences { pageSize?: number bytesStringBase2?: boolean defaultSnapshotView?: boolean - theme: Theme | undefined + theme: Theme + fontSize: fontSize } export interface UIPreferenceProviderProps { @@ -62,6 +66,33 @@ function normalizePageSize(pageSize: number): PageSize { export function UIPreferenceProvider(props: UIPreferenceProviderProps) { const [preferences, setPreferences] = useState(DEFAULT_PREFERENCES); + /** + * + * @param theme + * @returns + */ + const setTheme = useCallback((theme: Theme) => setPreferences(oldPreferences => { + syncTheme(theme, oldPreferences.theme); + return { ...oldPreferences, theme }; + }), []); + + const setPageSize = (pageSize: PageSize) => setPreferences(oldPreferences => { + return { ...oldPreferences, pageSize }; + }); + + const setByteStringBase = (input: String) => setPreferences(oldPreferences => { + var bytesStringBase2 = input === "true"; + return { ...oldPreferences, bytesStringBase2 }; + }); + + const setDefaultSnapshotViewAll = (input: boolean) => setPreferences(oldPreferences => { + return { ...oldPreferences, input }; + }); + + const setFontSize = useCallback((fontSize: fontSize) => setPreferences(oldPreferences => { + syncFontSize(fontSize, oldPreferences.fontSize); + return { ...oldPreferences, fontSize }; + }), []); useEffect(() => { axios.get(PREFERENCES_URL).then(result => { @@ -74,11 +105,12 @@ export function UIPreferenceProvider(props: UIPreferenceProviderProps) { } else { storedPreferences.pageSize = normalizePageSize(storedPreferences.pageSize); } - syncTheme(storedPreferences.theme) + setTheme(storedPreferences.theme); + setFontSize(storedPreferences.fontSize); setPreferences(storedPreferences); }).catch(err => console.error(err)); - }, []); + }, [setTheme, setFontSize]); useEffect(() => { if (!preferences) { @@ -93,36 +125,27 @@ export function UIPreferenceProvider(props: UIPreferenceProviderProps) { * @param theme * The theme to be set */ - const syncTheme = (theme: Theme) => { + const syncTheme = (newTheme: Theme, oldTheme: Theme) => { var doc = document.querySelector("html")!; - doc.className = theme + if (!doc.classList.replace(oldTheme, newTheme)) { + doc.classList.add(newTheme) + } } /** + * Synchronizes the selected theme with the html class * * @param theme - * @returns + * The theme to be set */ - const setTheme = (theme: Theme) => setPreferences(oldPreferences => { - syncTheme(theme); - return { ...oldPreferences, theme }; - }); - - const setPageSize = (pageSize: PageSize) => setPreferences(oldPreferences => { - return { ...oldPreferences, pageSize }; - }); - - const setByteStringBase = (input: String) => setPreferences(oldPreferences => { - var bytesStringBase2 = input === "true"; - return { ...oldPreferences, bytesStringBase2 }; - }); - - const setDefaultSnapshotViewAll = (input: boolean) => setPreferences(oldPreferences => { - var defaultSnapshotViewAll = input; - return { ...oldPreferences, defaultSnapshotViewAll }; - }); + const syncFontSize = (newFontSize: fontSize, oldFontSize: fontSize) => { + var doc = document.querySelector("html")!; + if (!doc.classList.replace(oldFontSize, newFontSize)) { + doc.classList.add(newFontSize) + } + } - const providedValue = { ...preferences, setTheme, setPageSize, setByteStringBase, setDefaultSnapshotViewAll} as UIPreferences; + const providedValue = { ...preferences, setTheme, setPageSize, setByteStringBase, setDefaultSnapshotViewAll, setFontSize } as UIPreferences; return {props.children} diff --git a/src/css/App.css b/src/css/App.css index d9eadbb..d75bd89 100644 --- a/src/css/App.css +++ b/src/css/App.css @@ -240,8 +240,9 @@ body { } .providerIcon { - width: 120px; - height: 110px; + min-width: 120px; + max-width: 240px; + min-height: 110px; margin: 10px; vertical-align: middle; } @@ -320,7 +321,7 @@ div.tab-body { .logs-table { font-family: monospace; - font-size: 11px; + font-size: 70%; overflow: auto; max-height: 400px; border: 1px solid #aaa; diff --git a/src/pages/Preferences.jsx b/src/pages/Preferences.jsx index 958d0f3..f831d6c 100644 --- a/src/pages/Preferences.jsx +++ b/src/pages/Preferences.jsx @@ -6,7 +6,7 @@ import { UIPreferencesContext } from '../contexts/UIPreferencesContext'; */ export class Preferences extends Component { render() { - const { pageSize, theme, bytesStringBase2, setByteStringBase, setTheme } = this.context; + const { pageSize, theme, bytesStringBase2, fontSize, setByteStringBase, setTheme, setFontSize} = this.context; return <>
@@ -29,6 +29,16 @@ export class Preferences extends Component { Specifies the representation of bytes

+
+ + + Specifies the appearance of the user interface +
+
{ + axios.post('/api/v1/mounts', { "root": this.state.oid} ).then(result => { this.setState({ mountInfo: result.data, }); @@ -151,3 +152,4 @@ export class SnapshotDirectory extends Component { } } +SnapshotDirectory.contextType = UIPreferencesContext \ No newline at end of file diff --git a/src/tests/__snapshots__/Preferences.test.js.snap b/src/tests/__snapshots__/Preferences.test.js.snap index 2298024..0974120 100644 --- a/src/tests/__snapshots__/Preferences.test.js.snap +++ b/src/tests/__snapshots__/Preferences.test.js.snap @@ -85,6 +85,44 @@ Object {

+
+ + + + Specifies the appearance of the user interface + +
+
@@ -193,6 +231,44 @@ Object {

+
+ + + + Specifies the appearance of the user interface + +
+
@@ -358,6 +434,44 @@ Object {

+
+ + + + Specifies the appearance of the user interface + +
+
@@ -466,6 +580,44 @@ Object {

+
+ + + + Specifies the appearance of the user interface + +
+
@@ -631,6 +783,44 @@ Object {

+
+ + + + Specifies the appearance of the user interface + +
+
@@ -739,6 +929,44 @@ Object {

+
+ + + + Specifies the appearance of the user interface + +
+
@@ -904,6 +1132,44 @@ Object {

+
+ + + + Specifies the appearance of the user interface + +
+
@@ -1012,6 +1278,44 @@ Object {

+
+ + + + Specifies the appearance of the user interface + +
+