diff --git a/src/App.js b/src/App.js
index 1cae1dd..f826b18 100644
--- a/src/App.js
+++ b/src/App.js
@@ -41,6 +41,14 @@ function makeThemes(rawCustomCardColors) {
};
}
+function parseVolume(raw) {
+ // Old versions stored "on"/"off"; new versions store a 0-100 string.
+ if (raw === "on") return 100;
+ if (raw === "off") return 0;
+ const n = Number(raw);
+ return Number.isFinite(n) ? Math.max(0, Math.min(100, Math.round(n))) : 100;
+}
+
function makeKeyboardLayout(keyboardLayoutName, customKeyboardLayout) {
const emptyLayout = { verticalLayout: "", horizontalLayout: "" };
if (keyboardLayoutName !== "Custom") {
@@ -88,7 +96,12 @@ function App() {
"orientation",
"vertical"
);
- const [volume, setVolume] = useStorage("volume", "on");
+ const [rawVolume, setRawVolume] = useStorage("volume", "100");
+ const volume = parseVolume(rawVolume);
+ const setVolume = (next) =>
+ setRawVolume((prev) =>
+ String(typeof next === "function" ? next(parseVolume(prev)) : next)
+ );
const [notifications, setNotifications] = useStorage("notifications", "on");
const [focusMode, setFocusMode] = useStorage("focusMode", "off");
diff --git a/src/components/Navbar.js b/src/components/Navbar.js
index 9047617..3f2dcdf 100644
--- a/src/components/Navbar.js
+++ b/src/components/Navbar.js
@@ -1,4 +1,4 @@
-import { useContext, useEffect, useState } from "react";
+import { useContext, useEffect, useRef, useState } from "react";
import AppBar from "@material-ui/core/AppBar";
import Divider from "@material-ui/core/Divider";
@@ -6,12 +6,15 @@ import IconButton from "@material-ui/core/IconButton";
import Link from "@material-ui/core/Link";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
+import Slider from "@material-ui/core/Slider";
import Toolbar from "@material-ui/core/Toolbar";
import Tooltip from "@material-ui/core/Tooltip";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core/styles";
import EditIcon from "@material-ui/icons/Edit";
import SettingsIcon from "@material-ui/icons/Settings";
+import VolumeOffIcon from "@material-ui/icons/VolumeOff";
+import VolumeUpIcon from "@material-ui/icons/VolumeUp";
import { version } from "../config";
import { SettingsContext, UserContext } from "../context";
@@ -44,6 +47,16 @@ const useStyles = makeStyles({
visibility: "visible",
},
},
+ volumeRow: {
+ display: "flex",
+ alignItems: "center",
+ gap: 8,
+ padding: "6px 16px",
+ minWidth: 200,
+ },
+ volumeButton: {
+ padding: 4,
+ },
});
function Navbar() {
@@ -99,8 +112,15 @@ function Navbar() {
}
}
- function handleChangeVolume() {
- settings.setVolume((volume) => (volume === "on" ? "off" : "on"));
+ // Remembers the level to restore when unmuting via the keyboard shortcut
+ // or speaker icon, so toggling back doesn't always snap to 100%.
+ const lastVolume = useRef(settings.volume > 0 ? settings.volume : 100);
+ useEffect(() => {
+ if (settings.volume > 0) lastVolume.current = settings.volume;
+ }, [settings.volume]);
+
+ function handleToggleMute() {
+ settings.setVolume((v) => (v > 0 ? 0 : lastVolume.current));
}
function handleChangeTheme() {
@@ -124,7 +144,7 @@ function Navbar() {
if (modifier === "Control|Shift") {
if (key === "S") {
event.preventDefault();
- handleChangeVolume();
+ handleToggleMute();
} else if (key === "F") {
event.preventDefault();
handleChangeFocusMode();
@@ -212,14 +232,25 @@ function Navbar() {
)}