Radish alpha
r
rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5
Radicle web interface
Radicle
Git
add follow system theme button & functionality
Jappie3 committed 1 year ago
commit b050924caa24cdf2166a8845e6b0bf43b12cf85d
parent 870f073
2 files changed +37 -5
modified src/App/Settings.svelte
@@ -5,6 +5,7 @@
    storeCodeFont,
    storeTheme,
    theme,
+
    followSystemTheme,
  } from "@app/lib/appearance";

  import Button from "@app/components/Button.svelte";
@@ -43,7 +44,9 @@
        <Button
          ariaLabel="Light Mode"
          styleBorderRadius="0"
-
          variant={$theme === "light" ? "selected" : "not-selected"}
+
          variant={!$followSystemTheme && $theme === "light"
+
            ? "selected"
+
            : "not-selected"}
          on:click={() => storeTheme("light")}>
          <Icon name="sun" />
        </Button>
@@ -51,10 +54,20 @@
        <Button
          ariaLabel="Dark Mode"
          styleBorderRadius="0"
-
          variant={$theme === "dark" ? "selected" : "not-selected"}
+
          variant={!$followSystemTheme && $theme === "dark"
+
            ? "selected"
+
            : "not-selected"}
          on:click={() => storeTheme("dark")}>
          <Icon name="moon" />
        </Button>
+
        <div class="global-spacer" />
+
        <Button
+
          ariaLabel="System Theme"
+
          styleBorderRadius="0"
+
          variant={$followSystemTheme ? "selected" : "not-selected"}
+
          on:click={() => storeTheme("system")}>
+
          <Icon name="device" />
+
        </Button>
      </Radio>
    </div>
  </div>
modified src/lib/appearance.ts
@@ -1,6 +1,7 @@
import { writable } from "svelte/store";

export type Theme = "dark" | "light";
+
export const followSystemTheme = writable<boolean>(shouldFollowSystemTheme());
export const theme = writable<Theme>(loadTheme());

export type CodeFont = "jetbrains" | "system";
@@ -29,19 +30,28 @@ function loadCodeFont(): CodeFont {
  }
}

+
function shouldFollowSystemTheme(): boolean {
+
  const storedTheme = localStorage ? localStorage.getItem("theme") : null;
+
  if (storedTheme === null) {
+
    return true; // default to following the system theme
+
  } else {
+
    return storedTheme === "system";
+
  }
+
}
+

function loadTheme(): Theme {
  const { matches } = window.matchMedia("(prefers-color-scheme: dark)");
  const storedTheme = localStorage ? localStorage.getItem("theme") : null;

-
  if (storedTheme === null) {
+
  if (storedTheme === null || storedTheme === "system") {
    return matches ? "dark" : "light";
  } else {
    return storedTheme as Theme;
  }
}

-
export function storeTheme(newTheme: Theme): void {
-
  theme.set(newTheme);
+
export function storeTheme(newTheme: Theme | "system"): void {
+
  followSystemTheme.set(newTheme === "system" ? true : false);
  if (localStorage) {
    localStorage.setItem("theme", newTheme);
  } else {
@@ -49,6 +59,15 @@ export function storeTheme(newTheme: Theme): void {
      "localStorage isn't available, not able to persist the selected theme without it.",
    );
  }
+
  if (newTheme !== "system") {
+
    // update the theme to newTheme
+
    theme.set(newTheme);
+
  } else {
+
    // update the theme to the current system theme
+
    theme.set(
+
      window.matchMedia("(prefers-color-scheme: dark)") ? "dark" : "light",
+
    );
+
  }
}

export function storeCodeFont(newCodeFont: CodeFont): void {