Added storage tab to settings app

This commit is contained in:
Prozilla 2023-08-07 14:09:42 +02:00
parent 9c1074061e
commit 36e6d90276
No known key found for this signature in database
GPG key ID: 5858DFE71CAF31EE
4 changed files with 109 additions and 7 deletions

View file

@ -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>

View file

@ -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);
}

View 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;
}

View file

@ -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;
}
}