Commit Graph

291 Commits

Author SHA1 Message Date
Davide fa293656f4
Fix missing beta check on tvOS (#925)
Reuse the same receipt trick from iOS.

Also, fix a regression in IAPManager.fetchLevelIfNeeded() from #903,
where a guard after an await was dropped leading to reentrancy issues.
2024-11-24 21:19:43 +01:00
Davide 16f0047046
Raise other test timeouts 2024-11-24 20:31:17 +01:00
Davide 6615b69d44
Bump timeout in ProfileManagerTests 2024-11-24 20:21:39 +01:00
Davide 2aa91eedb0
Simplify paywall entities (#923)
- PaywallView is the paywall content
- PaywallModifier attaches paywall with optional confirmation
- PurchaseRequiredButton presents paywall explicitly
- PaywallReason is the compound input

Refactoring:

- PurchaseRequiredButton takes a custom view
- PurchaseAlertModifier was merged into PaywallModifier
- PurchaseButtonModifier was merged into PurchaseRequiredButton
- Modal options were packed into a single struct

Confirmation alert presented on:

- Connect to ineligible profile (AppCoordinator)
- Save ineligible profile (ProfileCoordinator)
2024-11-24 20:01:30 +01:00
Davide cb530d8a65
Handle TV requirements on connection (#922)
Fixes #913
2024-11-24 01:01:04 +01:00
Davide bad9e8b58e
Add TV settings tab (#921)
Includes:

- Credits
- Donations
- Diagnostics
- Version

Had to:

- Wrap tab view into a NavigationStack for full-screen navigation
- Take out navigation titles of about subviews
- Customize donations view layout with modifier
- Fix credits and debug log to support scrolling

Closes #914
2024-11-23 23:01:11 +01:00
Davide f13a292b4b
Refactor String identifiers (#920)
- Group all views under "views.*"
- Split global strings into actions and nouns
- Use underscores
- Clean up unused

Fixes #835
2024-11-23 20:31:22 +01:00
Davide 3e2823c2e0
Suppress module name
Uneditable with #909, must hide potentially existing name.
2024-11-23 20:11:10 +01:00
Davide 2a46173169
Move more views to UILibrary (#919)
- Move about subviews to UILibrary
- Refactor about to single coordinator + platform views
- Refactor debug log to single view + content views
- Take out debug log routes from about routes
- Rename Settings* to Preferences*
- Reuse empty modifier in debug log
- Fix a visual bug in .themeTrailingValue() (extra Spacer)

Preparation for #914
2024-11-23 19:26:33 +01:00
Davide a301806ac7
Share migrated TV profiles (#918)
Fixes #912
2024-11-23 13:33:02 +01:00
Davide 3d092d6802
Revert marker width from #917 2024-11-23 13:30:29 +01:00
Davide 13118a5e2e
Improve profiles layout on small devices (#917)
- Smaller iCloud/TV icons
- Smaller marker width
- Less spacing before info button
2024-11-22 17:05:46 +01:00
Davide bd237c4a6f
Fix layout of multiline modules (#916)
- Align to .leading in multi-line
- Wrap profile rows into top/bottom spacers to adjust to tallest cell in
grid

See #915
2024-11-22 13:44:06 +01:00
Davide fb0d1abc8a
Add header to Mac menu profiles list 2024-11-22 13:09:22 +01:00
Davide 4b4fca8344
Replace active modules count with a description (#915)
To get access to modules, try to avoid full Profile objects. Instead,
replace the coupled ProfileHeader occurrences with a new intermediary
ProfilePreview everywhere.

This way, a ProfileProcessor can inject the localized modules
descriptions from above with the preview() method.
2024-11-22 12:52:51 +01:00
Davide a2f246454d
List other modules in TV active profile (#911)
Non-VPN profiles would otherwise be very shallow.
2024-11-22 10:56:37 +01:00
Davide 9b366dcaa0
Minor UI fixes (#910)
Update library with some more meaningful names for Profile accessors.

Refactor a few things about TV here and there.
2024-11-22 10:05:46 +01:00
Davide 366dc62231
Drop "Name" field from modules (#909)
Will rather add a "Notes" field to profiles. Module names feel
overwhelming.
2024-11-22 10:05:08 +01:00
Davide 72f6a1b1a1
Fix condition for #906
Was never disabling sharing for shared profiles.
2024-11-22 02:43:54 +01:00
Davide 0bff571d14
Polish TV profile view (#908)
- Layout with some profile details
- Add colors with adjusted brightness
- Add iOS/macOS instructions
- Add pending/sleeping markers
- Add previews
2024-11-22 02:20:41 +01:00
Davide 2636711e16
Do not disconnect active profile on remote import (#907)
Update library for this fix.
2024-11-22 01:15:51 +01:00
Davide 14398f5f20
Fix shared profile not updated on provider server selection (#906)
First, rename `force` parameter of ProfileManager.save() to `isLocal`,
because it's meant to be used when saving local profiles. In such
scenario, a profile that is also remotely shared _must_ be re-saved to
the remote repository.

This was not being done when selecting a provider server, and it could
be noticed because the other devices would only receive the iCloud
update after editing the profile and re-doing a manual "Save". Only at
that point would the new profile be re-shared on iCloud.
2024-11-22 00:46:58 +01:00
Davide b0c98ed27a
Lint XCTFail() 2024-11-21 23:01:08 +01:00
Davide 3d2a543a54
Fetch products from scratch each time (#905)
Do not risk getting products that may have been removed from sale.
2024-11-21 22:58:24 +01:00
Davide c5bdb9e363
Group IAP extensions into ad-hoc folder 2024-11-21 19:44:37 +01:00
Davide 5bec574841
Test MigrationManager (#904)
Decouple importer from ProfileManager.
2024-11-21 19:44:20 +01:00
Davide 842375ffce
Test IAPManager (#903)
Refactoring:

- Split tests
- Report purchase to receipt reader (real impl does nothing)
- Abstract BetaChecker from now TestFlightChecker

Bugfixing:

- Fix duplicated code in fetchLevelIfNeeded()
- Fix observeObjects() missing .didUpdate publisher
2024-11-21 18:57:32 +01:00
Davide 2478fb204b
Test ExtendedTunnel (#902)
Decouple .connectionStatus to TunnelStatus.withEnvironment() for easy
testing.
2024-11-21 16:48:12 +01:00
Davide a93fcd4c66
Test ProfileManager (#901)
With some housekeeping.

Bugfixing:

- Do NOT skip empty remote profiles, allow removal when mirroring
- Look up profile in all profiles, not just filtered
- Posptone non-included profile removal

Refactoring:

- Rename ProfileProcessor to InAppProcessor
- Provides ProfileProcessor + TunnelProcessor protocols
- willSave -> willRebuild (because not always called on save)
- Notify ProfileManager import events
2024-11-21 16:03:57 +01:00
Davide c7cef70eed
Move IAP extensions to CommonLibrary
Leave CommonIAP agnostic of business models.
2024-11-21 12:09:06 +01:00
Davide b45f9c23fe
Rearrange targets for unit testing (#900)
- Move and rename entities
- Split protocols and default extensions
- Move in-app entities to CommonIAP target
2024-11-20 18:05:47 +01:00
Davide 74ed93a966
Check provider requirements before connecting (#896)
E.g. interactive login must be presented afterwards.
2024-11-19 20:51:55 +01:00
Davide d8545a01b4
Update profiles requirements on new in-app receipt (#895)
Required features were only updated when reloading the local profiles,
but they may also change on in-app events due to changes in eligibility.
2024-11-19 19:44:31 +01:00
Davide 9528cecc27
Verify profile before presenting interactive login (#893)
If the profile is ineligible for features other than .interactiveLogin,
the interactive prompt would still be presented, but the user would hit
the paywall right afterwards.
2024-11-19 11:46:42 +01:00
Davide 35c10309a7
Reload receipt on purchase (#892)
StoreKit ProductView performs the purchases internally without calling
IAPManager.purchase(), which causes the IAPManager state to be
momentarily outdated.

Leverage PaywallView.onComplete() to reload the receipt and eventually
trigger IAPManager.objectWillChange, so that the app is immediately
unlocked on a successful purchase.
2024-11-19 11:36:36 +01:00
Davide bac1d494a4
Upscale upgrade icon only on macOS 2024-11-19 11:18:00 +01:00
Davide d78456bb90
Show upgrade icon in profiles list (#891)
Visually clarify that a profile requires a purchase to be enabled.

- Implement AppFeatureRequiring in Profile
- Refactor IAPManager.verify() accordingly
- Pre-compute required features in ProfileManager via ProfileProcessor
2024-11-19 08:55:41 +01:00
Davide 1536551922
Prepare WireGuard for provider selector (#890)
- Omit configuration on creation to show provider selector
- Take out ConfigurationView like OpenVPN
2024-11-18 17:49:47 +01:00
Davide 89d7af4df7
Rethink eligibility checks (#889)
- Allow unrestricted save, but show PurchaseRequiredButton
- Warn however about paid features (FIXME)
- Redesign features in paywall
- Strip already eligible features from paywall
- List required features in restricted alert
- Localize feature descriptions
- Review propagation of paywall modifiers/reasons

Extra:

- Move more domain entities from UILibrary to CommonLibrary
- Default on-demand policy to .any (free feature)
- Fix modals not reappearing after closing with gesture
- Extend UILibrary start-up assertions
2024-11-18 17:43:01 +01:00
Davide e82dac3152
Clear previous remote import task (#888)
Previous task was never nil-ed out on completion.
2024-11-18 10:56:54 +01:00
Davide a3dad4e445
Observe tunnel in grid/list
Can notice in Simulator not updating installed profile.

Regression from #843
2024-11-18 09:10:15 +01:00
Davide db592944ec
Rename module builders as functions 2024-11-17 22:30:22 +01:00
Davide 8e7f3e80ce
Update library with provider in modules (#887)
Move provider metadata from profile to module.
2024-11-17 22:27:02 +01:00
Davide 20813ac77e
Parametrize app name in strings 2024-11-17 18:48:40 +01:00
Davide 00ba67f135
Refactor buttons/menus
- Add divider in add profile menu
- Reuse trailing dots
2024-11-17 18:45:04 +01:00
Davide e58726d0af
Do not discard migrated profiles in TestFlight (#886)
Users would lose those profiles on downgrade to v2.
2024-11-17 18:21:37 +01:00
Davide a2f17cc905
Use long dash for excluded migration profiles 2024-11-17 16:26:22 +01:00
Davide 01e0559060
Fix some minor bugs
- Observe profiles on Simulator
- Dismiss on error when fetching migratable profiles
- Improve migration logs ambiguity
2024-11-17 15:47:19 +01:00
Davide c93a43702c
Improve migrate design (#885)
- Mention iCloud in informational message
- Redesign to always show message despite no migratable profiles
- Refine the looks
2024-11-17 14:02:40 +01:00
Davide 22e8e659e4
Discard old profiles once migrated (#884)
Otherwise, they would reappear if the migrated profiles are deleted from
the new store.
2024-11-17 11:40:49 +01:00