Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iris 3446 white label #160

Merged
merged 14 commits into from
Nov 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/boot/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
import { getInfo } from '../network/get-info';
import { useAppStore } from '../store/app';
import { loadApps } from './app/load-apps';
import { loginConfig } from '../network/login-config';

export const init = (): void => {
getInfo().finally(() => {
Promise.all([loginConfig(), getInfo()]).finally(() => {
loadApps(Object.values(useAppStore.getState().apps));
});
};
8 changes: 4 additions & 4 deletions src/boot/theme-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = (
Expand Down Expand Up @@ -136,7 +136,7 @@ export const ThemeProvider: FC = ({ children }) => {
icons: iconExtension()
}));
}, [zimbraPrefFontSize]);
const [darkReaderState, setDarkReaderState] = useState<'auto' | 'disabled' | 'enabled'>('auto');
const [darkReaderState, setDarkReaderState] = useState<DarkReaderPropValues>('disabled');
useEffect(() => {
switch (darkReaderState) {
case 'disabled':
Expand Down
2 changes: 2 additions & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,5 @@ export const FOLDER_VIEW = {
task: 'task',
chat: 'chat'
};

export const LOGIN_V3_CONFIG_PATH = '/zx/login/v3/config';
41 changes: 41 additions & 0 deletions src/custom-hooks/useDarkReaderResultValue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: 2022 Zextras <https://www.zextras.com>
*
* 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<ZimletProp, ZappDarkreaderModeZimletProp>(
settings.props,
(value): value is ZappDarkreaderModeZimletProp => isZappDarkreaderModeZimletProp(value)
)?._content;

return result || (carbonioWebUiDarkMode && 'enabled') || 'disabled';
}
return undefined;
}, [settingReceived, settings, carbonioWebUiDarkMode]);

return darkReaderResultValue;
}
4 changes: 1 addition & 3 deletions src/index.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
<html lang="">

<head>
<title>Carbonio Client</title>
<link rel="icon" type="image/svg+xml" href="<%- htmlWebpackPlugin.options.BASE_PATH %>favicon.svg">
<link rel="alternate icon" href="<%- htmlWebpackPlugin.options.BASE_PATH %>favicon.png">
<link rel="icon" id="favicon">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="minimum-scale=1.0, initial-scale=1.0, width=device-width, shrink-to-fit=no">
Expand Down
28 changes: 28 additions & 0 deletions src/network/login-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2021 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import { LoginConfigStore } from '../../types/loginConfig';
import { useLoginConfigStore } from '../store/login/store';
import { LOGIN_V3_CONFIG_PATH } from '../constants';

export const loginConfig = (): Promise<void> =>
fetch(LOGIN_V3_CONFIG_PATH)
.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);
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,19 @@
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 { 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, { name: 'zappDarkreaderMode', zimlet: SHELL_APP_ID })
?._content as DRPropValues,
[settings]
);

const darkReaderResultValue = useDarkReaderResultValue();

