Per account notifications count close #894

This commit is contained in:
Thomas Ricouard 2023-02-18 15:36:18 +01:00
parent 8d8955ee13
commit bfce92d71e
6 changed files with 69 additions and 42 deletions

View file

@ -99,8 +99,9 @@ struct IceCubesApp: App {
}
private func badgeFor(tab: Tab) -> Int {
if tab == .notifications && selectedTab != tab {
return watcher.unreadNotificationsCount + userPreferences.pushNotificationsCount
if tab == .notifications && selectedTab != tab,
let token = appAccountsManager.currentAccount.oauthToken {
return watcher.unreadNotificationsCount + userPreferences.getNotificationsCount(for: token)
}
return 0
}
@ -167,6 +168,11 @@ struct IceCubesApp: App {
}
}
selectedTab = newTab
if selectedTab == .notifications,
let token = appAccountsManager.currentAccount.oauthToken {
userPreferences.setNotification(count: 0, token: token)
watcher.unreadNotificationsCount = 0
}
}
HapticManager.shared.fireHaptic(of: .tabSelection)
})) {

View file

@ -19,44 +19,37 @@ struct SideBarView<Content: View>: View {
@ViewBuilder var content: () -> Content
private func badgeFor(tab: Tab) -> Int {
if tab == .notifications && selectedTab != tab {
return watcher.unreadNotificationsCount + userPreferences.pushNotificationsCount
if tab == .notifications && selectedTab != tab,
let token = appAccounts.currentAccount.oauthToken {
return watcher.unreadNotificationsCount + userPreferences.getNotificationsCount(for: token)
}
return 0
}
private var profileView: some View {
Button {
selectedTab = .profile
} label: {
AppAccountsSelectorView(routerPath: RouterPath(),
accountCreationEnabled: false,
avatarSize: .status)
}
.frame(width: .sidebarWidth, height: 60)
.background(selectedTab == .profile ? theme.secondaryBackgroundColor : .clear)
}
private func makeIconForTab(tab: Tab) -> some View {
ZStack(alignment: .topTrailing) {
SideBarIcon(systemIconName: tab.iconName,
isSelected: tab == selectedTab)
if let badge = badgeFor(tab: tab), badge > 0 {
ZStack {
Circle()
.fill(.red)
Text(String(badge))
.foregroundColor(.white)
.font(.caption2)
}
.frame(width: 20, height: 20)
.offset(x: 10, y: -10)
makeBadgeView(count: badge)
}
}
.contentShape(Rectangle())
.frame(width: .sidebarWidth, height: 50)
}
private func makeBadgeView(count: Int) -> some View {
ZStack {
Circle()
.fill(.red)
Text(String(count))
.foregroundColor(.white)
.font(.caption2)
}
.frame(width: 20, height: 20)
.offset(x: 10, y: -10)
}
private var postButton: some View {
Button {
routerPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
@ -70,7 +63,7 @@ struct SideBarView<Content: View>: View {
.keyboardShortcut("n", modifiers: .command)
}
private func makeAccountButton(account: AppAccount) -> some View {
private func makeAccountButton(account: AppAccount, showBadge: Bool) -> some View {
Button {
if account.id == appAccounts.currentAccount.id {
selectedTab = .profile
@ -82,7 +75,14 @@ struct SideBarView<Content: View>: View {
}
}
} label: {
AppAccountView(viewModel: .init(appAccount: account, isCompact: true))
ZStack(alignment: .topTrailing) {
AppAccountView(viewModel: .init(appAccount: account, isCompact: true))
if showBadge,
let token = account.oauthToken,
userPreferences.getNotificationsCount(for: token) > 0 {
makeBadgeView(count: userPreferences.getNotificationsCount(for: token))
}
}
}
.frame(width: .sidebarWidth, height: 50)
.padding(.vertical, 8)
@ -101,8 +101,10 @@ struct SideBarView<Content: View>: View {
}
selectedTab = tab
if tab == .notifications {
if let token = appAccounts.currentAccount.oauthToken {
userPreferences.setNotification(count: 0, token: token)
}
watcher.unreadNotificationsCount = 0
userPreferences.pushNotificationsCount = 0
}
} label: {
makeIconForTab(tab: tab)
@ -119,7 +121,8 @@ struct SideBarView<Content: View>: View {
tabsView
} else {
ForEach(appAccounts.availableAccounts) { account in
makeAccountButton(account: account)
makeAccountButton(account: account,
showBadge: account.id != appAccounts.currentAccount.id)
if account.id == appAccounts.currentAccount.id {
tabsView
}

View file

@ -44,8 +44,6 @@ struct NotificationsTab: View {
}
.onAppear {
routerPath.client = client
watcher.unreadNotificationsCount = 0
userPreferences.pushNotificationsCount = 0
}
.withSafariRouter()
.environmentObject(routerPath)
@ -72,8 +70,10 @@ struct NotificationsTab: View {
switch scenePhase {
case .active:
if isSecondaryColumn {
if let token = appAccount.currentAccount.oauthToken {
userPreferences.setNotification(count: 0, token: token)
}
watcher.unreadNotificationsCount = 0
userPreferences.pushNotificationsCount = 0
}
default:
break

View file

@ -64,9 +64,14 @@ class NotificationService: UNNotificationServiceExtension {
bestAttemptContent.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "glass.caf"))
let preferences = UserPreferences.shared
preferences.pushNotificationsCount += 1
if let token = AppAccountsManager.shared.availableAccounts.first(where: { $0.oauthToken?.accessToken == notification.accessToken})?.oauthToken {
var currentCount = preferences.getNotificationsCount(for: token)
currentCount += 1
preferences.setNotification(count: currentCount, token: token)
}
bestAttemptContent.badge = .init(integerLiteral: preferences.pushNotificationsCount)
let tokens = AppAccountsManager.shared.pushAccounts.map { $0.token }
bestAttemptContent.badge = .init(integerLiteral: preferences.getNotificationsTotalCount(for: tokens))
if let urlString = notification.icon,
let url = URL(string: urlString)

View file

@ -3,6 +3,7 @@ import Env
import SwiftUI
public struct AppAccountsSelectorView: View {
@EnvironmentObject private var preferences: UserPreferences
@EnvironmentObject private var currentAccount: CurrentAccount
@EnvironmentObject private var appAccounts: AppAccountsManager
@ -90,7 +91,12 @@ public struct AppAccountsSelectorView: View {
if let image = viewModel.roundedAvatar {
Image(uiImage: image)
}
Text("\(viewModel.account?.displayName ?? "")")
if let token = viewModel.appAccount.oauthToken,
preferences.getNotificationsCount(for: token) > 0 {
Text("\(viewModel.account?.displayName ?? "") (\(preferences.getNotificationsCount(for: token)))")
} else {
Text("\(viewModel.account?.displayName ?? "")")
}
}
}
}

View file

@ -97,13 +97,20 @@ public class UserPreferences: ObservableObject {
}
}
public var pushNotificationsCount: Int {
get {
Self.sharedDefault?.integer(forKey: "push_notifications_count") ?? 0
}
set {
Self.sharedDefault?.set(newValue, forKey: "push_notifications_count")
public func setNotification(count: Int, token: OauthToken) {
Self.sharedDefault?.set(count, forKey: "push_notifications_count_\(token.createdAt)")
}
public func getNotificationsCount(for token: OauthToken) -> Int {
Self.sharedDefault?.integer(forKey: "push_notifications_count_\(token.createdAt)") ?? 0
}
public func getNotificationsTotalCount(for tokens: [OauthToken]) -> Int {
var count: Int = 0
for token in tokens {
count += getNotificationsCount(for: token)
}
return count
}
public var chosenFont: UIFont? {