From 89b25926d022d4c95a74a55cb341b4270fa2133b Mon Sep 17 00:00:00 2001 From: Egor Egorov Date: Fri, 19 Jul 2024 12:52:46 +0300 Subject: [PATCH] Fix auto-enqueuing for authenticated visitor Previously, if an authenticated visitor has chat history, enqueuing was postponed until a visitor sends a message. This behaviour was broken after adding LO acknowledge. This commit fixes it. So now: - unauthenticated visitors, if LO acknowledge is enabled, will be enqueued once they accept LO acknowledge - unauthenticated visitors, if LO acknowledge is disabled, will be automatically enqueued - authenticated visitors, if they do not have chat history and LO acknowledge is disabled, will be enqueued automatically - authenticated visitors, if they do not have chat history and if LO acknowledge is enabled, will be enqueued once they accept LO acknowledge - authenticated visitors, if LO acknowledge is enabled and if they have chat history, will be enqueued only after sending a message and accepting LO acknowledge - authenticated visitors, if LO acknowledge is disabled and if they have chat history, will be enqueued after sending a message MOB- 3442 --- .../EngagementCoordinator.swift | 1 - .../Sources/ViewModel/Chat/ChatViewModel.swift | 18 +++++++++++++++--- .../EngagementCoordinatorTests.swift | 5 +++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.swift b/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.swift index 7e53f70e7..4c80f941e 100644 --- a/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.swift +++ b/GliaWidgets/Sources/Coordinators/EngagementCoordinator/EngagementCoordinator.swift @@ -71,7 +71,6 @@ class EngagementCoordinator: SubFlowCoordinator, FlowCoordinator { showsCallBubble: false ) engagement = .chat(chatViewController) - interactor.state = .enqueueing(.text) navigationPresenter.setViewControllers( [chatViewController], animated: false diff --git a/GliaWidgets/Sources/ViewModel/Chat/ChatViewModel.swift b/GliaWidgets/Sources/ViewModel/Chat/ChatViewModel.swift index 8187f6b67..0339aeab5 100644 --- a/GliaWidgets/Sources/ViewModel/Chat/ChatViewModel.swift +++ b/GliaWidgets/Sources/ViewModel/Chat/ChatViewModel.swift @@ -166,7 +166,18 @@ class ChatViewModel: EngagementViewModel { override func start() { super.start() - loadHistory() + + loadHistory { [weak self] history in + guard let self = self else { return } + // We only proceed to considering enqueue flow if `startAction` is about starting of engagement. + guard case .startEngagement = self.startAction else { return } + // We enqueue eagerly in case if this is the first engagement for visitor (by evaluating previous chat history) + // or in case if engagement has been restored. + + if history.isEmpty || self.environment.getCurrentEngagement() != nil { + self.interactor.state = .enqueueing(.text) + } + } } override func update(for state: InteractorState) { @@ -366,7 +377,7 @@ extension ChatViewModel { // MARK: History extension ChatViewModel { - private func loadHistory() { + private func loadHistory(_ completion: @escaping ([ChatMessage]) -> Void) { environment.fetchChatHistory { [weak self] result in guard let self else { return } let messages = (try? result.get()) ?? [] @@ -389,6 +400,7 @@ extension ChatViewModel { self.historySection.set(items) self.action?(.refreshSection(self.historySection.index)) self.action?(.scrollToBottom(animated: false)) + completion(messages) } } } @@ -489,7 +501,7 @@ extension ChatViewModel { case .enqueueing, .ended, .none: handle(pendingMessage: outgoingMessage) - enqueue(mediaType: .text) + interactor.state = .enqueueing(.text) } messageText = "" diff --git a/GliaWidgetsTests/Sources/Coordinators/EngagementCoordinator/EngagementCoordinatorTests.swift b/GliaWidgetsTests/Sources/Coordinators/EngagementCoordinator/EngagementCoordinatorTests.swift index bd0e7ebee..c299b0ff3 100644 --- a/GliaWidgetsTests/Sources/Coordinators/EngagementCoordinator/EngagementCoordinatorTests.swift +++ b/GliaWidgetsTests/Sources/Coordinators/EngagementCoordinator/EngagementCoordinatorTests.swift @@ -47,7 +47,7 @@ final class EngagementCoordinatorTests: XCTestCase { coordinator.start() - XCTAssertEqual(coordinator.interactor.state, .enqueueing(.text)) + XCTAssertEqual(coordinator.interactor.state, .none) let viewController = coordinator.navigationPresenter.viewControllers.first as? ChatViewController XCTAssertNotNil(viewController) XCTAssertNotNil(coordinator.gliaViewController) @@ -169,7 +169,6 @@ final class EngagementCoordinatorTests: XCTestCase { func test_chatCoordinatorBackOnInteractorStateNone() { coordinator.start() - coordinator.interactor.state = .none XCTAssertNotEqual(coordinator.coordinators.count, 0) @@ -190,6 +189,8 @@ final class EngagementCoordinatorTests: XCTestCase { coordinator.start() + coordinator.interactor.state = .enqueueing(.text) + let chatCoordinator = coordinator.coordinators.last as? ChatCoordinator chatCoordinator?.delegate?(.back)