diff --git a/public/media/applications/icons/settings.svg b/public/media/applications/icons/settings.svg new file mode 100644 index 0000000..c0b8c14 --- /dev/null +++ b/public/media/applications/icons/settings.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/components/applications/settings/Settings.jsx b/src/components/applications/settings/Settings.jsx new file mode 100644 index 0000000..236f809 --- /dev/null +++ b/src/components/applications/settings/Settings.jsx @@ -0,0 +1,65 @@ +import { useEffect, useState } from "react"; +import styles from "./Settings.module.css"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faPalette } from "@fortawesome/free-solid-svg-icons"; +import { useVirtualRoot } from "../../../hooks/virtual-drive/VirtualRootContext.js"; +import { useSettings } from "../../../hooks/settings/SettingsContext.js"; +import { SettingsManager } from "../../../features/settings/settings.js"; +// eslint-disable-next-line no-unused-vars +import { VirtualRoot } from "../../../features/virtual-drive/virtual-root.js"; + +/** + * @param {Object} props + * @param {VirtualRoot} props.virtualRoot + * @param {SettingsManager} props.settingsManager + */ +function AppearanceTab({ virtualRoot, settingsManager }) { + const [wallpaper, setWallpaper] = useState(null); + const settings = settingsManager.get(SettingsManager.VIRTUAL_PATHS.desktop); + + useEffect(() => { + settings.get("wallpaper", setWallpaper); + }, [settings]); + + const onChange = (event) => { + const value = event.target.value; + settings.set("wallpaper", value); + } + + return ( +
+

Wallpaper

+
+ {virtualRoot.navigate("~/Images").getFiles().map(({ name, id, source }) => + + )} +
+
+ ); +} + +export function Settings() { + const [tabIndex, setTabIndex] = useState(0); + const virtualRoot = useVirtualRoot(); + const settingsManager = useSettings(); + + return ( +
+
+ +
+
+ {tabIndex === 0 + ? + : null + } +
+
+ ); +} \ No newline at end of file diff --git a/src/components/applications/settings/Settings.module.css b/src/components/applications/settings/Settings.module.css new file mode 100644 index 0000000..86e3bfa --- /dev/null +++ b/src/components/applications/settings/Settings.module.css @@ -0,0 +1,89 @@ +.Container { + --tabs-width: 10rem; + + flex: 1; + display: flex; + width: 100%; + height: 100%; + background-color: var(--background-color-c); +} + +.Tabs { + display: flex; + gap: 0.25rem; + flex-direction: column; + min-width: calc(var(--tabs-width) / 2); + width: var(--tabs-width); + height: 100%; + max-width: 50%; + padding: 0.5rem; + background-color: var(--background-color-b); + resize: horizontal; + overflow: hidden; +} + +.Tab-button { + display: flex; + gap: 0.5rem; + align-items: center; + width: 100%; + padding: 0.5rem; + background: none; + border: none; + border-radius: 0.5rem; + outline: none; + cursor: pointer; + transition: background-color 100ms ease-in-out; +} + +.Tab-button:hover { + background-color: rgba(255, 255, 255, 10%); +} + +.Tab-button svg { + height: 1.35rem; + aspect-ratio: 1; +} + +.Tab-panel { + flex: 1; + display: flex; + flex-wrap: wrap; + align-content: flex-start; + height: 100%; + padding: 0.5rem 1rem; + overflow: auto; +} + +.Option { + text-align: start; + max-width: 100%; +} + +.Input { + display: flex; + gap: 0.5rem; +} + +.Input > label { + flex: 1; + display: flex; +} + +.Image-select > input { + position: absolute; + opacity: 0; + width: 0; + height: 0; +} + +.Image-select > input:checked + img { + outline: 0.25rem solid var(--foreground-color-a); +} + +.Image-select > img { + width: 100%; + height: 100%; + border-radius: 0.5rem; + cursor: pointer; +} \ No newline at end of file diff --git a/src/components/task-bar/menus/HomeMenu.jsx b/src/components/task-bar/menus/HomeMenu.jsx index 0c56f8d..f372ae2 100644 --- a/src/components/task-bar/menus/HomeMenu.jsx +++ b/src/components/task-bar/menus/HomeMenu.jsx @@ -50,7 +50,10 @@ export function HomeMenu({ active, setActive, search }) { -