This block is the system-level block for the contact. Extends the previous
work dropping calls for Do Not Disturb, where RingRTC is prevented from
sending a Hangup message, which allows other devices to continue ringing.
This snoozes the megaphone as soon as we *might* charge your card, even
if it ultimately fails. Even if that job fails, you probably already
know you can donate.
A couple of codegen scripts had an `--intermediates` flag. While I was
playing around with this (fixing something else), I noticed that these
flags don't work and cause a crash.
Instead of fixing those bugs, I thought it'd be better to just delete
this flag because I don't think anybody uses it.
Tested this by running `make` in the `sds_codegen/` directory, with
success.
Previously, sending a gift badge was not a durable operation, which
meant that crashes/failures could cause users to have their payment
methods charged without actually sending the badge.
Now, the flow is split up into two steps: non-durable parts before the
charge is attempted, and durable parts afterward.
The high-level flow is:
1. Prepare the payment, which involves a couple of repeatable network
requests.
2. Enqueue a job with the prepared payment, that:
1. Charges the payment method (idempotently)
2. Requests a receipt credential (idempotently)
3. Enqueues a gift message, and optionally a text message
3. When the job completes, open the conversation in the UI.
The `bottomBar.height` value includes the layout margin at the bottom,
and the `presentToast` method will count this as well, resulting in the
view being placed too high on devices with a notch/home indicator.
The database writes are ultimately serial, so there’s little benefit to
scheduling each of these on its own queue. If another slow-ish write is
already happening, there’s a chance that we may see thread explosion,
with many threads waiting to write to the database.
Previously, we checked capabilities on the "choose gift recipient"
screen. If you had stale profile data, people might _seem_ incapable,
but a later profile refresh would render them capable. We could have
solved this in a few ways, but I matched Android: check the capability
right before sending.
The pseudocode used to be something like this:
```python
def allowed_candidates(all_recipients):
for recipient in all_recipients:
if recipient.is_locally_capable:
yield recipient
```
The pseudocode is now something like this:
```python
def press_donate_button():
if recipient.is_locally_capable:
is_capable = True
else:
fetch_profile(recipient)
is_capable = recipient.is_locally_capable
if is_capable:
authorize_apple_pay_and_send_badge()
```