Skip to content

Draw custom lane colours, and mix one on Account - #15

Merged
simonhamp merged 2 commits into
mainfrom
feat/custom-lane-colours
Oct 19, 2026
Merged

simonhamp merged 2 commits into
mainfrom
feat/custom-lane-colours

Conversation

@simonhamp

Copy link
Copy Markdown
Member

The web now lets people pick any colour for their lane with a colour picker, and devnull sends that lane as a #rrggbb string instead of 0 to 5. The app treated it as no lane and fell back to the hashed one, so anyone with a custom colour showed up in the wrong colour.

What changed

  • Lane::from() reads a custom colour as lowercase #rrggbb. Lane::palette() is the old 0 to 5 reader, for Automatic and the picker's buttons.
  • Lane::token() turns a custom colour into a theme token of its own, lane-rrggbb, the first time it's drawn, through Theme::merge(). It gets an on- token for button labels, white or ink by the same contrast rule as the palette's. Like the web, it's the same colour in light and dark mode.
  • Every view now builds lane classes as bg-theme-{{ Lane::token($lane) }} instead of bg-theme-lane-{{ $lane }}. That covers rails, avatar rings, profiles, achievements, activity, notifications, the tab bar accent and the lane-coloured buttons. Rail Gray goes through token() too, which removed a few ternaries.
  • Account gets a Custom option after the six lanes, as on the web. It shows your custom colour, or a spectrum until you have one. Tapping it opens a sheet with hue, saturation and lightness sliders in place of the system colour picker the web opens, starting on your custom colour or the one you're previewing. Use color previews it, and Save color sends {"lane": null, "color": "#rrggbb"} like the web's form.
  • A small Hsl class does the colour maths.

Worth checking

  • The sheet's swatch is drawn with an arbitrary bg-[#rrggbb] class rather than a token, so dragging a slider doesn't add a theme token on every tick. Only the colour you use becomes one.
  • Theme::merge() pushes the theme to the native side, so the first time a new custom colour is drawn there's one extra bridge call. I haven't seen this on a device yet.
  • Saving a custom colour needs PUT /api/v1/me/lane to take color, which is in feat: sync from GitHub and save the lane color from the API nunomaduro/dev-null.sh#554. Drawing other people's custom colours works against production today.

Testing

846 tests pass and Pint is clean. New tests cover reading and tokenising custom colours, the HSL maths, drawing a custom colour on the Log, a profile, the tab bar and the main buttons, and mixing, previewing, saving and dismissing on Account. Not yet tried on a phone or simulator.

Closes the idea board's to-do #322.

🤖 Generated with Claude Code

simonhamp and others added 2 commits October 19, 2026 09:54
The web lets people pick any colour for their lane, and devnull sends it as
a #rrggbb lane. The app read that as no lane and fell back to the hashed
one, so those people showed in the wrong colour.

A custom colour now becomes a theme token of its own, lane-rrggbb, the
first time it's drawn, with a label colour picked the way the palette's
on-lane tokens are. Every view draws lanes through Lane::token(), so rails,
avatars, profiles, notifications, the tab bar and the main buttons all take
it. Like the web, it's the same colour in light and dark mode.

Account gets the web's Custom option after the six lanes. It opens a sheet
with hue, saturation and lightness sliders, standing in for the system
colour picker the web opens, and Save color sends {"lane": null, "color"}
as the web's form does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sliders were debounced, and iOS only sends a debounced slider once the
finger rests, so the swatch didn't change until you stopped dragging. They
now send every step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@simonhamp
simonhamp merged commit 5a64d29 into main Oct 19, 2026
1 check passed
@simonhamp
simonhamp deleted the feat/custom-lane-colours branch October 19, 2026 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant