1
0
mirror of https://github.com/stonith404/pingvin-share.git synced 2024-07-04 00:10:17 +02:00

feat: manually switch color scheme

This commit is contained in:
Elias Schneider 2022-12-24 23:58:31 +01:00
parent cabaee588b
commit ef21bac59b
4 changed files with 140 additions and 28 deletions

View File

@ -0,0 +1,67 @@
import {
Box,
Center,
ColorScheme,
SegmentedControl,
Stack,
useMantineColorScheme,
} from "@mantine/core";
import { useColorScheme } from "@mantine/hooks";
import { useState } from "react";
import { TbDeviceLaptop, TbMoon, TbSun } from "react-icons/tb";
import usePreferences from "../../hooks/usePreferences";
const ThemeSwitcher = () => {
const preferences = usePreferences();
const [colorScheme, setColorScheme] = useState(
preferences.get("colorScheme")
);
const { toggleColorScheme } = useMantineColorScheme();
const systemColorScheme = useColorScheme();
return (
<Stack>
<SegmentedControl
value={colorScheme}
onChange={(value) => {
preferences.set("colorScheme", value);
setColorScheme(value);
toggleColorScheme(
value == "system" ? systemColorScheme : (value as ColorScheme)
);
}}
data={[
{
label: (
<Center>
<TbMoon size={16} />
<Box ml={10}>Dark</Box>
</Center>
),
value: "dark",
},
{
label: (
<Center>
<TbSun size={16} />
<Box ml={10}>Light</Box>
</Center>
),
value: "light",
},
{
label: (
<Center>
<TbDeviceLaptop size={16} />
<Box ml={10}>System</Box>
</Center>
),
value: "system",
},
]}
/>
</Stack>
);
};
export default ThemeSwitcher;

View File

@ -0,0 +1,30 @@
const defaultPreferences = [
{
key: "colorScheme",
value: "system",
},
];
const get = (key: string) => {
if (typeof window !== "undefined") {
const preferences = JSON.parse(localStorage.getItem("preferences") ?? "{}");
return (
preferences[key] ??
defaultPreferences.find((p) => p.key == key)?.value ??
null
);
}
};
const set = (key: string, value: string) => {
if (typeof window !== "undefined") {
const preferences = JSON.parse(localStorage.getItem("preferences") ?? "{}");
preferences[key] = value;
localStorage.setItem("preferences", JSON.stringify(preferences));
}
};
const usePreferences = () => {
return { get, set };
};
export default usePreferences;

View File

@ -1,5 +1,6 @@
import {
ColorScheme,
ColorSchemeProvider,
Container,
LoadingOverlay,
MantineProvider,
@ -11,7 +12,8 @@ import type { AppProps } from "next/app";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import Header from "../components/navBar/NavBar";
import useConfig, { ConfigContext } from "../hooks/config.hook";
import { ConfigContext } from "../hooks/config.hook";
import usePreferences from "../hooks/usePreferences";
import { UserContext } from "../hooks/user.hook";
import authService from "../services/auth.service";
import configService from "../services/config.service";
@ -25,9 +27,9 @@ import { GlobalLoadingContext } from "../utils/loading.util";
function App({ Component, pageProps }: AppProps) {
const systemTheme = useColorScheme();
const router = useRouter();
const config = useConfig();
const preferences = usePreferences();
const [colorScheme, setColorScheme] = useState<ColorScheme>();
const [colorScheme, setColorScheme] = useState<ColorScheme>("light");
const [isLoading, setIsLoading] = useState(true);
const [user, setUser] = useState<CurrentUser | null>(null);
const [configVariables, setConfigVariables] = useState<Config[] | null>(null);
@ -56,7 +58,11 @@ function App({ Component, pageProps }: AppProps) {
}, [router.asPath]);
useEffect(() => {
setColorScheme(systemTheme);
setColorScheme(
preferences.get("colorScheme") == "system"
? systemTheme
: preferences.get("colorScheme")
);
}, [systemTheme]);
return (
@ -65,26 +71,31 @@ function App({ Component, pageProps }: AppProps) {
withNormalizeCSS
theme={{ colorScheme, ...globalStyle }}
>
<GlobalStyle />
<NotificationsProvider>
<ModalsProvider>
<GlobalLoadingContext.Provider value={{ isLoading, setIsLoading }}>
{isLoading ? (
<LoadingOverlay visible overlayOpacity={1} />
) : (
<ConfigContext.Provider value={configVariables}>
<UserContext.Provider value={{ user, setUser }}>
<LoadingOverlay visible={isLoading} overlayOpacity={1} />
<Header />
<Container>
<Component {...pageProps} />
</Container>
</UserContext.Provider>{" "}
</ConfigContext.Provider>
)}
</GlobalLoadingContext.Provider>
</ModalsProvider>
</NotificationsProvider>
<ColorSchemeProvider
colorScheme={colorScheme}
toggleColorScheme={(value) => setColorScheme(value ?? "light")}
>
<GlobalStyle />
<NotificationsProvider>
<ModalsProvider>
<GlobalLoadingContext.Provider value={{ isLoading, setIsLoading }}>
{isLoading ? (
<LoadingOverlay visible overlayOpacity={1} />
) : (
<ConfigContext.Provider value={configVariables}>
<UserContext.Provider value={{ user, setUser }}>
<LoadingOverlay visible={isLoading} overlayOpacity={1} />
<Header />
<Container>
<Component {...pageProps} />
</Container>
</UserContext.Provider>{" "}
</ConfigContext.Provider>
)}
</GlobalLoadingContext.Provider>
</ModalsProvider>
</NotificationsProvider>
</ColorSchemeProvider>
</MantineProvider>
);
}

View File

@ -17,6 +17,7 @@ import { useRouter } from "next/router";
import { Tb2Fa } from "react-icons/tb";
import * as yup from "yup";
import showEnableTotpModal from "../../components/account/showEnableTotpModal";
import ThemeSwitcher from "../../components/account/ThemeSwitcher";
import useUser from "../../hooks/user.hook";
import authService from "../../services/auth.service";
import userService from "../../services/user.service";
@ -164,8 +165,6 @@ const Account = () => {
</Tabs.List>
<Tabs.Panel value="totp" pt="xs">
{/* TODO: This is ugly, make it prettier */}
{/* If we have totp enabled, show different text */}
{user.totpVerified ? (
<>
<form
@ -236,8 +235,13 @@ const Account = () => {
</Tabs.Panel>
</Tabs>
</Paper>
<Center mt={80}>
<Paper withBorder p="xl" mt="lg">
<Title order={5} mb="xs">
Color scheme
</Title>
<ThemeSwitcher />
</Paper>
<Center mt={80} mb="lg">
<Stack>
<Button
variant="light"