| 1 | import * as Schema from "effect/Schema"; |
| 2 | import * as Struct from "effect/Struct"; |
| 3 | import { ClientSettingsPatch } from "./settings.ts"; |
| 4 | import { EnvironmentTheme } from "./server.ts"; |
| 5 | |
| 6 | export const UiThemePreferences = Schema.Struct({ |
| 7 | selection: Schema.String.check(Schema.isMaxLength(128)), |
| 8 | mode: Schema.Literals(["system", "light", "dark"]), |
| 9 | halves: Schema.Struct({ |
| 10 | light: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(128))), |
| 11 | dark: Schema.optionalKey(Schema.String.check(Schema.isMaxLength(128))), |
| 12 | }), |
| 13 | customThemes: Schema.Array( |
| 14 | Schema.Struct({ |
| 15 | ...EnvironmentTheme.fields, |
| 16 | colors: Schema.requiredKey(EnvironmentTheme.fields.colors), |
| 17 | collection: Schema.optionalKey(Schema.Struct({ id: Schema.String, label: Schema.String })), |
| 18 | managed: Schema.optionalKey(Schema.Boolean), |
| 19 | }), |
| 20 | ).check(Schema.isMaxLength(64)), |
| 21 | }); |
| 22 | export type UiThemePreferences = typeof UiThemePreferences.Type; |
| 23 | |
| 24 | /** Only portable presentation preferences belong in a personal profile. */ |
| 25 | export const UiSettingsValues = Schema.Struct({ |
| 26 | ...Struct.pick(ClientSettingsPatch.fields, [ |
| 27 | "diffColorScheme", |
| 28 | "chatWidth", |
| 29 | "appearanceContrast", |
| 30 | "panelAnimationDurationMs", |
| 31 | "diffFilesCollapsed", |
| 32 | "diffIgnoreWhitespace", |
| 33 | "diffLayout", |
| 34 | "environmentIdentificationMode", |
| 35 | "fontSizeInterface", |
| 36 | "fontSizePrompt", |
| 37 | "fontSizeCode", |
| 38 | "fontSizeTerminal", |
| 39 | "fontFamilyCode", |
| 40 | "fontFamilyComposer", |
| 41 | "fontFamilySans", |
| 42 | "fontFamilyTerminal", |
| 43 | "fontSmoothing", |
| 44 | "persistComposerContextStrip", |
| 45 | "contextWindowMeterEnabled", |
| 46 | "composerCollapseOnScroll", |
| 47 | "composerRichTextEnabled", |
| 48 | "sendShortcut", |
| 49 | "followUpBehavior", |
| 50 | "proactivePanelsEnabled", |
| 51 | "showSkillsInSlashMenu", |
| 52 | "sidebarWorkingShelfEnabled", |
| 53 | "sidebarProjectGroupingMode", |
| 54 | "sidebarProjectSortOrder", |
| 55 | "sidebarThreadSortOrder", |
| 56 | "sidebarThreadPreviewCount", |
| 57 | "timestampFormat", |
| 58 | "wordWrap", |
| 59 | ]), |
| 60 | theme: Schema.optionalKey(UiThemePreferences), |
| 61 | }); |
| 62 | export type UiSettingsValues = typeof UiSettingsValues.Type; |
| 63 | |
| 64 | const Revision = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)); |
| 65 | export const UiSettingsProfile = Schema.Struct({ |
| 66 | revision: Revision, |
| 67 | values: UiSettingsValues, |
| 68 | fieldRevisions: Schema.Record(Schema.String, Revision), |
| 69 | }); |
| 70 | export type UiSettingsProfile = typeof UiSettingsProfile.Type; |
| 71 | |
| 72 | export const UiSettingsPatchInput = Schema.Struct({ |
| 73 | patch: UiSettingsValues, |
| 74 | baseRevisions: Schema.Record(Schema.String, Revision), |
| 75 | }); |
| 76 | export type UiSettingsPatchInput = typeof UiSettingsPatchInput.Type; |
| 77 | |
| 78 | export const UiSettingsPatchResult = Schema.Struct({ |
| 79 | profile: UiSettingsProfile, |
| 80 | conflicts: Schema.Array(Schema.String), |
| 81 | }); |
| 82 | export type UiSettingsPatchResult = typeof UiSettingsPatchResult.Type; |
| 83 | |
| 84 | export class UiSettingsError extends Schema.TaggedError<UiSettingsError>()("UiSettingsError", { |
| 85 | operation: Schema.Literals(["read", "write"]), |
| 86 | cause: Schema.Defect(), |
| 87 | }) { |
| 88 | override get message(): string { |
| 89 | return "Unable to sync UI settings. Reconnect to the profile environment to try again."; |
| 90 | } |
| 91 | } |