diff --git a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesInteractor.swift index e198f8383..b1953934e 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesInteractor.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesInteractor.swift @@ -9,8 +9,8 @@ final class PushMessagesInteractor { self.subscription = subscription } - var notifyMessagePublisher: AnyPublisher { - return Notify.instance.notifyMessagePublisher + var messagesPublisher: AnyPublisher<[NotifyMessageRecord], Never> { + return Notify.instance.messagesPublisher(topic: subscription.topic) } func getPushMessages() -> [NotifyMessageRecord] { diff --git a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesPresenter.swift index 1c725aec6..c4c3252a9 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesPresenter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesPresenter.swift @@ -8,10 +8,16 @@ final class PushMessagesPresenter: ObservableObject { private let router: PushMessagesRouter private var disposeBag = Set() - @Published var pushMessages: [PushMessageViewModel] = [] + @Published private var pushMessages: [NotifyMessageRecord] = [] + + var messages: [PushMessageViewModel] { + return pushMessages + .sorted { $0.publishedAt > $1.publishedAt } + .map { PushMessageViewModel(pushMessageRecord: $0) } + } init(interactor: PushMessagesInteractor, router: PushMessagesRouter) { - defer { reloadPushMessages() } + defer { setupInitialState() } self.interactor = interactor self.router = router } @@ -20,7 +26,6 @@ final class PushMessagesPresenter: ObservableObject { if let index = indexSet.first { interactor.deletePushMessage(id: pushMessages[index].id) } - reloadPushMessages() } } @@ -40,27 +45,13 @@ extension PushMessagesPresenter: SceneViewModel { private extension PushMessagesPresenter { - func reloadPushMessages() { - self.pushMessages = interactor.getPushMessages() - .sorted { - // Most recent first - $0.publishedAt > $1.publishedAt - } - .map { pushMessageRecord in - PushMessageViewModel(pushMessageRecord: pushMessageRecord) - } - - interactor.notifyMessagePublisher + func setupInitialState() { + pushMessages = interactor.getPushMessages() + + interactor.messagesPublisher .receive(on: DispatchQueue.main) - .sink { [weak self] newPushMessage in - let newMessageViewModel = PushMessageViewModel(pushMessageRecord: newPushMessage) - guard let index = self?.pushMessages.firstIndex( - where: { $0.pushMessageRecord.publishedAt > newPushMessage.publishedAt } - ) else { - self?.pushMessages.append(newMessageViewModel) - return - } - self?.pushMessages.insert(newMessageViewModel, at: index) + .sink { [unowned self] messages in + pushMessages = interactor.getPushMessages() } .store(in: &disposeBag) } diff --git a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesView.swift b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesView.swift index c29766ed3..7f22c53f6 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/PushMessages/PushMessagesView.swift @@ -11,7 +11,7 @@ struct PushMessagesView: View { VStack(alignment: .leading, spacing: 16) { ZStack { - if presenter.pushMessages.isEmpty { + if presenter.messages.isEmpty { VStack(spacing: 10) { Image(systemName: "bell.badge.fill") .resizable() @@ -29,9 +29,9 @@ struct PushMessagesView: View { } VStack { - if !presenter.pushMessages.isEmpty { + if !presenter.messages.isEmpty { List { - ForEach(presenter.pushMessages, id: \.id) { pm in + ForEach(presenter.messages, id: \.id) { pm in notificationView(pushMessage: pm) .listRowSeparator(.hidden) .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 16, trailing: 0)) diff --git a/Sources/WalletConnectNotify/Client/Wallet/NotifyClient.swift b/Sources/WalletConnectNotify/Client/Wallet/NotifyClient.swift index 083ce9bca..99ba78a9c 100644 --- a/Sources/WalletConnectNotify/Client/Wallet/NotifyClient.swift +++ b/Sources/WalletConnectNotify/Client/Wallet/NotifyClient.swift @@ -23,7 +23,7 @@ public class NotifyClient { } public var notifyMessagePublisher: AnyPublisher { - notifyMessageSubscriber.notifyMessagePublisher + return notifyMessageSubscriber.notifyMessagePublisher } public var updateSubscriptionPublisher: AnyPublisher, Never> { @@ -119,6 +119,10 @@ public class NotifyClient { public func isSyncRegistered(account: Account) -> Bool { return notifySyncService.isSyncRegistered(account: account) } + + public func messagesPublisher(topic: String) -> AnyPublisher<[NotifyMessageRecord], Never> { + return notifyStorage.messagesPublisher(topic: topic) + } } #if targetEnvironment(simulator) diff --git a/Sources/WalletConnectNotify/Client/Wallet/NotifyStorage.swift b/Sources/WalletConnectNotify/Client/Wallet/NotifyStorage.swift index 23867f8f3..9ef73a705 100644 --- a/Sources/WalletConnectNotify/Client/Wallet/NotifyStorage.swift +++ b/Sources/WalletConnectNotify/Client/Wallet/NotifyStorage.swift @@ -18,6 +18,7 @@ final class NotifyStorage: NotifyStoring { private let newSubscriptionSubject = PassthroughSubject() private let updateSubscriptionSubject = PassthroughSubject() private let deleteSubscriptionSubject = PassthroughSubject() + private let messagesSubject = PassthroughSubject<[NotifyMessageRecord], Never>() private let subscriptionStoreDelegate: NotifySubscriptionStoreDelegate @@ -26,7 +27,7 @@ final class NotifyStorage: NotifyStoring { } var updateSubscriptionPublisher: AnyPublisher { - return newSubscriptionSubject.eraseToAnyPublisher() + return updateSubscriptionSubject.eraseToAnyPublisher() } var deleteSubscriptionPublisher: AnyPublisher { @@ -37,6 +38,10 @@ final class NotifyStorage: NotifyStoring { return subscriptionStore.dataUpdatePublisher } + var messagesPublisher: AnyPublisher<[NotifyMessageRecord], Never> { + return messagesSubject.eraseToAnyPublisher() + } + init( subscriptionStore: SyncStore, messagesStore: KeyedDatabase, @@ -88,6 +93,12 @@ final class NotifyStorage: NotifyStoring { // MARK: Messages + func messagesPublisher(topic: String) -> AnyPublisher<[NotifyMessageRecord], Never> { + return messagesPublisher + .map { $0.filter { $0.topic == topic } } + .eraseToAnyPublisher() + } + func getMessages(topic: String) -> [NotifyMessageRecord] { return messagesStore.getAll(for: topic) .sorted{$0.publishedAt > $1.publishedAt} @@ -110,6 +121,10 @@ final class NotifyStorage: NotifyStoring { private extension NotifyStorage { func setupSubscriptions() { + messagesStore.onUpdate = { [unowned self] in + messagesSubject.send(messagesStore.getAll()) + } + subscriptionStore.syncUpdatePublisher.sink { [unowned self] (_, _, update) in switch update { case .set(let subscription): diff --git a/Tests/WalletConnectUtilsTests/KeyedDatabaseTests.swift b/Tests/WalletConnectUtilsTests/KeyedDatabaseTests.swift index fc1674fbf..1cd08b53f 100644 --- a/Tests/WalletConnectUtilsTests/KeyedDatabaseTests.swift +++ b/Tests/WalletConnectUtilsTests/KeyedDatabaseTests.swift @@ -37,4 +37,14 @@ final class KeyedDatabaseTests: XCTestCase { XCTAssertEqual(value, updated) } + + func testOnUpdate() { + let new = Object(key: "key1", value: "value1") + + var onUpdateCalled = false + sut.onUpdate = { onUpdateCalled = true } + sut.set(element: new, for: storageKey) + + XCTAssertTrue(onUpdateCalled) + } }