_I recommend reviewing this with whitespace changes disabled._
`RemoteConfig.groupsV2InviteLinks` has been fully enabled for awhile
now. This removes it, and everything that depended on it. Even let us
remove a couple of strings!
This removes `FeatureFlags.giftBadgeReceiving` and
`FeatureFlags.giftBadgeSending`, replacing them with
`RemoteConfig.canReceiveGiftBadges` and
`RemoteConfig.canSendGiftBadges`.
If DNS resolution fails, then it’s expected that there won’t be any
addresses. Fail gracefully in this case.
If DNS resolution succeeds and provides a non-nil but empty list of
addresses, report an error. This shouldn’t happen.
Some users [are unable to register][1] because the server [returns a 400
error][2] if passed an invalid `Accept-Language` header.
This commit helps prevent two possible error modes:
- Filters out invalid language tags. Some users reported a "Workshopx"
language, which the server would reject because it's syntactically
invalid. Deleting this language (at the OS level) let them register.
- If no languages are valid, we should send `*` instead of the empty
string. There's no evidence that this happened in practice.
In addition, this commit:
- Adds tests.
- Sends a maximum of 10 languages instead of 6.
- Omits the `q` value when it's 1 because [that's the default][3].
- Marginally improves performance by iterating lazily.
[1]: https://github.com/signalapp/Signal-iOS/issues/5261
[2]: bf6d3aa324/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java (L271-L275)
[3]: https://www.rfc-editor.org/rfc/rfc9110.html#section-12.4.2
Co-authored-by: Nora Trapp <nora@signal.org>
This commit:
1. Adds a new donation receipt type: gifts.
2. Saves receipts when sending someone a gift.
The first part was the main challenge. Previously, donation receipts had
logic like this (pseudocode):
def getReceiptType(self):
if self.subscriptionLevel:
return "subscription"
else:
return "one-time"
Now, we explicitly encode the type and have logic to handle "legacy"
receipts that don't have a type encoded.
This disgusting hack removes GRDB's notification
center observers, which prevents it from calling
`DatabasePool.releaseMemory()`.
`releaseMemory` is harmful because it places all
future reads behind a dispatch barrier. The effect
is that even very short reads block on any db
reads that precede the barrier. Some of those can
be very slow, such as orphan message handling.
The practical effect of this barrier is that the
main thread gets stuck on what should be a very
quick operation, such as loading your own avatar
data. iOS can kill the app with 8badf00d.
This change is a temporary workaround. A proper
solution has been added to a PR that I sent to
GRDB, which you can see here:
https://github.com/groue/GRDB.swift/pull/1253
Once that is accepted upstream we should update
GRDB and revert this commit.
This change should fix IOS-2474 and doubtless many
other issues.
This are unused since things got refactored in ec66f3b21e. It
appears as though `contentDescription` is just called directly rather
than calling these wrappers.
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 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.