Per account notifications count close #894
This commit is contained in:
parent
8d8955ee13
commit
bfce92d71e
|
@ -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)
|
||||||
})) {
|
})) {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 ?? "")")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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? {
|
||||||
|
|
Loading…
Reference in New Issue