From adbfb2b9fdd30eff0cf9642cf46fd53bbced18f7 Mon Sep 17 00:00:00 2001 From: Anian Schleyer <98647423+anian03@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:26:34 +0200 Subject: [PATCH] `Communication`: Fix Favorites not being reflected correctly in all places (#174) * Reload sidebar if favorites change * Fix ConversationInfoSheet not having correct favorite status --- .../ConversationInfoSheetViewModel.swift | 5 ++ .../ConversationViewModel.swift | 21 +++++++++ .../MessagesAvailableViewModel.swift | 47 ++++++++++++++++++- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/ArtemisKit/Sources/Messages/ViewModels/ConversationViewModels/ConversationInfoSheetViewModel.swift b/ArtemisKit/Sources/Messages/ViewModels/ConversationViewModels/ConversationInfoSheetViewModel.swift index bfe6771d..1298f9e6 100644 --- a/ArtemisKit/Sources/Messages/ViewModels/ConversationViewModels/ConversationInfoSheetViewModel.swift +++ b/ArtemisKit/Sources/Messages/ViewModels/ConversationViewModels/ConversationInfoSheetViewModel.swift @@ -270,6 +270,11 @@ extension ConversationInfoSheetViewModel { convo.isFavorite?.toggle() conversation = .oneToOneChat(conversation: convo) } + NotificationCenter.default.post(name: .favoriteConversationChanged, + object: nil, + userInfo: [ + conversation.id: conversation.baseConversation.isFavorite as Any + ]) } func sendMessageToUser(with login: String, navigationController: NavigationController, completion: @escaping () -> Void) { diff --git a/ArtemisKit/Sources/Messages/ViewModels/ConversationViewModels/ConversationViewModel.swift b/ArtemisKit/Sources/Messages/ViewModels/ConversationViewModels/ConversationViewModel.swift index c0122c71..46a24440 100644 --- a/ArtemisKit/Sources/Messages/ViewModels/ConversationViewModels/ConversationViewModel.swift +++ b/ArtemisKit/Sources/Messages/ViewModels/ConversationViewModels/ConversationViewModel.swift @@ -74,6 +74,11 @@ class ConversationViewModel: BaseViewModel { subscribeToConversationTopic() fetchOfflineMessages() + + NotificationCenter.default.addObserver(self, + selector: #selector(updateFavorites(notification:)), + name: .favoriteConversationChanged, + object: nil) } deinit { @@ -414,6 +419,22 @@ private extension ConversationViewModel { diff -= 1 } } + + // Change favorites + @objc + private func updateFavorites(notification: Foundation.Notification) { + let isFavorite = notification.userInfo?[conversation.id] as? Bool ?? conversation.baseConversation.isFavorite + if var convo = conversation.baseConversation as? Channel { + convo.isFavorite = isFavorite + conversation = .channel(conversation: convo) + } else if var convo = conversation.baseConversation as? GroupChat { + convo.isFavorite = isFavorite + conversation = .groupChat(conversation: convo) + } else if var convo = conversation.baseConversation as? OneToOneChat { + convo.isFavorite = isFavorite + conversation = .oneToOneChat(conversation: convo) + } + } } // MARK: - ConversationViewModel+SendMessageViewModelDelegate diff --git a/ArtemisKit/Sources/Messages/ViewModels/MessagesTabViewModels/MessagesAvailableViewModel.swift b/ArtemisKit/Sources/Messages/ViewModels/MessagesTabViewModels/MessagesAvailableViewModel.swift index efb76119..0d723752 100644 --- a/ArtemisKit/Sources/Messages/ViewModels/MessagesTabViewModels/MessagesAvailableViewModel.swift +++ b/ArtemisKit/Sources/Messages/ViewModels/MessagesTabViewModels/MessagesAvailableViewModel.swift @@ -66,6 +66,11 @@ class MessagesAvailableViewModel: BaseViewModel { self.userSession = userSession super.init() + + NotificationCenter.default.addObserver(self, + selector: #selector(updateFavorites(notification:)), + name: .favoriteConversationChanged, + object: nil) } func subscribeToConversationMembershipTopic() async { @@ -90,6 +95,36 @@ class MessagesAvailableViewModel: BaseViewModel { allConversations = result } + @objc + private func updateFavorites(notification: Foundation.Notification) { + // User Info contains: + // - Key: Conversation ID + // - Value: New Value for isFavorite + notification.userInfo?.forEach { id, isFavorite in + guard let id = id as? Int64, + let isFavorite = isFavorite as? Bool else { return } + + // Find and update the corresponding conversation + let updatedConversations = allConversations.value?.map { conversation in + var newConversation = conversation + if conversation.id == id { + if var convo = conversation.baseConversation as? Channel { + convo.isFavorite = isFavorite + newConversation = .channel(conversation: convo) + } else if var convo = conversation.baseConversation as? GroupChat { + convo.isFavorite = isFavorite + newConversation = .groupChat(conversation: convo) + } else if var convo = conversation.baseConversation as? OneToOneChat { + convo.isFavorite = isFavorite + newConversation = .oneToOneChat(conversation: convo) + } + } + return newConversation + } + allConversations = .done(response: updatedConversations ?? []) + } + } + func setIsConversationFavorite(conversationId: Int64, isFavorite: Bool) async { isLoading = true let result = await messagesService.updateIsConversationFavorite(for: courseId, and: conversationId, isFavorite: isFavorite) @@ -97,7 +132,9 @@ class MessagesAvailableViewModel: BaseViewModel { case .notStarted, .loading: isLoading = false case .success: - await loadConversations() + NotificationCenter.default.post(name: .favoriteConversationChanged, + object: nil, + userInfo: [conversationId: isFavorite]) isLoading = false case .failure(let error): isLoading = false @@ -352,3 +389,11 @@ enum ConversationFilter: FilterPicker { } } } + +// MARK: Reload Notification + +extension Foundation.Notification.Name { + // Sending a notification of this type causes the Notification List to be reloaded, + // when favorites are changed from elsewhere. + static let favoriteConversationChanged = Foundation.Notification.Name("FavoriteConversationChanged") +}