mirror of
https://github.com/moku-project/Moku.git
synced 2026-06-13 09:19:56 -05:00
Feat: Discord RPC
This commit is contained in:
@@ -71,7 +71,7 @@
|
|||||||
inherit version;
|
inherit version;
|
||||||
src = frontendSrc;
|
src = frontendSrc;
|
||||||
fetcherVersion = 1;
|
fetcherVersion = 1;
|
||||||
hash = "sha256-4QUSgWgMu7FGn44+TGmACheokPhaBdHvA/055SqUs0Q=";
|
hash = "sha256-ezlckHhfSIe/Hs30tbiN0a/EuvGxhO5L020aup23Ozg=";
|
||||||
};
|
};
|
||||||
|
|
||||||
buildPhase = "pnpm build";
|
buildPhase = "pnpm build";
|
||||||
|
|||||||
+2
-1
@@ -15,7 +15,8 @@
|
|||||||
"@tauri-apps/plugin-shell": "^2.3.5",
|
"@tauri-apps/plugin-shell": "^2.3.5",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"phosphor-svelte": "^3.1.0",
|
"phosphor-svelte": "^3.1.0",
|
||||||
"svelte-spa-router": "^4.0.1"
|
"svelte-spa-router": "^4.0.1",
|
||||||
|
"tauri-plugin-drpc": "^1.0.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
||||||
|
|||||||
Generated
+12
@@ -26,6 +26,9 @@ importers:
|
|||||||
svelte-spa-router:
|
svelte-spa-router:
|
||||||
specifier: ^4.0.1
|
specifier: ^4.0.1
|
||||||
version: 4.0.2
|
version: 4.0.2
|
||||||
|
tauri-plugin-drpc:
|
||||||
|
specifier: ^1.0.3
|
||||||
|
version: 1.0.3(typescript@5.9.3)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@sveltejs/vite-plugin-svelte':
|
'@sveltejs/vite-plugin-svelte':
|
||||||
specifier: ^4.0.4
|
specifier: ^4.0.4
|
||||||
@@ -744,6 +747,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-TTDxwYnHkova6Wsyj1PGt9TByuWqvMoeY1bQiuAf2DM/JeDSMw7FjRKzk8K/5mJ99vGOKhbCqTDpyAKwjp4igg==}
|
resolution: {integrity: sha512-TTDxwYnHkova6Wsyj1PGt9TByuWqvMoeY1bQiuAf2DM/JeDSMw7FjRKzk8K/5mJ99vGOKhbCqTDpyAKwjp4igg==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
tauri-plugin-drpc@1.0.3:
|
||||||
|
resolution: {integrity: sha512-vl5dXhjKbl7+Nf9veW12usdmIUtZXwEf91SzxQPZlbRRJ/sjizbbQlnkUTtx6baJuGzz0KXXgP9xUhF39BdiXQ==}
|
||||||
|
peerDependencies:
|
||||||
|
typescript: ^5.0.0
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||||
engines: {node: '>=8.0'}
|
engines: {node: '>=8.0'}
|
||||||
@@ -1364,6 +1372,10 @@ snapshots:
|
|||||||
magic-string: 0.30.21
|
magic-string: 0.30.21
|
||||||
zimmerframe: 1.1.4
|
zimmerframe: 1.1.4
|
||||||
|
|
||||||
|
tauri-plugin-drpc@1.0.3(typescript@5.9.3):
|
||||||
|
dependencies:
|
||||||
|
typescript: 5.9.3
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-number: 7.0.0
|
is-number: 7.0.0
|
||||||
|
|||||||
Generated
+43
-4
@@ -290,7 +290,7 @@ checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"fnv",
|
"fnv",
|
||||||
"uuid",
|
"uuid 1.23.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2112,6 +2112,7 @@ dependencies = [
|
|||||||
"sysinfo",
|
"sysinfo",
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build",
|
"tauri-build",
|
||||||
|
"tauri-plugin-drpc",
|
||||||
"tauri-plugin-http",
|
"tauri-plugin-http",
|
||||||
"tauri-plugin-os",
|
"tauri-plugin-os",
|
||||||
"tauri-plugin-process",
|
"tauri-plugin-process",
|
||||||
@@ -3346,6 +3347,19 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rpcdiscord"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "71aa9a2097dc0176805e24debcb5d3ea5a17b796cd1d28e76b29f78fb49d7d5d"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"serde_repr",
|
||||||
|
"uuid 0.8.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-hash"
|
name = "rustc-hash"
|
||||||
version = "2.1.2"
|
version = "2.1.2"
|
||||||
@@ -3490,7 +3504,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid 1.23.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4270,7 +4284,7 @@ dependencies = [
|
|||||||
"thiserror 2.0.18",
|
"thiserror 2.0.18",
|
||||||
"time",
|
"time",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid 1.23.0",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -4305,6 +4319,22 @@ dependencies = [
|
|||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-drpc"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7b291669b7dbc05471fba380eeecf31e3f733ae6013aaa5216a43ca376027e5a"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"rpcdiscord",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin-fs"
|
name = "tauri-plugin-fs"
|
||||||
version = "2.4.5"
|
version = "2.4.5"
|
||||||
@@ -4518,7 +4548,7 @@ dependencies = [
|
|||||||
"toml 0.9.12+spec-1.1.0",
|
"toml 0.9.12+spec-1.1.0",
|
||||||
"url",
|
"url",
|
||||||
"urlpattern",
|
"urlpattern",
|
||||||
"uuid",
|
"uuid 1.23.0",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -5023,6 +5053,15 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.17",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uuid"
|
name = "uuid"
|
||||||
version = "1.23.0"
|
version = "1.23.0"
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ walkdir = "2"
|
|||||||
sysinfo = "0.32"
|
sysinfo = "0.32"
|
||||||
dirs = "5"
|
dirs = "5"
|
||||||
tauri-plugin-os = "2.3.2"
|
tauri-plugin-os = "2.3.2"
|
||||||
|
tauri-plugin-drpc = "0.1.6"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|||||||
@@ -32,6 +32,12 @@
|
|||||||
"process:default",
|
"process:default",
|
||||||
"process:allow-restart",
|
"process:allow-restart",
|
||||||
"http:default",
|
"http:default",
|
||||||
"http:allow-fetch"
|
"http:allow-fetch",
|
||||||
|
"drpc:default",
|
||||||
|
"drpc:allow-is-running",
|
||||||
|
"drpc:allow-spawn-thread",
|
||||||
|
"drpc:allow-destroy-thread",
|
||||||
|
"drpc:allow-set-activity",
|
||||||
|
"drpc:allow-clear-activity"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -527,6 +527,7 @@ fn restart_app(app: tauri::AppHandle) {
|
|||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.plugin(tauri_plugin_drpc::init())
|
||||||
.plugin(tauri_plugin_os::init())
|
.plugin(tauri_plugin_os::init())
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
.plugin(tauri_plugin_http::init())
|
.plugin(tauri_plugin_http::init())
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
import { gql } from "./lib/client";
|
import { gql } from "./lib/client";
|
||||||
import { GET_DOWNLOAD_STATUS } from "./lib/queries";
|
import { GET_DOWNLOAD_STATUS } from "./lib/queries";
|
||||||
import { store, addToast, setActiveDownloads, setSettingsOpen } from "./store/state.svelte";
|
import { store, addToast, setActiveDownloads, setSettingsOpen } from "./store/state.svelte";
|
||||||
|
import { initRpc, setIdle, clearReading, destroyRpc } from "./lib/discord";
|
||||||
import type { DownloadStatus, DownloadQueueItem } from "./lib/types";
|
import type { DownloadStatus, DownloadQueueItem } from "./lib/types";
|
||||||
import Layout from "./components/layout/Layout.svelte";
|
import Layout from "./components/layout/Layout.svelte";
|
||||||
import Reader from "./components/reader/Reader.svelte";
|
import Reader from "./components/reader/Reader.svelte";
|
||||||
@@ -263,6 +264,7 @@
|
|||||||
cancelProbe = true;
|
cancelProbe = true;
|
||||||
unlistenResize();
|
unlistenResize();
|
||||||
unlistenScale();
|
unlistenScale();
|
||||||
|
destroyRpc();
|
||||||
if (store.settings.autoStartServer) invoke("kill_server").catch(() => {});
|
if (store.settings.autoStartServer) invoke("kill_server").catch(() => {});
|
||||||
if (idleTimer) clearTimeout(idleTimer);
|
if (idleTimer) clearTimeout(idleTimer);
|
||||||
if (pollInterval) clearInterval(pollInterval);
|
if (pollInterval) clearInterval(pollInterval);
|
||||||
@@ -277,6 +279,23 @@
|
|||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (store.settings.discordRpc) {
|
||||||
|
initRpc();
|
||||||
|
} else {
|
||||||
|
clearReading();
|
||||||
|
destroyRpc();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// When the reader closes, show idle presence.
|
||||||
|
$effect(() => {
|
||||||
|
if (!store.activeChapter) {
|
||||||
|
if (store.settings.discordRpc) setIdle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function handleRetry() {
|
function handleRetry() {
|
||||||
failed = false;
|
failed = false;
|
||||||
notConfigured = false;
|
notConfigured = false;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import { FETCH_CHAPTER_PAGES, MARK_CHAPTER_READ, ENQUEUE_DOWNLOAD, ENQUEUE_CHAPTERS_DOWNLOAD } from "../../lib/queries";
|
import { FETCH_CHAPTER_PAGES, MARK_CHAPTER_READ, ENQUEUE_DOWNLOAD, ENQUEUE_CHAPTERS_DOWNLOAD } from "../../lib/queries";
|
||||||
import { store, closeReader, openReader, addHistory, updateSettings, checkAndMarkCompleted, setSettingsOpen } from "../../store/state.svelte";
|
import { store, closeReader, openReader, addHistory, updateSettings, checkAndMarkCompleted, setSettingsOpen } from "../../store/state.svelte";
|
||||||
import { matchesKeybind, toggleFullscreen, DEFAULT_KEYBINDS } from "../../lib/keybinds";
|
import { matchesKeybind, toggleFullscreen, DEFAULT_KEYBINDS } from "../../lib/keybinds";
|
||||||
|
import { setReading } from "../../lib/discord";
|
||||||
import type { FitMode } from "../../store/state.svelte";
|
import type { FitMode } from "../../store/state.svelte";
|
||||||
|
|
||||||
// ─── Constants ────────────────────────────────────────────────────────────────
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
||||||
@@ -190,6 +191,19 @@
|
|||||||
: store.activeChapter
|
: store.activeChapter
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// ─── Discord RPC ──────────────────────────────────────────────────────────────
|
||||||
|
// displayChapter already handles both single/double (store.activeChapter) and
|
||||||
|
// longstrip auto-next (visibleChapterId) — so reacting to it here means RPC
|
||||||
|
// updates on every chapter transition regardless of reading mode.
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
const chapter = displayChapter;
|
||||||
|
const manga = store.activeManga;
|
||||||
|
if (store.settings.discordRpc && chapter && manga) {
|
||||||
|
setReading(manga, chapter);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const adjacent = $derived.by(() => {
|
const adjacent = $derived.by(() => {
|
||||||
const ref = displayChapter ?? store.activeChapter;
|
const ref = displayChapter ?? store.activeChapter;
|
||||||
if (!ref || !store.activeChapterList.length) return { prev: null, next: null, remaining: [] };
|
if (!ref || !store.activeChapterList.length) return { prev: null, next: null, remaining: [] };
|
||||||
|
|||||||
@@ -775,6 +775,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="section">
|
||||||
|
<p class="section-title">Integrations</p>
|
||||||
|
<label class="toggle-row">
|
||||||
|
<div class="toggle-info"><span class="toggle-label">Discord Rich Presence</span><span class="toggle-desc">Show what you're reading in your Discord status</span></div>
|
||||||
|
<button role="switch" aria-checked={store.settings.discordRpc} aria-label="Discord Rich Presence" class="toggle" class:on={store.settings.discordRpc} onclick={() => updateSettings({ discordRpc: !store.settings.discordRpc })}><span class="toggle-thumb"></span></button>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -1778,7 +1785,7 @@
|
|||||||
<p class="section-title">Links</p>
|
<p class="section-title">Links</p>
|
||||||
<div class="about-block">
|
<div class="about-block">
|
||||||
<a href="https://github.com/Youwes09/Moku" target="_blank" class="about-line" style="color:var(--accent-fg);text-decoration:none">GitHub →</a>
|
<a href="https://github.com/Youwes09/Moku" target="_blank" class="about-line" style="color:var(--accent-fg);text-decoration:none">GitHub →</a>
|
||||||
<a href="https://discord.gg/cfncTbJ2" target="_blank" class="about-line" style="color:var(--accent-fg);text-decoration:none;margin-top:var(--sp-1)">Discord →</a>
|
<a href="https://discord.gg/Jq3pwuNqPp" target="_blank" class="about-line" style="color:var(--accent-fg);text-decoration:none;margin-top:var(--sp-1)">Discord →</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
import { start, stop, setActivity, clearActivity } from "tauri-plugin-drpc";
|
||||||
|
import { Activity, Assets, Button, Timestamps } from "tauri-plugin-drpc/activity";
|
||||||
|
import type { Manga, Chapter } from "./types";
|
||||||
|
|
||||||
|
const APP_ID = "1487894643613106298";
|
||||||
|
const FALLBACK_IMAGE = "moku_logo";
|
||||||
|
|
||||||
|
function isPublicUrl(url: string | null | undefined): boolean {
|
||||||
|
return typeof url === "string" && url.startsWith("https://");
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveCoverImage(manga: Manga): string {
|
||||||
|
return isPublicUrl(manga.thumbnailUrl) ? manga.thumbnailUrl : FALLBACK_IMAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
function trunc(s: string, max = 128): string {
|
||||||
|
return s.length <= max ? s : `${s.slice(0, max - 1)}…`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatChapter(chapter: Chapter): string {
|
||||||
|
const n = chapter.chapterNumber;
|
||||||
|
return `Chapter ${Number.isInteger(n) ? n : n.toFixed(1)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BUTTONS = [
|
||||||
|
new Button("GitHub", "https://github.com/Youwes09/Moku"),
|
||||||
|
new Button("Discord", "https://discord.gg/Jq3pwuNqPp"),
|
||||||
|
];
|
||||||
|
|
||||||
|
export async function initRpc(): Promise<void> {
|
||||||
|
await start(APP_ID)
|
||||||
|
.then(() => console.log("[discord] RPC started"))
|
||||||
|
.catch((e) => console.error("[discord] initRpc failed:", e));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setReading(manga: Manga, chapter: Chapter): Promise<void> {
|
||||||
|
const assets = new Assets()
|
||||||
|
.setLargeImage(resolveCoverImage(manga))
|
||||||
|
.setLargeText(trunc(manga.title))
|
||||||
|
.setSmallImage(FALLBACK_IMAGE)
|
||||||
|
.setSmallText("Moku");
|
||||||
|
|
||||||
|
const activity = new Activity()
|
||||||
|
.setDetails(trunc(manga.title))
|
||||||
|
.setState(`${formatChapter(chapter)} · Reading`)
|
||||||
|
.setAssets(assets)
|
||||||
|
.setTimestamps(new Timestamps(Date.now()));
|
||||||
|
activity.setButton(BUTTONS);
|
||||||
|
|
||||||
|
await setActivity(activity)
|
||||||
|
.then(() => console.log("[discord] reading →", manga.title, formatChapter(chapter)))
|
||||||
|
.catch((e) => console.error("[discord] setActivity failed:", e));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setIdle(): Promise<void> {
|
||||||
|
const assets = new Assets()
|
||||||
|
.setLargeImage(FALLBACK_IMAGE)
|
||||||
|
.setLargeText("Moku");
|
||||||
|
|
||||||
|
const activity = new Activity()
|
||||||
|
.setDetails("Browsing")
|
||||||
|
.setAssets(assets)
|
||||||
|
.setTimestamps(new Timestamps(Date.now()));
|
||||||
|
activity.setButton(BUTTONS);
|
||||||
|
|
||||||
|
await setActivity(activity)
|
||||||
|
.then(() => console.log("[discord] idle"))
|
||||||
|
.catch((e) => console.error("[discord] setActivity failed (idle):", e));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function clearReading(): Promise<void> {
|
||||||
|
await clearActivity()
|
||||||
|
.then(() => console.log("[discord] activity cleared"))
|
||||||
|
.catch((e) => console.error("[discord] clearActivity failed:", e));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function destroyRpc(): Promise<void> {
|
||||||
|
await stop()
|
||||||
|
.then(() => console.log("[discord] RPC stopped"))
|
||||||
|
.catch((e) => console.error("[discord] destroyRpc failed:", e));
|
||||||
|
}
|
||||||
@@ -180,6 +180,7 @@ export interface Settings {
|
|||||||
libraryCropCovers: boolean;
|
libraryCropCovers: boolean;
|
||||||
libraryPageSize: number;
|
libraryPageSize: number;
|
||||||
showNsfw: boolean;
|
showNsfw: boolean;
|
||||||
|
discordRpc: boolean;
|
||||||
chapterSortDir: ChapterSortDir;
|
chapterSortDir: ChapterSortDir;
|
||||||
chapterSortMode: ChapterSortMode;
|
chapterSortMode: ChapterSortMode;
|
||||||
chapterPageSize: number;
|
chapterPageSize: number;
|
||||||
@@ -252,6 +253,7 @@ export const DEFAULT_SETTINGS: Settings = {
|
|||||||
libraryCropCovers: true,
|
libraryCropCovers: true,
|
||||||
libraryPageSize: 48,
|
libraryPageSize: 48,
|
||||||
showNsfw: false,
|
showNsfw: false,
|
||||||
|
discordRpc: false,
|
||||||
chapterSortDir: "desc",
|
chapterSortDir: "desc",
|
||||||
chapterSortMode: "source",
|
chapterSortMode: "source",
|
||||||
chapterPageSize: 25,
|
chapterPageSize: 25,
|
||||||
|
|||||||
Reference in New Issue
Block a user