mirror of
				https://github.com/Vomitblood/stort.git
				synced 2025-11-04 12:47:22 +08:00 
			
		
		
		
	added background settings panel
This commit is contained in:
		
							parent
							
								
									150bafb7bf
								
							
						
					
					
						commit
						a964264134
					
				
							
								
								
									
										6
									
								
								build.sh
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								build.sh
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -29,7 +29,7 @@ docker run --rm -it \
 | 
			
		|||
    mise settings set experimental true && \
 | 
			
		||||
    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"
 | 
			
		||||
    "
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,12 +13,7 @@
 | 
			
		|||
  "tauri": {
 | 
			
		||||
    "allowlist": {
 | 
			
		||||
      "dialog": {
 | 
			
		||||
        "all": true,
 | 
			
		||||
        "ask": true,
 | 
			
		||||
        "confirm": true,
 | 
			
		||||
        "message": true,
 | 
			
		||||
        "open": true,
 | 
			
		||||
        "save": true
 | 
			
		||||
        "all": true
 | 
			
		||||
      },
 | 
			
		||||
      "fs": {
 | 
			
		||||
        "all": true,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,12 +3,15 @@ import { convertFileSrc } from "@tauri-apps/api/tauri";
 | 
			
		|||
import { useState } from "react";
 | 
			
		||||
import { FooterBar } from "../FooterBar";
 | 
			
		||||
import { HeaderBar } from "../HeaderBar/HeaderBar";
 | 
			
		||||
import { useSettings } from "../../contexts/SettingsContext";
 | 
			
		||||
 | 
			
		||||
export const Layout = () => {
 | 
			
		||||
  const { settings } = useSettings();
 | 
			
		||||
 | 
			
		||||
  const [imageUrl, setImageUrl] = useState<string | null>(null);
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +19,7 @@ export const Layout = () => {
 | 
			
		|||
    <Box
 | 
			
		||||
      sx={{
 | 
			
		||||
        // Use the URL function for background images
 | 
			
		||||
        backgroundColor: settings.background.background_color,
 | 
			
		||||
        backgroundImage: `url(${imageUrl})`,
 | 
			
		||||
        backgroundSize: "cover", // Cover the entire area
 | 
			
		||||
        backgroundPosition: "center", // Center the image
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,6 +9,7 @@ import { stagedSettingsAtom } from "../../../lib/store/jotai/settings";
 | 
			
		|||
import { FloatingDialog } from "../../Generic/FloatingDialog";
 | 
			
		||||
import { SettingsTabStyle } from "./SettingsTabs/SettingsTabStyle";
 | 
			
		||||
import { SettingsTabWindow } from "./SettingsTabs/SettingsTabWindow";
 | 
			
		||||
import { SettingsTabBackground } from "./SettingsTabs/SettingsTabBackground";
 | 
			
		||||
 | 
			
		||||
export const Settings = () => {
 | 
			
		||||
  // contexts
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +105,10 @@ export const Settings = () => {
 | 
			
		|||
                label="Style"
 | 
			
		||||
                value="style"
 | 
			
		||||
              />
 | 
			
		||||
              <Tab
 | 
			
		||||
                label="Background"
 | 
			
		||||
                value="background"
 | 
			
		||||
              />
 | 
			
		||||
              <Tab
 | 
			
		||||
                label="Window"
 | 
			
		||||
                value="window"
 | 
			
		||||
| 
						 | 
				
			
			@ -122,6 +127,12 @@ export const Settings = () => {
 | 
			
		|||
              >
 | 
			
		||||
                <SettingsTabStyle />
 | 
			
		||||
              </TabPanel>
 | 
			
		||||
              <TabPanel
 | 
			
		||||
                sx={{ p: 2 }}
 | 
			
		||||
                value="background"
 | 
			
		||||
              >
 | 
			
		||||
                <SettingsTabBackground />
 | 
			
		||||
              </TabPanel>
 | 
			
		||||
              <TabPanel
 | 
			
		||||
                sx={{ p: 2 }}
 | 
			
		||||
                value="window"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 Image from "next/image";
 | 
			
		||||
import { FC } from "react";
 | 
			
		||||
import { stagedSettingsAtom } from "../../../../lib/store/jotai/settings";
 | 
			
		||||
import { CategoryTitle } from "../CategoryTitle";
 | 
			
		||||
import { SettingsItem } from "../SettingsItem";
 | 
			
		||||
 | 
			
		||||
interface SettingsTabWindowProps {
 | 
			
		||||
interface SettingsTabBackgroundProps {
 | 
			
		||||
  sx?: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const SettingsTabWindow: FC<SettingsTabWindowProps> = ({ sx }) => {
 | 
			
		||||
export const SettingsTabBackground: FC<SettingsTabBackgroundProps> = ({ sx }) => {
 | 
			
		||||
  // atoms
 | 
			
		||||
  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 = {
 | 
			
		||||
      ...stagedSettings,
 | 
			
		||||
      window: {
 | 
			
		||||
        ...stagedSettings.window,
 | 
			
		||||
      background: {
 | 
			
		||||
        ...stagedSettings.background,
 | 
			
		||||
        [settingKey]: settingValue,
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
    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 (
 | 
			
		||||
    <Box sx={{ sx }}>
 | 
			
		||||
      <CategoryTitle title="Fullscreen" />
 | 
			
		||||
      <CategoryTitle title="Wallpaper" />
 | 
			
		||||
      <Box>
 | 
			
		||||
        <Image
 | 
			
		||||
          src="/wallpaper.jpg"
 | 
			
		||||
          alt="Image not found"
 | 
			
		||||
          width={200}
 | 
			
		||||
          height={200}
 | 
			
		||||
        />
 | 
			
		||||
      </Box>
 | 
			
		||||
      <Box
 | 
			
		||||
        sx={{
 | 
			
		||||
          mb: 2,
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        <Stack
 | 
			
		||||
          direction="row"
 | 
			
		||||
          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
 | 
			
		||||
        defaultText="On"
 | 
			
		||||
        description="Fullscreen on startup"
 | 
			
		||||
        defaultText="#202124"
 | 
			
		||||
        description="Background color"
 | 
			
		||||
        input={
 | 
			
		||||
          <Switch
 | 
			
		||||
            checked={stagedSettings.window.start_fullscreen}
 | 
			
		||||
            name="start_fullscreen"
 | 
			
		||||
          <TextField
 | 
			
		||||
            name="background_color"
 | 
			
		||||
            onChange={(e) => {
 | 
			
		||||
              handleSettingsWindowValueChange(e.target.name, e.target.checked);
 | 
			
		||||
              handleSettingsBackgroundValueChange(e.target.name, e.target.value);
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
        }
 | 
			
		||||
      />
 | 
			
		||||
      <CategoryTitle title="Titlebar Buttons" />
 | 
			
		||||
      <SettingsItem
 | 
			
		||||
        defaultText="Off"
 | 
			
		||||
        description="Minimize button"
 | 
			
		||||
        input={
 | 
			
		||||
          <Switch
 | 
			
		||||
            checked={stagedSettings.window.minimize_button}
 | 
			
		||||
            name="minimize_button"
 | 
			
		||||
            onChange={(e) => {
 | 
			
		||||
              handleSettingsWindowValueChange(e.target.name, e.target.checked);
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
        }
 | 
			
		||||
      />
 | 
			
		||||
      <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);
 | 
			
		||||
            sx={{
 | 
			
		||||
              width: "100%",
 | 
			
		||||
            }}
 | 
			
		||||
            size="small"
 | 
			
		||||
            type="color"
 | 
			
		||||
            value={stagedSettings.background.background_color}
 | 
			
		||||
            variant="standard"
 | 
			
		||||
          />
 | 
			
		||||
        }
 | 
			
		||||
      />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,12 +4,8 @@ import { readTomlFile, writeTomlFile } from "./utils/toml";
 | 
			
		|||
 | 
			
		||||
export const defaultSettings = {
 | 
			
		||||
  background: {
 | 
			
		||||
    background_color: "#8ab4f8" as string,
 | 
			
		||||
    background_image: "" 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,
 | 
			
		||||
    background_color: "#202124" as string,
 | 
			
		||||
    background_image_path: "" as string,
 | 
			
		||||
  },
 | 
			
		||||
  style: {
 | 
			
		||||
    accent_color: "#8ab4f8" as string,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ import { BugReport } from "@mui/icons-material";
 | 
			
		|||
import { Box, Button, IconButton, TextField, Typography } from "@mui/material";
 | 
			
		||||
import { useRouter } from "next/router";
 | 
			
		||||
import { useState } from "react";
 | 
			
		||||
import { SettingsItem } from "../components/HeaderBar/Settings/SettingsItem";
 | 
			
		||||
import { useSettings } from "../contexts/SettingsContext";
 | 
			
		||||
import { testing } from "../lib/testing";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +13,7 @@ export default function Testing() {
 | 
			
		|||
 | 
			
		||||
  // states
 | 
			
		||||
  const [text, setText] = useState("");
 | 
			
		||||
  const [color, setColor] = useState("#000000");
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Box>
 | 
			
		||||
| 
						 | 
				
			
			@ -29,28 +31,7 @@ export default function Testing() {
 | 
			
		|||
      >
 | 
			
		||||
        reset settings
 | 
			
		||||
      </Button>
 | 
			
		||||
      <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>update settings</Button>
 | 
			
		||||
      <Button
 | 
			
		||||
        onClick={() => {
 | 
			
		||||
          console.log(settings);
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +47,25 @@ export default function Testing() {
 | 
			
		|||
        testing
 | 
			
		||||
      </Button>
 | 
			
		||||
      <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>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue