added window section to settings

This commit is contained in:
Vomitblood 2024-08-07 11:43:32 +08:00
parent 67c72909ff
commit 19e1b05faa
9 changed files with 178 additions and 63 deletions

View file

@ -1,8 +1,11 @@
import { useEffect } from "react";
import Paths from "../../lib/path";
import { createDir, exists } from "@tauri-apps/api/fs"; import { createDir, exists } from "@tauri-apps/api/fs";
import { useEffect } from "react";
import { useSettings } from "../../contexts/SettingsContext";
import Paths from "../../lib/path";
export const Initialization = () => { export const Initialization = () => {
const { settings } = useSettings();
useEffect(() => { useEffect(() => {
const initializePaths = async () => { const initializePaths = async () => {
try { try {
@ -17,8 +20,14 @@ export const Initialization = () => {
if (!configDirectoryExists) await createDir(Paths.getPath("configDirectory")); if (!configDirectoryExists) await createDir(Paths.getPath("configDirectory"));
}; };
const fullscreen = async () => {
const { appWindow } = await import("@tauri-apps/api/window");
await appWindow.setFullscreen(true);
};
initializePaths().then(() => createDirectories()); initializePaths().then(() => createDirectories());
}); if (settings.window.start_fullscreen) fullscreen();
}, []);
return null; return null;
}; };

View file

@ -51,13 +51,6 @@ export const HeaderBar = () => {
flexDirection: "row", flexDirection: "row",
}} }}
> >
<IconButton
onClick={() => {
router.push("/testing");
}}
>
<BugReportOutlined />
</IconButton>
<Settings /> <Settings />
<WindowButtons /> <WindowButtons />
</Stack> </Stack>

View file

