Commit Graph

50 Commits

Author SHA1 Message Date
Davide
81aa3a2714
Skip onboarding migration if no migratable profiles (#1002)
Annoying!
2024-12-11 22:20:14 +01:00
Davide
ff88b3562d
Clean up dangling module preferences (#999)
Erase on module removal, reference is otherwise lost forever.
2024-12-10 20:33:35 +01:00
Davide
d8447ddb38
Fix a few things about screenshots
- Postpone "Connected" screenshot
- Disable "Only favorites" to avoid iOS failure
- Prefix screenshot filename with device name and "0"
2024-12-10 18:37:53 +01:00
Davide
f441a2eed0
Autogenerate screenshots for all platforms (#998)
Unframed for now.

- Split Main/TV targets
- Extend ProfileManager for screenshot scenarios
- Rename UITesting to UIAccessibility

Active profile looks very big on TV simulator, temporarily commented
`.padding(.top, 50)` in ActiveProfileView.

Closes #974
2024-12-10 18:06:23 +01:00
Davide
a626722224
Fix TV active toggle color when on-demand 2024-12-10 17:31:33 +01:00
Davide
ddd45c1855
Bump version 2024-12-10 15:30:45 +01:00
Davide
2b3c28832b
Migrate provider favorites to Core Data entities (#997)
Rather than a Codable array.
2024-12-10 15:19:07 +01:00
Davide
c7bba033fe
Fix incorrect selection of VPN preset (#996)
Drop "Any" to rather make the preset filter an explicit preset
selection.

Regardless of `filtersWithSelection`, _always_ enforce the preset filter
to:

- The preset of the currently selected entity
- The first among available presets (normally non-empty)

Fixes #995
2024-12-10 14:45:07 +01:00
Davide
6f9c78b257
Track module preferences history in Core Data (#994)
Restore CDModulePreferencesV3 to track the history of module prefrences.

This way, excluded endpoints may be saved globally to Core Data as a
starting point. Then in Profile.userInfo we only save the relevant
exclusions for the current configuration.

The .excludedEndpoints relationship is therefore moved out of
CDProviderPreferencesV3.

Further refactoring:

- ModuleViewParameters now includes a ModulePreferences observable that
module views can observe
- Tunnel doesn't need access to PreferencesManager anymore (exclusions
are in Profile.userInfo)
2024-12-10 14:13:10 +01:00
Davide
aeec943c58
Move ModulePreferences to Profile.userInfo (#993)
Store module preferences in the Profile.userInfo field for atomicity.
Access and modification are dramatically simplified, and synchronization
comes for free.

On the other side, fix provider preferences synchronization by using
viewContext for the CloudKit container.

Fixes #992
2024-12-10 11:18:52 +01:00
Davide
912f62b29e
Revert "Unobserve ProfileEditor"
This reverts commit f1a0ecadfa.
2024-12-09 20:35:42 +01:00
Davide
a642b27d2b
Deduplicate preferences by last update (#991)
Fixes #990
2024-12-09 09:13:16 +01:00
Davide
93a15cd766
Review incorrect behavior in preferences (#989)
- Save/rollback was done outside of MOC
- Use different contexts for module/provider preferences
  - Save providers → also saves modules
  - Discard modules → also discards providers
- Use background context because it's not automatically merged (can
rollback)
- Expose ModulePreferences in OpenVPNView as StateObject
- Rework Blacklist to a more reusable ObservableList
- Reapply #988
2024-12-09 08:44:13 +01:00
Davide
c72a69829b
Fix compile error on TV 2024-12-09 07:59:37 +01:00
Davide
fae0200995
Exclude OpenVPN endpoints (#987)
Exclude endpoints from OpenVPN modules and providers with the generic
Blacklist<T> observable. Eventually, rebuild the Profile in
PacketTunnelProvider (via DefaultTunnelProcessor) with the applied
exclusions from preferences.

Revisit approach to preferences:

- Module preferences
  - Tied to the module and therefore to the parent profile
- Load/save in ProfileEditor on request (rather than on
ProfileEditor.load)
- Provider preferences
  - Shared globally across profiles
  - Load/save in module view if needed

For more consistency with Core Data:

- Revert to observables for both module and provider preferences
- Treat excluded endpoints as relationships rather than a serialized
Array
- Add/remove single relationships over bulk delete + re-add
- Do not map the relationships, Blacklist only needs exists/add/remove:
  - isExcludedEndpoint
  - addExcludedEndpoint
  - removeExcludedEndpoint

Some clean-up:

- Move the importer logic to OpenVPNView.ImportModifier
- Move the preview data to OpenVPN.Configuration.Builder.forPreviews
- Drop objectWillChange.send() on .repository didSet to avoid potential
recursion during SwiftUI updates

Closes #971
2024-12-09 02:00:55 +01:00
Davide
5f20d791c2
Show module UUID in DEBUG 2024-12-09 01:01:01 +01:00
Davide
52bda60b05
Fix missing animations in profiles list (#986)
The list was not animating e.g. on iCloud updates. Move
.themeAnimation() from ProfileContainerView (ContainerModifier) to
ProfileListView/ProfileGridView.
2024-12-09 00:53:46 +01:00
Davide
f1a0ecadfa
Unobserve ProfileEditor 2024-12-09 00:25:54 +01:00
Davide
e2402007c9
Select preset matching current filter (#985)
E.g. Mullvad was not selecting "Custom DNS".
2024-12-09 00:25:09 +01:00
Davide
f7013a98a9
Separate App/Tunnel responsibilities (#984)
Sort out the increasing mess coming from:

- AppContext*
- Dependencies
- Shared*

by doing the following:

- Keep in the "Shared" folder only the entities actually shared by
App/Tunnel
  - Create TunnelContext
  - Move AppContext and related to the App/Context folder
  - Move TunnelContext and related to the Tunnel/Context folder
- Delete Shared+* extensions, use AppContext/TunnelContext singletons
from the app
- Create a Dependencies factory singleton to create entities in a single
place
  - Split extensions by domain
- Make it clear with `func` vs `var` when a dependency method returns a
new instance
2024-12-08 18:56:39 +01:00
Davide
aac04c4008
Move processor implementations to concrete objects (#983)
Formerly via blocks, now with final classes.

App:

- ProfileProcessor
- AppTunnelProcessor
- Implemented by DefaultAppProcessor in app
- Implemented by MockAppProcessor in UILibrary (for previews)

Tunnel:

- PacketTunnelProcessor
- Implemented by DefaultTunnelProcessor
2024-12-08 16:24:23 +01:00
Davide
a4ebea1f95
Handle load/save preferences inside ProfileEditor (#982)
Simplify preferences model by doing a bulk load/save together with
load/save Profile. ModulePreferences is now a struct rather than an
ObservableObject, because it doesn't need ad hoc observation. It's just
a binding to ProfileEditor.preferences

Fix:

- Disable CloudKit in tunnel singleton of PreferencesManager
(.sharedForTunnel)

Additionally:

- Replace MainActor in PreferencesManager with Sendable (immutable)
- Replace MainActor from ProviderPreferencesRepository with Sendable
(syncs on NSManagedObjectContext)
- Drop ModuleMetadata for good
2024-12-08 16:05:23 +01:00
Davide
d4eed89e9f
Allow "Routing" module in beta 2024-12-06 15:31:01 +01:00
Davide
e663f48bc3
Update library
- Make userInfo AnyHashable
- Prepare for profile processing in tunnel
2024-12-06 11:25:54 +01:00
Davide
dfae6afcb4
Store complex preferences to Core Data (#981)
Replace favorites entities with a PreferencesManager, that returns
observables for:

- Module preferences (by module UUID)
- Provider preferences (by ProviderID)

Automate preferences availability in:

- Module views (empty for now)
- VPN server view (favorites)

Synchronize preferences by making this a CloudKit container. Preferences
are also available in the Tunnel by storing the container in the App
Group.
2024-12-06 11:24:51 +01:00
Davide
f8655b09af
Move error handler to AppCoordinator 2024-12-06 10:29:50 +01:00
Davide
0fd544348f
Disclose details about selected provider server configuration (#980)
Like in v2.
2024-12-04 20:50:51 +01:00
Davide
d8f5caa2f7
Improve "Purchased" view (#979)
- Show eligible features first
- Render ineligible features as secondary
2024-12-04 17:38:13 +01:00
Davide
4ef47dfd77
Bump version 2024-12-04 14:21:29 +01:00
Davide
79bb6e6bdb
Update library again
- Drop -Type suffixes from associated types
- Rename to IdentifiableConfiguration
2024-12-04 13:47:26 +01:00
Davide
355974292e
Update library with provider entities (#978) 2024-12-04 12:40:47 +01:00
Davide
d4543b49ac
Update library with Provider.Metadata renaming 2024-12-04 09:26:10 +01:00
Davide
d53a01864b
Fix unfriendly message on import OpenVPN
Fixes #977
2024-12-04 09:11:16 +01:00
Davide
0aaef04a25
Refactor with provider customizations (#976)
Update library with new API.
2024-12-03 20:28:33 +01:00
Davide
2d93fa64c6
Embrace simplifications in PassepartoutProviders (#975)
Update library with the new domain reorganization.
2024-12-03 16:18:05 +01:00
Davide
d6ebf4bc18
Fix .lifetime not being credited all features 2024-12-02 12:08:30 +01:00
Davide
3540e1cb1a
Redesign confusing paywall (#973)
- Split suggested product and full version
- Hide sections with no products
- Hide full features if no full products
- Fail if no purchasable products
2024-12-02 10:40:25 +01:00
Davide
2447db19e2
Fix compile error on TV 2024-12-02 00:23:13 +01:00
Davide
c50862ff6f
Bump version 2024-12-02 00:16:16 +01:00
Davide
abd1d5bb9b
Enable animations in OpenVPN credentials 2024-12-02 00:11:52 +01:00
Davide
a2544b33ac
Hide OpenVPN password if provider does not require it (#970) 2024-12-02 00:01:35 +01:00
Davide
14ce23f25b
Improve confusing footer modifiers (#969)
There was duplication and a ugly `#if os(macOS)` with some footers
explicitly rendered on macOS with .themeFooter() (now .themeSubtitle()).

Move this logic to the .themeSection() modifiers by adding a
`forcesFooter` parameter. When true, a fake footer is added on macOS as
the last row of a section.
2024-12-01 23:23:51 +01:00
Davide
0a1886fe31
Handle all connection attempts in AppCoordinator (#968)
Let the AppCoordinator take care of the connection requirements via
modals:

- onInteractiveLogin() - now presented on AppError
- onProviderEntityRequired()
- onPurchaseRequired()
- Any other connection error

Subviews must not use tunnel.connect(), rather they route connection
requests via the ConnectionFlow callbacks. In particular, migrate to the
AppCoordinator the connection logic from:

- TunnelToggleButton.perform()
- ProviderEntitySelector.onSelect()

onInteractiveLogin() and onPurchaseRequired() are now handled
internally, while onProviderEntityRequired() is kept public because it's
how subviews may present the entity selector.

Extras:

- Avoid modals overlap with a 500ms delay
- Shrink interactive login size on macOS
2024-12-01 22:34:41 +01:00
Davide
f87cc1da0b
Fix OpenVPN/WireGuard import error messages (#967)
OpenVPN parser was indirectly swallowing WireGuard errors.
2024-12-01 21:33:58 +01:00
Davide
725168b652
Show guidance regardless of OTP method 2024-11-30 16:15:04 +01:00
Davide
1a25102ec3
Add guidance for OpenVPN provider credentials (#966)
Some providers require specific credentials for OpenVPN, different from
account credentials. Update the API index with this information to show
an information footer and possibly a link to the OpenVPN credentials.

Also, fix the OTP footer not appearing on macOS.
2024-11-29 15:25:22 +01:00
Davide
8c305688cc
Always use setLater for paywall
Fixes #951
2024-11-29 00:13:00 +01:00
Davide
63496725c8
Transparent logo in version screen (#963)
Looks better on macOS and allows gradient on tvOS.
2024-11-28 22:59:37 +01:00
Davide
e761979134
Extend ProfileManager events (#964)
Especially for flaky tests:

- Do objectWillChange.send() _before_ performing the change
- Send more events to .didChange to be more deterministic about test
expectations
2024-11-28 22:56:12 +01:00
Davide
7af703c164
Move app library to the root (#962)
Makes it easier to search among app files and library files.
2024-11-28 17:45:18 +01:00