Doceditor: Fixed theme
This commit is contained in:
parent
3eb4671598
commit
098a540aaa
@ -24,15 +24,18 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
import { redirect } from "next/navigation";
|
||||
import { headers } from "next/headers";
|
||||
import { headers, cookies } from "next/headers";
|
||||
|
||||
import { ThemeKeys } from "@docspace/shared/enums";
|
||||
import { getBaseUrl } from "@docspace/shared/utils/next-ssr-helper";
|
||||
import { SYSTEM_THEME_KEY } from "@docspace/shared/constants";
|
||||
|
||||
import Providers from "@/providers";
|
||||
import Scripts from "@/components/Scripts";
|
||||
import StyledComponentsRegistry from "@/utils/registry";
|
||||
import { getColorTheme, getSettings, getUser } from "@/utils/actions";
|
||||
|
||||
import "@/styles/globals.scss";
|
||||
import Providers from "@/providers";
|
||||
import { getSettings, getUser } from "@/utils/actions";
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
@ -41,13 +44,23 @@ export default async function RootLayout({
|
||||
}) {
|
||||
const hdrs = headers();
|
||||
|
||||
const cookieStore = cookies();
|
||||
|
||||
const systemTheme = cookieStore.get(SYSTEM_THEME_KEY)?.value as
|
||||
| ThemeKeys
|
||||
| undefined;
|
||||
|
||||
if (hdrs.get("x-health-check") || hdrs.get("referer")?.includes("/health")) {
|
||||
console.log("is health check");
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const startDate = new Date();
|
||||
const [user, settings] = await Promise.all([getUser(), getSettings()]);
|
||||
const [user, settings, colorTheme] = await Promise.all([
|
||||
getUser(),
|
||||
getSettings(),
|
||||
getColorTheme(),
|
||||
]);
|
||||
const timer = new Date().getTime() - startDate.getTime();
|
||||
|
||||
if (settings === "access-restricted") redirect(`${getBaseUrl()}/${settings}`);
|
||||
@ -70,7 +83,7 @@ export default async function RootLayout({
|
||||
<body>
|
||||
<StyledComponentsRegistry>
|
||||
<Providers
|
||||
contextData={{ user, settings }}
|
||||
contextData={{ user, settings, systemTheme, colorTheme }}
|
||||
api_host={api_host}
|
||||
timer={timer}
|
||||
>
|
||||
|
@ -26,34 +26,59 @@
|
||||
|
||||
import React from "react";
|
||||
import { i18n } from "i18next";
|
||||
import { match, P } from "ts-pattern";
|
||||
|
||||
import { Base, Dark, TColorScheme, TTheme } from "@docspace/shared/themes";
|
||||
import { getSystemTheme } from "@docspace/shared/utils";
|
||||
import { setCookie } from "@docspace/shared/utils/cookie";
|
||||
import { ThemeKeys } from "@docspace/shared/enums";
|
||||
import { getAppearanceTheme } from "@docspace/shared/api/settings";
|
||||
import { TUser } from "@docspace/shared/api/people/types";
|
||||
import { getFontFamilyDependingOnLanguage } from "@docspace/shared/utils/rtlUtils";
|
||||
import { SYSTEM_THEME_KEY } from "@docspace/shared/constants";
|
||||
|
||||
const SYSTEM_THEME = getSystemTheme();
|
||||
import type { TUser } from "@docspace/shared/api/people/types";
|
||||
import type { TGetColorTheme } from "@docspace/shared/api/settings/types";
|
||||
|
||||
type MatchType = [ThemeKeys | undefined, ThemeKeys | undefined];
|
||||
|
||||
export interface UseThemeProps {
|
||||
user?: TUser;
|
||||
i18n?: i18n;
|
||||
systemTheme?: ThemeKeys;
|
||||
colorTheme?: TGetColorTheme;
|
||||
}
|
||||
|
||||
const useTheme = ({ user, i18n }: UseThemeProps) => {
|
||||
const useTheme = ({ user, i18n, systemTheme, colorTheme }: UseThemeProps) => {
|
||||
const [currentColorTheme, setCurrentColorTheme] =
|
||||
React.useState<TColorScheme>({} as TColorScheme);
|
||||
React.useState<TColorScheme>(() => {
|
||||
console.log("currentColorTheme");
|
||||
|
||||
if (!colorTheme) return {} as TColorScheme;
|
||||
|
||||
return (
|
||||
colorTheme.themes.find((theme) => theme.id === colorTheme.selected) ??
|
||||
({} as TColorScheme)
|
||||
);
|
||||
});
|
||||
|
||||
const [theme, setTheme] = React.useState<TTheme>(() => {
|
||||
if (user?.theme === ThemeKeys.DarkStr)
|
||||
const interfaceDirection = i18n?.dir ? i18n.dir() : "ltr";
|
||||
|
||||
const newTheme = match<MatchType>([user?.theme, systemTheme])
|
||||
.returnType<TTheme>()
|
||||
.with([ThemeKeys.DarkStr, P._], () => Dark)
|
||||
.with([ThemeKeys.BaseStr, P._], () => Base)
|
||||
.with([ThemeKeys.SystemStr, ThemeKeys.BaseStr], () => Base)
|
||||
.with([ThemeKeys.SystemStr, ThemeKeys.DarkStr], () => Dark)
|
||||
.with([undefined, ThemeKeys.DarkStr], () => Dark)
|
||||
.with([undefined, ThemeKeys.BaseStr], () => Base)
|
||||
.otherwise(() => Base);
|
||||
|
||||
return {
|
||||
...Dark,
|
||||
currentColorScheme: currentColorTheme,
|
||||
};
|
||||
return {
|
||||
...Base,
|
||||
...newTheme,
|
||||
currentColorScheme: currentColorTheme,
|
||||
interfaceDirection,
|
||||
fontFamily: getFontFamilyDependingOnLanguage(i18n?.language ?? "en"),
|
||||
};
|
||||
});
|
||||
|
||||
@ -73,28 +98,26 @@ const useTheme = ({ user, i18n }: UseThemeProps) => {
|
||||
}, []);
|
||||
|
||||
const getUserTheme = React.useCallback(() => {
|
||||
if (!user?.theme) return;
|
||||
let theme = user.theme;
|
||||
const SYSTEM_THEME = getSystemTheme();
|
||||
|
||||
let theme = user?.theme ?? SYSTEM_THEME;
|
||||
const interfaceDirection = i18n?.dir ? i18n.dir() : "ltr";
|
||||
|
||||
if (user.theme === ThemeKeys.SystemStr) theme = SYSTEM_THEME;
|
||||
if (user?.theme === ThemeKeys.SystemStr) theme = SYSTEM_THEME;
|
||||
|
||||
if (theme === ThemeKeys.BaseStr) {
|
||||
setTheme({
|
||||
...Base,
|
||||
currentColorScheme: currentColorTheme,
|
||||
interfaceDirection,
|
||||
fontFamily: getFontFamilyDependingOnLanguage(i18n?.language),
|
||||
});
|
||||
const fontFamily = getFontFamilyDependingOnLanguage(i18n?.language ?? "en");
|
||||
|
||||
return;
|
||||
}
|
||||
const isBaseTheme = theme === ThemeKeys.BaseStr;
|
||||
const themeCookie = isBaseTheme ? ThemeKeys.BaseStr : ThemeKeys.DarkStr;
|
||||
|
||||
setTheme({
|
||||
...Dark,
|
||||
...(isBaseTheme ? Base : Dark),
|
||||
currentColorScheme: currentColorTheme,
|
||||
interfaceDirection,
|
||||
fontFamily,
|
||||
});
|
||||
|
||||
setCookie(SYSTEM_THEME_KEY, themeCookie);
|
||||
}, [user?.theme, i18n, currentColorTheme]);
|
||||
|
||||
React.useEffect(() => {
|
||||
@ -105,6 +128,16 @@ const useTheme = ({ user, i18n }: UseThemeProps) => {
|
||||
getUserTheme();
|
||||
}, [currentColorTheme, getUserTheme]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
|
||||
mediaQuery.addEventListener("change", getUserTheme);
|
||||
|
||||
return () => {
|
||||
mediaQuery.removeEventListener("change", getUserTheme);
|
||||
};
|
||||
}, [getUserTheme]);
|
||||
|
||||
return { theme, currentColorTheme };
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,11 @@ import React from "react";
|
||||
|
||||
import { ThemeProvider as ComponentThemeProvider } from "@docspace/shared/components/theme-provider";
|
||||
import { TUser } from "@docspace/shared/api/people/types";
|
||||
import { TSettings } from "@docspace/shared/api/settings/types";
|
||||
import type {
|
||||
TGetColorTheme,
|
||||
TSettings,
|
||||
} from "@docspace/shared/api/settings/types";
|
||||
import type { ThemeKeys } from "@docspace/shared/enums";
|
||||
|
||||
import useTheme from "@/hooks/useTheme";
|
||||
import useI18N from "@/hooks/useI18N";
|
||||
@ -39,12 +43,25 @@ type TThemeProvider = {
|
||||
children: React.ReactNode;
|
||||
settings: TSettings | undefined;
|
||||
user: TUser | undefined;
|
||||
systemTheme: ThemeKeys | undefined;
|
||||
colorTheme: TGetColorTheme | undefined;
|
||||
};
|
||||
|
||||
const ThemeProvider = ({ children, user, settings }: TThemeProvider) => {
|
||||
const ThemeProvider = ({
|
||||
children,
|
||||
user,
|
||||
settings,
|
||||
systemTheme,
|
||||
colorTheme,
|
||||
}: TThemeProvider) => {
|
||||
const { i18n } = useI18N({ settings, user });
|
||||
|
||||
const { theme, currentColorTheme } = useTheme({ user, i18n });
|
||||
const { theme, currentColorTheme } = useTheme({
|
||||
user,
|
||||
i18n,
|
||||
systemTheme,
|
||||
colorTheme,
|
||||
});
|
||||
|
||||
return (
|
||||
<ComponentThemeProvider
|
||||
|
@ -24,9 +24,13 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import { TUser } from "@docspace/shared/api/people/types";
|
||||
import { TSettings } from "@docspace/shared/api/settings/types";
|
||||
import { Toast } from "@docspace/shared/components/toast/Toast";
|
||||
import type { TUser } from "@docspace/shared/api/people/types";
|
||||
import type {
|
||||
TGetColorTheme,
|
||||
TSettings,
|
||||
} from "@docspace/shared/api/settings/types";
|
||||
import type { ThemeKeys } from "@docspace/shared/enums";
|
||||
|
||||
import ThemeProvider from "./ThemeProvider";
|
||||
import TranslationProvider from "./TranslationProvider";
|
||||
@ -35,6 +39,8 @@ import ErrorProvider from "./ErrorProvider";
|
||||
export type TContextData = {
|
||||
user: TUser | undefined;
|
||||
settings: TSettings | undefined;
|
||||
systemTheme: ThemeKeys | undefined;
|
||||
colorTheme: TGetColorTheme | undefined;
|
||||
};
|
||||
|
||||
export type TProviders = {
|
||||
|
@ -36,7 +36,10 @@ import type {
|
||||
TFile,
|
||||
} from "@docspace/shared/api/files/types";
|
||||
import { TUser } from "@docspace/shared/api/people/types";
|
||||
import { TSettings } from "@docspace/shared/api/settings/types";
|
||||
import type {
|
||||
TGetColorTheme,
|
||||
TSettings,
|
||||
} from "@docspace/shared/api/settings/types";
|
||||
|
||||
import type {
|
||||
ActionType,
|
||||
@ -500,3 +503,19 @@ export async function getEditorUrl(
|
||||
|
||||
return editorUrl.response as TDocServiceLocation;
|
||||
}
|
||||
|
||||
export async function getColorTheme() {
|
||||
const [getSettings] = createRequest(
|
||||
[`/settings/colortheme`],
|
||||
[["", ""]],
|
||||
"GET",
|
||||
);
|
||||
|
||||
const res = await fetch(getSettings);
|
||||
|
||||
if (!res.ok) return;
|
||||
|
||||
const colorTheme = await res.json();
|
||||
|
||||
return colorTheme.response as TGetColorTheme;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user