Add native iOS notifications (#64)
This commit is contained in:
@@ -4,6 +4,8 @@ import UIKit
|
||||
final class SettingsViewController: UITableViewController {
|
||||
private let context: AppContext
|
||||
private let appearanceControl = UISegmentedControl(items: ["Auto", "Light", "Dark"])
|
||||
private let notificationSwitch = UISwitch()
|
||||
private var notificationStatus = "Managed by iOS"
|
||||
|
||||
init(context: AppContext) {
|
||||
self.context = context
|
||||
@@ -19,23 +21,58 @@ final class SettingsViewController: UITableViewController {
|
||||
let settings = context.core.settings()
|
||||
appearanceControl.selectedSegmentIndex = Int(settings.appearance)
|
||||
appearanceControl.addTarget(self, action: #selector(appearanceChanged), for: .valueChanged)
|
||||
notificationSwitch.isOn = settings.notificationsEnabled
|
||||
notificationSwitch.accessibilityLabel = "Background notifications"
|
||||
notificationSwitch.addTarget(self, action: #selector(notificationsChanged), for: .valueChanged)
|
||||
}
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int { 1 }
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 1 }
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
notificationSwitch.isOn = context.core.settings().notificationsEnabled
|
||||
Task {
|
||||
notificationStatus = await context.notifications.authorizationDescription()
|
||||
updateNotificationSettingsCell()
|
||||
}
|
||||
}
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int { 2 }
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
section == 0 ? 1 : 2
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
"Appearance"
|
||||
section == 0 ? "Appearance" : "Notifications"
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
|
||||
"Follow iOS automatically or choose a fixed appearance."
|
||||
if section == 0 {
|
||||
return "Follow iOS automatically or choose a fixed appearance."
|
||||
}
|
||||
return "Gotcha checks periodically for server notifications. iOS decides when background refresh runs; delivery style, sounds, Focus, and summaries remain under your control in iOS Settings."
|
||||
}
|
||||
|
||||
override func tableView(
|
||||
_ tableView: UITableView,
|
||||
cellForRowAt indexPath: IndexPath
|
||||
) -> UITableViewCell {
|
||||
guard indexPath.section == 0 else {
|
||||
if indexPath.row == 0 {
|
||||
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
|
||||
var content = cell.defaultContentConfiguration()
|
||||
content.text = "Background notifications"
|
||||
cell.contentConfiguration = content
|
||||
cell.accessoryView = notificationSwitch
|
||||
cell.selectionStyle = .none
|
||||
return cell
|
||||
}
|
||||
let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
|
||||
var content = cell.defaultContentConfiguration()
|
||||
content.text = "Notification Settings"
|
||||
content.secondaryText = notificationStatus
|
||||
cell.contentConfiguration = content
|
||||
cell.accessoryType = .disclosureIndicator
|
||||
return cell
|
||||
}
|
||||
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
|
||||
appearanceControl.translatesAutoresizingMaskIntoConstraints = false
|
||||
cell.contentView.addSubview(appearanceControl)
|
||||
@@ -48,6 +85,12 @@ final class SettingsViewController: UITableViewController {
|
||||
return cell
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
guard indexPath.section == 1, indexPath.row == 1 else { return }
|
||||
context.notifications.openSystemSettings()
|
||||
}
|
||||
|
||||
@objc private func appearanceChanged() {
|
||||
do {
|
||||
try context.core.setAppearance(index: UInt32(appearanceControl.selectedSegmentIndex))
|
||||
@@ -56,4 +99,43 @@ final class SettingsViewController: UITableViewController {
|
||||
show(error: error)
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func notificationsChanged() {
|
||||
let requested = notificationSwitch.isOn
|
||||
notificationSwitch.isEnabled = false
|
||||
Task {
|
||||
do {
|
||||
let enabled = try await context.notifications.setEnabled(requested)
|
||||
notificationSwitch.isOn = enabled
|
||||
if requested && !enabled { showNotificationsDisabledAlert() }
|
||||
} catch {
|
||||
notificationSwitch.isOn = context.core.settings().notificationsEnabled
|
||||
show(error: error)
|
||||
}
|
||||
notificationSwitch.isEnabled = true
|
||||
notificationStatus = await context.notifications.authorizationDescription()
|
||||
updateNotificationSettingsCell()
|
||||
}
|
||||
}
|
||||
|
||||
private func updateNotificationSettingsCell() {
|
||||
guard let cell = tableView.cellForRow(at: IndexPath(row: 1, section: 1)) else { return }
|
||||
var content = cell.defaultContentConfiguration()
|
||||
content.text = "Notification Settings"
|
||||
content.secondaryText = notificationStatus
|
||||
cell.contentConfiguration = content
|
||||
}
|
||||
|
||||
private func showNotificationsDisabledAlert() {
|
||||
let alert = UIAlertController(
|
||||
title: "Notifications Are Disabled",
|
||||
message: "Allow notifications in iOS Settings, then turn Background notifications on again.",
|
||||
preferredStyle: .alert
|
||||
)
|
||||
alert.addAction(UIAlertAction(title: "Not Now", style: .cancel))
|
||||
alert.addAction(UIAlertAction(title: "Open Settings", style: .default) { [weak self] _ in
|
||||
self?.context.notifications.openSystemSettings()
|
||||
})
|
||||
present(alert, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user