aboutsummaryrefslogtreecommitdiffstats
path: root/packages/shared
diff options
context:
space:
mode:
authorEvan Simkowitz <esimkowitz@users.noreply.github.com>2025-12-14 16:39:25 -0800
committerGitHub <noreply@github.com>2025-12-15 00:39:25 +0000
commit7f4202afd73105b850498b55ad66922b3505f0e3 (patch)
treea45f9f1b2599f4c9925e36dc51563b06ba6854ac /packages/shared
parent6db14ac492cd5d9e26d0d986513771f14faa7fd0 (diff)
downloadkarakeep-7f4202afd73105b850498b55ad66922b3505f0e3.tar.zst
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
Diffstat (limited to 'packages/shared')
-rw-r--r--packages/shared/types/readers.ts59
-rw-r--r--packages/shared/types/users.ts10
2 files changed, 69 insertions, 0 deletions
diff --git a/packages/shared/types/readers.ts b/packages/shared/types/readers.ts
new file mode 100644
index 00000000..117dd51b
--- /dev/null
+++ b/packages/shared/types/readers.ts
@@ -0,0 +1,59 @@
+import { z } from "zod";
+
+import { ZReaderFontFamily, zReaderFontFamilySchema } from "./users";
+
+export const READER_DEFAULTS = {
+ fontSize: 18,
+ lineHeight: 1.6,
+ fontFamily: "serif" as const,
+} as const;
+
+export const READER_FONT_FAMILIES: Record<ZReaderFontFamily, string> = {
+ serif: "ui-serif, Georgia, Cambria, serif",
+ sans: "ui-sans-serif, system-ui, sans-serif",
+ mono: "ui-monospace, Menlo, Monaco, monospace",
+} as const;
+
+// Setting constraints for UI controls
+export const READER_SETTING_CONSTRAINTS = {
+ fontSize: { min: 12, max: 24, step: 1 },
+ lineHeight: { min: 1.2, max: 2.5, step: 0.1 },
+} as const;
+
+// Formatting functions for display
+export function formatFontSize(value: number): string {
+ return `${value}px`;
+}
+
+export function formatLineHeight(value: number): string {
+ return value.toFixed(1);
+}
+
+export function formatFontFamily(
+ value: ZReaderFontFamily,
+ t?: (key: string) => string,
+): string {
+ if (t) {
+ return t(`settings.info.reader_settings.${value}`);
+ }
+ // Fallback labels when no translation function provided
+ switch (value) {
+ case "serif":
+ return "Serif";
+ case "sans":
+ return "Sans Serif";
+ case "mono":
+ return "Monospace";
+ }
+}
+
+export const zReaderSettings = z.object({
+ fontSize: z.number().int().min(12).max(24),
+ lineHeight: z.number().min(1.2).max(2.5),
+ fontFamily: zReaderFontFamilySchema,
+});
+
+export type ReaderSettings = z.infer<typeof zReaderSettings>;
+
+export const zReaderSettingsPartial = zReaderSettings.partial();
+export type ReaderSettingsPartial = z.infer<typeof zReaderSettingsPartial>;
diff --git a/packages/shared/types/users.ts b/packages/shared/types/users.ts
index 9f020d52..73b99885 100644
--- a/packages/shared/types/users.ts
+++ b/packages/shared/types/users.ts
@@ -102,6 +102,9 @@ export const zUserStatsResponseSchema = z.object({
),
});
+export const zReaderFontFamilySchema = z.enum(["serif", "sans", "mono"]);
+export type ZReaderFontFamily = z.infer<typeof zReaderFontFamilySchema>;
+
export const zUserSettingsSchema = z.object({
bookmarkClickAction: z.enum([
"open_original_link",
@@ -112,6 +115,10 @@ export const zUserSettingsSchema = z.object({
backupsEnabled: z.boolean(),
backupsFrequency: z.enum(["daily", "weekly"]),
backupsRetentionDays: z.number().int().min(1).max(365),
+ // Reader settings (nullable = opt-in, null means use client default)
+ readerFontSize: z.number().int().min(12).max(24).nullable(),
+ readerLineHeight: z.number().min(1.2).max(2.5).nullable(),
+ readerFontFamily: zReaderFontFamilySchema.nullable(),
});
export type ZUserSettings = z.infer<typeof zUserSettingsSchema>;
@@ -123,6 +130,9 @@ export const zUpdateUserSettingsSchema = zUserSettingsSchema.partial().pick({
backupsEnabled: true,
backupsFrequency: true,
backupsRetentionDays: true,
+ readerFontSize: true,
+ readerLineHeight: true,
+ readerFontFamily: true,
});
export const zUpdateBackupSettingsSchema = zUpdateUserSettingsSchema.pick({