/** * Client-only settings - persisted in localStorage. * * These settings affect only the frontend UX and never need to be read by * the server. Server-authoritative settings live in `ServerSettings` * (defined in `@t3tools/contracts/server`). */ import { Option, Schema } from "effect"; export const CLIENT_SETTINGS_STORAGE_KEY = "t3code:client-settings:v1"; export const TimestampFormat = Schema.Literals(["locale", "12-hour", "24-hour"]); export type TimestampFormat = typeof TimestampFormat.Type; export const DEFAULT_TIMESTAMP_FORMAT: TimestampFormat = "locale"; export const SidebarProjectSortOrder = Schema.Literals(["updated_at", "created_at", "manual"]); export type SidebarProjectSortOrder = typeof SidebarProjectSortOrder.Type; export const DEFAULT_SIDEBAR_PROJECT_SORT_ORDER: SidebarProjectSortOrder = "updated_at"; export const SidebarThreadSortOrder = Schema.Literals(["updated_at", "created_at"]); export type SidebarThreadSortOrder = typeof SidebarThreadSortOrder.Type; export const DEFAULT_SIDEBAR_THREAD_SORT_ORDER: SidebarThreadSortOrder = "updated_at"; const withDefaults = < S extends Schema.Top & Schema.WithoutConstructorDefault, D extends S["~type.make.in"] & S["Encoded"], >( fallback: () => D, ) => (schema: S) => schema.pipe( Schema.withConstructorDefault(() => Option.some(fallback())), Schema.withDecodingDefault(() => fallback()), ); export const ClientSettingsSchema = Schema.Struct({ confirmThreadDelete: Schema.Boolean.pipe(withDefaults(() => true)), diffWordWrap: Schema.Boolean.pipe(withDefaults(() => false)), sidebarProjectSortOrder: SidebarProjectSortOrder.pipe( withDefaults(() => DEFAULT_SIDEBAR_PROJECT_SORT_ORDER), ), sidebarThreadSortOrder: SidebarThreadSortOrder.pipe( withDefaults(() => DEFAULT_SIDEBAR_THREAD_SORT_ORDER), ), timestampFormat: TimestampFormat.pipe(withDefaults(() => DEFAULT_TIMESTAMP_FORMAT)), }); export type ClientSettings = typeof ClientSettingsSchema.Type; export const DEFAULT_CLIENT_SETTINGS: ClientSettings = ClientSettingsSchema.makeUnsafe({});