feat(reader): add light/dark mode toggle for reading themes
Add explicit light/dark mode toggle switch to the reading theme settings. The reading mode defaults based on the chrome theme (dark chrome themes like tokyo-night default to dark reading mode). - Add readingMode property to readerShell Alpine component - Add toggleReadingMode() method that toggles dark class on body - Add detectChromeDarkMode() to infer default from chrome theme - Update applyTheme() to add/remove dark class and persist reading_mode - Add toggle switch UI in settings panel (blue pill style, next to Reading Theme heading) - Add reading_mode to default settings in settings-manager
This commit is contained in:
@@ -84,7 +84,8 @@ document.addEventListener("alpine:init", () => {
|
||||
bookmarksOpen: false,
|
||||
navigatorOpen: false,
|
||||
tocItems: [] as any[],
|
||||
readingTheme: "dark" as string,
|
||||
readingTheme: "light" as string,
|
||||
readingMode: "light" as string,
|
||||
readingFont: "literata" as string,
|
||||
fontSize: 16 as number,
|
||||
lineHeight: 1.6 as number,
|
||||
@@ -97,13 +98,21 @@ document.addEventListener("alpine:init", () => {
|
||||
}) {
|
||||
this.settings = await loadSettings();
|
||||
if (this.settings) {
|
||||
this.readingTheme = this.settings.reading_theme || "dark";
|
||||
this.readingTheme = this.settings.reading_theme || "light";
|
||||
this.readingFont = this.settings.reading_font || "literata";
|
||||
this.fontSize = this.settings.font_size || 16;
|
||||
this.lineHeight = this.settings.line_height || 1.6;
|
||||
if (this.settings.reading_theme) {
|
||||
document.body.classList.add(`theme-${this.settings.reading_theme}`);
|
||||
}
|
||||
if (this.settings.reading_mode) {
|
||||
this.readingMode = this.settings.reading_mode;
|
||||
} else {
|
||||
this.readingMode = this.detectChromeDarkMode() ? "dark" : "light";
|
||||
}
|
||||
if (this.readingMode === "dark") {
|
||||
document.body.classList.add("dark");
|
||||
}
|
||||
}
|
||||
this.view = document.getElementById("reader-view") as any;
|
||||
const resp = await fetch(config.fileUrl, {
|
||||
@@ -258,10 +267,29 @@ document.addEventListener("alpine:init", () => {
|
||||
applyTheme() {
|
||||
document.body.className = document.body.className
|
||||
.replace(/theme-(?!tokyo|dracula|nord|solarized|monokai|one-dark|material|catppuccin)[\w-]+/g, "")
|
||||
.replace(/\bdark\b/g, "")
|
||||
.trim();
|
||||
document.body.classList.add(`theme-${this.readingTheme}`);
|
||||
if (this.readingMode === "dark") {
|
||||
document.body.classList.add("dark");
|
||||
}
|
||||
this.applyStyles();
|
||||
saveSettings({ reading_theme: this.readingTheme });
|
||||
saveSettings({
|
||||
reading_theme: this.readingTheme,
|
||||
reading_mode: this.readingMode,
|
||||
});
|
||||
},
|
||||
toggleReadingMode() {
|
||||
this.readingMode = this.readingMode === "dark" ? "light" : "dark";
|
||||
this.applyTheme();
|
||||
},
|
||||
detectChromeDarkMode(): boolean {
|
||||
const darkChromeThemes = [
|
||||
"theme-tokyo-night", "theme-dracula", "theme-nord",
|
||||
"theme-monokai", "theme-one-dark", "theme-material",
|
||||
"theme-catppuccin",
|
||||
];
|
||||
return darkChromeThemes.some((t) => document.body.classList.contains(t));
|
||||
},
|
||||
applyFont() {
|
||||
this.applyStyles();
|
||||
|
||||
@@ -70,7 +70,8 @@ export function getDefaultSettings(): ReaderSettings {
|
||||
chrome_behavior: "auto-hide",
|
||||
progress_mode: "pages",
|
||||
chrome_theme: "tokyo-night",
|
||||
reading_theme: "dark",
|
||||
reading_theme: "light",
|
||||
reading_mode: "dark",
|
||||
reading_font: "literata",
|
||||
tap_zone_size: 30,
|
||||
auto_scroll: false,
|
||||
|
||||
Reference in New Issue
Block a user