Skip to content

Pastéis mode, as on the web - #12

Merged
simonhamp merged 1 commit into
mainfrom
feat/pasteis
Oct 18, 2026
Merged

simonhamp merged 1 commit into
mainfrom
feat/pasteis

Conversation

@simonhamp

@simonhamp simonhamp commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

The web's new pastéis mode, in the app. It copies the web's behaviour, wording and look.

This depends on an API branch that isn't on GitHub. The app needs feat/mobile-api-pasteis, which only exists locally in ~/Projects/devnull.com--pasteis. It sits on a local rebase of nunomaduro/dev-null.sh#130 onto current upstream production, since #130's base is older than the pastéis migration. Until that lands somewhere, this can't work against any API that's online.

What changed

Account screen. A Pastéis mode section after Color, as on the web's settings page, with the web's heading and its two paragraphs word for word. The switch is the system's own (native:toggle, the iOS 26 UISwitch). It flips at once and isn't greyed out while it saves. If it's flipped again before devnull answers, the last flip is what gets saved. If the PUT fails it goes back, with the web's "Could not save pastéis mode. Please try again." under it.

New mobile-air branch. native:toggle used to ignore taps, because the screen's keyboard-dismiss tap swallowed taps on UIKit controls. The app now requires nativephp/mobile from combined/dev-null-app on NativePHP/mobile-air: feat/custom-icons (NativePHP/mobile-air#544) with the fix from NativePHP/mobile-air#545 merged in, the same way the app already tracks combined/dev-null-app on mobile-ui. The README lists it, and its mobile-ui line now lists everything mobile-ui's combined branch carries (#131 and #134 to #139). Every app PR picks it up when it rebases onto main after this merges.

Commit rows. With the mode on, the pastel sits right after the star, where the web puts it, in the row #7 made (star, Quote, Reply, "› 3 replies", then ⋯). Reply and the replies link keep their full words: the pastel de nata and the commit's count, even 0. Tapping it on someone else's published commit gives one pastel. The count and today's allowance change straight away and the request goes from the background, so you can keep tapping. When devnull turns one down, the pastel comes off the commit again and a toast says why, using the web's words ("you ran out of pastéis. wait until tomorrow." or "Could not award a pastel. Please try again."). With none left, the toast shows without a request. After the tenth goes, the toast shows too, as on the web. On your own commits and unpublished ones it's just the count. The allowance comes back at 00:00 UTC, not 24 hours after the first one.

Profiles. "N pastéis received" under the counts in the profile header (partials/profile-header), as on the web.

Mode off. Nothing changes from today. No pastel, no counts, no profile line.

The app learns the mode and today's allowance from GET /me, which it already asks for on most screens. A pastel that goes patches every kept copy of the commit, the author's kept profile and the kept me.

EDGE limits hit

  • The web draws the words pastel, pasteis and pastéis in commit bodies as the pastel picture in pastéis mode. EDGE text can't hold an inline image, so the app leaves the words as text.
  • The pastel picture is in colour, and custom icons are tinted templates, so it ships as a PNG (public/images/pastel-de-nata@3x.png) drawn from the web's SVG and shown with native:image.

What to check

  • The wording on the Account screen keeps the web's "one per click". On a phone that's a tap. I left it word for word as asked.
  • WritesInBackground now passes the ApiException to the failure callback as a second argument, so the pastel can tell pasteis_exhausted and rate_limited apart. Existing callbacks take one argument and are unaffected.
  • Commit::withReactionsFrom() now also takes pasteis_count from the fresh copy after a star or save.

How it was verified

php artisan test passes (809 tests, rebased onto main 5758923) and Pint is clean. On a fresh iPhone 17 Pro simulator against the local API branch, signed in as local_dev:

  • With the mode off, the log, profile and Account screen looked as before.
  • One tap on the switch turned the mode on, and later off again. The API's users.pasteis_mode matched each time. After moving to the new mobile-air branch I rebuilt on a fresh simulator: the system switch flips on a plain tap, both ways, and the keyboard still goes away when you tap outside the Log's composer. The Account screen has no text field to try that on. The simulator tool's instant, zero-length taps don't flip any UISwitch, Apple's own in Settings included, so I tapped for about 0.1s, as a finger does.
  • I gave one commit ten pastéis. The count went 1 to 10 and the API agreed. After the tenth the toast said I'd run out, and an eleventh tap showed the toast again and sent nothing.
  • The author's profile showed "10 pastéis received". My own showed 0.

I have screenshots and a recording of the run locally.

🤖 Generated with Claude Code

The web's new pastéis mode comes to the app. It's switched on from a new
section on the Account screen, after Color, with the web's wording and
the system's own switch. The switch moves at once and isn't greyed out
while it saves. Flipped again before devnull answers, the last flip is
what gets saved, and if devnull says no it goes back with the web's
error line.

With the mode on, commit rows get the web's pastel button after the
star: the pastel de nata and the commit's count, even 0. Tapping someone
else's published commit gives it one, from the ten a day that come back
at 00:00 UTC. The count and today's allowance change straight away and
the pastel is sent in the background, so taps keep coming. If devnull
turns one down it comes back off the commit, and a toast says why in
the web's words. With none left the toast says so without asking
devnull. Your own commits and unpublished ones only show the count.
Profiles show "N pastéis received" under their counts. With the mode
off nothing changes.

The picture ships as a PNG drawn from the web's SVG, since it's in
colour and custom icons are tinted.

native:toggle ignored taps because the screen's keyboard-dismiss tap
swallowed them, so the app now requires nativephp/mobile from
combined/dev-null-app on NativePHP/mobile-air: feat/custom-icons (#544)
with that fix (#545) merged in. The README lists it with everything
mobile-ui's combined branch carries now.

Needs the local API branch feat/mobile-api-pasteis.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@simonhamp
simonhamp merged commit d055983 into main Oct 18, 2026
1 check passed
@simonhamp
simonhamp deleted the feat/pasteis branch October 19, 2026 09:25
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