import { DeleteOutline, FileOpenOutlined } from "@mui/icons-material"; import { Box, Button, CircularProgress, LinearProgress, Stack, TextField, Typography } from "@mui/material"; import { open } from "@tauri-apps/api/dialog"; import { readBinaryFile } from "@tauri-apps/api/fs"; import { invoke } from "@tauri-apps/api/tauri"; import { useAtom } from "jotai"; import Image from "next/image"; import { FC, useEffect, useState } from "react"; import { useSettings } from "../../../../contexts/SettingsContext"; import { defaultSettings } from "../../../../lib/settings"; import { stagedSettingsAtom } from "../../../../lib/store/jotai/settings"; import { CategoryTitle } from "../CategoryTitle"; import { SettingsItem } from "../SettingsItem"; interface BackgroundProps { sx?: any; } export const Background: FC = ({ sx }) => { // contexts const { settings } = useSettings(); // atoms const [stagedSettings, setStagedSettings] = useAtom(stagedSettingsAtom); // states const [oldWallpaperPath, setOldWallpaperPath] = useState(null); const [targetWallpaperPath, setTargetWallpaperPath] = useState(null); const [imageBlob, setImageBlob] = useState(null); const [noImageSelectedIcon, setNoImageSelectedIcon] = useState(null); const handleSettingsBackgroundValueChange = ( settingKey: string, settingValue: boolean | number | string | number[], ) => { const newSettings = { ...stagedSettings, background: { ...stagedSettings.background, [settingKey]: settingValue, }, }; setStagedSettings(newSettings); return newSettings; }; const setImageSrc = async (filePath: string) => { const imageBlobTemp = await readBinaryFile(filePath); if (imageBlobTemp) setImageBlob(URL.createObjectURL(new Blob([imageBlobTemp]))); }; const selectImage = async () => { const { appLocalDataDir, basename } = await import("@tauri-apps/api/path"); // clear the states first setTargetWallpaperPath(null); setImageBlob(null); let selectedFilePath = await open({ multiple: false, filters: [ { name: "Images", extensions: ["jpg", "png", "jpeg", "webp", "gif"], }, ], }); // if the user somehow manages to select multiple files, take the first file if (Array.isArray(selectedFilePath)) { selectedFilePath = selectedFilePath[0]; } if (selectedFilePath) { setTargetWallpaperPath(selectedFilePath); // construct the destination file path const appLocalDataDirPath = await appLocalDataDir(); const filename = await basename(selectedFilePath); const destinationFilePath = appLocalDataDirPath + "wallpaper/" + filename; handleSettingsBackgroundValueChange("background_image_path", destinationFilePath); } }; const clearImage = async () => { handleSettingsBackgroundValueChange("background_image_path", ""); }; // if settings.background.background_image_path changes, update the image useEffect(() => { const applyWallpaper = async () => { // apply the new wallpaper image try { // if there is already a wallpaper file, delete it if (settings.background.background_image_path && oldWallpaperPath) { try { await invoke("delete_old_wallpaper_images"); } catch (error) { console.error("Failed to delete old wallpaper image", error); } } if (targetWallpaperPath) await invoke("process_wallpaper_image", { filePathString: targetWallpaperPath, }); } catch (error) { console.error(error); } }; applyWallpaper(); setOldWallpaperPath(settings.background.background_image_path); // eslint-disable-next-line react-hooks/exhaustive-deps }, [settings.background.background_image_path]); // update the preview image when stagedSettings.background.background_image_path changes useEffect(() => { if (targetWallpaperPath) { setImageSrc(targetWallpaperPath); } else { setImageBlob(null); } }, [targetWallpaperPath]); useEffect(() => {}); return ( {imageBlob ? ( Image not found ) : ( {targetWallpaperPath ? ( ) : ( <> {/* eslint-disable-next-line @next/next/no-img-element */} Image not found No image selected )} )} { handleSettingsBackgroundValueChange(e.target.name, e.target.value); }} sx={{ width: "100%", }} size="small" type="color" value={stagedSettings.background.background_color} variant="standard" /> } /> { handleSettingsBackgroundValueChange(e.target.name, e.target.value); }} sx={{ width: "100%", }} size="small" type="color" value={stagedSettings.background.background_color_popup} variant="standard" /> } /> ); };