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
Clarify the use of contexts:
- **Production** (.shared)
- **Previews** (.mock → .forPreviews)
- ONLY use it in UILibrary for, well, previews
- This context has dumb profiles with UUIDs as names
- Registry is fake
- **UI Tests** (.forUITesting)
- Add new context for UI testing
- Selected based on command line arguments
- This context has mock data tuned for decent screenshots
- Registry is real
Share the same InAppProcessor in .shared and .forTesting contexts
because the app behavior was inconsistent regarding e.g. in-app
purchases.