Improve rendering and work around some SwiftUI bugs, e.g. with .menu
Picker on iOS (use .navigationLink instead).
Here goes the hierarchy bottom-up:
- ProviderPicker: a Picker wrapper built around ProviderManager
- ProviderContentModifier: adds a ProviderPicker on top and replaces the
content with a set of provider selectors when a provider is selected
- VPNProviderContentModifier: wrapper for ProviderContentModifier that
adds a VPN server selector
- OpenVPNView: provides a view of specific OpenVPN settings, and adds a
credentials selector to the provider/server selectors provided by
VPNProviderContentModifier
When e.g. a OpenVPNModule is created without a configuration and a
provider/server is then selected, the ProfileProcessor class serializes
the profile with the provider configuration injected. When the module is
re-edited, we can see the provider server configuration in the module
after selecting "None" as provider.
Instead, validate the provider modules in ProfileProcessor, but generate the provider configuration on the fly in the tunnel.
Update library to allow optional VPN configurations. This in turn allows
a module to be used with a provider, where the configuration is
generated on the fly.
- [x] NE managers were not deleted when unable to be decoded to a
profile
- [x] Keychain items were not deleted on profile removal
- [x] Perform clean-up on app launch
- [x] Perform clean-up on app active
Prematurely merged as #727 then reverted, this is the complete PR.
Initial integration of providers via API:
- Generic views and modifiers for provider/server selection
- Add in OpenVPNView
- Prepare in WireGuardView
Also:
- Introduce ProfileProcessor, move IAP processing there
- Move .asModuleView() to ModuleViewModifier for proper animation
- Use .themeModal() rather than .sheet()
Mainly:
- Aggregate shared/mock entities in less scattered files
- Review package dependencies
Also:
- Decouple ProfileRepository from Core Data Repository in UtilsLibrary
(filters done by ProfileManager)
Profiles are being maintained in two places:
- Core Data
- NetworkExtension
Core Data is redundant for local profiles, so make NetworkExtension the
only source of truth.
Remote profiles were never deleted. Now, when removing a profile:
- The profile is deleted from the local store
- The profile is deleted from the remote store
- Other synced devices receive the update and delete the profile from
their remote store
- However, they retain a local copy of the profile
- The copy doesn't appear as "Shared on iCloud" anymore
Also, fix SwiftUI not refreshing when remote profiles are updated. There
was no objectWillChange nor Published around
ProfileManager.allRemoteProfiles, and ProfileRowView was not treating it
as ObservedObject.
Closes#673
Follow the same approach as #636, because if no profiles are formerly
installed the first import will trigger a VPN permission alert. Weird
things may happen in that case if profiles are imported in parallel.