add custom theme

This commit is contained in:
Pas 2026-02-20 15:04:18 -07:00
parent 51211c4716
commit e72dacf32d
3 changed files with 17 additions and 5 deletions

View file

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "user_settings" ADD COLUMN "custom_theme" JSONB;

View file

@ -95,6 +95,7 @@ model user_group_order {
model user_settings { model user_settings {
id String @id id String @id
application_theme String? @db.VarChar(255) application_theme String? @db.VarChar(255)
custom_theme Json?
application_language String? @db.VarChar(255) application_language String? @db.VarChar(255)
default_subtitle_language String? @db.VarChar(255) default_subtitle_language String? @db.VarChar(255)
proxy_urls String[] proxy_urls String[]

View file

@ -1,13 +1,17 @@
import { useAuth } from '~/utils/auth'; import { useAuth } from '~/utils/auth';
import { z } from 'zod'; import { z } from 'zod';
import { scopedLogger } from '~/utils/logger'; import { scopedLogger } from '~/utils/logger';
import type { user_settings } from '~/../generated/client';
import { prisma } from '~/utils/prisma'; import { prisma } from '~/utils/prisma';
const log = scopedLogger('user-settings'); const log = scopedLogger('user-settings');
const userSettingsSchema = z.object({ const userSettingsSchema = z.object({
applicationTheme: z.string().nullable().optional(), applicationTheme: z.string().nullable().optional(),
customTheme: z.object({
primary: z.string(),
secondary: z.string(),
tertiary: z.string(),
}).nullable().optional(),
applicationLanguage: z.string().optional().default('en'), applicationLanguage: z.string().optional().default('en'),
defaultSubtitleLanguage: z.string().nullable().optional(), defaultSubtitleLanguage: z.string().nullable().optional(),
proxyUrls: z.array(z.string()).nullable().optional(), proxyUrls: z.array(z.string()).nullable().optional(),
@ -66,13 +70,14 @@ export default defineEventHandler(async event => {
if (event.method === 'GET') { if (event.method === 'GET') {
try { try {
const settings = (await prisma.user_settings.findUnique({ const settings = await prisma.user_settings.findUnique({
where: { id: userId }, where: { id: userId },
})) as unknown as user_settings | null; });
return { return {
id: userId, id: userId,
applicationTheme: settings?.application_theme || null, applicationTheme: settings?.application_theme || null,
customTheme: settings?.custom_theme || null,
applicationLanguage: settings?.application_language || 'en', applicationLanguage: settings?.application_language || 'en',
defaultSubtitleLanguage: settings?.default_subtitle_language || null, defaultSubtitleLanguage: settings?.default_subtitle_language || null,
proxyUrls: settings?.proxy_urls.length === 0 ? null : settings?.proxy_urls || null, proxyUrls: settings?.proxy_urls.length === 0 ? null : settings?.proxy_urls || null,
@ -124,6 +129,7 @@ export default defineEventHandler(async event => {
const createData = { const createData = {
application_theme: validatedBody.applicationTheme ?? null, application_theme: validatedBody.applicationTheme ?? null,
custom_theme: validatedBody.customTheme ?? null,
application_language: validatedBody.applicationLanguage, application_language: validatedBody.applicationLanguage,
default_subtitle_language: validatedBody.defaultSubtitleLanguage ?? null, default_subtitle_language: validatedBody.defaultSubtitleLanguage ?? null,
proxy_urls: validatedBody.proxyUrls === null ? [] : validatedBody.proxyUrls || [], proxy_urls: validatedBody.proxyUrls === null ? [] : validatedBody.proxyUrls || [],
@ -159,6 +165,8 @@ export default defineEventHandler(async event => {
const updateData: Partial<typeof createData> = {}; const updateData: Partial<typeof createData> = {};
if (Object.prototype.hasOwnProperty.call(body, 'applicationTheme')) if (Object.prototype.hasOwnProperty.call(body, 'applicationTheme'))
updateData.application_theme = createData.application_theme; updateData.application_theme = createData.application_theme;
if (Object.prototype.hasOwnProperty.call(body, 'customTheme'))
updateData.custom_theme = createData.custom_theme;
if (Object.prototype.hasOwnProperty.call(body, 'applicationLanguage')) if (Object.prototype.hasOwnProperty.call(body, 'applicationLanguage'))
updateData.application_language = createData.application_language; updateData.application_language = createData.application_language;
if (Object.prototype.hasOwnProperty.call(body, 'defaultSubtitleLanguage')) if (Object.prototype.hasOwnProperty.call(body, 'defaultSubtitleLanguage'))
@ -224,20 +232,21 @@ export default defineEventHandler(async event => {
createData: { id: userId, ...createData }, createData: { id: userId, ...createData },
}); });
const settings = (await prisma.user_settings.upsert({ const settings = await prisma.user_settings.upsert({
where: { id: userId }, where: { id: userId },
update: updateData, update: updateData,
create: { create: {
id: userId, id: userId,
...createData, ...createData,
}, },
})) as unknown as user_settings; });
log.info('Settings updated successfully', { userId }); log.info('Settings updated successfully', { userId });
return { return {
id: userId, id: userId,
applicationTheme: settings.application_theme, applicationTheme: settings.application_theme,
customTheme: settings.custom_theme,
applicationLanguage: settings.application_language, applicationLanguage: settings.application_language,
defaultSubtitleLanguage: settings.default_subtitle_language, defaultSubtitleLanguage: settings.default_subtitle_language,
proxyUrls: settings.proxy_urls.length === 0 ? null : settings.proxy_urls, proxyUrls: settings.proxy_urls.length === 0 ? null : settings.proxy_urls,