(READ ONLY) Margin is an open annotation layer for the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
98
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 79 lines 2.0 kB view raw
1import { atom, onMount } from "nanostores"; 2 3export type Theme = "light" | "dark" | "system"; 4export type Layout = "sidebar" | "compact"; 5 6export const $theme = atom<Theme>("system"); 7export const $layout = atom<Layout>("sidebar"); 8 9onMount($theme, () => { 10 if (typeof window !== "undefined") { 11 const stored = localStorage.getItem("theme") as Theme | null; 12 if (stored && ["light", "dark", "system"].includes(stored)) { 13 $theme.set(stored); 14 } 15 applyTheme($theme.get()); 16 } 17 18 return $theme.subscribe((theme) => { 19 if (typeof window !== "undefined") { 20 localStorage.setItem("theme", theme); 21 applyTheme(theme); 22 } 23 }); 24}); 25 26onMount($layout, () => { 27 if (typeof window !== "undefined") { 28 const stored = localStorage.getItem("layout_preference") as Layout | null; 29 if (stored && ["sidebar", "compact"].includes(stored)) { 30 $layout.set(stored); 31 } 32 } 33 34 return $layout.subscribe((layout) => { 35 if (typeof window !== "undefined") { 36 localStorage.setItem("layout_preference", layout); 37 } 38 }); 39}); 40 41function applyTheme(theme: Theme) { 42 const root = window.document.documentElement; 43 root.classList.remove("light", "dark"); 44 delete root.dataset.theme; 45 46 if (theme === "system") { 47 const systemTheme = window.matchMedia("(prefers-color-scheme: dark)") 48 .matches 49 ? "dark" 50 : "light"; 51 root.dataset.theme = systemTheme; 52 } else { 53 root.dataset.theme = theme; 54 } 55} 56 57if (typeof window !== "undefined") { 58 const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); 59 mediaQuery.addEventListener("change", () => { 60 if ($theme.get() === "system") { 61 applyTheme("system"); 62 } 63 }); 64} 65 66export function setTheme(theme: Theme) { 67 $theme.set(theme); 68} 69 70export function setLayout(layout: Layout) { 71 $layout.set(layout); 72} 73 74export function cycleTheme() { 75 const current = $theme.get(); 76 const next: Theme = 77 current === "system" ? "light" : current === "light" ? "dark" : "system"; 78 $theme.set(next); 79}