const t = getT();
const items = useMemo(
() => [
Expand All @@ -43,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 (
Expand Down
2 changes: 1 addition & 1 deletion src/settings/general-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const GeneralSettings: FC = () => {
padding={{ all: 'medium' }}
style={{ overflow: 'auto' }}
>
<AppearanceSettings settings={settings} addMod={addMod} />
<AppearanceSettings addMod={addMod} />
<LanguageAndTimeZoneSettings
settings={settings}
addMod={addMod}
Expand Down
50 changes: 45 additions & 5 deletions src/shell/shell-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,64 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/

import React, { FC, useState } from 'react';
import React, { FC, useEffect, useMemo, useState } from 'react';
import {
Container,
IconButton,
Padding,
Responsive,
useScreenMode,
Catcher,
Button
Catcher
} from '@zextras/carbonio-design-system';
import { times } 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 { useDarkReaderResultValue } from '../custom-hooks/useDarkReaderResultValue';
import { getPrefersColorSchemeDarkMedia } from '../utils/utils';

const CustomImg = styled.img`
height: 2rem;
`;

const ShellHeader: FC<{
mobileNavIsOpen: boolean;
onMobileMenuClick: () => void;
}> = ({ mobileNavIsOpen, onMobileMenuClick, children }) => {
const { carbonioWebUiAppLogo, carbonioWebUiDarkAppLogo } = useLoginConfigStore();

const darkReaderResultValue = useDarkReaderResultValue();

const [darkModeEnabled, setDarkModeEnabled] = useState(false);

useEffect(() => {
if (darkReaderResultValue) {
setDarkModeEnabled(
(darkReaderResultValue === 'auto' && getPrefersColorSchemeDarkMedia().matches) ||
darkReaderResultValue === 'enabled'
);
}
}, [darkReaderResultValue]);

useEffect(() => {
const setCallback = (event: MediaQueryListEvent): void => {
setDarkModeEnabled(event.matches);
};
getPrefersColorSchemeDarkMedia().addEventListener('change', setCallback);
return (): void => {
getPrefersColorSchemeDarkMedia().removeEventListener('change', setCallback);
};
}, []);

const logoSrc = useMemo(() => {
if (darkModeEnabled) {
return carbonioWebUiDarkAppLogo || carbonioWebUiAppLogo;
}
return carbonioWebUiAppLogo || carbonioWebUiDarkAppLogo;
}, [carbonioWebUiDarkAppLogo, carbonioWebUiAppLogo, darkModeEnabled]);

const screenMode = useScreenMode();
const searchEnabled = useAppStore((s) => s.views.search.length > 0);
return (
Expand Down Expand Up @@ -53,7 +91,9 @@ const ShellHeader: FC<{
</Padding>
</Responsive>
<Container width="15.625rem" height="2rem" crossAlignment="flex-start">
<Logo height="2rem" />
{darkReaderResultValue && (
<>{logoSrc ? <CustomImg src={logoSrc} /> : <Logo height="2rem" />}</>
)}
</Container>
<Padding horizontal="large">
<CreationButton />
Expand Down
31 changes: 15 additions & 16 deletions src/shell/shell-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,27 @@

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 {
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';
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 { useDarkReaderResultValue } from '../custom-hooks/useDarkReaderResultValue';

const Background = styled.div`
background: ${({ theme }): string => theme.palette.gray6.regular};
Expand All @@ -36,19 +42,12 @@ const Background = styled.div`

function DarkReaderListener(): null {
const { setDarkReaderState } = useContext(ThemeCallbacksContext);
const settings = useUserSettings();
const currentDRMSetting = useMemo(
() =>
find(settings?.props ?? [], {
name: 'zappDarkreaderMode',
zimlet: SHELL_APP_ID
})?._content as DRPropValues,
[settings]
);

const darkReaderResultValue = useDarkReaderResultValue();
useEffect(() => {
setDarkReaderState(currentDRMSetting);
}, [currentDRMSetting, setDarkReaderState]);
if (darkReaderResultValue) {
setDarkReaderState(darkReaderResultValue);
}
}, [darkReaderResultValue, setDarkReaderState]);
return null;
}

Expand Down
15 changes: 15 additions & 0 deletions src/store/login/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* SPDX-FileCopyrightText: 2021 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import create from 'zustand';
import { LoginConfigStore } from '../../../types/loginConfig';

export const useLoginConfigStore = create<LoginConfigStore>(() => ({
carbonioWebUIDarkMode: undefined,
carbonioWebUiAppLogo: undefined,
carbonioWebUiDarkAppLogo: undefined,
carbonioWebUiTitle: undefined
}));
8 changes: 8 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2022 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

export const getPrefersColorSchemeDarkMedia = (): MediaQueryList =>
window.matchMedia('(prefers-color-scheme: dark)');
20 changes: 17 additions & 3 deletions types/account/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 { DarkReaderPropValues } from '../misc';

export interface ZimletProp {
name: string;
zimlet: string;
_content: string;
};
}

export interface ZappDarkreaderModeZimletProp extends ZimletProp {
name: 'zappDarkreaderMode';
zimlet: SHELL_APP_ID;
_content: DarkReaderPropValues;
}

export function isZappDarkreaderModeZimletProp(
prop: ZimletProp
): ZimletProp is ZappDarkreaderModeZimletProp {
return prop.name === 'zappDarkreaderMode' && prop.zimlet === SHELL_APP_ID;
}

export type SoapFetch = <Request, Response>(
api: string,
Expand Down
13 changes: 13 additions & 0 deletions types/loginConfig/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* SPDX-FileCopyrightText: 2021 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

export type LoginConfigStore = {
carbonioWebUiDarkMode?: boolean;
carbonioWebUiAppLogo?: string;
carbonioWebUiDarkAppLogo?: string;
carbonioWebUiTitle?: string;
carbonioWebUiFavicon?: string;
};
Loading