@ -1,20 +1,23 @@
import { SettingsOutlined } from "@mui/icons-material"; import { BugReportOutlined, SettingsOutlined } from "@mui/icons-material";
import { LoadingButton, TabContext, TabList, TabPanel } from "@mui/lab"; import { LoadingButton, TabContext, TabList, TabPanel } from "@mui/lab";
import { Box, Button, IconButton, Tab, useTheme } from "@mui/material"; import { Box, Button, IconButton, Tab, Tooltip, useTheme } from "@mui/material";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { useRouter } from "next/router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useSettings } from "../../../contexts/SettingsContext"; import { useSettings } from "../../../contexts/SettingsContext";
import { settingsAtom } from "../../../lib/store/jotai/settings"; import { stagedSettingsAtom } from "../../../lib/store/jotai/settings";
import { FloatingDialog } from "../../Generic/FloatingDialog"; import { FloatingDialog } from "../../Generic/FloatingDialog";
import { SettingsTabDisplay } from "./SettingsTabDisplay"; import { SettingsTabDisplay } from "./SettingsTabs/SettingsTabDisplay";
import { SettingsTabWindow } from "./SettingsTabs/SettingsTabWindow";
export const Settings = () => { export const Settings = () => {
// contexts // contexts
const theme = useTheme(); const theme = useTheme();
const { settings, updateSettings, resetSettings } = useSettings(); const { settings, updateSettings } = useSettings();
const router = useRouter();
// atoms // atoms
const [stagedSettings, setStagedSettings] = useAtom(settingsAtom); const [stagedSettings, setStagedSettings] = useAtom(stagedSettingsAtom);
// states // states
const [settingsOpenState, setSettingsOpenState] = useState<boolean>(false); const [settingsOpenState, setSettingsOpenState] = useState<boolean>(false);
@ -61,10 +64,23 @@ export const Settings = () => {
return ( return (
<FloatingDialog <FloatingDialog
actionButtons={
<>
<IconButton
onClick={() => {
router.push("/testing");
}}
sx={{
mr: 1,
}}
>
<BugReportOutlined />
</IconButton>
</>
}
body={ body={
<Box <Box
sx={{ sx={{
// TODO: make look nice
border: "1px solid " + theme.palette.grey[700], border: "1px solid " + theme.palette.grey[700],
borderRadius: settings.display.radius + "px", borderRadius: settings.display.radius + "px",
display: "flex", display: "flex",
@ -90,6 +106,10 @@ export const Settings = () => {
label="Display" label="Display"
value="display" value="display"
/> />
<Tab
label="Window"
value="window"
/>
</TabList> </TabList>
<Box <Box
overflow="auto" overflow="auto"
@ -104,6 +124,12 @@ export const Settings = () => {
> >
<SettingsTabDisplay /> <SettingsTabDisplay />
</TabPanel> </TabPanel>
<TabPanel
sx={{ p: 2 }}
value="window"
>
<SettingsTabWindow />
</TabPanel>
</Box> </Box>
</TabContext> </TabContext>
</Box> </Box>
@ -151,12 +177,14 @@ export const Settings = () => {
close={closeSettings} close={closeSettings}
maximisedState={settingsMaximisedState} maximisedState={settingsMaximisedState}
openButton={ openButton={
<Tooltip title="Settings">
<IconButton <IconButton
onClick={toggleSettings} onClick={toggleSettings}
size="small" size="small"
> >
<SettingsOutlined /> <SettingsOutlined />
</IconButton> </IconButton>
</Tooltip>
} }
openState={settingsOpenState} openState={settingsOpenState}
setMaximisedState={setSettingsMaximisedState} setMaximisedState={setSettingsMaximisedState}

View file

@ -1,9 +1,9 @@
import { Box, Chip, InputAdornment, MenuItem, Slider, Switch, TextField, Typography } from "@mui/material"; import { Box, Chip, InputAdornment, MenuItem, Slider, Switch, TextField, Typography } from "@mui/material";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { FC } from "react"; import { FC } from "react";
import { settingsAtom } from "../../../lib/store/jotai/settings"; import { stagedSettingsAtom } from "../../../../lib/store/jotai/settings";
import { SettingsCategoryTitle } from "./SettingsCategoryTitle"; import { SettingsCategoryTitle } from "../SettingsCategoryTitle";
import { SettingsItem } from "./SettingsItem"; import { SettingsItem } from "../SettingsItem";
interface SettingsTabDisplayProps { interface SettingsTabDisplayProps {
sx?: any; sx?: any;
@ -11,7 +11,7 @@ interface SettingsTabDisplayProps {
export const SettingsTabDisplay: FC<SettingsTabDisplayProps> = ({ sx }) => { export const SettingsTabDisplay: FC<SettingsTabDisplayProps> = ({ sx }) => {
// atoms // atoms
const [stagedSettings, setStagedSettings] = useAtom(settingsAtom); const [stagedSettings, setStagedSettings] = useAtom(stagedSettingsAtom);
const handleSettingsDisplayValueChange = (settingKey: string, settingValue: boolean | number | string | number[]) => { const handleSettingsDisplayValueChange = (settingKey: string, settingValue: boolean | number | string | number[]) => {
const newSettings = { const newSettings = {
@ -26,7 +26,7 @@ export const SettingsTabDisplay: FC<SettingsTabDisplayProps> = ({ sx }) => {
return ( return (
<Box sx={{ sx }}> <Box sx={{ sx }}>
<SettingsCategoryTitle title="Basic settings" /> <SettingsCategoryTitle title="Styles" />
<SettingsItem <SettingsItem
settingsDescription={ settingsDescription={
<> <>

View file

@ -0,0 +1,81 @@
import { Box, Chip, InputAdornment, MenuItem, Slider, Switch, TextField, Typography } from "@mui/material";
import { useAtom } from "jotai";
import { FC } from "react";
import { stagedSettingsAtom } from "../../../../lib/store/jotai/settings";
import { SettingsCategoryTitle } from "../SettingsCategoryTitle";
import { SettingsItem } from "../SettingsItem";
interface SettingsTabWindowProps {
sx?: any;
}
export const SettingsTabWindow: FC<SettingsTabWindowProps> = ({ sx }) => {
// atoms
const [stagedSettings, setStagedSettings] = useAtom(stagedSettingsAtom);
const handleSettingsWindowValueChange = (settingKey: string, settingValue: boolean | number | string | number[]) => {
const newSettings = {
...stagedSettings,
window: {
...stagedSettings.window,
[settingKey]: settingValue,
},
};
setStagedSettings(newSettings);
};
return (
<Box sx={{ sx }}>
<SettingsCategoryTitle title="Fullscreen" />
<SettingsItem
settingsDescription={
<>
<Typography>Fullscreen on startup</Typography>
</>
}
settingsInput={
<Switch
checked={stagedSettings.window.start_fullscreen}
name="start_fullscreen"
onChange={(e) => {
handleSettingsWindowValueChange(e.target.name, e.target.checked);
}}
/>
}
/>
<SettingsCategoryTitle title="Titlebar Buttons" />
<SettingsItem
settingsDescription={
<>
<Typography>Minimize button</Typography>
</>
}
settingsInput={
<Switch
checked={stagedSettings.window.minimize_button}
name="minimize_button"
onChange={(e) => {
handleSettingsWindowValueChange(e.target.name, e.target.checked);
}}
/>
}
/>
<SettingsItem
settingsDescription={
<>
<Typography>Maximize button</Typography>
</>
}
settingsInput={
<Switch
checked={stagedSettings.window.maximize_button}
name="maximize_button"
onChange={(e) => {
handleSettingsWindowValueChange(e.target.name, e.target.checked);
}}
/>
}
/>
</Box>
);
};

View file

@ -1,7 +1,8 @@
// TODO: add settings functionality, refer to whensapp project // TODO: add settings functionality, refer to whensapp project
import { FC, ReactNode } from "react";
import { createTheme, ThemeProvider } from "@mui/material/styles"; import { createTheme, ThemeProvider } from "@mui/material/styles";
import { FC, ReactNode } from "react";
import { useSettings } from "./SettingsContext";
interface UserThemeProviderProps { interface UserThemeProviderProps {
children: ReactNode; children: ReactNode;
@ -62,31 +63,33 @@ export const userPalette = {
}; };
export const UserThemeProvider: FC<UserThemeProviderProps> = ({ children }) => { export const UserThemeProvider: FC<UserThemeProviderProps> = ({ children }) => {
const { settings } = useSettings();
// font family settings // font family settings
// TODO: figure out how to bundle fonts in tauri // TODO: figure out how to bundle fonts in tauri
let fontFamily = "GoogleSans"; let fontFamily = "GoogleSans";
// switch (settings.display.font_family) { switch (settings.display.font_family) {
// case "sans_serif": case "sans_serif":
// fontFamily = "GoogleSans, sans-serif"; fontFamily = "GoogleSans, sans-serif";
// break; break;
// case "monospace": case "monospace":
// fontFamily = "JetBrainsMono, monospace"; fontFamily = "JetBrainsMono, monospace";
// break; break;
// case "comic_sans": case "comic_sans":
// fontFamily = "ComicSans, sans-serif"; fontFamily = "ComicSans, sans-serif";
// break; break;
// case "system_font": case "system_font":
// fontFamily = "system-ui"; fontFamily = "system-ui";
// break; break;
// } }
// font scaling settings // font scaling settings
// const fontSize = (settings.display.font_scaling / 100) * 14; const fontSize = (settings.display.font_scaling / 100) * 14;
const userTheme = createTheme({ const userTheme = createTheme({
typography: { typography: {
fontFamily: fontFamily, fontFamily: fontFamily,
// fontSize: fontSize, fontSize: fontSize,
}, },
palette: { palette: {
mode: "dark", mode: "dark",
@ -94,17 +97,17 @@ export const UserThemeProvider: FC<UserThemeProviderProps> = ({ children }) => {
}, },
transitions: { transitions: {
duration: { duration: {
// shortest: settings.display.transition_duration, shortest: settings.display.transition_duration,
// shorter: settings.display.transition_duration, shorter: settings.display.transition_duration,
// short: settings.display.transition_duration, short: settings.display.transition_duration,
// // most basic recommended timing // most basic recommended timing
// standard: settings.display.transition_duration, standard: settings.display.transition_duration,
// // this is to be used in complex animations // this is to be used in complex animations
// complex: settings.display.transition_duration, complex: settings.display.transition_duration,
// // recommended when something is entering screen // recommended when something is entering screen
// enteringScreen: settings.display.transition_duration, enteringScreen: settings.display.transition_duration,
// // recommended when something is leaving screen // recommended when something is leaving screen
// leavingScreen: settings.display.transition_duration, leavingScreen: settings.display.transition_duration,
}, },
}, },
components: { components: {

View file

@ -4,18 +4,19 @@ import { readTomlFile, writeTomlFile } from "./utils/toml";
export const defaultSettings = { export const defaultSettings = {
display: { display: {
dark_mode: true as boolean,
accent_color: "#8ab4f8" as string, accent_color: "#8ab4f8" as string,
transition_duration: 200 as number, dark_mode: true as boolean,
radius: 8 as number,
window_height: 60 as number,
window_width: 400 as number,
font_family: "monospace" as string, font_family: "monospace" as string,
font_scaling: 100, font_scaling: 100,
radius: 8 as number,
transition_duration: 200 as number,
window_height: 80 as number,
window_width: 400 as number,
}, },
window: { window: {
minimize_button: false as boolean,
maximize_button: false as boolean, maximize_button: false as boolean,
minimize_button: false as boolean,
start_fullscreen: false as boolean, // TODO: this should be true on prod
}, },
}; };

View file

@ -1,4 +1,4 @@
import { atom } from "jotai"; import { atom } from "jotai";
import { defaultSettings } from "../../settings"; import { defaultSettings } from "../../settings";
export const settingsAtom = atom(defaultSettings); export const stagedSettingsAtom = atom(defaultSettings);