mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-25 17:51:01 +00:00
Handle badge for push notifications
This commit is contained in:
parent
8768f28073
commit
d59ba03ba3
11 changed files with 36 additions and 12 deletions
|
@ -1,4 +1,5 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import AVFoundation
|
||||||
import Timeline
|
import Timeline
|
||||||
import Network
|
import Network
|
||||||
import KeychainSwift
|
import KeychainSwift
|
||||||
|
@ -72,9 +73,7 @@ struct IceCubesApp: App {
|
||||||
|
|
||||||
private func badgeFor(tab: Tab) -> Int {
|
private func badgeFor(tab: Tab) -> Int {
|
||||||
if tab == .notifications && selectedTab != tab {
|
if tab == .notifications && selectedTab != tab {
|
||||||
return watcher.unreadNotificationsCount
|
return watcher.unreadNotificationsCount + userPreferences.pushNotificationsCount
|
||||||
} else if tab == .messages && selectedTab != tab {
|
|
||||||
return watcher.unreadMessagesCount
|
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -131,6 +130,7 @@ struct IceCubesApp: App {
|
||||||
watcher.stopWatching()
|
watcher.stopWatching()
|
||||||
case .active:
|
case .active:
|
||||||
watcher.watch(streams: [.user, .direct])
|
watcher.watch(streams: [.user, .direct])
|
||||||
|
UIApplication.shared.applicationIconBadgeNumber = 0
|
||||||
case .inactive:
|
case .inactive:
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
|
@ -151,6 +151,7 @@ struct IceCubesApp: App {
|
||||||
class AppDelegate: NSObject, UIApplicationDelegate {
|
class AppDelegate: NSObject, UIApplicationDelegate {
|
||||||
func application(_ application: UIApplication,
|
func application(_ application: UIApplication,
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
||||||
|
try? AVAudioSession.sharedInstance().setCategory(.ambient, options: .mixWithOthers)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ struct MessagesTab: View {
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
routeurPath.client = client
|
routeurPath.client = client
|
||||||
watcher.unreadMessagesCount = 0
|
|
||||||
}
|
}
|
||||||
.withSafariRouteur()
|
.withSafariRouteur()
|
||||||
.environmentObject(routeurPath)
|
.environmentObject(routeurPath)
|
||||||
|
|
|
@ -8,6 +8,7 @@ struct NotificationsTab: View {
|
||||||
@EnvironmentObject private var client: Client
|
@EnvironmentObject private var client: Client
|
||||||
@EnvironmentObject private var watcher: StreamWatcher
|
@EnvironmentObject private var watcher: StreamWatcher
|
||||||
@EnvironmentObject private var currentAccount: CurrentAccount
|
@EnvironmentObject private var currentAccount: CurrentAccount
|
||||||
|
@EnvironmentObject private var userPreferences: UserPreferences
|
||||||
@StateObject private var routeurPath = RouterPath()
|
@StateObject private var routeurPath = RouterPath()
|
||||||
@Binding var popToRootTab: Tab
|
@Binding var popToRootTab: Tab
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ struct NotificationsTab: View {
|
||||||
.onAppear {
|
.onAppear {
|
||||||
routeurPath.client = client
|
routeurPath.client = client
|
||||||
watcher.unreadNotificationsCount = 0
|
watcher.unreadNotificationsCount = 0
|
||||||
|
userPreferences.pushNotificationsCount = 0
|
||||||
}
|
}
|
||||||
.withSafariRouteur()
|
.withSafariRouteur()
|
||||||
.environmentObject(routeurPath)
|
.environmentObject(routeurPath)
|
||||||
|
|
|
@ -17,7 +17,7 @@ struct PushNotificationsView: View {
|
||||||
Form {
|
Form {
|
||||||
Section {
|
Section {
|
||||||
Toggle(isOn: $pushNotifications.isPushEnabled) {
|
Toggle(isOn: $pushNotifications.isPushEnabled) {
|
||||||
Text("Push notification")
|
Text("Push notifications")
|
||||||
}
|
}
|
||||||
} footer: {
|
} footer: {
|
||||||
Text("Receive push notifications on new activities")
|
Text("Receive push notifications on new activities")
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
<string>development</string>
|
<string>development</string>
|
||||||
<key>com.apple.security.app-sandbox</key>
|
<key>com.apple.security.app-sandbox</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>com.apple.security.application-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>group.icecubesapps</string>
|
||||||
|
</array>
|
||||||
<key>com.apple.security.files.user-selected.read-only</key>
|
<key>com.apple.security.files.user-selected.read-only</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>keychain-access-groups</key>
|
<key>keychain-access-groups</key>
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>com.apple.security.application-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>group.icecubesapps</string>
|
||||||
|
</array>
|
||||||
<key>keychain-access-groups</key>
|
<key>keychain-access-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>$(AppIdentifierPrefix)com.thomasricouard.IceCubesApp</string>
|
<string>$(AppIdentifierPrefix)com.thomasricouard.IceCubesApp</string>
|
||||||
|
|
|
@ -54,6 +54,11 @@ class NotificationService: UNNotificationServiceExtension {
|
||||||
bestAttemptContent.userInfo["plaintext"] = plaintextData
|
bestAttemptContent.userInfo["plaintext"] = plaintextData
|
||||||
bestAttemptContent.sound = UNNotificationSound.init(named: UNNotificationSoundName(rawValue: "glass.wav"))
|
bestAttemptContent.sound = UNNotificationSound.init(named: UNNotificationSoundName(rawValue: "glass.wav"))
|
||||||
|
|
||||||
|
let preferences = UserPreferences()
|
||||||
|
preferences.pushNotificationsCount += 1
|
||||||
|
|
||||||
|
bestAttemptContent.badge = .init(integerLiteral: preferences.pushNotificationsCount)
|
||||||
|
|
||||||
if let urlString = notification.icon,
|
if let urlString = notification.icon,
|
||||||
let url = URL(string: urlString) {
|
let url = URL(string: urlString) {
|
||||||
let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("notification-attachments")
|
let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("notification-attachments")
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Foundation
|
||||||
|
|
||||||
extension CGFloat {
|
extension CGFloat {
|
||||||
public static let layoutPadding: CGFloat = 20
|
public static let layoutPadding: CGFloat = 20
|
||||||
public static let dividerPadding: CGFloat = 4
|
public static let dividerPadding: CGFloat = 2
|
||||||
public static let statusColumnsSpacing: CGFloat = 8
|
public static let statusColumnsSpacing: CGFloat = 8
|
||||||
public static let maxColumnWidth: CGFloat = 650
|
public static let maxColumnWidth: CGFloat = 650
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,12 +48,14 @@ public class PushNotificationsService: ObservableObject {
|
||||||
|
|
||||||
private var keychain: KeychainSwift {
|
private var keychain: KeychainSwift {
|
||||||
let keychain = KeychainSwift()
|
let keychain = KeychainSwift()
|
||||||
|
#if !DEBUG
|
||||||
keychain.accessGroup = Constants.keychainGroup
|
keychain.accessGroup = Constants.keychainGroup
|
||||||
|
#endif
|
||||||
return keychain
|
return keychain
|
||||||
}
|
}
|
||||||
|
|
||||||
public func requestPushNotifications() {
|
public func requestPushNotifications() {
|
||||||
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { (_, _) in
|
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (_, _) in
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
UIApplication.shared.registerForRemoteNotifications()
|
UIApplication.shared.registerForRemoteNotifications()
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ public class StreamWatcher: ObservableObject {
|
||||||
|
|
||||||
@Published public var events: [any StreamEvent] = []
|
@Published public var events: [any StreamEvent] = []
|
||||||
@Published public var unreadNotificationsCount: Int = 0
|
@Published public var unreadNotificationsCount: Int = 0
|
||||||
@Published public var unreadMessagesCount: Int = 0
|
|
||||||
@Published public var latestEvent: (any StreamEvent)?
|
@Published public var latestEvent: (any StreamEvent)?
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
|
@ -81,8 +80,6 @@ public class StreamWatcher: ObservableObject {
|
||||||
self.latestEvent = event
|
self.latestEvent = event
|
||||||
if let event = event as? StreamEventNotification, event.notification.status?.visibility != .direct {
|
if let event = event as? StreamEventNotification, event.notification.status?.visibility != .direct {
|
||||||
self.unreadNotificationsCount += 1
|
self.unreadNotificationsCount += 1
|
||||||
} else if event is StreamEventConversation {
|
|
||||||
self.unreadMessagesCount += 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,18 @@ import SwiftUI
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public class UserPreferences: ObservableObject {
|
public class UserPreferences: ObservableObject {
|
||||||
|
private static let sharedDefault = UserDefaults.init(suiteName: "group.icecubesapps")
|
||||||
|
|
||||||
@AppStorage("remote_local_timeline") public var remoteLocalTimelines: [String] = []
|
@AppStorage("remote_local_timeline") public var remoteLocalTimelines: [String] = []
|
||||||
@AppStorage("preferred_browser") public var preferredBrowser: PreferredBrowser = .inAppSafari
|
@AppStorage("preferred_browser") public var preferredBrowser: PreferredBrowser = .inAppSafari
|
||||||
|
public var pushNotificationsCount: Int {
|
||||||
|
get {
|
||||||
|
Self.sharedDefault?.integer(forKey: "push_notifications_count") ?? 0
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
Self.sharedDefault?.set(newValue, forKey: "push_notifications_count")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public init() { }
|
public init() { }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue