From d2bbbe5e230478c17c5bedb51ddc00ef5dfa4434 Mon Sep 17 00:00:00 2001 From: Giuliano Caregnato Date: Mon, 14 Nov 2022 14:58:12 +0100 Subject: [PATCH 01/13] chore: save progress --- src/boot/init.ts | 4 +++ src/network/login-config.ts | 17 ++++++++++++ src/store/login/index.ts | 7 +++++ src/store/login/normalization.ts | 45 ++++++++++++++++++++++++++++++++ src/store/login/store.ts | 15 +++++++++++ types/loginConfig/index.d.ts | 12 +++++++++ 6 files changed, 100 insertions(+) create mode 100644 src/network/login-config.ts create mode 100644 src/store/login/index.ts create mode 100644 src/store/login/normalization.ts create mode 100644 src/store/login/store.ts create mode 100644 types/loginConfig/index.d.ts diff --git a/src/boot/init.ts b/src/boot/init.ts index 95775d04..3b8fa561 100644 --- a/src/boot/init.ts +++ b/src/boot/init.ts @@ -7,8 +7,12 @@ import { getInfo } from '../network/get-info'; import { useAppStore } from '../store/app'; import { loadApps } from './app/load-apps'; +import { loginConfig } from '../network/login-config'; +import { useLoginConfigStore } from '../store/login'; export const init = (): void => { + loginConfig(); + console.log('@@init', useLoginConfigStore.getState()); getInfo().finally(() => { loadApps(Object.values(useAppStore.getState().apps)); }); diff --git a/src/network/login-config.ts b/src/network/login-config.ts new file mode 100644 index 00000000..751e26e8 --- /dev/null +++ b/src/network/login-config.ts @@ -0,0 +1,17 @@ +/* + * SPDX-FileCopyrightText: 2021 Zextras + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { LoginConfigStore } from '../../types/loginConfig'; +import { useLoginConfigStore } from '../store/login'; + +export const loginConfig = (): void => { + fetch('/zx/login/v3/config').then((response) => { + response.json().then((data: LoginConfigStore) => { + useLoginConfigStore.setState(data); + console.log('@@', useLoginConfigStore()); + }); + }); +}; diff --git a/src/store/login/index.ts b/src/store/login/index.ts new file mode 100644 index 00000000..f3edd078 --- /dev/null +++ b/src/store/login/index.ts @@ -0,0 +1,7 @@ +/* + * SPDX-FileCopyrightText: 2022 Zextras + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export * from './store'; diff --git a/src/store/login/normalization.ts b/src/store/login/normalization.ts new file mode 100644 index 00000000..ce7d2438 --- /dev/null +++ b/src/store/login/normalization.ts @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2021 Zextras + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { GetInfoResponse, Account, AccountSettings } from '../../../types'; + +const normalizeSettings = ( + settings: Pick +): AccountSettings => ({ + attrs: settings.attrs._attrs, + prefs: settings.prefs._attrs, + props: settings.props.prop ?? [] +}); + +export const normalizeAccount = ({ + id, + name, + attrs, + prefs, + identities, + signatures, + props, + version, + rights +}: GetInfoResponse): { + account: Account; + settings: AccountSettings; + version: string; +} => { + const settings = normalizeSettings({ attrs, prefs, props }); + return { + account: { + id, + name, + displayName: attrs._attrs.displayName, + identities, + signatures, + rights + }, + settings, + version + }; +}; diff --git a/src/store/login/store.ts b/src/store/login/store.ts new file mode 100644 index 00000000..94581570 --- /dev/null +++ b/src/store/login/store.ts @@ -0,0 +1,15 @@ +/* + * SPDX-FileCopyrightText: 2021 Zextras + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import create from 'zustand'; +import { LoginConfigStore } from '../../../types/loginConfig'; + +export const useLoginConfigStore = create((set) => ({ + carbonioWebUIDarkMode: undefined, + carbonioWebUiAppLogo: undefined, + carbonioWebUiDarkAppLogo: undefined, + carbonioWebUiTitle: undefined +})); diff --git a/types/loginConfig/index.d.ts b/types/loginConfig/index.d.ts new file mode 100644 index 00000000..e5eda8ef --- /dev/null +++ b/types/loginConfig/index.d.ts @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: 2021 Zextras + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export type LoginConfigStore = { + carbonioWebUIDarkMode?: boolean; + carbonioWebUiAppLogo?: string; + carbonioWebUiDarkAppLogo?: string; + carbonioWebUiTitle?: string; +}; From 395944a83e55491a184196040c764e9aca03d05e Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Tue, 15 Nov 2022 10:23:07 +0100 Subject: [PATCH 02/13] feat: whitelabeling refs: IRIS-3446 --- src/boot/init.ts | 5 +--- src/network/login-config.ts | 13 +++++----- src/shell/shell-header.tsx | 47 +++++++++++++++++++++++++++++++++--- src/shell/shell-view.tsx | 30 +++++++++++++++++------ types/loginConfig/index.d.ts | 2 +- 5 files changed, 75 insertions(+), 22 deletions(-) diff --git a/src/boot/init.ts b/src/boot/init.ts index 3b8fa561..002842f2 100644 --- a/src/boot/init.ts +++ b/src/boot/init.ts @@ -8,12 +8,9 @@ import { getInfo } from '../network/get-info'; import { useAppStore } from '../store/app'; import { loadApps } from './app/load-apps'; import { loginConfig } from '../network/login-config'; -import { useLoginConfigStore } from '../store/login'; export const init = (): void => { - loginConfig(); - console.log('@@init', useLoginConfigStore.getState()); - getInfo().finally(() => { + Promise.all([loginConfig(), getInfo()]).finally(() => { loadApps(Object.values(useAppStore.getState().apps)); }); }; diff --git a/src/network/login-config.ts b/src/network/login-config.ts index 751e26e8..5a17cd29 100644 --- a/src/network/login-config.ts +++ b/src/network/login-config.ts @@ -7,11 +7,12 @@ import { LoginConfigStore } from '../../types/loginConfig'; import { useLoginConfigStore } from '../store/login'; -export const loginConfig = (): void => { - fetch('/zx/login/v3/config').then((response) => { - response.json().then((data: LoginConfigStore) => { - useLoginConfigStore.setState(data); - console.log('@@', useLoginConfigStore()); - }); +export const loginConfig = (): Promise => { + return fetch('/zx/login/v3/config').then((response) => { + return response.json(); + }).then((data: LoginConfigStore) => { + useLoginConfigStore.setState(data); + }).catch((reason) => { + console.warn(reason); }); }; diff --git a/src/shell/shell-header.tsx b/src/shell/shell-header.tsx index 46b04ffd..d8d3d9fc 100644 --- a/src/shell/shell-header.tsx +++ b/src/shell/shell-header.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import React, { FC, useState } from 'react'; +import React, {FC, useEffect, useMemo, useState} from 'react'; import { Container, IconButton, @@ -14,16 +14,57 @@ import { Catcher, Button } from '@zextras/carbonio-design-system'; -import { times } from 'lodash'; +import {find} from 'lodash'; import Logo from '../svg/carbonio.svg'; import { SearchBar } from '../search/search-bar'; import { CreationButton } from './creation-button'; import { useAppStore } from '../store/app'; +import {useLoginConfigStore} from "../store/login"; +import {useUserSettings} from "../store/account"; +import {SHELL_APP_ID} from "../constants"; +import {DRPropValues} from "../../types"; +import {isEnabled as isDarkReaderEnabled} from 'darkreader'; +import styled from "styled-components"; + +const CustomImg = styled.img` + height: 2rem +`; const ShellHeader: FC<{ mobileNavIsOpen: boolean; onMobileMenuClick: () => void; }> = ({ mobileNavIsOpen, onMobileMenuClick, children }) => { + + const [darkMediaEnabled, setDarkMediaEnabled] = useState(isDarkReaderEnabled()); + + const settings = useUserSettings(); + const currentDRMSetting = useMemo( + () => + find(settings.props, { name: 'zappDarkreaderMode', zimlet: SHELL_APP_ID }) + ?._content as DRPropValues, + [settings] + ); + + useEffect(() => { + if (currentDRMSetting !== "auto") { + setDarkMediaEnabled(currentDRMSetting === 'enabled'); + } + },[currentDRMSetting]) + + const { carbonioWebUiAppLogo, carbonioWebUiDarkAppLogo } = useLoginConfigStore(); + + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { + setDarkMediaEnabled(event.matches); + }); + + const logoSrc = useMemo(() => { + if (darkMediaEnabled) { + return carbonioWebUiDarkAppLogo || carbonioWebUiAppLogo; + } else { + return carbonioWebUiAppLogo || carbonioWebUiDarkAppLogo; + } + }, [carbonioWebUiDarkAppLogo, carbonioWebUiAppLogo, darkMediaEnabled]); + const screenMode = useScreenMode(); const searchEnabled = useAppStore((s) => s.views.search.length > 0); return ( @@ -53,7 +94,7 @@ const ShellHeader: FC<{ - + {logoSrc ? : } diff --git a/src/shell/shell-view.tsx b/src/shell/shell-view.tsx index 0da6b2c0..b54aa102 100644 --- a/src/shell/shell-view.tsx +++ b/src/shell/shell-view.tsx @@ -6,12 +6,12 @@ import { Responsive, Row } from '@zextras/carbonio-design-system'; import { PreviewManager } from '@zextras/carbonio-ui-preview'; -import { find } from 'lodash'; +import {find, size} from 'lodash'; import React, { FC, useContext, useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; import { AppRoute, DRPropValues } from '../../types'; import { ThemeCallbacksContext } from '../boot/theme-provider'; -import { IS_STANDALONE, SHELL_APP_ID } from '../constants'; +import {IS_STANDALONE, SHELL_APP_ID} from '../constants'; import { useCurrentRoute } from '../history/hooks'; import { goToLogin } from '../network/go-to-login'; import { useAccountStore, useUserSettings } from '../store/account'; @@ -21,6 +21,7 @@ import { BoardContainer } from './boards/board-container'; import ShellContextProvider from './shell-context-provider'; import ShellHeader from './shell-header'; import ShellNavigationBar from './shell-navigation-bar'; +import {useLoginConfigStore} from "../store/login"; const Background = styled.div` background: ${({ theme }): string => theme.palette.gray6.regular}; @@ -37,18 +38,31 @@ const Background = styled.div` function DarkReaderListener(): null { const { setDarkReaderState } = useContext(ThemeCallbacksContext); const settings = useUserSettings(); + const { carbonioWebUiDarkMode } = useLoginConfigStore(); + + const settingReceived = useMemo(() => { + return size(settings.prefs) > 0 || size(settings.attrs) > 0 || size(settings.props) > 0; + }, [settings]); + const currentDRMSetting = useMemo( - () => - find(settings?.props ?? [], { + () =>{ + const result = find(settings?.props ?? [], { name: 'zappDarkreaderMode', zimlet: SHELL_APP_ID - })?._content as DRPropValues, - [settings] + })?._content as DRPropValues; + if (result) { + return result; + } + return carbonioWebUiDarkMode !== undefined ? carbonioWebUiDarkMode ? 'enabled' : 'disabled' : 'auto' + + }, [settings, carbonioWebUiDarkMode] ); useEffect(() => { - setDarkReaderState(currentDRMSetting); - }, [currentDRMSetting, setDarkReaderState]); + if (currentDRMSetting && settingReceived) { + setDarkReaderState(currentDRMSetting); + } + }, [currentDRMSetting, setDarkReaderState, settingReceived]); return null; } diff --git a/types/loginConfig/index.d.ts b/types/loginConfig/index.d.ts index e5eda8ef..a148b084 100644 --- a/types/loginConfig/index.d.ts +++ b/types/loginConfig/index.d.ts @@ -5,7 +5,7 @@ */ export type LoginConfigStore = { - carbonioWebUIDarkMode?: boolean; + carbonioWebUiDarkMode?: boolean; carbonioWebUiAppLogo?: string; carbonioWebUiDarkAppLogo?: string; carbonioWebUiTitle?: string; From 175c6a7ba2e08e8f432dae09de9debe25da44403 Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Tue, 15 Nov 2022 10:25:54 +0100 Subject: [PATCH 03/13] feat: whitelabeling --- src/network/login-config.ts | 18 ++++++++--------- src/shell/shell-header.tsx | 28 +++++++++++++------------- src/shell/shell-view.tsx | 39 ++++++++++++++++++++----------------- 3 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/network/login-config.ts b/src/network/login-config.ts index 5a17cd29..c4c54d83 100644 --- a/src/network/login-config.ts +++ b/src/network/login-config.ts @@ -7,12 +7,12 @@ import { LoginConfigStore } from '../../types/loginConfig'; import { useLoginConfigStore } from '../store/login'; -export const loginConfig = (): Promise => { - return fetch('/zx/login/v3/config').then((response) => { - return response.json(); - }).then((data: LoginConfigStore) => { - useLoginConfigStore.setState(data); - }).catch((reason) => { - console.warn(reason); - }); -}; +export const loginConfig = (): Promise => + fetch('/zx/login/v3/config') + .then((response) => response.json()) + .then((data: LoginConfigStore) => { + useLoginConfigStore.setState(data); + }) + .catch((reason) => { + console.warn(reason); + }); diff --git a/src/shell/shell-header.tsx b/src/shell/shell-header.tsx index d8d3d9fc..5ce1b12d 100644 --- a/src/shell/shell-header.tsx +++ b/src/shell/shell-header.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import React, {FC, useEffect, useMemo, useState} from 'react'; +import React, { FC, useEffect, useMemo, useState } from 'react'; import { Container, IconButton, @@ -14,27 +14,26 @@ import { Catcher, Button } from '@zextras/carbonio-design-system'; -import {find} from 'lodash'; +import { find } from 'lodash'; +import { isEnabled as isDarkReaderEnabled } from 'darkreader'; +import styled from 'styled-components'; import Logo from '../svg/carbonio.svg'; import { SearchBar } from '../search/search-bar'; import { CreationButton } from './creation-button'; import { useAppStore } from '../store/app'; -import {useLoginConfigStore} from "../store/login"; -import {useUserSettings} from "../store/account"; -import {SHELL_APP_ID} from "../constants"; -import {DRPropValues} from "../../types"; -import {isEnabled as isDarkReaderEnabled} from 'darkreader'; -import styled from "styled-components"; +import { useLoginConfigStore } from '../store/login'; +import { useUserSettings } from '../store/account'; +import { SHELL_APP_ID } from '../constants'; +import { DRPropValues } from '../../types'; const CustomImg = styled.img` - height: 2rem + height: 2rem; `; const ShellHeader: FC<{ mobileNavIsOpen: boolean; onMobileMenuClick: () => void; }> = ({ mobileNavIsOpen, onMobileMenuClick, children }) => { - const [darkMediaEnabled, setDarkMediaEnabled] = useState(isDarkReaderEnabled()); const settings = useUserSettings(); @@ -46,23 +45,22 @@ const ShellHeader: FC<{ ); useEffect(() => { - if (currentDRMSetting !== "auto") { + if (currentDRMSetting !== 'auto') { setDarkMediaEnabled(currentDRMSetting === 'enabled'); } - },[currentDRMSetting]) + }, [currentDRMSetting]); const { carbonioWebUiAppLogo, carbonioWebUiDarkAppLogo } = useLoginConfigStore(); - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => { + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => { setDarkMediaEnabled(event.matches); }); const logoSrc = useMemo(() => { if (darkMediaEnabled) { return carbonioWebUiDarkAppLogo || carbonioWebUiAppLogo; - } else { - return carbonioWebUiAppLogo || carbonioWebUiDarkAppLogo; } + return carbonioWebUiAppLogo || carbonioWebUiDarkAppLogo; }, [carbonioWebUiDarkAppLogo, carbonioWebUiAppLogo, darkMediaEnabled]); const screenMode = useScreenMode(); diff --git a/src/shell/shell-view.tsx b/src/shell/shell-view.tsx index b54aa102..b68d365a 100644 --- a/src/shell/shell-view.tsx +++ b/src/shell/shell-view.tsx @@ -6,12 +6,12 @@ import { Responsive, Row } from '@zextras/carbonio-design-system'; import { PreviewManager } from '@zextras/carbonio-ui-preview'; -import {find, size} from 'lodash'; +import { find, size } from 'lodash'; import React, { FC, useContext, useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; import { AppRoute, DRPropValues } from '../../types'; import { ThemeCallbacksContext } from '../boot/theme-provider'; -import {IS_STANDALONE, SHELL_APP_ID} from '../constants'; +import { IS_STANDALONE, SHELL_APP_ID } from '../constants'; import { useCurrentRoute } from '../history/hooks'; import { goToLogin } from '../network/go-to-login'; import { useAccountStore, useUserSettings } from '../store/account'; @@ -21,7 +21,7 @@ import { BoardContainer } from './boards/board-container'; import ShellContextProvider from './shell-context-provider'; import ShellHeader from './shell-header'; import ShellNavigationBar from './shell-navigation-bar'; -import {useLoginConfigStore} from "../store/login"; +import { useLoginConfigStore } from '../store/login'; const Background = styled.div` background: ${({ theme }): string => theme.palette.gray6.regular}; @@ -40,23 +40,26 @@ function DarkReaderListener(): null { const settings = useUserSettings(); const { carbonioWebUiDarkMode } = useLoginConfigStore(); - const settingReceived = useMemo(() => { - return size(settings.prefs) > 0 || size(settings.attrs) > 0 || size(settings.props) > 0; - }, [settings]); + const settingReceived = useMemo( + () => size(settings.prefs) > 0 || size(settings.attrs) > 0 || size(settings.props) > 0, + [settings] + ); - const currentDRMSetting = useMemo( - () =>{ - const result = find(settings?.props ?? [], { - name: 'zappDarkreaderMode', - zimlet: SHELL_APP_ID - })?._content as DRPropValues; - if (result) { - return result; - } - return carbonioWebUiDarkMode !== undefined ? carbonioWebUiDarkMode ? 'enabled' : 'disabled' : 'auto' + const currentDRMSetting = useMemo(() => { + const result = find(settings?.props ?? [], { + name: 'zappDarkreaderMode', + zimlet: SHELL_APP_ID + })?._content as DRPropValues; + if (result) { + return result; + } - }, [settings, carbonioWebUiDarkMode] - ); + return ( + (carbonioWebUiDarkMode === undefined && 'auto') || + (carbonioWebUiDarkMode && 'enabled') || + 'disabled' + ); + }, [settings, carbonioWebUiDarkMode]); useEffect(() => { if (currentDRMSetting && settingReceived) { From 9722e7c257e3431f76255602516f6c763b097f2c Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Tue, 15 Nov 2022 12:20:11 +0100 Subject: [PATCH 04/13] feat: whitelabeling favicon and title --- src/index.template.html | 4 +--- src/network/login-config.ts | 9 +++++++++ types/loginConfig/index.d.ts | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/index.template.html b/src/index.template.html index 5db1d3f7..fe566832 100644 --- a/src/index.template.html +++ b/src/index.template.html @@ -8,9 +8,7 @@ - Carbonio Client - - + diff --git a/src/network/login-config.ts b/src/network/login-config.ts index c4c54d83..dea2f8db 100644 --- a/src/network/login-config.ts +++ b/src/network/login-config.ts @@ -12,6 +12,15 @@ export const loginConfig = (): Promise => .then((response) => response.json()) .then((data: LoginConfigStore) => { useLoginConfigStore.setState(data); + const favicon = document.getElementById('favicon'); + if (favicon && favicon instanceof HTMLLinkElement) { + favicon.href = data.carbonioWebUiFavicon + ? data.carbonioWebUiFavicon + : `${BASE_PATH}favicon.svg`; + } + if (data.carbonioWebUiTitle) { + document.title = data.carbonioWebUiTitle; + } }) .catch((reason) => { console.warn(reason); diff --git a/types/loginConfig/index.d.ts b/types/loginConfig/index.d.ts index a148b084..78bf7045 100644 --- a/types/loginConfig/index.d.ts +++ b/types/loginConfig/index.d.ts @@ -9,4 +9,5 @@ export type LoginConfigStore = { carbonioWebUiAppLogo?: string; carbonioWebUiDarkAppLogo?: string; carbonioWebUiTitle?: string; + carbonioWebUiFavicon?: string; }; From 794acb8078302cc3e9877d64c3e4b952fb6701d3 Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Tue, 15 Nov 2022 17:44:01 +0100 Subject: [PATCH 05/13] feat: whitelabeling --- src/shell/shell-header.tsx | 62 +++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/shell/shell-header.tsx b/src/shell/shell-header.tsx index 5ce1b12d..6fc746e0 100644 --- a/src/shell/shell-header.tsx +++ b/src/shell/shell-header.tsx @@ -11,11 +11,9 @@ import { Padding, Responsive, useScreenMode, - Catcher, - Button + Catcher } from '@zextras/carbonio-design-system'; -import { find } from 'lodash'; -import { isEnabled as isDarkReaderEnabled } from 'darkreader'; +import { find, size } from 'lodash'; import styled from 'styled-components'; import Logo from '../svg/carbonio.svg'; import { SearchBar } from '../search/search-bar'; @@ -34,34 +32,54 @@ const ShellHeader: FC<{ mobileNavIsOpen: boolean; onMobileMenuClick: () => void; }> = ({ mobileNavIsOpen, onMobileMenuClick, children }) => { - const [darkMediaEnabled, setDarkMediaEnabled] = useState(isDarkReaderEnabled()); - + const { carbonioWebUiAppLogo, carbonioWebUiDarkAppLogo, carbonioWebUiDarkMode } = + useLoginConfigStore(); const settings = useUserSettings(); - const currentDRMSetting = useMemo( - () => - find(settings.props, { name: 'zappDarkreaderMode', zimlet: SHELL_APP_ID }) - ?._content as DRPropValues, + const settingReceived = useMemo( + () => size(settings.prefs) > 0 || size(settings.attrs) > 0 || size(settings.props) > 0, [settings] ); + const [darkModeEnabled, setDarkModeEnabled] = useState(false); useEffect(() => { - if (currentDRMSetting !== 'auto') { - setDarkMediaEnabled(currentDRMSetting === 'enabled'); + if (settingReceived) { + const result = find(settings?.props ?? [], { + name: 'zappDarkreaderMode', + zimlet: SHELL_APP_ID + })?._content as DRPropValues; + if (result) { + setDarkModeEnabled( + (result === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) || + result === 'enabled' + ); + } else { + setDarkModeEnabled( + (carbonioWebUiDarkMode === undefined && + window.matchMedia('(prefers-color-scheme: dark)').matches) || + (carbonioWebUiDarkMode !== undefined && carbonioWebUiDarkMode) + ); + } } - }, [currentDRMSetting]); - - const { carbonioWebUiAppLogo, carbonioWebUiDarkAppLogo } = useLoginConfigStore(); + }, [settings, carbonioWebUiDarkMode, settingReceived]); - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => { - setDarkMediaEnabled(event.matches); - }); + useEffect(() => { + const setCallback = (event: MediaQueryListEvent): void => { + if (event.matches) { + setDarkModeEnabled(event.matches); + } + }; + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', setCallback); + return (): void => { + window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', setCallback); + }; + }, []); const logoSrc = useMemo(() => { - if (darkMediaEnabled) { + if (darkModeEnabled) { return carbonioWebUiDarkAppLogo || carbonioWebUiAppLogo; } return carbonioWebUiAppLogo || carbonioWebUiDarkAppLogo; - }, [carbonioWebUiDarkAppLogo, carbonioWebUiAppLogo, darkMediaEnabled]); + }, [carbonioWebUiDarkAppLogo, carbonioWebUiAppLogo, darkModeEnabled]); const screenMode = useScreenMode(); const searchEnabled = useAppStore((s) => s.views.search.length > 0); @@ -92,7 +110,9 @@ const ShellHeader: FC<{ - {logoSrc ? : } + {settingReceived && ( + <>{logoSrc ? : } + )} From 7db4516356c27130388a95afe4ed1ec786901136 Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Wed, 16 Nov 2022 10:35:27 +0100 Subject: [PATCH 06/13] feat: whitelabeling --- src/boot/theme-provider.tsx | 4 +++- src/shell/shell-view.tsx | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/boot/theme-provider.tsx b/src/boot/theme-provider.tsx index 8f1eebae..cbc8af5a 100644 --- a/src/boot/theme-provider.tsx +++ b/src/boot/theme-provider.tsx @@ -136,7 +136,9 @@ export const ThemeProvider: FC = ({ children }) => { icons: iconExtension() })); }, [zimbraPrefFontSize]); - const [darkReaderState, setDarkReaderState] = useState<'auto' | 'disabled' | 'enabled'>('auto'); + const [darkReaderState, setDarkReaderState] = useState<'auto' | 'disabled' | 'enabled'>( + 'disabled' + ); useEffect(() => { switch (darkReaderState) { case 'disabled': diff --git a/src/shell/shell-view.tsx b/src/shell/shell-view.tsx index b68d365a..8eccfc10 100644 --- a/src/shell/shell-view.tsx +++ b/src/shell/shell-view.tsx @@ -55,7 +55,7 @@ function DarkReaderListener(): null { } return ( - (carbonioWebUiDarkMode === undefined && 'auto') || + (carbonioWebUiDarkMode === undefined && 'disabled') || (carbonioWebUiDarkMode && 'enabled') || 'disabled' ); From 9b9cb87a86851305bfc6f08456b7a6b4ad8be6ce Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Wed, 16 Nov 2022 16:24:44 +0100 Subject: [PATCH 07/13] fix: fix listener --- src/shell/shell-header.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/shell/shell-header.tsx b/src/shell/shell-header.tsx index 6fc746e0..048a32dc 100644 --- a/src/shell/shell-header.tsx +++ b/src/shell/shell-header.tsx @@ -64,9 +64,7 @@ const ShellHeader: FC<{ useEffect(() => { const setCallback = (event: MediaQueryListEvent): void => { - if (event.matches) { - setDarkModeEnabled(event.matches); - } + setDarkModeEnabled(event.matches); }; window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', setCallback); return (): void => { From 7960d13a63b0903704720d4b69be7cbe6dc2640d Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Thu, 17 Nov 2022 10:00:27 +0100 Subject: [PATCH 08/13] refactor: apply review hints --- src/boot/theme-provider.tsx | 4 +-- src/constants/index.ts | 2 ++ src/network/login-config.ts | 5 ++-- src/shell/shell-header.tsx | 21 ++++++++------- src/shell/shell-view.tsx | 26 +++++++++--------- src/store/login/index.ts | 7 ----- src/store/login/normalization.ts | 45 -------------------------------- src/store/login/store.ts | 2 +- types/account/index.d.ts | 20 +++++++++++--- 9 files changed, 48 insertions(+), 84 deletions(-) delete mode 100644 src/store/login/index.ts delete mode 100644 src/store/login/normalization.ts diff --git a/src/boot/theme-provider.tsx b/src/boot/theme-provider.tsx index cbc8af5a..3642eb79 100644 --- a/src/boot/theme-provider.tsx +++ b/src/boot/theme-provider.tsx @@ -136,9 +136,7 @@ export const ThemeProvider: FC = ({ children }) => { icons: iconExtension() })); }, [zimbraPrefFontSize]); - const [darkReaderState, setDarkReaderState] = useState<'auto' | 'disabled' | 'enabled'>( - 'disabled' - ); + const [darkReaderState, setDarkReaderState] = useState('disabled'); useEffect(() => { switch (darkReaderState) { case 'disabled': diff --git a/src/constants/index.ts b/src/constants/index.ts index e163291d..5830dec7 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -103,3 +103,5 @@ export const FOLDER_VIEW = { task: 'task', chat: 'chat' }; + +export const LOGIN_V3_CONFIG_PATH = '/zx/login/v3/config'; diff --git a/src/network/login-config.ts b/src/network/login-config.ts index dea2f8db..976de408 100644 --- a/src/network/login-config.ts +++ b/src/network/login-config.ts @@ -5,10 +5,11 @@ */ import { LoginConfigStore } from '../../types/loginConfig'; -import { useLoginConfigStore } from '../store/login'; +import { useLoginConfigStore } from '../store/login/store'; +import { LOGIN_V3_CONFIG_PATH } from '../constants'; export const loginConfig = (): Promise => - fetch('/zx/login/v3/config') + fetch(LOGIN_V3_CONFIG_PATH) .then((response) => response.json()) .then((data: LoginConfigStore) => { useLoginConfigStore.setState(data); diff --git a/src/shell/shell-header.tsx b/src/shell/shell-header.tsx index 048a32dc..30f01ea9 100644 --- a/src/shell/shell-header.tsx +++ b/src/shell/shell-header.tsx @@ -19,10 +19,13 @@ import Logo from '../svg/carbonio.svg'; import { SearchBar } from '../search/search-bar'; import { CreationButton } from './creation-button'; import { useAppStore } from '../store/app'; -import { useLoginConfigStore } from '../store/login'; +import { useLoginConfigStore } from '../store/login/store'; import { useUserSettings } from '../store/account'; -import { SHELL_APP_ID } from '../constants'; -import { DRPropValues } from '../../types'; +import { + isZappDarkreaderModeZimletProp, + ZappDarkreaderModeZimletProp, + ZimletProp +} from '../../types'; const CustomImg = styled.img` height: 2rem; @@ -43,10 +46,10 @@ const ShellHeader: FC<{ useEffect(() => { if (settingReceived) { - const result = find(settings?.props ?? [], { - name: 'zappDarkreaderMode', - zimlet: SHELL_APP_ID - })?._content as DRPropValues; + const result = find( + settings.props, + (value): value is ZappDarkreaderModeZimletProp => isZappDarkreaderModeZimletProp(value) + )?._content; if (result) { setDarkModeEnabled( (result === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) || @@ -54,9 +57,7 @@ const ShellHeader: FC<{ ); } else { setDarkModeEnabled( - (carbonioWebUiDarkMode === undefined && - window.matchMedia('(prefers-color-scheme: dark)').matches) || - (carbonioWebUiDarkMode !== undefined && carbonioWebUiDarkMode) + carbonioWebUiDarkMode ?? window.matchMedia('(prefers-color-scheme: dark)').matches ); } } diff --git a/src/shell/shell-view.tsx b/src/shell/shell-view.tsx index 8eccfc10..2317733e 100644 --- a/src/shell/shell-view.tsx +++ b/src/shell/shell-view.tsx @@ -9,9 +9,14 @@ import { PreviewManager } from '@zextras/carbonio-ui-preview'; import { find, size } from 'lodash'; import React, { FC, useContext, useEffect, useMemo, useState } from 'react'; import styled from 'styled-components'; -import { AppRoute, DRPropValues } from '../../types'; +import { + AppRoute, + isZappDarkreaderModeZimletProp, + ZappDarkreaderModeZimletProp, + ZimletProp +} from '../../types'; import { ThemeCallbacksContext } from '../boot/theme-provider'; -import { IS_STANDALONE, SHELL_APP_ID } from '../constants'; +import { IS_STANDALONE } from '../constants'; import { useCurrentRoute } from '../history/hooks'; import { goToLogin } from '../network/go-to-login'; import { useAccountStore, useUserSettings } from '../store/account'; @@ -21,7 +26,7 @@ import { BoardContainer } from './boards/board-container'; import ShellContextProvider from './shell-context-provider'; import ShellHeader from './shell-header'; import ShellNavigationBar from './shell-navigation-bar'; -import { useLoginConfigStore } from '../store/login'; +import { useLoginConfigStore } from '../store/login/store'; const Background = styled.div` background: ${({ theme }): string => theme.palette.gray6.regular}; @@ -46,19 +51,14 @@ function DarkReaderListener(): null { ); const currentDRMSetting = useMemo(() => { - const result = find(settings?.props ?? [], { - name: 'zappDarkreaderMode', - zimlet: SHELL_APP_ID - })?._content as DRPropValues; + const result = find( + settings.props, + (value): value is ZappDarkreaderModeZimletProp => isZappDarkreaderModeZimletProp(value) + )?._content; if (result) { return result; } - - return ( - (carbonioWebUiDarkMode === undefined && 'disabled') || - (carbonioWebUiDarkMode && 'enabled') || - 'disabled' - ); + return (carbonioWebUiDarkMode && 'enabled') || 'disabled'; }, [settings, carbonioWebUiDarkMode]); useEffect(() => { diff --git a/src/store/login/index.ts b/src/store/login/index.ts deleted file mode 100644 index f3edd078..00000000 --- a/src/store/login/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Zextras - * - * SPDX-License-Identifier: AGPL-3.0-only - */ - -export * from './store'; diff --git a/src/store/login/normalization.ts b/src/store/login/normalization.ts deleted file mode 100644 index ce7d2438..00000000 --- a/src/store/login/normalization.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Zextras - * - * SPDX-License-Identifier: AGPL-3.0-only - */ - -import { GetInfoResponse, Account, AccountSettings } from '../../../types'; - -const normalizeSettings = ( - settings: Pick -): AccountSettings => ({ - attrs: settings.attrs._attrs, - prefs: settings.prefs._attrs, - props: settings.props.prop ?? [] -}); - -export const normalizeAccount = ({ - id, - name, - attrs, - prefs, - identities, - signatures, - props, - version, - rights -}: GetInfoResponse): { - account: Account; - settings: AccountSettings; - version: string; -} => { - const settings = normalizeSettings({ attrs, prefs, props }); - return { - account: { - id, - name, - displayName: attrs._attrs.displayName, - identities, - signatures, - rights - }, - settings, - version - }; -}; diff --git a/src/store/login/store.ts b/src/store/login/store.ts index 94581570..f9508ed1 100644 --- a/src/store/login/store.ts +++ b/src/store/login/store.ts @@ -7,7 +7,7 @@ import create from 'zustand'; import { LoginConfigStore } from '../../../types/loginConfig'; -export const useLoginConfigStore = create((set) => ({ +export const useLoginConfigStore = create(() => ({ carbonioWebUIDarkMode: undefined, carbonioWebUiAppLogo: undefined, carbonioWebUiDarkAppLogo: undefined, diff --git a/types/account/index.d.ts b/types/account/index.d.ts index 15bb3e1a..922daad8 100644 --- a/types/account/index.d.ts +++ b/types/account/index.d.ts @@ -3,13 +3,27 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { Tag } from '../tags'; -export type ZimletProp = { +import { SHELL_APP_ID } from '../../src/constants'; +import { DRPropValues } from '../misc'; + +export interface ZimletProp { name: string; zimlet: string; _content: string; -}; +} + +export interface ZappDarkreaderModeZimletProp extends ZimletProp { + name: 'zappDarkreaderMode'; + zimlet: SHELL_APP_ID; + _content: DRPropValues; +} + +export function isZappDarkreaderModeZimletProp( + prop: ZimletProp +): ZimletProp is ZappDarkreaderModeZimletProp { + return prop.name === 'zappDarkreaderMode' && prop.zimlet === SHELL_APP_ID; +} export type SoapFetch = ( api: string, From 0c4c472921008f3f1f104780b7a7a1d131024ca2 Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Thu, 17 Nov 2022 12:20:26 +0100 Subject: [PATCH 09/13] refactor: move darkmode setting and config in a custom hook --- src/boot/theme-provider.tsx | 8 ++-- src/custom-hooks/useDarkReaderResultValue.ts | 43 ++++++++++++++++++ .../general-settings/appearance-settings.tsx | 4 +- src/shell/shell-header.tsx | 44 ++++++------------- src/shell/shell-view.tsx | 30 +++---------- types/account/index.d.ts | 4 +- types/misc/index.d.ts | 2 +- 7 files changed, 71 insertions(+), 64 deletions(-) create mode 100644 src/custom-hooks/useDarkReaderResultValue.ts diff --git a/src/boot/theme-provider.tsx b/src/boot/theme-provider.tsx index 3642eb79..3a62a535 100644 --- a/src/boot/theme-provider.tsx +++ b/src/boot/theme-provider.tsx @@ -9,19 +9,19 @@ import { ThemeProvider as UIThemeProvider } from '@zextras/carbonio-design-syste import { enable, disable, auto, setFetchMethod } from 'darkreader'; import { reduce } from 'lodash'; import { useAccountStore } from '../store/account'; -import { DRPropValues, ThemeExtension, ThemeExtensionMap } from '../../types'; +import { DarkReaderPropValues, ThemeExtension, ThemeExtensionMap } from '../../types'; import { darkReaderDynamicThemeFixes } from '../constants'; setFetchMethod(window.fetch); export const ThemeCallbacksContext = createContext<{ addExtension: (newExtension: ThemeExtension, id: string) => void; - setDarkReaderState: (newState: DRPropValues) => void; + setDarkReaderState: (newState: DarkReaderPropValues) => void; }>({ // eslint-disable-next-line @typescript-eslint/no-empty-function addExtension: (newExtension: ThemeExtension, id: string) => {}, // eslint-disable-next-line @typescript-eslint/no-empty-function - setDarkReaderState: (newState: DRPropValues) => {} + setDarkReaderState: (newState: DarkReaderPropValues) => {} }); const themeSizes = ( @@ -136,7 +136,7 @@ export const ThemeProvider: FC = ({ children }) => { icons: iconExtension() })); }, [zimbraPrefFontSize]); - const [darkReaderState, setDarkReaderState] = useState('disabled'); + const [darkReaderState, setDarkReaderState] = useState('disabled'); useEffect(() => { switch (darkReaderState) { case 'disabled': diff --git a/src/custom-hooks/useDarkReaderResultValue.ts b/src/custom-hooks/useDarkReaderResultValue.ts new file mode 100644 index 00000000..17b0ed12 --- /dev/null +++ b/src/custom-hooks/useDarkReaderResultValue.ts @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2022 Zextras + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { useMemo } from 'react'; +import { find, size } from 'lodash'; +import { useUserSettings } from '../store/account'; +import { useLoginConfigStore } from '../store/login/store'; +import { + DarkReaderPropValues, + isZappDarkreaderModeZimletProp, + ZappDarkreaderModeZimletProp, + ZimletProp +} from '../../types'; + +// return the final calculated value between ZappDarkreaderModeZimletProp value and carbonioWebUiDarkMode config +export function useDarkReaderResultValue(): undefined | DarkReaderPropValues { + const settings = useUserSettings(); + const { carbonioWebUiDarkMode } = useLoginConfigStore(); + + const settingReceived = useMemo( + () => size(settings.prefs) > 0 || size(settings.attrs) > 0 || size(settings.props) > 0, + [settings] + ); + + const darkReaderResultValue = useMemo(() => { + if (settingReceived) { + const result = find( + settings.props, + (value): value is ZappDarkreaderModeZimletProp => isZappDarkreaderModeZimletProp(value) + )?._content; + if (result) { + return result; + } + return (carbonioWebUiDarkMode && 'enabled') || 'disabled'; + } + return undefined; + }, [settingReceived, settings, carbonioWebUiDarkMode]); + + return darkReaderResultValue; +} diff --git a/src/settings/components/general-settings/appearance-settings.tsx b/src/settings/components/general-settings/appearance-settings.tsx index a2678bc9..d0a0b265 100644 --- a/src/settings/components/general-settings/appearance-settings.tsx +++ b/src/settings/components/general-settings/appearance-settings.tsx @@ -7,7 +7,7 @@ import { FormSubSection, Select } from '@zextras/carbonio-design-system'; import { find } from 'lodash'; import React, { FC, useCallback, useContext, useMemo } from 'react'; -import { AccountSettings, DRPropValues } from '../../../../types'; +import { AccountSettings, DarkReaderPropValues } from '../../../../types'; import { ThemeCallbacksContext } from '../../../boot/theme-provider'; import { DR_VALUES, SHELL_APP_ID } from '../../../constants'; import { getT } from '../../../store/i18n'; @@ -21,7 +21,7 @@ const AppearanceSettings: FC<{ const currentDRMSetting = useMemo( () => find(settings.props, { name: 'zappDarkreaderMode', zimlet: SHELL_APP_ID }) - ?._content as DRPropValues, + ?._content as DarkReaderPropValues, [settings] ); const t = getT(); diff --git a/src/shell/shell-header.tsx b/src/shell/shell-header.tsx index 30f01ea9..6b77c45b 100644 --- a/src/shell/shell-header.tsx +++ b/src/shell/shell-header.tsx @@ -13,19 +13,13 @@ import { useScreenMode, Catcher } from '@zextras/carbonio-design-system'; -import { find, size } from 'lodash'; import styled from 'styled-components'; import Logo from '../svg/carbonio.svg'; import { SearchBar } from '../search/search-bar'; import { CreationButton } from './creation-button'; import { useAppStore } from '../store/app'; import { useLoginConfigStore } from '../store/login/store'; -import { useUserSettings } from '../store/account'; -import { - isZappDarkreaderModeZimletProp, - ZappDarkreaderModeZimletProp, - ZimletProp -} from '../../types'; +import { useDarkReaderResultValue } from '../custom-hooks/useDarkReaderResultValue'; const CustomImg = styled.img` height: 2rem; @@ -35,33 +29,21 @@ const ShellHeader: FC<{ mobileNavIsOpen: boolean; onMobileMenuClick: () => void; }> = ({ mobileNavIsOpen, onMobileMenuClick, children }) => { - const { carbonioWebUiAppLogo, carbonioWebUiDarkAppLogo, carbonioWebUiDarkMode } = - useLoginConfigStore(); - const settings = useUserSettings(); - const settingReceived = useMemo( - () => size(settings.prefs) > 0 || size(settings.attrs) > 0 || size(settings.props) > 0, - [settings] - ); + const { carbonioWebUiAppLogo, carbonioWebUiDarkAppLogo } = useLoginConfigStore(); + + const darkReaderResultValue = useDarkReaderResultValue(); + const [darkModeEnabled, setDarkModeEnabled] = useState(false); useEffect(() => { - if (settingReceived) { - const result = find( - settings.props, - (value): value is ZappDarkreaderModeZimletProp => isZappDarkreaderModeZimletProp(value) - )?._content; - if (result) { - setDarkModeEnabled( - (result === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) || - result === 'enabled' - ); - } else { - setDarkModeEnabled( - carbonioWebUiDarkMode ?? window.matchMedia('(prefers-color-scheme: dark)').matches - ); - } + if (darkReaderResultValue) { + setDarkModeEnabled( + (darkReaderResultValue === 'auto' && + window.matchMedia('(prefers-color-scheme: dark)').matches) || + darkReaderResultValue === 'enabled' + ); } - }, [settings, carbonioWebUiDarkMode, settingReceived]); + }, [darkReaderResultValue]); useEffect(() => { const setCallback = (event: MediaQueryListEvent): void => { @@ -109,7 +91,7 @@ const ShellHeader: FC<{ - {settingReceived && ( + {darkReaderResultValue && ( <>{logoSrc ? : } )} diff --git a/src/shell/shell-view.tsx b/src/shell/shell-view.tsx index 2317733e..a5347dd6 100644 --- a/src/shell/shell-view.tsx +++ b/src/shell/shell-view.tsx @@ -19,14 +19,14 @@ import { ThemeCallbacksContext } from '../boot/theme-provider'; import { IS_STANDALONE } from '../constants'; import { useCurrentRoute } from '../history/hooks'; import { goToLogin } from '../network/go-to-login'; -import { useAccountStore, useUserSettings } from '../store/account'; +import { useAccountStore } from '../store/account'; import { ShellUtilityBar, ShellUtilityPanel } from '../utility-bar'; import AppViewContainer from './app-view-container'; import { BoardContainer } from './boards/board-container'; import ShellContextProvider from './shell-context-provider'; import ShellHeader from './shell-header'; import ShellNavigationBar from './shell-navigation-bar'; -import { useLoginConfigStore } from '../store/login/store'; +import { useDarkReaderResultValue } from '../custom-hooks/useDarkReaderResultValue'; const Background = styled.div` background: ${({ theme }): string => theme.palette.gray6.regular}; @@ -42,30 +42,12 @@ const Background = styled.div` function DarkReaderListener(): null { const { setDarkReaderState } = useContext(ThemeCallbacksContext); - const settings = useUserSettings(); - const { carbonioWebUiDarkMode } = useLoginConfigStore(); - - const settingReceived = useMemo( - () => size(settings.prefs) > 0 || size(settings.attrs) > 0 || size(settings.props) > 0, - [settings] - ); - - const currentDRMSetting = useMemo(() => { - const result = find( - settings.props, - (value): value is ZappDarkreaderModeZimletProp => isZappDarkreaderModeZimletProp(value) - )?._content; - if (result) { - return result; - } - return (carbonioWebUiDarkMode && 'enabled') || 'disabled'; - }, [settings, carbonioWebUiDarkMode]); - + const darkReaderResultValue = useDarkReaderResultValue(); useEffect(() => { - if (currentDRMSetting && settingReceived) { - setDarkReaderState(currentDRMSetting); + if (darkReaderResultValue) { + setDarkReaderState(darkReaderResultValue); } - }, [currentDRMSetting, setDarkReaderState, settingReceived]); + }, [darkReaderResultValue, setDarkReaderState]); return null; } diff --git a/types/account/index.d.ts b/types/account/index.d.ts index 922daad8..2a29ddcc 100644 --- a/types/account/index.d.ts +++ b/types/account/index.d.ts @@ -5,7 +5,7 @@ */ import { SHELL_APP_ID } from '../../src/constants'; -import { DRPropValues } from '../misc'; +import { DarkReaderPropValues } from '../misc'; export interface ZimletProp { name: string; @@ -16,7 +16,7 @@ export interface ZimletProp { export interface ZappDarkreaderModeZimletProp extends ZimletProp { name: 'zappDarkreaderMode'; zimlet: SHELL_APP_ID; - _content: DRPropValues; + _content: DarkReaderPropValues; } export function isZappDarkreaderModeZimletProp( diff --git a/types/misc/index.d.ts b/types/misc/index.d.ts index 70c9b974..a4147eaf 100644 --- a/types/misc/index.d.ts +++ b/types/misc/index.d.ts @@ -18,7 +18,7 @@ export enum JSNS { SYNC = 'urn:zimbraSync' } -export type DRPropValues = 'auto' | 'enabled' | 'disabled'; +export type DarkReaderPropValues = 'auto' | 'enabled' | 'disabled'; // eslint-disable-next-line @typescript-eslint/ban-types export type PackageDependentFunction = (app: string) => Function; From 8ed3e8dc7b9b96282c4d56eccee909f6bd725e94 Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Thu, 17 Nov 2022 12:42:26 +0100 Subject: [PATCH 10/13] refactor: move error prone string in a getter --- src/custom-hooks/useDarkReaderResultValue.ts | 6 ++---- src/shell/shell-header.tsx | 8 ++++---- src/utils/utils.ts | 8 ++++++++ 3 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 src/utils/utils.ts diff --git a/src/custom-hooks/useDarkReaderResultValue.ts b/src/custom-hooks/useDarkReaderResultValue.ts index 17b0ed12..d78b6b03 100644 --- a/src/custom-hooks/useDarkReaderResultValue.ts +++ b/src/custom-hooks/useDarkReaderResultValue.ts @@ -31,10 +31,8 @@ export function useDarkReaderResultValue(): undefined | DarkReaderPropValues { settings.props, (value): value is ZappDarkreaderModeZimletProp => isZappDarkreaderModeZimletProp(value) )?._content; - if (result) { - return result; - } - return (carbonioWebUiDarkMode && 'enabled') || 'disabled'; + + return result || (carbonioWebUiDarkMode && 'enabled') || 'disabled'; } return undefined; }, [settingReceived, settings, carbonioWebUiDarkMode]); diff --git a/src/shell/shell-header.tsx b/src/shell/shell-header.tsx index 6b77c45b..c8ab8892 100644 --- a/src/shell/shell-header.tsx +++ b/src/shell/shell-header.tsx @@ -20,6 +20,7 @@ import { CreationButton } from './creation-button'; import { useAppStore } from '../store/app'; import { useLoginConfigStore } from '../store/login/store'; import { useDarkReaderResultValue } from '../custom-hooks/useDarkReaderResultValue'; +import { getPrefersColorSchemeDarkMedia } from '../utils/utils'; const CustomImg = styled.img` height: 2rem; @@ -38,8 +39,7 @@ const ShellHeader: FC<{ useEffect(() => { if (darkReaderResultValue) { setDarkModeEnabled( - (darkReaderResultValue === 'auto' && - window.matchMedia('(prefers-color-scheme: dark)').matches) || + (darkReaderResultValue === 'auto' && getPrefersColorSchemeDarkMedia().matches) || darkReaderResultValue === 'enabled' ); } @@ -49,9 +49,9 @@ const ShellHeader: FC<{ const setCallback = (event: MediaQueryListEvent): void => { setDarkModeEnabled(event.matches); }; - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', setCallback); + getPrefersColorSchemeDarkMedia().addEventListener('change', setCallback); return (): void => { - window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', setCallback); + getPrefersColorSchemeDarkMedia().removeEventListener('change', setCallback); }; }, []); diff --git a/src/utils/utils.ts b/src/utils/utils.ts new file mode 100644 index 00000000..e185c725 --- /dev/null +++ b/src/utils/utils.ts @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Zextras + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export const getPrefersColorSchemeDarkMedia = (): MediaQueryList => + window.matchMedia('(prefers-color-scheme: dark)'); From c96d0b14a83c1117a927b88abb80300141e0a603 Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Thu, 17 Nov 2022 14:14:23 +0100 Subject: [PATCH 11/13] refactor: remove cast --- .../general-settings/appearance-settings.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/settings/components/general-settings/appearance-settings.tsx b/src/settings/components/general-settings/appearance-settings.tsx index d0a0b265..058044cd 100644 --- a/src/settings/components/general-settings/appearance-settings.tsx +++ b/src/settings/components/general-settings/appearance-settings.tsx @@ -7,7 +7,12 @@ import { FormSubSection, Select } from '@zextras/carbonio-design-system'; import { find } from 'lodash'; import React, { FC, useCallback, useContext, useMemo } from 'react'; -import { AccountSettings, DarkReaderPropValues } from '../../../../types'; +import { + AccountSettings, + isZappDarkreaderModeZimletProp, + ZappDarkreaderModeZimletProp, + ZimletProp +} from '../../../../types'; import { ThemeCallbacksContext } from '../../../boot/theme-provider'; import { DR_VALUES, SHELL_APP_ID } from '../../../constants'; import { getT } from '../../../store/i18n'; @@ -20,8 +25,10 @@ const AppearanceSettings: FC<{ const { setDarkReaderState } = useContext(ThemeCallbacksContext); const currentDRMSetting = useMemo( () => - find(settings.props, { name: 'zappDarkreaderMode', zimlet: SHELL_APP_ID }) - ?._content as DarkReaderPropValues, + find( + settings.props, + (value): value is ZappDarkreaderModeZimletProp => isZappDarkreaderModeZimletProp(value) + )?._content, [settings] ); const t = getT(); From 078c94997e1464ab37490be5c8120071eeb0fa5a Mon Sep 17 00:00:00 2001 From: Cataldo Mazzilli Date: Fri, 18 Nov 2022 10:25:50 +0100 Subject: [PATCH 12/13] feat: use carbonioWebUiDarkMode as appearance setting fallback value refs: IRIS-3446 --- .../general-settings/appearance-settings.tsx | 29 ++++++------------- src/settings/general-settings.tsx | 2 +- 2 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/settings/components/general-settings/appearance-settings.tsx b/src/settings/components/general-settings/appearance-settings.tsx index 058044cd..5bf2de27 100644 --- a/src/settings/components/general-settings/appearance-settings.tsx +++ b/src/settings/components/general-settings/appearance-settings.tsx @@ -7,30 +7,19 @@ import { FormSubSection, Select } from '@zextras/carbonio-design-system'; import { find } from 'lodash'; import React, { FC, useCallback, useContext, useMemo } from 'react'; -import { - AccountSettings, - isZappDarkreaderModeZimletProp, - ZappDarkreaderModeZimletProp, - ZimletProp -} from '../../../../types'; import { ThemeCallbacksContext } from '../../../boot/theme-provider'; import { DR_VALUES, SHELL_APP_ID } from '../../../constants'; import { getT } from '../../../store/i18n'; import { themeSubSection } from '../../general-settings-sub-sections'; +import { useDarkReaderResultValue } from '../../../custom-hooks/useDarkReaderResultValue'; const AppearanceSettings: FC<{ - settings: AccountSettings; addMod: (type: 'prefs' | 'props', key: string, value: { value: any; app: string }) => void; -}> = ({ settings, addMod }) => { +}> = ({ addMod }) => { const { setDarkReaderState } = useContext(ThemeCallbacksContext); - const currentDRMSetting = useMemo( - () => - find( - settings.props, - (value): value is ZappDarkreaderModeZimletProp => isZappDarkreaderModeZimletProp(value) - )?._content, - [settings] - ); + + const darkReaderResultValue = useDarkReaderResultValue(); + const t = getT(); const items = useMemo( () => [ @@ -50,17 +39,17 @@ const AppearanceSettings: FC<{ [t] ); const defaultSelection = useMemo( - () => find(items, { value: currentDRMSetting }), - [currentDRMSetting, items] + () => find(items, { value: darkReaderResultValue }), + [darkReaderResultValue, items] ); const onSelectionChange = useCallback( (v) => { - if (DR_VALUES.includes(v) && v !== currentDRMSetting) { + if (DR_VALUES.includes(v) && v !== darkReaderResultValue) { setDarkReaderState(v); addMod('props', 'zappDarkreaderMode', { app: SHELL_APP_ID, value: v }); } }, - [addMod, currentDRMSetting, setDarkReaderState] + [addMod, darkReaderResultValue, setDarkReaderState] ); const subSection = useMemo(() => themeSubSection(t), [t]); return ( diff --git a/src/settings/general-settings.tsx b/src/settings/general-settings.tsx index 5aad7826..a0b4c402 100644 --- a/src/settings/general-settings.tsx +++ b/src/settings/general-settings.tsx @@ -78,7 +78,7 @@ const GeneralSettings: FC = () => { padding={{ all: 'medium' }} style={{ overflow: 'auto' }} > - + Date: Fri, 18 Nov 2022 13:15:03 +0100 Subject: [PATCH 13/13] feat(whitelabel): use configs to set logo, title, favicon and dark mode default * feat: whitelabeling favicon and title * refactor: move darkmode setting and config in a custom hook * refactor: move error prone string in a getter * feat: use carbonioWebUiDarkMode as appearance setting fallback value refs: IRIS-3446, IRIS-3471, IRIS-3472