Skip to content

Commit be33009

Browse files
authored
Merge pull request #4 from lancewilhelm/codex/update-reader-component-dark-mode-options
Reader: add 'gray' and 'shadow' themes, update theme picker and normalize settings
2 parents 4a2ef59 + 164d931 commit be33009

2 files changed

Lines changed: 65 additions & 20 deletions

File tree

‎app/pages/books/[id]/read.vue‎

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import type Book from 'epubjs/types/book';
33
import type Rendition from 'epubjs/types/rendition';
4+
import type { ReaderTheme } from '~/stores/userSettings';
45
56
definePageMeta({
67
auth: {
@@ -21,7 +22,6 @@ type FetchErrorLike = {
2122
};
2223
2324
type ReaderDisplayMode = 'scroll' | 'pages';
24-
type ReaderTheme = 'light' | 'dark' | 'app';
2525
2626
const route = useRoute();
2727
const bookId = computed(() => String(route.params.id || ''));
@@ -132,11 +132,16 @@ function getThemeTokens() {
132132
const delbText = rootStyles.getPropertyValue('--text-color').trim();
133133
const delbMain = rootStyles.getPropertyValue('--main-color').trim();
134134
135-
return readerTheme.value === 'light'
136-
? { bg: '#ffffff', text: '#111111', link: '#2563eb' }
137-
: readerTheme.value === 'dark'
138-
? { bg: '#1b1b1b', text: '#dddddd', link: '#93c5fd' }
139-
: { bg: delbBg, text: delbText, link: delbMain };
135+
switch (readerTheme.value) {
136+
case 'light':
137+
return { bg: '#ffffff', text: '#111111', link: '#2563eb' };
138+
case 'gray':
139+
return { bg: '#1b1b1b', text: '#dddddd', link: '#93c5fd' };
140+
case 'shadow':
141+
return { bg: '#000000', text: '#eeeeee', link: '#eeeeee' };
142+
default:
143+
return { bg: delbBg, text: delbText, link: delbMain };
144+
}
140145
}
141146
142147
function ensureReaderThemeRegistered(rendition: {
@@ -281,15 +286,18 @@ function getThemeClass(hover?: boolean) {
281286
const theme = readerTheme.value ?? 'app';
282287
283288
const base =
284-
theme === 'dark'
289+
theme === 'gray'
285290
? 'bg-[#1b1b1b] text-[#ddd]'
286-
: theme === 'light'
287-
? 'bg-[#fff] text-[#111]'
288-
: '';
291+
: theme === 'shadow'
292+
? 'bg-black text-[#eee]'
293+
: theme === 'light'
294+
? 'bg-[#fff] text-[#111]'
295+
: '';
289296
290297
if (!hover) return base;
291298
292-
if (theme === 'dark') return base + ' hover:bg-[#222]';
299+
if (theme === 'gray') return base + ' hover:bg-[#222]';
300+
if (theme === 'shadow') return base + ' hover:bg-[#111]';
293301
if (theme === 'light') return base + ' hover:bg-[#eee]';
294302
return base + ' hover:bg-(--sub-color)/5';
295303
}
@@ -612,7 +620,7 @@ watch(readerDisplayMode, async () => {
612620

613621
<div class="space-y-2">
614622
<div class="text-sm">Theme</div>
615-
<div class="grid grid-cols-3 gap-2">
623+
<div class="grid grid-cols-4 gap-2">
616624
<label class="cursor-pointer">
617625
<input
618626
v-model="readerTheme"
@@ -621,7 +629,7 @@ watch(readerDisplayMode, async () => {
621629
class="sr-only peer"
622630
/>
623631
<span
624-
class="block rounded-md px-2 py-1 text-center text-xs font-medium bg-white text-[#111] border-white peer-checked:border-(--main-color) border-2"
632+
class="flex items-center justify-center rounded-md px-2 py-1 text-center text-xs font-medium bg-white text-[#111] border-white peer-checked:border-(--main-color) border-2"
625633
>
626634
Light
627635
</span>
@@ -630,13 +638,26 @@ watch(readerDisplayMode, async () => {
630638
<input
631639
v-model="readerTheme"
632640
type="radio"
633-
value="dark"
641+
value="gray"
642+
class="sr-only peer"
643+
/>
644+
<span
645+
class="flex items-center justify-center rounded-md px-2 py-1 text-center text-xs font-medium bg-[#1b1b1b] text-[#ddd] border-[#1b1b1b] peer-checked:border-(--main-color) border-2"
646+
>
647+
Gray
648+
</span>
649+
</label>
650+
<label class="cursor-pointer">
651+
<input
652+
v-model="readerTheme"
653+
type="radio"
654+
value="shadow"
634655
class="sr-only peer"
635656
/>
636657
<span
637-
class="block rounded-md px-2 py-1 text-center text-xs font-medium bg-[#1b1b1b] text-[#ddd] border-[#1b1b1b] peer-checked:border-(--main-color) border-2"
658+
class="flex items-center justify-center rounded-md px-2 py-1 text-center text-xs font-medium bg-black text-[#eee] border-black peer-checked:border-(--main-color) border-2"
638659
>
639-
Dark
660+
Shadow
640661
</span>
641662
</label>
642663
<label class="cursor-pointer">
@@ -647,7 +668,7 @@ watch(readerDisplayMode, async () => {
647668
class="sr-only peer"
648669
/>
649670
<span
650-
class="block rounded-md px-2 py-1 text-center text-xs font-medium bg-(--sub-alt-color) text-(--text-color) border-(--sub-alt-color) peer-checked:border-(--main-color) border-2"
671+
class="flex items-center justify-center rounded-md px-2 py-1 text-center text-xs font-medium bg-(--bg-color) text-(--text-color) border-(--sub-color) peer-checked:border-(--main-color) border-2"
651672
>
652673
Delb
653674
</span>

‎app/stores/userSettings.ts‎

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export type FontFamily = (typeof fontFamilyOptions)[number];
2020
export const funboxModes = ['confetti', 'snow'];
2121
export type FunboxMode = (typeof funboxModes)[number];
2222

23+
export type ReaderTheme = 'system' | 'light' | 'gray' | 'shadow' | 'app';
24+
2325
export interface BaseUserSettings {
2426
theme?: string;
2527
fontFamily: FontFamily;
@@ -77,7 +79,7 @@ export interface BaseUserSettings {
7779
lineHeight: number;
7880
fontFamily: string;
7981
displayMode: 'pages' | 'scroll';
80-
theme: 'system' | 'light' | 'dark' | 'app';
82+
theme: ReaderTheme;
8183
};
8284
}
8385

@@ -200,6 +202,26 @@ function applyOverrides(
200202
) as unknown as BaseUserSettings;
201203
}
202204

205+
function normalizeReaderTheme(theme: unknown): ReaderTheme {
206+
if (theme === 'dark') return 'gray';
207+
if (theme === 'system') return 'system';
208+
if (theme === 'light') return 'light';
209+
if (theme === 'gray') return 'gray';
210+
if (theme === 'shadow') return 'shadow';
211+
if (theme === 'app') return 'app';
212+
return 'app';
213+
}
214+
215+
function normalizeReaderSettings(settings: BaseUserSettings): BaseUserSettings {
216+
return {
217+
...settings,
218+
reader: {
219+
...settings.reader,
220+
theme: normalizeReaderTheme(settings.reader?.theme),
221+
},
222+
};
223+
}
224+
203225
function normalizeSettings(remote: Partial<UserSettings>): UserSettings {
204226
const baseDefaults = getBaseDefaults();
205227
const defaults = getDefaultSettings();
@@ -213,6 +235,7 @@ function normalizeSettings(remote: Partial<UserSettings>): UserSettings {
213235
: defaults.mobile;
214236

215237
const base = getBaseSettings(merged);
238+
const normalizedBase = normalizeReaderSettings(base);
216239
const legacyOverrides = isPlainObject(
217240
(mobileBase as unknown as Record<string, unknown>).overrides,
218241
)
@@ -226,15 +249,16 @@ function normalizeSettings(remote: Partial<UserSettings>): UserSettings {
226249
mobileBase.settings as unknown as Record<string, unknown>,
227250
) as unknown as BaseUserSettings)
228251
: legacyOverrides
229-
? applyOverrides(base, legacyOverrides)
252+
? applyOverrides(normalizedBase, legacyOverrides)
230253
: cloneValue(baseDefaults);
231254

232255
return {
233256
...merged,
257+
...normalizedBase,
234258
mobile: {
235259
enabled: !!mobileBase.enabled,
236260
searchButton: !!mobileBase.searchButton,
237-
settings: mobileSettings,
261+
settings: normalizeReaderSettings(mobileSettings),
238262
},
239263
};
240264
}

0 commit comments

Comments
 (0)