Live notifications
This commit is contained in:
parent
93543cad6b
commit
a8fb18559d
|
@ -393,7 +393,7 @@
|
|||
CODE_SIGN_IDENTITY = "-";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 300;
|
||||
CURRENT_PROJECT_VERSION = 350;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"IceCubesApp/Resources\"";
|
||||
DEVELOPMENT_TEAM = Z6P74P6T99;
|
||||
|
@ -415,7 +415,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 0.3.0;
|
||||
MARKETING_VERSION = 0.3.5;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = auto;
|
||||
|
@ -437,7 +437,7 @@
|
|||
CODE_SIGN_IDENTITY = "-";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 300;
|
||||
CURRENT_PROJECT_VERSION = 350;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"IceCubesApp/Resources\"";
|
||||
DEVELOPMENT_TEAM = Z6P74P6T99;
|
||||
|
@ -459,7 +459,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 0.3.0;
|
||||
MARKETING_VERSION = 0.3.5;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = auto;
|
||||
|
|
|
@ -47,6 +47,7 @@ struct IceCubesApp: App {
|
|||
.tabItem {
|
||||
Label("Notifications", systemImage: "bell")
|
||||
}
|
||||
.badge(watcher.unreadNotificationsCount)
|
||||
.tag(Tab.notifications)
|
||||
ExploreTab(popToRootTab: $popToRootTab)
|
||||
.tabItem {
|
||||
|
|
|
@ -5,6 +5,7 @@ import Network
|
|||
import Notifications
|
||||
|
||||
struct NotificationsTab: View {
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@StateObject private var routeurPath = RouterPath()
|
||||
@Binding var popToRootTab: IceCubesApp.Tab
|
||||
|
||||
|
@ -14,6 +15,9 @@ struct NotificationsTab: View {
|
|||
.withAppRouteur()
|
||||
.withSheetDestinations(sheetDestinations: $routeurPath.presentedSheet)
|
||||
}
|
||||
.onAppear {
|
||||
watcher.unreadNotificationsCount = 0
|
||||
}
|
||||
.environmentObject(routeurPath)
|
||||
.onChange(of: $popToRootTab.wrappedValue) { popToRootTab in
|
||||
if popToRootTab == .notifications {
|
||||
|
|
|
@ -17,6 +17,7 @@ public class StreamWatcher: ObservableObject {
|
|||
}
|
||||
|
||||
@Published public var events: [any StreamEvent] = []
|
||||
@Published public var unreadNotificationsCount: Int = 0
|
||||
@Published public var latestEvent: (any StreamEvent)?
|
||||
|
||||
public init() {
|
||||
|
@ -38,6 +39,9 @@ public class StreamWatcher: ObservableObject {
|
|||
}
|
||||
|
||||
public func watch(stream: Stream) {
|
||||
if client?.isAuth == false && stream == .user {
|
||||
return
|
||||
}
|
||||
if task == nil {
|
||||
connect()
|
||||
}
|
||||
|
@ -71,6 +75,9 @@ public class StreamWatcher: ObservableObject {
|
|||
Task { @MainActor in
|
||||
self.events.append(event)
|
||||
self.latestEvent = event
|
||||
if event is StreamEventNotification {
|
||||
self.unreadNotificationsCount += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
|
|
|
@ -3,8 +3,10 @@ import Network
|
|||
import Models
|
||||
import Shimmer
|
||||
import DesignSystem
|
||||
import Env
|
||||
|
||||
public struct NotificationsListView: View {
|
||||
@EnvironmentObject private var watcher: StreamWatcher
|
||||
@EnvironmentObject private var client: Client
|
||||
@StateObject private var viewModel = NotificationsViewModel()
|
||||
|
||||
|
@ -39,6 +41,11 @@ public struct NotificationsListView: View {
|
|||
.refreshable {
|
||||
await viewModel.fetchNotifications()
|
||||
}
|
||||
.onChange(of: watcher.latestEvent?.id, perform: { _ in
|
||||
if let latestEvent = watcher.latestEvent {
|
||||
viewModel.handleEvent(event: latestEvent)
|
||||
}
|
||||
})
|
||||
.navigationTitle(Text("Notifications"))
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
}
|
||||
|
|
|
@ -71,4 +71,11 @@ class NotificationsViewModel: ObservableObject {
|
|||
state = .error(error: error)
|
||||
}
|
||||
}
|
||||
|
||||
func handleEvent(event: any StreamEvent) {
|
||||
if let event = event as? StreamEventNotification {
|
||||
notifications.insert(event.notification, at: 0)
|
||||
state = .display(notifications: notifications, nextPageState: .hasNextPage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue