This test-only change should have no user impact.
I wrote these tests last year (in
c5bdf6c094). They test every single
string, which proves annoying to update and offers little value. This
updates the tests in an effort to make them more useful.
We plan to support PayPal and credit/debit cards for gift badges. This
change, invisible to external users, is a step towards that.
Before this change, Apple Pay was always shown as the only payment
method. Now, all supported payment methods are shown.
PayPal and card don't do anything right now—they show an error UI if
tapped.
This change should have no user impact.
`DONATION_PAYMENT_ERROR_*` is now `APPLE_PAY_DONATION_ERROR_*`, and
Apple Pay is now mentioned in the string comments. None of the
user-visible strings actually change.
We plan to show different errors for cards and PayPal and this will help
us get there, but I think this is a useful change on its own.
This formats the text users enter on the card donation screen. For
example, "4242424242424242" becomes "4242 4242 4242 4242".
It uses [the `textField(_:shouldChangeCharactersIn:replacementString:)`
method of `UITextFieldDelegate`][0] to accomplish this, and implements a
helper that can handle all the cases (inserting, deleting, replacing,
pasting, and so on).
Tested this in an iPhone 14 simulator and on a physical iOS 12 device.
[0]: https://developer.apple.com/documentation/uikit/uitextfielddelegate/1619599-textfield
This is the keystone commit of turning MediaTileView asynchronous.
Because updates to the collection view's datasource now happen asynchronously and out-of-order, the batch update must be computed on the main queue based on what has changed.
MediaGalleryCollectionViewUpdater combines a log of operations from JournalingOrderedDictionary with the previous state of the collection view to compute insertions/deletions/reloads of items and sections.
This adds very basic support for donations via credit/debit card. It's
missing important features which is why it's behind an internal-only
feature flag.
At a high level, this adds a new screen with a card form. This card data
is submitted to Stripe and then uses the same "rails" as our existing
Apple Pay donations.
This change is missing a few important features, intended to be added
soon:
- [3D Secure][3DS] support
- Validation error messages
- Input formatting (e.g., "1234" becomes "12/34")
- Gift badge support (currently only supports Apple Pay)
- Various smaller UI changes
[3DS]: https://stripe.com/docs/payments/3d-secure
We shouldn't ask for Apple Pay when users update their subscriptions.
The update should just happen, unless there was previously a charge
failure.
This also fixes two other bugs:
- Some race conditions around observing subscription jobs
- One-time donations used the wrong progress spinner
This makes an upcoming change easier but is also useful on its own.
This change also moves mutation to the ordered
dictionary into a separate queue. There is no
change to behavior yet because the queue is only
dispatched to synchronously so far. Doing this
forces changes to how database transactions are
acquired since they must be used on the same queue
where they orignated.
This is a wrappar around OrderedDictionary that
maintains a change log to facilitate
UICollectionView batch updates in a system with
concurrent updates to the dictionary.
_I recommend reviewing this with whitespace changes disabled._
The server's `global.donations.apayDisabledRegions` is a list of regions
(phone number prefixes) where Apple Pay is disallowed. This respects
that.
The badge expiration sheet sometimes shows "Okay" and sometimes shows
"Ok". This makes it consistent.
I think this is a useful change on its own but it'll make an upcoming
change a little smaller.
Previously, one-time donations were on one screen and monthly donations
were on another. Now, they're on a single screen with a picker.
Most of the interesting changes are in `DonateViewController`.
Other things of note:
- There are some new TODOs here for existing bugs I didn't fix. For
example, one-time donations don't do so well if there are any problems
at all.
- Even though we only support Apple Pay, there's code that alludes to
additional payment methods. For example,
`DonateChoosePaymentMethodSheet`. We'll expand on this in the future.
- Users should only be able to select currencies that the server
supports. For example, you shouldn't be able to select EUR if the
server doesn't support euros. This wasn't working correctly before,
but is fixed here.
We already fixed one part, where users could change to an unsupported
currency (see dab02f30ae). However, if
your _default_ currency is unsupported and you didn't change it,
that's no good. This is unlikely for most users but could happen.
I fixed this by changing it from (effectively)
`Locale.current.currencyCode ?? "USD"`, which might not be supported,
to a preference list, choosing the first one the server likes.
- I skip animations if the Reduce Motion setting is enabled.
- On the donation screen, the logic for the preview badge has changed
slightly. If you already have a badge, we'll always use that.
In order to get the most out of struct method
mutability annotations, move the code that
modifies MediaGallerySections.State into State.
The remaining methods in MediaGallerySections are
wafer-thin wrappers. Eventually
MediaGallerySections will justify its existence by
managing two instances of state.
* Encapsulate mutable state of MediaGallerySections.
This is the first baby step toward imbuing
MediaGallerySections with multi-version
concurrency.
* Store rowid for each item in MediaGallerySections
This is necessary for forthcoming asynchronicity
as well as to correct existing problems where an
IndexPath is used as an identifier for an item.
IndexPath is a bad identifier because a database
change can invalidate it at any time. This will be
needed, for example, by an async ensureItemLoaded
method.