Repository navigation
Keep unsent drafts, as the web's stash does - #13
Merged
Merged
Conversation
The Log's composer, the compose sheet, quotes and replies now stash what
you type, per user, under the web's names: commit, quote-{id} and
reply-{id}. The sheet shares the composer's draft, as the web's dialog
does. A draft that comes back shows the web's stash@{0} and drop.
Sending, emptying the field, drop, signing out and deleting the account
forget it. Quote and Reply mark a commit with a stashed draft with a dot,
since the web's stash@{0} doesn't fit the action row.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saved joined the tabs after the stash was written, so its rows had no dots on Quote and Reply. It passes the drafts' names like the other screens. A test also checks the dots stay inside their buttons in pastéis mode, beside the pastel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
simonhamp
force-pushed
the
feat/draft-stash
branch
from
October 18, 2026 21:45
b5a45e0 to
765a892
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closing a composer or leaving a screen no longer loses what you typed. The app now keeps unsent drafts the way the web's
useStashdoes.Rebased onto main at d055983, after #3 to #12 merged. Two commits: the stash itself, and a small follow-up that gives Saved's rows the dots too.
What gets stashed
Same names as the web, per signed-in user:
commit: the Log's inline composer. The compose sheet from the nav bar uses the same draft, as the web's dialog shares the Log composer's stash. When the sheet closes, the inline composer takes the draft as the sheet left it.quote-{id}: a quote, per quoted commit.reply-{id}: a reply, per commit, from the commit page's reply bar.A draft is saved as its field's model changes. EDGE sends no focus or blur, so this rides on the
native:model.debouncesyncs the fields already send, inupdated*hooks. No extra renders.When the composer opens again (the Log mounting, the sheet opening, the commit page mounting), the draft is back in the field with the web's
stash@{0}anddropbeside Commit or under the reply bar.dropthrows it away. Emptying the field clears the stash and the label. Sending clears it. If devnull says no, the draft stays.Sign out and delete account both go through
Account::forget(), which now forgets the user's drafts too. That also covers being signed out because devnull no longer takes the key, which the web has no equivalent of.Storage is a new
App\Devnull\Stash: one entry per user in the default cache, likeShownTabsandLastVisit. It keeps at most 50 drafts and drops the one written longest ago, so old quote and reply drafts can't pile up forever.Row badges
The web adds
stash@{0}after Quote and Reply when that commit has a stashed draft ("You have an unsent quote here"). That text doesn't fit the action row on a phone, so here it's a 5pt dot after the icon or label, inside the button's 44x36pt target. VoiceOver reads the web's wording. Quote's icon moves about 4pt left of centre while it has a dot, which is worth a look on a real phone. Log, Profile (both pager pages), Saved and the commit page pass the draft names to their rows.In pastéis mode the pastel sits after the star. The dots on Quote and on an icon-only Reply fit inside the 44pt minimum those buttons already have, so they add no width. Reply only shows its label when there's no "› N replies" link, so a label and a dot never share a row with that link.
Differences from the web
@sanity-labs/secret-scan). The app has no secret scanner, so it stashes whatever you type, on the phone only.commit:laterkey. The app has no series composer, so there's nothing to clear.What to check
stash@{0} dropare there.How it was verified
php artisan test --compact: 833 pass on the rebased branch, with 24 intests/Feature/Devnull/StashTest.phpandtests/Feature/Screens/DraftStashTest.php. They cover stash, restore, drop, discard on send and sign-out clearing for each kind of draft, plus the dots on Saved and in pastéis mode. Three older tests that expected the sheet to forget its draft now expect it kept. Pint is clean. CI passes.After the rebase, on a fresh iPhone 17 Pro simulator (iOS 26.2) against the timeline API, signed in as local_dev:
stash@{0} drop.dropemptied it and the dot went.No local API serves pastéis mode any more, and the timeline API's
/meswitches it off on every refresh. So for the pastéis check I made a throwaway build where the app always thinks it's on, never committed. The Quote dot sits beside the pastel, "Reply •" keeps its label, and an icon-only Reply's dot fits beside "› 1 reply".Screenshots live on the
draft-stash-screenshotsbranch. Delete it after merge.🤖 Generated with Claude Code