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

View File

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

View File

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

View File

@ -64,9 +64,14 @@ class NotificationService: UNNotificationServiceExtension {
bestAttemptContent.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "glass.caf")) bestAttemptContent.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "glass.caf"))
let preferences = UserPreferences.shared 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, if let urlString = notification.icon,
let url = URL(string: urlString) let url = URL(string: urlString)

View File

@ -3,6 +3,7 @@ import Env
import SwiftUI import SwiftUI
public struct AppAccountsSelectorView: View { public struct AppAccountsSelectorView: View {
@EnvironmentObject private var preferences: UserPreferences
@EnvironmentObject private var currentAccount: CurrentAccount @EnvironmentObject private var currentAccount: CurrentAccount
@EnvironmentObject private var appAccounts: AppAccountsManager @EnvironmentObject private var appAccounts: AppAccountsManager
@ -90,7 +91,12 @@ public struct AppAccountsSelectorView: View {
if let image = viewModel.roundedAvatar { if let image = viewModel.roundedAvatar {
Image(uiImage: image) 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 { public func setNotification(count: Int, token: OauthToken) {
get { Self.sharedDefault?.set(count, forKey: "push_notifications_count_\(token.createdAt)")
Self.sharedDefault?.integer(forKey: "push_notifications_count") ?? 0 }
}
set { public func getNotificationsCount(for token: OauthToken) -> Int {
Self.sharedDefault?.set(newValue, forKey: "push_notifications_count") 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? { public var chosenFont: UIFont? {