- Use StoreKit views when available
- Offer one-time purchase
- Recurring subscriptions for all features
- Restore purchases
Remove .siri (Shortcuts), now free.
Closes#819Closes#469
Revisit the use of informational footers in forms because:
- iOS uses Section footers
- macOS uses a secondary label below the main row label
Therefore:
- Add .themeRow() modifier to accomplish macOS behavior
- iOS: leave .themeSection() as is, and add a dummy .themeRow() that
does nothing
- macOS: make footer ineffective in .themeSection(), but add .themeRow()
modifiers to move footers to rows
Based on in-app eligibility, expire TV profiles after 10 minutes.
Refactor/redesign general sections and offer .sharing feature for free,
it makes it simpler to focus on Apple TV product.
Streamline initialization of AppContext objects without singletons,
especially because some are interconnected.
Rethink ProfileProcessor to be the only gateway of profile processing
for:
- Include
- Save
- Connect
Provide closures with access to the IAPManager for eligibility checks.
Finally, take a ProfileProcessor parameter in:
- ProfileManager (for isIncluded and willSave)
- ExtendedTunnel (for willConnect)
so that it's used implicitly without having to put it into the SwiftUI
environment.
Other than that:
- Move AppError to CommonLibrary
- Skip decoding of attributes from Core Data because they are already
part of the profile
- [x] tvOS: When profile selector appears, if it's closed without
selecting any profile, it instantly reopens
- [x] Set initial focus in OpenVPN credentials
Define two styles for interactive login:
- Modal (iOS/macOS) - Form inside NavigationStack
- Inline (tvOS) - VStack
Requires OpenVPN credentials view to be container-agnostic.
Play with focus to improve the overall TV experience.