feat(compose): prompt before sending when a mentioned attachment is missing #80

Merged
JMR-dev merged 2 commits from feat-compose-attachment-reminder into main 2026-07-01 23:20:57 +00:00
JMR-dev commented 2026-07-01 22:04:38 +00:00 (Migrated from github.com)

Summary

Closes #79.

When the user taps Send and the subject or body mentions an attachment — the word "attach" or a variant (attached, attachment(s), attaching, attaches; word-bounded, case-insensitive) — but nothing is attached, a dialog asks "Need to attach anything?":

  • Yes — returns to the compose screen and pulses the attach button to draw the eye.
  • No — sends the message as-is.
  • Dismissing the dialog (tap outside / back) cancels the send without highlighting.

The check lives in ComposeViewModel (send() → trySend(checkAttachments)), runs only after the account/recipient validations, and is bypassed exactly once when the user answers "No". Reply prefill carries no quoted body in this app, so the scan cannot false-positive on quoted original text.

Tests

  • ComposeViewModelTest: prompt on body/subject mention, variant + lookalike coverage ("attack"/"attachable" don't trigger), no prompt when an attachment is present, and one test per dialog outcome (send anyway / attach instead / dismiss).
  • ComposeScreenTest (E2E): full flow — Send → dialog → Yes (nothing sent) → Send → No → message delivered.
  • Local gate: assembleDebug, testDebugUnitTest, lintDebug, ktlintCheck, detekt, and compileDebugAndroidTestKotlin all green; emulator E2E left to CI.

🤖 Generated with Claude Code

## Summary Closes #79. When the user taps **Send** and the subject or body mentions an attachment — the word "attach" or a variant (attached, attachment(s), attaching, attaches; word-bounded, case-insensitive) — but nothing is attached, a dialog asks **"Need to attach anything?"**: - **Yes** — returns to the compose screen and pulses the attach button to draw the eye. - **No** — sends the message as-is. - Dismissing the dialog (tap outside / back) cancels the send without highlighting. The check lives in `ComposeViewModel` (`send()` → `trySend(checkAttachments)`), runs only after the account/recipient validations, and is bypassed exactly once when the user answers "No". Reply prefill carries no quoted body in this app, so the scan cannot false-positive on quoted original text. ## Tests - `ComposeViewModelTest`: prompt on body/subject mention, variant + lookalike coverage ("attack"/"attachable" don't trigger), no prompt when an attachment is present, and one test per dialog outcome (send anyway / attach instead / dismiss). - `ComposeScreenTest` (E2E): full flow — Send → dialog → Yes (nothing sent) → Send → No → message delivered. - Local gate: assembleDebug, testDebugUnitTest, lintDebug, ktlintCheck, detekt, and `compileDebugAndroidTestKotlin` all green; emulator E2E left to CI. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign in to join this conversation.