Skip to content

Commit 1634bf0

Browse files
committed
Document the pinned appearance invariants in CLAUDE.md
Several of these were fixed more than once because a stored setting silently overrode the theme default — the violet bubble being the last case. Writing down where each one is pinned, and why the defaults alone are not enough, so the next pass does not re-derive it.
1 parent 19e1fae commit 1634bf0

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

‎CLAUDE.md‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,39 @@ A standalone watchOS Telegram client (developed in the separate `~/build/tgwatch
8585

8686
**Status:** verified with **development** signing on `debug_arm64` only. Open follow-ups before App Store shipping: secure timestamp (drop `codesign --timestamp=none`), distribution profile (`get-task-allow=false`), `release_arm64` + `altool --validate-app`, and committing a `Package.resolved` for hermetic remote-SwiftPM resolution.
8787

88+
## Appearance is fixed, not configurable
89+
90+
The fork targets the iOS Messages look, and the pieces that define it are pinned in
91+
code rather than left to settings. Treat these as invariants — several of them were
92+
"fixed" more than once because a stored setting silently overrode the default.
93+
94+
- **Two themes, chosen by the system.** `forkNormalizedThemeSettings`
95+
(`TelegramPresentationData/Sources/PresentationData.swift`) rewrites the copy of
96+
`PresentationThemeSettings` that each read hands downstream: `theme = .builtin(.day)`,
97+
`automaticThemeSwitchSetting = (force: false, trigger: .system, theme: .builtin(.night))`.
98+
Stored settings on disk are never mutated, so deleting that one function restores
99+
whatever the user last chose. Any *new* code path that builds a theme from
100+
`presentationThemeSettings` must route through it — `ChatController` and
101+
`InstantPageController` already do; the wallpaper, QR and media-editor screens
102+
deliberately do not, since they preview a theme rather than display the app's.
103+
- **Outgoing bubble is `#007AFF`.** Pinned inside `customizeDefaultDayTheme` and
104+
`customizeDefaultDarkPresentationTheme`, gated on `editing` so gift and chat themes
105+
(which arrive with `editing: false`) keep the colours their sender chose. The theme
106+
*defaults* are not enough on their own: they are only consulted when no accent is
107+
stored, and Night expands the default accent `0x3e88f7` into a blue→violet gradient.
108+
- **Bubble radius is 18/4 with no tails**`higChatBubbleCorners`, same file.
109+
- Consequence, and it is intended: the bubble-colour half of the accent picker and the
110+
radius sliders do nothing on the shipped themes. The accent still drives buttons,
111+
links and checkmarks.
112+
- **There is no Appearance row in Settings.** `PeerInfoSettingsItems.swift` has an App
113+
Icon row instead, which pushes the same controller focused on `.icon`. The
114+
`.appearance` destination stays wired so Settings search and `tg://settings/theme`
115+
keep working.
116+
- **Composer controls are 40 pt circles.** The mic, send and attachment buttons all
117+
derive their background from a size the caller passes; handing them the input field's
118+
height produces ovals. See the comments in `ChatTextInputPanelNode` and
119+
`ChatTextInputActionButtonsNode`.
120+
88121
## View frame ownership
89122

90123
A view does not control its own `frame`. The parent (or a layout system) sets the frame; the view positions its own subviews against `self.bounds` in response.

0 commit comments

Comments
 (0)