Skip to content

Attach photos, start polls and preview from the composer, and vote on polls - #24

Draft
simonhamp wants to merge 1 commit into
mainfrom
feat/composer-media
Draft

simonhamp wants to merge 1 commit into
mainfrom
feat/composer-media

Conversation

@simonhamp

Copy link
Copy Markdown
Member

The composer sheet gets what the web's composer has: photos with descriptions, a poll, and a preview. Polls in lists can be voted on too, which the app couldn't do before.

It needs four API PRs that aren't merged yet: images (nunomaduro/dev-null.sh#660), polls (#662), votes (#663) and previews (#664). Against production as it is, those buttons get a 401 or a 404 back.

What changed

  • The sheet has a row of tools under the field, as the web's composer wraps them on a phone: photos from the library, a photo from the camera, a poll, and the preview. Scheduling isn't in here; that's another branch.
  • Photos come through the official camera plugin (nativephp/mobile-camera, new). Up to three, each checked the way devnull checks them (JPEG, PNG or WebP, 10 MB, 6000 pixels a side), with the web's error messages. A kept photo is moved into the app's storage (DraftImages) and deleted once it's sent, taken off, or the sheet closes. Each one can have a description, through the web's ALT badge. A commit with photos is signed as multipart with the photos' SHA-256s, which is what #660 asks for, and goes from the background with Commit spinning, since uploads take a while.
  • Polls work like the web's editor: two options to start, up to four, 50 characters each, and 1 hour to 7 days. A commit has photos or a poll, not both, and a reply never has a poll.
  • Preview swaps the field for the draft drawn as a commit: the body, the photos, the poll's options with how long it'll run, and the quoted commit. It shows straight away, then takes the body devnull sends back from POST /commits/preview, with emoji replaced and code and mentions found. If devnull can't be reached it keeps the body as written.
  • Replies: the reply bar has no room for any of this, so it gets an expand button that opens the reply in the same sheet, with the commit being answered as a card above the field. The draft goes back to the bar if the sheet closes unsent.
  • Voting: on someone else's open poll you tap an option, then Vote, as on the web, since votes are final. The poll then shows its results here and in every cached copy.

Worth checking

  • The camera plugin is pinned to fix/present-over-sheets (NativePHP/mobile-camera#17). The plugin presented its pickers from the root view controller, which can't present while our sheet is up, so the buttons did nothing. That branch is also main, which has the HEIC to JPEG conversion that 1.0.4 doesn't. Without it a real iPhone's library photos would be refused. A 1.0.5 release would let the app go back to a tag.
  • The plugin adds microphone and location usage strings to Info.plist for features the app never calls. The camera and photo library strings are overridden in config/nativephp.php with our own wording.
  • Photos aren't kept with the stashed draft, unlike the web, which keeps them in IndexedDB. Closing the sheet drops them. That felt like a separate change.
  • WritesInBackground::writeInBackground() now goes through a new sendInBackground(), so a write can be signed some other way and given a longer timeout. SignedRequest and FetchInBackground carry a content type for that.
  • This shares commit-sheet.blade.php and OpensCommitSheet with the scheduling and slash command branches. The tools row is its own partial (composer-tools), which is probably where the schedule button should end up.

Testing

896 tests pass and Pint is clean. New tests cover the image store's checks, signing a multipart commit, polls in the JSON body, the photo, poll and preview flows in the sheet, the reply sheet, and voting.

On an iOS 27 simulator, signed in through a tunnel to a devnull running all four API branches:

  • picked three photos from the library, one of them a HEIC sample that arrived as JPEG, described one, and committed. devnull stored three WebP images with the description, and the pending commit's images loaded through the temporary URLs from #660.
  • made a poll with three options and a 3-day length, previewed it (:rocket: came back as 🚀 from devnull), and committed it.
  • replied to a commit with a photo from the expanded reply sheet.
  • voted on another user's poll and saw the results.

The camera itself can't be tried on a simulator. Screenshots 43 and 45 were taken before I stopped the reply sheet marking the draft it was handed as stash@{0}.

Closes the idea board's to-do #309 (the composer part; scheduling is separate) and covers #295's pending images.

🤖 Generated with Claude Code

…ote on polls

The composer sheet gets the web composer's tools on a row under the field:
photos from the library, a photo from the camera, a poll, and a preview.

Photos come through the official camera plugin, up to three, each checked
the way devnull checks them and moved into the app's storage until the
commit goes. Each can have a description. A commit with photos is signed
as multipart with the image hashes, the way the API asks, and sent from the
background, so Commit spins while it uploads.

A new commit or a quote can have a poll instead, with two to four options
and a length, as on the web. The preview shows the draft as the commit it
would become, and fills in the body devnull sends back for it.

A commit page's reply bar has no room for these, so it gets an expand
button that opens the reply in the same sheet, and the draft goes back to
the bar if the sheet closes unsent.

Polls in lists can now be voted on: pick an option, then Vote.

The camera plugin is pinned to a branch until NativePHP/mobile-camera#17
is released, since its pickers did nothing when opened from a sheet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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