| author | |
| committer | |
| log | 20a8f1de3668e0ff4da236d75258e2184a68d727 |
| tree | 890d47d0b4be2104662ee7d15e33af64ac0d02a5 |
| parent | db6e0531e4faac0fc5ac0e12088b01bed6e7b851 |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Claude Code <noreply@anthropic.com>11 files changed, 67 insertions(+), 34 deletions(-)
apps/mobile/modules/t3-markdown-text/src/NativeMarkdownSelectableText.tsx+1-1| ... | @@ -98,7 +98,7 @@ function resolveHeadingFontSize(textStyle: NativeMarkdownTextStyle, headingLevel | ... | @@ -98,7 +98,7 @@ function resolveHeadingFontSize(textStyle: NativeMarkdownTextStyle, headingLevel |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | const scale = textStyle.fontSize / DEFAULT_BODY_FONT_SIZE; | 100 | const scale = textStyle.fontSize / DEFAULT_BODY_FONT_SIZE; |
| 101 | return Math.max(12, Math.round(DEFAULT_HEADING_FONT_SIZES[index] * scale)); | 101 | return Math.max(12, Math.round((DEFAULT_HEADING_FONT_SIZES[index] ?? 15) * scale)); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | function runStyle(run: NativeMarkdownTextRun, textStyle: NativeMarkdownTextStyle): TextStyle { | 104 | function runStyle(run: NativeMarkdownTextRun, textStyle: NativeMarkdownTextStyle): TextStyle { |
apps/mobile/scripts/generate-uniwind-themes.mts+3-3| ... | @@ -53,7 +53,7 @@ const color = (family: TailwindColorFamily, shade?: TailwindColorShade, opacity | ... | @@ -53,7 +53,7 @@ const color = (family: TailwindColorFamily, shade?: TailwindColorShade, opacity |
| 53 | // These replace the remaining dark:* utility pairs. A registered palette theme is | 53 | // These replace the remaining dark:* utility pairs. A registered palette theme is |
| 54 | // neither literally `light` nor `dark`, so appearance-sensitive values must also be | 54 | // neither literally `light` nor `dark`, so appearance-sensitive values must also be |
| 55 | // represented as semantic variables for custom themes. | 55 | // represented as semantic variables for custom themes. |
| 56 | const ADAPTIVE_COLORS = { | 56 | const ADAPTIVE_COLORS: Readonly<Record<string, readonly [light: string, dark: string]>> = { |
| 57 | "--color-adaptive-amber-50-950-a40": [color("amber", 50), color("amber", 950, 0.4)], | 57 | "--color-adaptive-amber-50-950-a40": [color("amber", 50), color("amber", 950, 0.4)], |
| 58 | "--color-adaptive-amber-200-900-a60": [color("amber", 200), color("amber", 900, 0.6)], | 58 | "--color-adaptive-amber-200-900-a60": [color("amber", 200), color("amber", 900, 0.6)], |
| 59 | "--color-adaptive-amber-500-a12-a16": [color("amber", 500, 0.12), color("amber", 500, 0.16)], | 59 | "--color-adaptive-amber-500-a12-a16": [color("amber", 500, 0.12), color("amber", 500, 0.16)], |
| ... | @@ -143,9 +143,9 @@ export const customThemeNames = BUILT_IN_THEME_IDS.flatMap((themeId) => | ... | @@ -143,9 +143,9 @@ export const customThemeNames = BUILT_IN_THEME_IDS.flatMap((themeId) => |
| 143 | 143 | ||
| 144 | const adaptiveVariablesFor = (appearance: MobileThemeAppearance) => | 144 | const adaptiveVariablesFor = (appearance: MobileThemeAppearance) => |
| 145 | Object.fromEntries( | 145 | Object.fromEntries( |
| 146 | Object.entries(ADAPTIVE_COLORS).map(([name, values]) => [ | 146 | Object.entries(ADAPTIVE_COLORS).map(([name, [light, dark]]) => [ |
| 147 | name, | 147 | name, |
| 148 | values[appearance === "light" ? 0 : 1], | 148 | appearance === "light" ? light : dark, |
| 149 | ]), | 149 | ]), |
| 150 | ); | 150 | ); |
| 151 | 151 |
apps/mobile/src/components/AndroidAnchoredMenu.tsx+1-1| ... | @@ -125,7 +125,7 @@ export function AndroidAnchoredMenu(props: AndroidAnchoredMenuProps) { | ... | @@ -125,7 +125,7 @@ export function AndroidAnchoredMenu(props: AndroidAnchoredMenuProps) { |
| 125 | return () => subscription.remove(); | 125 | return () => subscription.remove(); |
| 126 | }, [anchor, close, submenuDepth]); | 126 | }, [anchor, close, submenuDepth]); |
| 127 | 127 | ||
| 128 | const parent = path.length > 0 ? path[path.length - 1] : null; | 128 | const parent = path[path.length - 1] ?? null; |
| 129 | const levelActions = (parent?.subactions ?? props.actions).filter( | 129 | const levelActions = (parent?.subactions ?? props.actions).filter( |
| 130 | (action) => !(action.attributes?.hidden ?? false), | 130 | (action) => !(action.attributes?.hidden ?? false), |
| 131 | ); | 131 | ); |
apps/mobile/src/features/review/nativeReviewDiffAdapter.ts+4-1| ... | @@ -53,7 +53,7 @@ function opaqueNativeHexColor(color: string, background: string): string { | ... | @@ -53,7 +53,7 @@ function opaqueNativeHexColor(color: string, background: string): string { |
| 53 | const alpha = rgba[4] === undefined ? 1 : Math.min(1, Math.max(0, Number(rgba[4]))); | 53 | const alpha = rgba[4] === undefined ? 1 : Math.min(1, Math.max(0, Number(rgba[4]))); |
| 54 | const channels = [1, 2, 3].map((index) => { | 54 | const channels = [1, 2, 3].map((index) => { |
| 55 | const foreground = Number(rgba[index]); | 55 | const foreground = Number(rgba[index]); |
| 56 | const behind = Number.parseInt(backgroundHex[index], 16); | 56 | const behind = Number.parseInt(backgroundHex[index] ?? "0", 16); |
| 57 | return Math.round(foreground * alpha + behind * (1 - alpha)); | 57 | return Math.round(foreground * alpha + behind * (1 - alpha)); |
| 58 | }); | 58 | }); |
| 59 | return `#${channels.map((channel) => channel.toString(16).padStart(2, "0")).join("")}`; | 59 | return `#${channels.map((channel) => channel.toString(16).padStart(2, "0")).join("")}`; |
| ... | @@ -358,6 +358,9 @@ function addNativeWordDiffRanges( | ... | @@ -358,6 +358,9 @@ function addNativeWordDiffRanges( |
| 358 | for (let pairIndex = 0; pairIndex < pairedCount; pairIndex += 1) { | 358 | for (let pairIndex = 0; pairIndex < pairedCount; pairIndex += 1) { |
| 359 | const deletedRowIndex = deletedRowIndexes[pairIndex]; | 359 | const deletedRowIndex = deletedRowIndexes[pairIndex]; |
| 360 | const addedRowIndex = addedRowIndexes[pairIndex]; | 360 | const addedRowIndex = addedRowIndexes[pairIndex]; |
| 361 | if (deletedRowIndex === undefined || addedRowIndex === undefined) { | ||
| 362 | continue; | ||
| 363 | } | ||
| 361 | const deletedRow = nextRows[deletedRowIndex]; | 364 | const deletedRow = nextRows[deletedRowIndex]; |
| 362 | const addedRow = nextRows[addedRowIndex]; | 365 | const addedRow = nextRows[addedRowIndex]; |
| 363 | if (!deletedRow?.content || !addedRow?.content) { | 366 | if (!deletedRow?.content || !addedRow?.content) { |
apps/mobile/src/features/review/reviewModel.test.ts+2-2| ... | @@ -84,7 +84,7 @@ describe("buildReviewSectionItems", () => { | ... | @@ -84,7 +84,7 @@ describe("buildReviewSectionItems", () => { |
| 84 | }, | 84 | }, |
| 85 | ]; | 85 | ]; |
| 86 | 86 | ||
| 87 | const loadedTurnId = getReviewSectionIdForCheckpoint(checkpoints[0]); | 87 | const loadedTurnId = getReviewSectionIdForCheckpoint(checkpoints[0]!); |
| 88 | const items = buildReviewSectionItems({ | 88 | const items = buildReviewSectionItems({ |
| 89 | checkpoints, | 89 | checkpoints, |
| 90 | gitSections, | 90 | gitSections, |
| ... | @@ -92,7 +92,7 @@ describe("buildReviewSectionItems", () => { | ... | @@ -92,7 +92,7 @@ describe("buildReviewSectionItems", () => { |
| 92 | [loadedTurnId]: "diff --git a/loaded.ts b/loaded.ts", | 92 | [loadedTurnId]: "diff --git a/loaded.ts b/loaded.ts", |
| 93 | }, | 93 | }, |
| 94 | loadingTurnIds: { | 94 | loadingTurnIds: { |
| 95 | [getReviewSectionIdForCheckpoint(checkpoints[1])]: true, | 95 | [getReviewSectionIdForCheckpoint(checkpoints[1]!)]: true, |
| 96 | }, | 96 | }, |
| 97 | loadingGitSections: false, | 97 | loadingGitSections: false, |
| 98 | }); | 98 | }); |
apps/mobile/src/features/terminal/terminalTheme.ts+27-3| ... | @@ -1,4 +1,8 @@ | ... | @@ -1,4 +1,8 @@ |
| 1 | import { BUILT_IN_THEMES, getThemeColorsForAppearance } from "@t3tools/shared/themePalettes"; | 1 | import { |
| 2 | BUILT_IN_THEMES, | ||
| 3 | T3_CHAT_THEME, | ||
| 4 | getThemeColorsForAppearance, | ||
| 5 | } from "@t3tools/shared/themePalettes"; | ||
| 2 | 6 | ||
| 3 | import { | 7 | import { |
| 4 | getMobileThemeVariables, | 8 | getMobileThemeVariables, |
| ... | @@ -15,9 +19,29 @@ export interface TerminalTheme { | ... | @@ -15,9 +19,29 @@ export interface TerminalTheme { |
| 15 | readonly border: string; | 19 | readonly border: string; |
| 16 | readonly cursorForeground: string; | 20 | readonly cursorForeground: string; |
| 17 | readonly cursorBackground: string; | 21 | readonly cursorBackground: string; |
| 18 | readonly palette: readonly string[]; | 22 | /** The 16 ANSI colors, in order. A fixed tuple so indexed reads are never undefined. */ |
| 23 | readonly palette: TerminalPalette; | ||
| 19 | } | 24 | } |
| 20 | 25 | ||
| 26 | type TerminalPalette = readonly [ | ||
| 27 | string, | ||
| 28 | string, | ||
| 29 | string, | ||
| 30 | string, | ||
| 31 | string, | ||
| 32 | string, | ||
| 33 | string, | ||
| 34 | string, | ||
| 35 | string, | ||
| 36 | string, | ||
| 37 | string, | ||
| 38 | string, | ||
| 39 | string, | ||
| 40 | string, | ||
| 41 | string, | ||
| 42 | string, | ||
| 43 | ]; | ||
| 44 | |||
| 21 | const PIERRE_LIGHT_THEME: TerminalTheme = { | 45 | const PIERRE_LIGHT_THEME: TerminalTheme = { |
| 22 | // Pierre terminal palette with the app's shared screen background. | 46 | // Pierre terminal palette with the app's shared screen background. |
| 23 | background: "#f2f2f7", | 47 | background: "#f2f2f7", |
| ... | @@ -85,7 +109,7 @@ export function getMobileTerminalTheme( | ... | @@ -85,7 +109,7 @@ export function getMobileTerminalTheme( |
| 85 | const base = getPierreTerminalTheme(scheme); | 109 | const base = getPierreTerminalTheme(scheme); |
| 86 | if (themeId === "t3-code" || themeId === "material-you") return base; | 110 | if (themeId === "t3-code" || themeId === "material-you") return base; |
| 87 | 111 | ||
| 88 | const theme = BUILT_IN_THEMES.find((candidate) => candidate.id === themeId) ?? BUILT_IN_THEMES[0]; | 112 | const theme = BUILT_IN_THEMES.find((candidate) => candidate.id === themeId) ?? T3_CHAT_THEME; |
| 89 | const palette = getThemeColorsForAppearance(theme, scheme) ?? theme.colors; | 113 | const palette = getThemeColorsForAppearance(theme, scheme) ?? theme.colors; |
| 90 | const colors = getMobileThemeVariables(themeId, scheme); | 114 | const colors = getMobileThemeVariables(themeId, scheme); |
| 91 | const background = themeColorToNativeColor(palette.terminalBackground); | 115 | const background = themeColorToNativeColor(palette.terminalBackground); |
apps/mobile/src/lib/mobileTheme.test-support.ts+1-1| ... | @@ -14,7 +14,7 @@ export function readDefaultMobileThemeVariables( | ... | @@ -14,7 +14,7 @@ export function readDefaultMobileThemeVariables( |
| 14 | return Object.fromEntries( | 14 | return Object.fromEntries( |
| 15 | Array.from(variant.matchAll(/(--color-[a-z0-9-]+):\s*([^;]+);/gu), ([, name, value]) => [ | 15 | Array.from(variant.matchAll(/(--color-[a-z0-9-]+):\s*([^;]+);/gu), ([, name, value]) => [ |
| 16 | name, | 16 | name, |
| 17 | value.trim(), | 17 | (value ?? "").trim(), |
| 18 | ]), | 18 | ]), |
| 19 | ) as MobileThemeVariables; | 19 | ) as MobileThemeVariables; |
| 20 | } | 20 | } |
apps/mobile/src/lib/mobileTheme.test.ts+6-6| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | import { describe, expect, it } from "vite-plus/test"; | 1 | import { describe, expect, it } from "vite-plus/test"; |
| 2 | import { BUILT_IN_THEME_IDS, BUILT_IN_THEMES } from "@t3tools/shared/themePalettes"; | 2 | import { BUILT_IN_THEME_IDS, BUILT_IN_THEMES, T3_CHAT_THEME } from "@t3tools/shared/themePalettes"; |
| 3 | import { readDefaultMobileThemeVariables } from "./mobileTheme.test-support"; | 3 | import { readDefaultMobileThemeVariables } from "./mobileTheme.test-support"; |
| 4 | 4 | ||
| 5 | import { | 5 | import { |
| ... | @@ -49,7 +49,7 @@ function compositeOver(overlay: string, background: string): string { | ... | @@ -49,7 +49,7 @@ function compositeOver(overlay: string, background: string): string { |
| 49 | 49 | ||
| 50 | describe("mobile themes", () => { | 50 | describe("mobile themes", () => { |
| 51 | it("declares every runtime theme variable in the static stylesheet", () => { | 51 | it("declares every runtime theme variable in the static stylesheet", () => { |
| 52 | const generatedVariables = createMobileThemeVariables(BUILT_IN_THEMES[0].colors, "light"); | 52 | const generatedVariables = createMobileThemeVariables(T3_CHAT_THEME.colors, "light"); |
| 53 | expect(Object.keys(readDefaultMobileThemeVariables("light")).sort()).toEqual( | 53 | expect(Object.keys(readDefaultMobileThemeVariables("light")).sort()).toEqual( |
| 54 | Object.keys(generatedVariables).sort(), | 54 | Object.keys(generatedVariables).sort(), |
| 55 | ); | 55 | ); |
| ... | @@ -152,16 +152,16 @@ describe("mobile themes", () => { | ... | @@ -152,16 +152,16 @@ describe("mobile themes", () => { |
| 152 | }); | 152 | }); |
| 153 | 153 | ||
| 154 | it("maps semantic palette roles onto every mobile color variable", () => { | 154 | it("maps semantic palette roles onto every mobile color variable", () => { |
| 155 | const variables = createMobileThemeVariables(BUILT_IN_THEMES[0].colors, "light"); | 155 | const variables = createMobileThemeVariables(T3_CHAT_THEME.colors, "light"); |
| 156 | expect(Object.keys(variables)).toHaveLength(75); | 156 | expect(Object.keys(variables)).toHaveLength(75); |
| 157 | expect(variables["--color-sheet-solid"]).toBe( | 157 | expect(variables["--color-sheet-solid"]).toBe( |
| 158 | themeColorToNativeColor(BUILT_IN_THEMES[0].colors.chrome), | 158 | themeColorToNativeColor(T3_CHAT_THEME.colors.chrome), |
| 159 | ); | 159 | ); |
| 160 | expect(variables["--color-warning"]).toBe( | 160 | expect(variables["--color-warning"]).toBe( |
| 161 | themeColorToNativeColor(BUILT_IN_THEMES[0].colors.warningSurface), | 161 | themeColorToNativeColor(T3_CHAT_THEME.colors.warningSurface), |
| 162 | ); | 162 | ); |
| 163 | expect(variables["--color-warning-foreground"]).toBe( | 163 | expect(variables["--color-warning-foreground"]).toBe( |
| 164 | themeColorToNativeColor(BUILT_IN_THEMES[0].colors.warningForeground), | 164 | themeColorToNativeColor(T3_CHAT_THEME.colors.warningForeground), |
| 165 | ); | 165 | ); |
| 166 | expect(variables["--color-primary"]).not.toBe(variables["--color-screen"]); | 166 | expect(variables["--color-primary"]).not.toBe(variables["--color-screen"]); |
| 167 | expect(variables["--color-primary-shadow"]).toBe("#000000"); | 167 | expect(variables["--color-primary-shadow"]).toBe("#000000"); |
apps/mobile/src/lib/mobileTheme.ts+14-14| ... | @@ -1,5 +1,6 @@ | ... | @@ -1,5 +1,6 @@ |
| 1 | import { | 1 | import { |
| 2 | BUILT_IN_THEMES, | 2 | BUILT_IN_THEMES, |
| 3 | T3_CHAT_THEME, | ||
| 3 | getThemeColorsForAppearance, | 4 | getThemeColorsForAppearance, |
| 4 | MOBILE_DEFAULT_THEME_ID, | 5 | MOBILE_DEFAULT_THEME_ID, |
| 5 | MOBILE_THEME_IDS as SHARED_MOBILE_THEME_IDS, | 6 | MOBILE_THEME_IDS as SHARED_MOBILE_THEME_IDS, |
| ... | @@ -29,7 +30,9 @@ export const MOBILE_THEME_OPTIONS: ReadonlyArray<{ | ... | @@ -29,7 +30,9 @@ export const MOBILE_THEME_OPTIONS: ReadonlyArray<{ |
| 29 | ...BUILT_IN_THEMES.map((theme) => ({ id: theme.id as MobileThemeId, label: theme.label })), | 30 | ...BUILT_IN_THEMES.map((theme) => ({ id: theme.id as MobileThemeId, label: theme.label })), |
| 30 | ]; | 31 | ]; |
| 31 | 32 | ||
| 32 | export type MobileThemeVariable = `--color-${string}`; | 33 | // Closed set: every key `createMobileThemeVariables` writes. Reads of a |
| 34 | // misspelled variable then fail to compile instead of yielding undefined. | ||
| 35 | export type MobileThemeVariable = keyof ReturnType<typeof createMobileThemeVariables>; | ||
| 33 | export type MobileThemeVariables = Readonly<Record<MobileThemeVariable, string>>; | 36 | export type MobileThemeVariables = Readonly<Record<MobileThemeVariable, string>>; |
| 34 | 37 | ||
| 35 | export function normalizeMobileThemeId(value: unknown): MobileThemeId { | 38 | export function normalizeMobileThemeId(value: unknown): MobileThemeId { |
| ... | @@ -136,9 +139,9 @@ function withAlpha(color: string, alpha: number): string { | ... | @@ -136,9 +139,9 @@ function withAlpha(color: string, alpha: number): string { |
| 136 | 139 | ||
| 137 | function rgbChannels(color: string): readonly [number, number, number] | null { | 140 | function rgbChannels(color: string): readonly [number, number, number] | null { |
| 138 | const match = /^#([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i.exec(color); | 141 | const match = /^#([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i.exec(color); |
| 139 | return match | 142 | if (!match) return null; |
| 140 | ? [Number.parseInt(match[1], 16), Number.parseInt(match[2], 16), Number.parseInt(match[3], 16)] | 143 | const [, red = "0", green = "0", blue = "0"] = match; |
| 141 | : null; | 144 | return [Number.parseInt(red, 16), Number.parseInt(green, 16), Number.parseInt(blue, 16)]; |
| 142 | } | 145 | } |
| 143 | 146 | ||
| 144 | /** | 147 | /** |
| ... | @@ -216,18 +219,15 @@ function readableMessageAccent(accent: string, surface: string): string { | ... | @@ -216,18 +219,15 @@ function readableMessageAccent(accent: string, surface: string): string { |
| 216 | } | 219 | } |
| 217 | 220 | ||
| 218 | export function themeColorWithAlpha(color: string, alpha: number): string { | 221 | export function themeColorWithAlpha(color: string, alpha: number): string { |
| 219 | const hex = /^#([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i.exec(color); | 222 | const channels = rgbChannels(color); |
| 220 | if (hex) { | 223 | if (channels) { |
| 221 | return `rgba(${Number.parseInt(hex[1], 16)}, ${Number.parseInt(hex[2], 16)}, ${Number.parseInt(hex[3], 16)}, ${alpha})`; | 224 | return `rgba(${channels[0]}, ${channels[1]}, ${channels[2]}, ${alpha})`; |
| 222 | } | 225 | } |
| 223 | const rgb = /^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/.exec(color); | 226 | const rgb = /^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/.exec(color); |
| 224 | return rgb ? `rgba(${rgb[1]}, ${rgb[2]}, ${rgb[3]}, ${alpha})` : color; | 227 | return rgb ? `rgba(${rgb[1]}, ${rgb[2]}, ${rgb[3]}, ${alpha})` : color; |
| 225 | } | 228 | } |
| 226 | 229 | ||
| 227 | export function createMobileThemeVariables( | 230 | export function createMobileThemeVariables(colors: ThemeColors, appearance: MobileThemeAppearance) { |
| 228 | colors: ThemeColors, | ||
| 229 | appearance: MobileThemeAppearance, | ||
| 230 | ): MobileThemeVariables { | ||
| 231 | const c = nativeColors(colors); | 231 | const c = nativeColors(colors); |
| 232 | return { | 232 | return { |
| 233 | "--color-screen": c.canvas, | 233 | "--color-screen": c.canvas, |
| ... | @@ -315,7 +315,7 @@ export function createMobileThemeVariables( | ... | @@ -315,7 +315,7 @@ export function createMobileThemeVariables( |
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | export const MOBILE_THEME_VARIABLE_NAMES = Object.keys( | 317 | export const MOBILE_THEME_VARIABLE_NAMES = Object.keys( |
| 318 | createMobileThemeVariables(BUILT_IN_THEMES[0].colors, "light"), | 318 | createMobileThemeVariables(T3_CHAT_THEME.colors, "light"), |
| 319 | ) as ReadonlyArray<MobileThemeVariable>; | 319 | ) as ReadonlyArray<MobileThemeVariable>; |
| 320 | 320 | ||
| 321 | export function getMobileThemeVariables( | 321 | export function getMobileThemeVariables( |
| ... | @@ -323,7 +323,7 @@ export function getMobileThemeVariables( | ... | @@ -323,7 +323,7 @@ export function getMobileThemeVariables( |
| 323 | appearance: MobileThemeAppearance, | 323 | appearance: MobileThemeAppearance, |
| 324 | overrides: Partial<MobileThemeVariables> | null = null, | 324 | overrides: Partial<MobileThemeVariables> | null = null, |
| 325 | ): MobileThemeVariables { | 325 | ): MobileThemeVariables { |
| 326 | const theme = BUILT_IN_THEMES.find((candidate) => candidate.id === themeId) ?? BUILT_IN_THEMES[0]; | 326 | const theme = BUILT_IN_THEMES.find((candidate) => candidate.id === themeId) ?? T3_CHAT_THEME; |
| 327 | const colors = getThemeColorsForAppearance(theme, appearance) ?? theme.colors; | 327 | const colors = getThemeColorsForAppearance(theme, appearance) ?? theme.colors; |
| 328 | const baseVariables = createMobileThemeVariables(colors, appearance); | 328 | const baseVariables = createMobileThemeVariables(colors, appearance); |
| 329 | 329 | ||
| ... | @@ -337,7 +337,7 @@ export function getMobileThemePreviewColors( | ... | @@ -337,7 +337,7 @@ export function getMobileThemePreviewColors( |
| 337 | ): ThemePreviewColors { | 337 | ): ThemePreviewColors { |
| 338 | if (themeId === DEFAULT_MOBILE_THEME_ID || themeId === "material-you") | 338 | if (themeId === DEFAULT_MOBILE_THEME_ID || themeId === "material-you") |
| 339 | return STANDARD_THEME_PREVIEW_COLORS[appearance]; | 339 | return STANDARD_THEME_PREVIEW_COLORS[appearance]; |
| 340 | const theme = BUILT_IN_THEMES.find((candidate) => candidate.id === themeId) ?? BUILT_IN_THEMES[0]; | 340 | const theme = BUILT_IN_THEMES.find((candidate) => candidate.id === themeId) ?? T3_CHAT_THEME; |
| 341 | const colors = getThemeColorsForAppearance(theme, appearance) ?? theme.colors; | 341 | const colors = getThemeColorsForAppearance(theme, appearance) ?? theme.colors; |
| 342 | return { | 342 | return { |
| 343 | canvas: themeColorToNativeColor(colors.canvas), | 343 | canvas: themeColorToNativeColor(colors.canvas), |
apps/mobile/src/lib/wideMarkdownBlocks.ts+5-1| ... | @@ -81,7 +81,11 @@ function hasOrderedListItem(text: string): boolean { | ... | @@ -81,7 +81,11 @@ function hasOrderedListItem(text: string): boolean { |
| 81 | const nestedMatch = INDENTED_ORDERED_LIST_ITEM.exec(line); | 81 | const nestedMatch = INDENTED_ORDERED_LIST_ITEM.exec(line); |
| 82 | const parentMatch = | 82 | const parentMatch = |
| 83 | previousNonEmptyLine === null ? null : ANY_LIST_ITEM.exec(previousNonEmptyLine); | 83 | previousNonEmptyLine === null ? null : ANY_LIST_ITEM.exec(previousNonEmptyLine); |
| 84 | if (nestedMatch && parentMatch && parentMatch[1].length < nestedMatch[1].length) { | 84 | if ( |
| 85 | nestedMatch?.[1] !== undefined && | ||
| 86 | parentMatch?.[1] !== undefined && | ||
| 87 | parentMatch[1].length < nestedMatch[1].length | ||
| 88 | ) { | ||
| 85 | return true; | 89 | return true; |
| 86 | } | 90 | } |
| 87 | 91 |
apps/mobile/tsconfig.json+3-1| ... | @@ -2,6 +2,8 @@ | ... | @@ -2,6 +2,8 @@ |
| 2 | "extends": "expo/tsconfig.base", | 2 | "extends": "expo/tsconfig.base", |
| 3 | "compilerOptions": { | 3 | "compilerOptions": { |
| 4 | "allowImportingTsExtensions": true, | 4 | "allowImportingTsExtensions": true, |
| 5 | "strict": true | 5 | "strict": true, |
| 6 | "noUncheckedIndexedAccess": true, | ||
| 7 | "noImplicitOverride": true | ||
| 6 | } | 8 | } |
| 7 | } | 9 | } |