Added storage tab to settings app
This commit is contained in:
parent
9c1074061e
commit
36e6d90276
4 changed files with 109 additions and 7 deletions
|
|
@ -1,12 +1,13 @@
|
|||
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 { faHardDrive, 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";
|
||||
|
||||
import { VirtualRoot } from "../../../features/virtual-drive/virtual-root.js";
|
||||
import { StorageManager } from "../../../features/storage/storage.js";
|
||||
import { round } from "../../../features/math/round.js";
|
||||
|
||||
/**
|
||||
* @param {object} props
|
||||
|
|
@ -26,9 +27,9 @@ function AppearanceTab({ virtualRoot, settingsManager }) {
|
|||
settings.set("wallpaper", value);
|
||||
};
|
||||
|
||||
return (
|
||||
return (<>
|
||||
<div className={styles["Option"]}>
|
||||
<p>Wallpaper</p>
|
||||
<p className={styles["Label"]}>Wallpaper</p>
|
||||
<div className={styles["Input"]}>
|
||||
{virtualRoot.navigate("~/Images")?.getFiles()?.map(({ name, id, source }) =>
|
||||
<label className={styles["Image-select"]} key={id}>
|
||||
|
|
@ -38,7 +39,31 @@ function AppearanceTab({ virtualRoot, settingsManager }) {
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
</>);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} root
|
||||
* @param {VirtualRoot} root.virtualRoot
|
||||
*/
|
||||
function StorageTab({ virtualRoot }) {
|
||||
const maxBytes = StorageManager.MAX_BYTES;
|
||||
const usedBytes = StorageManager.getByteSize(virtualRoot.toString());
|
||||
|
||||
const maxKB = StorageManager.byteToKilobyte(maxBytes);
|
||||
const usedKB = StorageManager.byteToKilobyte(usedBytes);
|
||||
const freeKB = maxKB - usedKB;
|
||||
|
||||
return (<>
|
||||
<div className={styles["Option"]}>
|
||||
<p className={styles["Label"]}>Virtual Drive ({round(maxKB, 1)} KB)</p>
|
||||
<p>{round(usedKB, 1)} KB used - {round(freeKB, 1)} KB free</p>
|
||||
</div>
|
||||
<div className={styles["Option"]}>
|
||||
<p className={styles["Label"]}>Manage data</p>
|
||||
<button title="Reset" className={`${styles.Button} ${styles["Button-red"]}`}>Reset</button>
|
||||
</div>
|
||||
</>);
|
||||
}
|
||||
|
||||
export function Settings() {
|
||||
|
|
@ -49,15 +74,21 @@ export function Settings() {
|
|||
return (
|
||||
<div className={styles.Container}>
|
||||
<div className={styles.Tabs}>
|
||||
<button title="Home" className={styles["Tab-button"]} onClick={() => { setTabIndex(0); }}>
|
||||
<button title="Appearance" className={styles["Tab-button"]} onClick={() => { setTabIndex(0); }}>
|
||||
<FontAwesomeIcon icon={faPalette}/>
|
||||
Appearance
|
||||
</button>
|
||||
<button title="Storage" className={styles["Tab-button"]} onClick={() => { setTabIndex(1); }}>
|
||||
<FontAwesomeIcon icon={faHardDrive}/>
|
||||
Storage
|
||||
</button>
|
||||
</div>
|
||||
<div className={styles["Tab-panel"]}>
|
||||
{tabIndex === 0
|
||||
? <AppearanceTab virtualRoot={virtualRoot} settingsManager={settingsManager}/>
|
||||
: null
|
||||
: tabIndex === 1
|
||||
? <StorageTab virtualRoot={virtualRoot}/>
|
||||
: null
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
flex: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
align-content: flex-start;
|
||||
height: 100%;
|
||||
padding: 0.5rem 1rem;
|
||||
|
|
@ -60,6 +61,14 @@
|
|||
max-width: 100%;
|
||||
}
|
||||
|
||||
.Option > .Label {
|
||||
color: var(--foreground-color-a);
|
||||
}
|
||||
|
||||
.Option > p {
|
||||
color: var(--foreground-color-c);
|
||||
}
|
||||
|
||||
.Input {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
|
|
@ -86,4 +95,31 @@
|
|||
height: 100%;
|
||||
border-radius: 0.5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.Button {
|
||||
--hover-color: var(--background-color-b);
|
||||
|
||||
padding: 0.5rem 1rem;
|
||||
color: var(--foreground-color-a);
|
||||
background-color: var(--background-color-a);
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
outline: none;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.05rem;
|
||||
transition: background-color 100ms ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.Button:hover, .Button:focus {
|
||||
background-color: var(--hover-color);
|
||||
}
|
||||
|
||||
.Button-red {
|
||||
--hover-color: var(--red-b);
|
||||
|
||||
color: var(--background-color-a);
|
||||
background-color: var(--red-a);
|
||||
}
|
||||
9
src/features/math/round.js
Normal file
9
src/features/math/round.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* @param {number} value
|
||||
* @param {number} precision
|
||||
* @returns {number}
|
||||
*/
|
||||
export function round(value, precision) {
|
||||
const multiplier = Math.pow(10, precision || 0);
|
||||
return Math.round(value * multiplier) / multiplier;
|
||||
}
|
||||
|
|
@ -1,8 +1,18 @@
|
|||
export class StorageManager {
|
||||
static MAX_BYTES = 5_000_000;
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @param {string} value
|
||||
*/
|
||||
static store(key, value) {
|
||||
localStorage.setItem(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @returns {string | null}
|
||||
*/
|
||||
static load(key) {
|
||||
return localStorage.getItem(key);
|
||||
}
|
||||
|
|
@ -10,4 +20,20 @@ export class StorageManager {
|
|||
static clear() {
|
||||
localStorage.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} string
|
||||
* @returns {number} bytes
|
||||
*/
|
||||
static getByteSize(string) {
|
||||
return new Blob([string]).size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} bytes
|
||||
* @returns {number} kilobytes
|
||||
*/
|
||||
static byteToKilobyte(bytes) {
|
||||
return bytes / 1000;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue