added background settings panel

This commit is contained in:
Vomitblood 2024-08-07 15:04:05 +08:00
parent 150bafb7bf
commit a964264134
7 changed files with 125 additions and 78 deletions

View file

@ -29,7 +29,7 @@ docker run --rm -it \
mise settings set experimental true && \ mise settings set experimental true && \
mise exec bun --command \"bun run tauri build\" mise exec bun --command \"bun run tauri build\"
chown -R $USER_ID:$GROUP_ID $CONTAINER_PROJECT_DIR chown -R $USER_ID:$GROUP_ID $CONTAINER_PROJECT_DIR && \
"
echo "Build complete. Output available in $HOST_OUTPUT_DIR" echo "Build complete. Output available in $HOST_OUTPUT_DIR"
"

View file

@ -13,12 +13,7 @@
"tauri": { "tauri": {
"allowlist": { "allowlist": {
"dialog": { "dialog": {
"all": true, "all": true
"ask": true,
"confirm": true,
"message": true,
"open": true,
"save": true
}, },
"fs": { "fs": {
"all": true, "all": true,

View file

@ -3,12 +3,15 @@ import { convertFileSrc } from "@tauri-apps/api/tauri";
import { useState } from "react"; import { useState } from "react";
import { FooterBar } from "../FooterBar"; import { FooterBar } from "../FooterBar";
import { HeaderBar } from "../HeaderBar/HeaderBar"; import { HeaderBar } from "../HeaderBar/HeaderBar";
import { useSettings } from "../../contexts/SettingsContext";
export const Layout = () => { export const Layout = () => {
const { settings } = useSettings();
const [imageUrl, setImageUrl] = useState<string | null>(null); const [imageUrl, setImageUrl] = useState<string | null>(null);
const setBackground = async () => { const setBackground = async () => {
const assetUrl = convertFileSrc("/home/vomitblood/build/stort/public/images/background.jpg"); const assetUrl = convertFileSrc("/home/vomitblood/Downloads/toothless-dance.gif");
setImageUrl(assetUrl); setImageUrl(assetUrl);
}; };
@ -16,6 +19,7 @@ export const Layout = () => {
<Box <Box
sx={{ sx={{
// Use the URL function for background images // Use the URL function for background images
backgroundColor: settings.background.background_color,
backgroundImage: `url(${imageUrl})`, backgroundImage: `url(${imageUrl})`,
backgroundSize: "cover", // Cover the entire area backgroundSize: "cover", // Cover the entire area
backgroundPosition: "center", // Center the image backgroundPosition: "center", // Center the image

View file

@ -9,6 +9,7 @@ import { stagedSettingsAtom } from "../../../lib/store/jotai/settings";
import { FloatingDialog } from "../../Generic/FloatingDialog"; import { FloatingDialog } from "../../Generic/FloatingDialog";
import { SettingsTabStyle } from "./SettingsTabs/SettingsTabStyle"; import { SettingsTabStyle } from "./SettingsTabs/SettingsTabStyle";
import { SettingsTabWindow } from "./SettingsTabs/SettingsTabWindow"; import { SettingsTabWindow } from "./SettingsTabs/SettingsTabWindow";
import { SettingsTabBackground } from "./SettingsTabs/SettingsTabBackground";
export const Settings = () => { export const Settings = () => {
// contexts // contexts
@ -104,6 +105,10 @@ export const Settings = () => {
label="Style" label="Style"
value="style" value="style"
/> />
<Tab
label="Background"
value="background"
/>
<Tab <Tab
label="Window" label="Window"
value="window" value="window"
@ -122,6 +127,12 @@ export const Settings = () => {
> >
<SettingsTabStyle /> <SettingsTabStyle />
</TabPanel> </TabPanel>
<TabPanel
sx={{ p: 2 }}
value="background"
>
<SettingsTabBackground />
</TabPanel>
<TabPanel <TabPanel
sx={{ p: 2 }} sx={{ p: 2 }}
value="window" value="window"

View file

@ -1,69 +1,111 @@
import { Box, Switch } from "@mui/material"; import { DeleteOutline, FileOpenOutlined } from "@mui/icons-material";
import { Box, Button, Stack, TextField } from "@mui/material";
import { open } from "@tauri-apps/api/dialog";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import Image from "next/image";
import { FC } from "react"; import { FC } from "react";
import { stagedSettingsAtom } from "../../../../lib/store/jotai/settings"; import { stagedSettingsAtom } from "../../../../lib/store/jotai/settings";
import { CategoryTitle } from "../CategoryTitle"; import { CategoryTitle } from "../CategoryTitle";
import { SettingsItem } from "../SettingsItem"; import { SettingsItem } from "../SettingsItem";
interface SettingsTabWindowProps { interface SettingsTabBackgroundProps {
sx?: any; sx?: any;
} }
export const SettingsTabWindow: FC<SettingsTabWindowProps> = ({ sx }) => { export const SettingsTabBackground: FC<SettingsTabBackgroundProps> = ({ sx }) => {
// atoms // atoms
const [stagedSettings, setStagedSettings] = useAtom(stagedSettingsAtom); const [stagedSettings, setStagedSettings] = useAtom(stagedSettingsAtom);
const handleSettingsWindowValueChange = (settingKey: string, settingValue: boolean | number | string | number[]) => { const handleSettingsBackgroundValueChange = (
settingKey: string,
settingValue: boolean | number | string | number[],
) => {
const newSettings = { const newSettings = {
...stagedSettings, ...stagedSettings,
window: { background: {
...stagedSettings.window, ...stagedSettings.background,
[settingKey]: settingValue, [settingKey]: settingValue,
}, },
}; };
setStagedSettings(newSettings); setStagedSettings(newSettings);
}; };
const selectImage = async () => {
const selected = await open({
multiple: false,
filters: [
{
name: "Images",
extensions: ["jpg", "png", "jpeg", "webp", "gif"],
},
],
});
if (selected) {
console.log(selected);
}
};
// TODO: implement
const clearImage = async () => {};
return ( return (
<Box sx={{ sx }}> <Box sx={{ sx }}>
<CategoryTitle title="Fullscreen" /> <CategoryTitle title="Wallpaper" />
<SettingsItem <Box>
defaultText="On" <Image
description="Fullscreen on startup" src="/wallpaper.jpg"
input={ alt="Image not found"
<Switch width={200}
checked={stagedSettings.window.start_fullscreen} height={200}
name="start_fullscreen" />
onChange={(e) => { </Box>
handleSettingsWindowValueChange(e.target.name, e.target.checked); <Box
sx={{
mb: 2,
}} }}
/> >
} <Stack
/> direction="row"
<CategoryTitle title="Titlebar Buttons" /> spacing={1}
>
<Button
color="primary"
onClick={selectImage}
startIcon={<FileOpenOutlined />}
size="small"
variant="outlined"
>
Select
</Button>
<Button
color="warning"
onClick={clearImage}
startIcon={<DeleteOutline />}
size="small"
variant="outlined"
>
Clear
</Button>
</Stack>
</Box>
<CategoryTitle title="Colors" />
<SettingsItem <SettingsItem
defaultText="Off" defaultText="#202124"
description="Minimize button" description="Background color"
input={ input={
<Switch <TextField
checked={stagedSettings.window.minimize_button} name="background_color"
name="minimize_button"
onChange={(e) => { onChange={(e) => {
handleSettingsWindowValueChange(e.target.name, e.target.checked); handleSettingsBackgroundValueChange(e.target.name, e.target.value);
}} }}
/> sx={{
} width: "100%",
/>
<SettingsItem
defaultText="Off"
description="Maximize button"
input={
<Switch
checked={stagedSettings.window.maximize_button}
name="maximize_button"
onChange={(e) => {
handleSettingsWindowValueChange(e.target.name, e.target.checked);
}} }}
size="small"
type="color"
value={stagedSettings.background.background_color}
variant="standard"
/> />
} }
/> />

View file

@ -4,12 +4,8 @@ import { readTomlFile, writeTomlFile } from "./utils/toml";
export const defaultSettings = { export const defaultSettings = {
background: { background: {
background_color: "#8ab4f8" as string, background_color: "#202124" as string,
background_image: "" as string, background_image_path: "" as string,
background_image_size: "cover" as string,
background_image_position: "center" as string,
background_image_repeat: "no-repeat" as string,
footer_background_color: "#8ab4f8" as string,
}, },
style: { style: {
accent_color: "#8ab4f8" as string, accent_color: "#8ab4f8" as string,

View file

@ -2,6 +2,7 @@ import { BugReport } from "@mui/icons-material";
import { Box, Button, IconButton, TextField, Typography } from "@mui/material"; import { Box, Button, IconButton, TextField, Typography } from "@mui/material";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useState } from "react"; import { useState } from "react";
import { SettingsItem } from "../components/HeaderBar/Settings/SettingsItem";
import { useSettings } from "../contexts/SettingsContext"; import { useSettings } from "../contexts/SettingsContext";
import { testing } from "../lib/testing"; import { testing } from "../lib/testing";
@ -12,6 +13,7 @@ export default function Testing() {
// states // states
const [text, setText] = useState(""); const [text, setText] = useState("");
const [color, setColor] = useState("#000000");
return ( return (
<Box> <Box>
@ -29,28 +31,7 @@ export default function Testing() {
> >
reset settings reset settings
</Button> </Button>
<Button <Button>update settings</Button>
onClick={() => {
updateSettings({
style: {
dark_mode: false as boolean,
accent_color: "#8ab4f8" as string,
transition_duration: 200 as number,
radius: 8 as number,
window_height: 60 as number,
window_width: 400 as number,
font_family: "monospace" as string,
font_scaling: 100,
},
window: {
minimize_button: true as boolean,
maximize_button: true as boolean,
},
});
}}
>
update settings
</Button>
<Button <Button
onClick={() => { onClick={() => {
console.log(settings); console.log(settings);
@ -66,7 +47,25 @@ export default function Testing() {
testing testing
</Button> </Button>
<Typography>{text}</Typography> <Typography>{text}</Typography>
<TextField rows={10} /> <SettingsItem
defaultText="#8ab4f8"
description="Accent color"
input={
<TextField
name="accent_color"
onChange={(e) => {
setColor(e.target.value);
}}
sx={{
width: "100%",
}}
size="small"
type="color"
value={color}
variant="standard"
/>
}
/>
</Box> </Box>
); );
} }