forked from Archives/Athou_commafeed
add option to follow system dark/light mode (#1083)
This commit is contained in:
@@ -38,6 +38,7 @@ function Providers(props: { children: React.ReactNode }) {
|
|||||||
return (
|
return (
|
||||||
<I18nProvider i18n={i18n}>
|
<I18nProvider i18n={i18n}>
|
||||||
<MantineProvider
|
<MantineProvider
|
||||||
|
defaultColorScheme="auto"
|
||||||
theme={{
|
theme={{
|
||||||
primaryColor: "orange",
|
primaryColor: "orange",
|
||||||
fontFamily: "Open Sans",
|
fontFamily: "Open Sans",
|
||||||
|
|||||||
@@ -1,12 +1,21 @@
|
|||||||
import { Trans } from "@lingui/macro"
|
import { Trans } from "@lingui/macro"
|
||||||
import { Box, Divider, Group, Menu, SegmentedControl, type SegmentedControlItem, useMantineColorScheme } from "@mantine/core"
|
import {
|
||||||
|
Box,
|
||||||
|
Divider,
|
||||||
|
Group,
|
||||||
|
type MantineColorScheme,
|
||||||
|
Menu,
|
||||||
|
SegmentedControl,
|
||||||
|
type SegmentedControlItem,
|
||||||
|
useMantineColorScheme,
|
||||||
|
} from "@mantine/core"
|
||||||
import { showNotification } from "@mantine/notifications"
|
import { showNotification } from "@mantine/notifications"
|
||||||
import { client } from "app/client"
|
import { client } from "app/client"
|
||||||
import { redirectToAbout, redirectToAdminUsers, redirectToDonate, redirectToMetrics, redirectToSettings } from "app/redirect/thunks"
|
import { redirectToAbout, redirectToAdminUsers, redirectToDonate, redirectToMetrics, redirectToSettings } from "app/redirect/thunks"
|
||||||
import { useAppDispatch, useAppSelector } from "app/store"
|
import { useAppDispatch, useAppSelector } from "app/store"
|
||||||
import { type ViewMode } from "app/types"
|
import { type ViewMode } from "app/types"
|
||||||
import { useViewMode } from "hooks/useViewMode"
|
import { useViewMode } from "hooks/useViewMode"
|
||||||
import { useState } from "react"
|
import { type ReactNode, useState } from "react"
|
||||||
import {
|
import {
|
||||||
TbChartLine,
|
TbChartLine,
|
||||||
TbHeartFilled,
|
TbHeartFilled,
|
||||||
@@ -19,6 +28,7 @@ import {
|
|||||||
TbPower,
|
TbPower,
|
||||||
TbSettings,
|
TbSettings,
|
||||||
TbSun,
|
TbSun,
|
||||||
|
TbSunMoon,
|
||||||
TbUsers,
|
TbUsers,
|
||||||
TbWorldDownload,
|
TbWorldDownload,
|
||||||
} from "react-icons/tb"
|
} from "react-icons/tb"
|
||||||
@@ -27,56 +37,56 @@ interface ProfileMenuProps {
|
|||||||
control: React.ReactElement
|
control: React.ReactElement
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ViewModeControlItem extends SegmentedControlItem {
|
const ProfileMenuControlItem = ({ icon, label }: { icon: ReactNode; label: ReactNode }) => {
|
||||||
value: ViewMode
|
return (
|
||||||
|
<Group>
|
||||||
|
{icon}
|
||||||
|
<Box ml={6}>{label}</Box>
|
||||||
|
</Group>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconSize = 16
|
const iconSize = 16
|
||||||
|
|
||||||
|
interface ColorSchemeControlItem extends SegmentedControlItem {
|
||||||
|
value: MantineColorScheme
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorSchemeData: ColorSchemeControlItem[] = [
|
||||||
|
{
|
||||||
|
value: "light",
|
||||||
|
label: <ProfileMenuControlItem icon={<TbSun size={iconSize} />} label={<Trans>Light</Trans>} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "dark",
|
||||||
|
label: <ProfileMenuControlItem icon={<TbMoon size={iconSize} />} label={<Trans>Dark</Trans>} />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "auto",
|
||||||
|
label: <ProfileMenuControlItem icon={<TbSunMoon size={iconSize} />} label={<Trans>System</Trans>} />,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
interface ViewModeControlItem extends SegmentedControlItem {
|
||||||
|
value: ViewMode
|
||||||
|
}
|
||||||
|
|
||||||
const viewModeData: ViewModeControlItem[] = [
|
const viewModeData: ViewModeControlItem[] = [
|
||||||
{
|
{
|
||||||
value: "title",
|
value: "title",
|
||||||
label: (
|
label: <ProfileMenuControlItem icon={<TbList size={iconSize} />} label={<Trans>Compact</Trans>} />,
|
||||||
<Group>
|
|
||||||
<TbList size={iconSize} />
|
|
||||||
<Box ml={6}>
|
|
||||||
<Trans>Compact</Trans>
|
|
||||||
</Box>
|
|
||||||
</Group>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "cozy",
|
value: "cozy",
|
||||||
label: (
|
label: <ProfileMenuControlItem icon={<TbLayoutList size={iconSize} />} label={<Trans>Cozy</Trans>} />,
|
||||||
<Group>
|
|
||||||
<TbLayoutList size={iconSize} />
|
|
||||||
<Box ml={6}>
|
|
||||||
<Trans>Cozy</Trans>
|
|
||||||
</Box>
|
|
||||||
</Group>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "detailed",
|
value: "detailed",
|
||||||
label: (
|
label: <ProfileMenuControlItem icon={<TbListDetails size={iconSize} />} label={<Trans>Detailed</Trans>} />,
|
||||||
<Group>
|
|
||||||
<TbListDetails size={iconSize} />
|
|
||||||
<Box ml={6}>
|
|
||||||
<Trans>Detailed</Trans>
|
|
||||||
</Box>
|
|
||||||
</Group>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "expanded",
|
value: "expanded",
|
||||||
label: (
|
label: <ProfileMenuControlItem icon={<TbNotes size={iconSize} />} label={<Trans>Expanded</Trans>} />,
|
||||||
<Group>
|
|
||||||
<TbNotes size={iconSize} />
|
|
||||||
<Box ml={6}>
|
|
||||||
<Trans>Expanded</Trans>
|
|
||||||
</Box>
|
|
||||||
</Group>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -86,8 +96,7 @@ export function ProfileMenu(props: ProfileMenuProps) {
|
|||||||
const profile = useAppSelector(state => state.user.profile)
|
const profile = useAppSelector(state => state.user.profile)
|
||||||
const admin = useAppSelector(state => state.user.profile?.admin)
|
const admin = useAppSelector(state => state.user.profile?.admin)
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const { colorScheme, toggleColorScheme } = useMantineColorScheme()
|
const { colorScheme, setColorScheme } = useMantineColorScheme()
|
||||||
const dark = colorScheme === "dark"
|
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
window.location.href = "logout"
|
window.location.href = "logout"
|
||||||
@@ -128,9 +137,14 @@ export function ProfileMenu(props: ProfileMenuProps) {
|
|||||||
<Menu.Label>
|
<Menu.Label>
|
||||||
<Trans>Theme</Trans>
|
<Trans>Theme</Trans>
|
||||||
</Menu.Label>
|
</Menu.Label>
|
||||||
<Menu.Item leftSection={dark ? <TbSun size={iconSize} /> : <TbMoon size={iconSize} />} onClick={() => toggleColorScheme()}>
|
<SegmentedControl
|
||||||
{dark ? <Trans>Switch to light theme</Trans> : <Trans>Switch to dark theme</Trans>}
|
fullWidth
|
||||||
</Menu.Item>
|
orientation="vertical"
|
||||||
|
data={colorSchemeData}
|
||||||
|
value={colorScheme}
|
||||||
|
onChange={e => setColorScheme(e as MantineColorScheme)}
|
||||||
|
mb="xs"
|
||||||
|
/>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user