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
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.
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