From 7f4202afd73105b850498b55ad66922b3505f0e3 Mon Sep 17 00:00:00 2001
From: Evan Simkowitz <esimkowitz@users.noreply.github.com>
Date: Sun, 14 Dec 2025 16:39:25 -0800
Subject: feat: Add unified reader settings with local overrides (#2230)

* Add initial impl

* fix some format inconsistencies, add indicator in user settings when local is out of sync

* Fix sliders in user settings, unify constants and formatting

* address CodeRabbit suggestions

* add mobile implementation

* address coderabbit nitpicks

* fix responsiveness of the reader settings popover

* Move more of the web UI strings to i18n

* update translations for more coverage

* remove duplicate logic/definitions

* fix android font family

* add shared reading setting hook between web and mobile

* unify reader settings context for both web and mobile

* remove unused export

* address coderabbit suggestions

* fix tests
---
 apps/web/app/reader/layout.tsx | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 apps/web/app/reader/layout.tsx

(limited to 'apps/web/app/reader/layout.tsx')

diff --git a/apps/web/app/reader/layout.tsx b/apps/web/app/reader/layout.tsx
new file mode 100644
index 00000000..b0c27c84
--- /dev/null
+++ b/apps/web/app/reader/layout.tsx
@@ -0,0 +1,39 @@
+import { redirect } from "next/navigation";
+import { ReaderSettingsProvider } from "@/lib/readerSettings";
+import { UserSettingsContextProvider } from "@/lib/userSettings";
+import { api } from "@/server/api/client";
+import { getServerAuthSession } from "@/server/auth";
+import { TRPCError } from "@trpc/server";
+
+import { tryCatch } from "@karakeep/shared/tryCatch";
+
+export default async function ReaderLayout({
+  children,
+}: Readonly<{
+  children: React.ReactNode;
+}>) {
+  const session = await getServerAuthSession();
+  if (!session) {
+    redirect("/");
+  }
+
+  const userSettings = await tryCatch(api.users.settings());
+
+  if (userSettings.error) {
+    if (userSettings.error instanceof TRPCError) {
+      if (
+        userSettings.error.code === "NOT_FOUND" ||
+        userSettings.error.code === "UNAUTHORIZED"
+      ) {
+        redirect("/logout");
+      }
+    }
+    throw userSettings.error;
+  }
+
+  return (
+    <UserSettingsContextProvider userSettings={userSettings.data}>
+      <ReaderSettingsProvider>{children}</ReaderSettingsProvider>
+    </UserSettingsContextProvider>
+  );
+}
-- 
cgit v1.2.3-70-g09d2

