Support settings -> app notification preferences link

This commit is contained in:
Shadowfacts 2024-04-11 18:26:58 -04:00
parent bc516a6326
commit baf96a8b06
10 changed files with 62 additions and 15 deletions

View File

@ -84,7 +84,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
BackgroundManager.shared.registerHandlers()
initializePushManager()
initializePushNotifications()
return true
}
@ -180,7 +180,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
PushManager.shared.didFailToRegisterForRemoteNotifications(error: error)
}
private func initializePushManager() {
private func initializePushNotifications() {
UNUserNotificationCenter.current().delegate = self
Task {
PushManager.captureError = { SentrySDK.capture(error: $0) }
await PushManager.shared.updateIfNecessary(updateSubscription: {
@ -255,3 +256,23 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
#endif
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) {
let mainSceneDelegate: MainSceneDelegate
if let delegate = UIApplication.shared.activeScene?.delegate as? MainSceneDelegate {
mainSceneDelegate = delegate
} else if let scene = UIApplication.shared.connectedScenes.first(where: { $0.delegate is MainSceneDelegate }) {
mainSceneDelegate = scene.delegate as! MainSceneDelegate
} else if let accountID = UserAccountsManager.shared.mostRecentAccountID {
let activity = UserActivityManager.mainSceneActivity(accountID: accountID)
activity.addUserInfoEntries(from: ["showNotificationsPreferences": true])
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil)
return
} else {
// without an account, we can't do anything
return
}
mainSceneDelegate.showNotificationsPreferences()
}
}

View File

@ -283,6 +283,16 @@ class MainSceneDelegate: UIResponder, UIWindowSceneDelegate, TuskerSceneDelegate
}
}
func showNotificationsPreferences() {
let preferencesVC: PreferencesNavigationController?
if let presented = rootViewController?.presentedViewController as? PreferencesNavigationController {
preferencesVC = presented
} else {
preferencesVC = rootViewController?.presentPreferences(completion: nil)
}
preferencesVC?.navigationState.showNotificationPreferences = true
}
}
extension MainSceneDelegate: OnboardingViewControllerDelegate {

View File

@ -152,9 +152,9 @@ extension AccountSwitchingContainerViewController: TuskerRootViewController {
root.performSearch(query: query)
}
func presentPreferences(completion: (() -> Void)?) {
func presentPreferences(completion: (() -> Void)?) -> PreferencesNavigationController? {
loadViewIfNeeded()
root.presentPreferences(completion: completion)
return root.presentPreferences(completion: completion)
}
func handleStatusBarTapped(xPosition: CGFloat) -> StatusBarTapActionResult {

View File

@ -47,7 +47,7 @@ extension DuckableContainerViewController: AccountSwitchableViewController {
(child as? TuskerRootViewController)?.performSearch(query: query)
}
func presentPreferences(completion: (() -> Void)?) {
func presentPreferences(completion: (() -> Void)?) -> PreferencesNavigationController? {
(child as? TuskerRootViewController)?.presentPreferences(completion: completion)
}

View File

@ -623,8 +623,10 @@ extension MainSplitViewController: TuskerRootViewController {
searchViewController.resultsController.performSearch(query: query)
}
func presentPreferences(completion: (() -> Void)?) {
present(PreferencesNavigationController(mastodonController: mastodonController), animated: true, completion: completion)
func presentPreferences(completion: (() -> Void)?) -> PreferencesNavigationController? {
let vc = PreferencesNavigationController(mastodonController: mastodonController)
present(vc, animated: true, completion: completion)
return vc
}
func handleStatusBarTapped(xPosition: CGFloat) -> StatusBarTapActionResult {

View File

@ -342,8 +342,10 @@ extension MainTabBarViewController: TuskerRootViewController {
exploreController.resultsController.performSearch(query: query)
}
func presentPreferences(completion: (() -> Void)?) {
present(PreferencesNavigationController(mastodonController: mastodonController), animated: true, completion: completion)
func presentPreferences(completion: (() -> Void)?) -> PreferencesNavigationController? {
let vc = PreferencesNavigationController(mastodonController: mastodonController)
present(vc, animated: true, completion: completion)
return vc
}
func handleStatusBarTapped(xPosition: CGFloat) -> StatusBarTapActionResult {

View File

@ -17,7 +17,8 @@ protocol TuskerRootViewController: UIViewController, StateRestorableViewControll
func getNavigationDelegate() -> TuskerNavigationDelegate?
func getNavigationController() -> NavigationControllerProtocol
func performSearch(query: String)
func presentPreferences(completion: (() -> Void)?)
@discardableResult
func presentPreferences(completion: (() -> Void)?) -> PreferencesNavigationController?
}
//extension TuskerRootViewController {

View File

@ -70,8 +70,7 @@ struct NotificationsPrefsView: View {
private func startRegistration() async -> Bool {
let authorized: Bool
do {
// TODO: support .providesAppNotificationSettings
authorized = try await UNUserNotificationCenter.current().requestAuthorization(options: [.alert])
authorized = try await UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .providesAppNotificationSettings])
} catch {
self.error = .requestingAuthorization(error)
return false

View File

@ -13,16 +13,24 @@ import SafariServices
import AuthenticationServices
import Pachyderm
// TODO: replace this with NavigationStack and path once we target iOS 16
class PreferencesNavigationState: ObservableObject {
@Published var showNotificationPreferences = false
}
class PreferencesNavigationController: UINavigationController {
private let mastodonController: MastodonController
let navigationState: PreferencesNavigationState
private var isSwitchingAccounts = false
init(mastodonController: MastodonController) {
self.mastodonController = mastodonController
let navigationState = PreferencesNavigationState()
self.navigationState = navigationState
let view = PreferencesView(mastodonController: mastodonController)
let view = PreferencesView(mastodonController: mastodonController, navigationState: navigationState)
let hostingController = UIHostingController(rootView: view)
super.init(rootViewController: hostingController)
hostingController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(donePressed))

View File

@ -10,12 +10,14 @@ import UserAccounts
struct PreferencesView: View {
let mastodonController: MastodonController
@ObservedObject var navigationState: PreferencesNavigationState
@ObservedObject private var userAccounts = UserAccountsManager.shared
@State private var showingLogoutConfirmation = false
init(mastodonController: MastodonController) {
init(mastodonController: MastodonController, navigationState: PreferencesNavigationState) {
self.mastodonController = mastodonController
self.navigationState = navigationState
}
var body: some View {
@ -92,7 +94,9 @@ struct PreferencesView: View {
private var notificationsSection: some View {
Section {
NavigationLink(destination: NotificationsPrefsView()) {
NavigationLink(isActive: $navigationState.showNotificationPreferences) {
NotificationsPrefsView()
} label: {
Text("Notifications")
}
}