From 8ee5da319cdc5665a5bd881001c6cf7082d43af0 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Mon, 1 Jan 2024 16:46:34 +0100 Subject: [PATCH] Reflect edit / post / delete status better --- IceCubesApp/App/Main/IceCubesApp.swift | 2 +- Packages/Env/Sources/Env/StreamWatcher.swift | 22 ++++++++++++++++++- .../Sources/Models/Stream/StreamEvent.swift | 2 +- .../Status/Editor/StatusEditorViewModel.swift | 6 +++++ .../Status/Row/StatusRowViewModel.swift | 1 + .../Timeline/View/TimelineViewModel.swift | 5 ++++- 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/IceCubesApp/App/Main/IceCubesApp.swift b/IceCubesApp/App/Main/IceCubesApp.swift index 37662820..c25219e2 100644 --- a/IceCubesApp/App/Main/IceCubesApp.swift +++ b/IceCubesApp/App/Main/IceCubesApp.swift @@ -23,7 +23,7 @@ struct IceCubesApp: App { @State var currentAccount = CurrentAccount.shared @State var userPreferences = UserPreferences.shared @State var pushNotificationsService = PushNotificationsService.shared - @State var watcher = StreamWatcher() + @State var watcher = StreamWatcher.shared @State var quickLook = QuickLook.shared @State var theme = Theme.shared diff --git a/Packages/Env/Sources/Env/StreamWatcher.swift b/Packages/Env/Sources/Env/StreamWatcher.swift index 7e162c42..2f4be81a 100644 --- a/Packages/Env/Sources/Env/StreamWatcher.swift +++ b/Packages/Env/Sources/Env/StreamWatcher.swift @@ -26,7 +26,9 @@ import Observation public var unreadNotificationsCount: Int = 0 public var latestEvent: (any StreamEvent)? - public init() { + public static let shared = StreamWatcher() + + private init() { decoder.keyDecodingStrategy = .convertFromSnakeCase } @@ -149,4 +151,22 @@ import Observation return nil } } + + public func emmitDeleteEvent(for status: String) { + let event = StreamEventDelete(status: status) + self.events.append(event) + self.latestEvent = event + } + + public func emmitEditEvent(for status: Status) { + let event = StreamEventStatusUpdate(status: status) + self.events.append(event) + self.latestEvent = event + } + + public func emmitPostEvent(for status: Status) { + let event = StreamEventUpdate(status: status) + self.events.append(event) + self.latestEvent = event + } } diff --git a/Packages/Models/Sources/Models/Stream/StreamEvent.swift b/Packages/Models/Sources/Models/Stream/StreamEvent.swift index 1e067197..c97d9ebb 100644 --- a/Packages/Models/Sources/Models/Stream/StreamEvent.swift +++ b/Packages/Models/Sources/Models/Stream/StreamEvent.swift @@ -22,7 +22,7 @@ public struct StreamEventUpdate: StreamEvent { public struct StreamEventStatusUpdate: StreamEvent { public let date = Date() - public var id: String { status.id } + public var id: String { status.id + (status.editedAt?.asDate.description ?? "")} public let status: Status public init(status: Status) { self.status = status diff --git a/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift b/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift index 31c91c45..294aa5dd 100644 --- a/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift +++ b/Packages/Status/Sources/Status/Editor/StatusEditorViewModel.swift @@ -201,8 +201,14 @@ import SwiftUI switch mode { case .new, .replyTo, .quote, .mention, .shareExtension: postStatus = try await client.post(endpoint: Statuses.postStatus(json: data)) + if let postStatus { + StreamWatcher.shared.emmitPostEvent(for: postStatus) + } case let .edit(status): postStatus = try await client.put(endpoint: Statuses.editStatus(id: status.id, json: data)) + if let postStatus { + StreamWatcher.shared.emmitEditEvent(for: postStatus) + } } HapticManager.shared.fireHaptic(.notification(.success)) if hasExplicitlySelectedLanguage, let selectedLanguage { diff --git a/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift b/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift index 65f59ab5..948cac5e 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift @@ -295,6 +295,7 @@ import SwiftUI func delete() async { do { _ = try await client.delete(endpoint: Statuses.status(id: status.id)) + StreamWatcher.shared.emmitDeleteEvent(for: status.id) } catch {} } diff --git a/Packages/Timeline/Sources/Timeline/View/TimelineViewModel.swift b/Packages/Timeline/Sources/Timeline/View/TimelineViewModel.swift index 77739edb..b3e3275e 100644 --- a/Packages/Timeline/Sources/Timeline/View/TimelineViewModel.swift +++ b/Packages/Timeline/Sources/Timeline/View/TimelineViewModel.swift @@ -110,6 +110,7 @@ import SwiftUI func handleEvent(event: any StreamEvent) async { if let event = event as? StreamEventUpdate, + let client, timeline == .home, canStreamEvents, isTimelineVisible, @@ -119,6 +120,7 @@ import SwiftUI let newStatus = event.status await datasource.insert(newStatus, at: 0) await cacheHome() + StatusDataControllerProvider.shared.updateDataControllers(for: [event.status], client: client) let statuses = await datasource.get() withAnimation { statusesState = .display(statuses: statuses, nextPageState: .hasNextPage) @@ -130,8 +132,9 @@ import SwiftUI withAnimation { statusesState = .display(statuses: statuses, nextPageState: .hasNextPage) } - } else if let event = event as? StreamEventStatusUpdate { + } else if let event = event as? StreamEventStatusUpdate, let client { if let originalIndex = await datasource.indexOf(statusId: event.status.id) { + StatusDataControllerProvider.shared.updateDataControllers(for: [event.status], client: client) await datasource.replace(event.status, at: originalIndex) let statuses = await datasource.get() await cacheHome()