Skip to content

Commit

Permalink
Display Live Observation alert before normal engagement
Browse files Browse the repository at this point in the history
This PR displays Live Observation confirmation alert before normal engagement.
This alert can't be skipped and needs visitor's manual confirmation to
enqueue.

MOB-2678
  • Loading branch information
rasmustautsglia authored and github-review-helper committed Oct 3, 2023
1 parent 1e7c941 commit a7f5e8e
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 11 deletions.
2 changes: 0 additions & 2 deletions GliaWidgets/Sources/Interactor/Interactor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ extension Interactor {
success: @escaping () -> Void,
failure: @escaping (CoreSdkClient.SalemoveError) -> Void
) {
state = .enqueueing

let options = mediaType == .audio || mediaType == .video
? CoreSdkClient.EngagementOptions(mediaDirection: .twoWay)
: nil
Expand Down
40 changes: 40 additions & 0 deletions GliaWidgets/Sources/ViewController/Call/CallViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ final class CallViewController: EngagementViewController {
private let viewModel: CallViewModel
private let environment: Environment
private var proximityManager: ProximityManager?
private var hasViewAppeared = false

private var pendingLiveObservationConfirmation: LiveObservationConfirmation?

init(viewModel: CallViewModel, viewFactory: ViewFactory, environment: Environment) {
self.environment = environment
Expand Down Expand Up @@ -63,6 +66,15 @@ final class CallViewController: EngagementViewController {
view.checkBarsOrientation()
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
hasViewAppeared = true
if let alertConfig = pendingLiveObservationConfirmation {
showLiveObservationConfirmationAlert(with: alertConfig)
pendingLiveObservationConfirmation = nil
}
}

@objc
private func deviceDidRotate() {
guard let view = view as? CallView else { return }
Expand Down Expand Up @@ -125,6 +137,8 @@ final class CallViewController: EngagementViewController {
view.isVisitrOnHold = isOnHold
case .transferring:
view.setConnectState(.transferring, animated: true)
case let .showLiveObservationConfirmation(configuration):
self?.showLiveObservationConfirmation(with: configuration)
}
}
}
Expand All @@ -140,6 +154,26 @@ final class CallViewController: EngagementViewController {
style: props.style
)
}

private func showLiveObservationConfirmation(with config: LiveObservationConfirmation) {
switch hasViewAppeared {
case true: showLiveObservationConfirmationAlert(with: config)
case false: pendingLiveObservationConfirmation = config
}
}

private func showLiveObservationConfirmationAlert(with config: LiveObservationConfirmation) {
let alert = AlertViewController(
kind: .liveObservationConfirmation(
config.conf,
accepted: config.accepted,
declined: config.declined
),
viewFactory: self.viewFactory
)

replacePresentedOfferIfPossible(with: alert)
}
}

private extension CallViewModel.CallButton {
Expand Down Expand Up @@ -194,4 +228,10 @@ extension CallViewController {
var uiDevice: UIKitBased.UIDevice
var notificationCenter: FoundationBased.NotificationCenter
}

struct LiveObservationConfirmation {
let conf: ConfirmationAlertConfiguration
let accepted: () -> Void
let declined: () -> Void
}
}
34 changes: 34 additions & 0 deletions GliaWidgets/Sources/ViewController/Chat/ChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ final class ChatViewController: EngagementViewController, PopoverPresenter {
}
}
private var lastVisibleRowIndexPath: IndexPath?
private var hasViewAppeared = false
private var pendingLiveObservationConfirmation: CallViewController.LiveObservationConfirmation?

init(
viewModel: SecureConversations.ChatWithTranscriptModel,
Expand Down Expand Up @@ -36,6 +38,15 @@ final class ChatViewController: EngagementViewController, PopoverPresenter {
viewModel.event(.viewDidLoad)
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
hasViewAppeared = true
if let alertConfig = pendingLiveObservationConfirmation {
showLiveObservationConfirmationAlert(with: alertConfig)
pendingLiveObservationConfirmation = nil
}
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

Expand Down Expand Up @@ -168,12 +179,35 @@ final class ChatViewController: EngagementViewController, PopoverPresenter {
view?.messageEntryView.uploadListView.props = fileUploadListProps
case let .quickReplyPropsUpdated(props):
view?.renderQuickReply(props: props)
case let .showLiveObservationConfirmation(configuration):
self?.showLiveObservationConfirmation(with: configuration)
}
self?.renderProps()
}
}
// swiftlint:enable function_body_length

private func showLiveObservationConfirmation(
with config: CallViewController.LiveObservationConfirmation) {
switch hasViewAppeared {
case true: showLiveObservationConfirmationAlert(with: config)
case false: pendingLiveObservationConfirmation = config
}
}

private func showLiveObservationConfirmationAlert(with config: CallViewController.LiveObservationConfirmation) {
let alert = AlertViewController(
kind: .liveObservationConfirmation(
config.conf,
accepted: config.accepted,
declined: config.declined
),
viewFactory: self.viewFactory
)

replacePresentedOfferIfPossible(with: alert)
}

private func presentMediaPicker(
from sourceView: UIView,
itemSelected: @escaping (AttachmentSourceItemKind) -> Void
Expand Down
24 changes: 22 additions & 2 deletions GliaWidgets/Sources/ViewModel/Call/CallViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ class CallViewModel: EngagementViewModel, ViewModel {

switch startWith {
case .engagement(let mediaType):
enqueue(mediaType: mediaType)

interactor.state = .enqueueing
showLiveObservationConfirmation(in: mediaType)
case .call(offer: let offer, answer: let answer):
call.upgrade(to: offer)
showConnecting()
Expand Down Expand Up @@ -315,6 +315,25 @@ extension CallViewModel {
)
)
}

private func showLiveObservationConfirmation(in mediaType: CoreSdkClient.MediaType) {
let liveObservationAlertConfig = createLiveObservationAlertConfig(with: mediaType)
action?(.showLiveObservationConfirmation(liveObservationAlertConfig))
}

private func createLiveObservationAlertConfig(
with mediaType: CoreSdkClient.MediaType
) -> CallViewController.LiveObservationConfirmation {
.init(
conf: self.alertConfiguration.liveObservationConfirmation,
accepted: { [weak self] in
self?.enqueue(mediaType: mediaType)
},
declined: { [weak self] in
self?.endSession()
}
)
}
}

extension CallViewModel {
Expand Down Expand Up @@ -537,6 +556,7 @@ extension CallViewModel {
case setRemoteVideo(CoreSdkClient.StreamView?)
case setLocalVideo(CoreSdkClient.StreamView?)
case setVisitorOnHold(isOnHold: Bool)
case showLiveObservationConfirmation(CallViewController.LiveObservationConfirmation)
}

enum DelegateEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ extension ChatViewModel: ViewModel {
case setAttachmentButtonVisibility(MediaPickerButtonVisibility)
case fileUploadListPropsUpdated(SecureConversations.FileUploadListView.Props)
case quickReplyPropsUpdated(QuickReplyView.Props)
case showLiveObservationConfirmation(CallViewController.LiveObservationConfirmation)
}

enum DelegateEvent {
Expand Down
28 changes: 25 additions & 3 deletions GliaWidgets/Sources/ViewModel/Chat/ChatViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class ChatViewModel: EngagementViewModel {
// or in case if engagement has been restored.

if history.isEmpty || self.environment.getCurrentEngagement() != nil {
self.enqueue(mediaType: .text)
self.interactor.state = .enqueueing
}
}
}
Expand All @@ -198,7 +198,7 @@ class ChatViewModel: EngagementViewModel {

action?(.queue)
action?(.scrollToBottom(animated: true))

showLiveObservationConfirmation(in: .text)
case .engaged(let engagedOperator):
let name = engagedOperator?.firstName
let pictureUrl = engagedOperator?.picture?.url
Expand Down Expand Up @@ -247,7 +247,6 @@ class ChatViewModel: EngagementViewModel {
}
}
}

default:
break
}
Expand Down Expand Up @@ -932,6 +931,29 @@ extension ChatViewModel {
}
}

// MARK: Live Observation

extension ChatViewModel {
private func showLiveObservationConfirmation(in mediaType: CoreSdkClient.MediaType) {
let liveObservationAlertConfig = createLiveObservationAlertConfig(with: mediaType)
action?(.showLiveObservationConfirmation(liveObservationAlertConfig))
}

private func createLiveObservationAlertConfig(
with mediaType: CoreSdkClient.MediaType
) -> CallViewController.LiveObservationConfirmation {
.init(
conf: self.alertConfiguration.liveObservationConfirmation,
accepted: { [weak self] in
self?.enqueue(mediaType: mediaType)
},
declined: { [weak self] in
self?.endSession()
}
)
}
}

extension ChatViewModel {
static func shouldSkipEnqueueingState(for chatType: ChatType) -> Bool {
switch chatType {
Expand Down
1 change: 0 additions & 1 deletion GliaWidgets/Sources/ViewModel/EngagementViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ class EngagementViewModel: CommonEngagementModel {
)
)
})

default:
break
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,8 @@ extension ChatViewModelTests {
env.createFileUploadListModel = { _ in .mock() }
env.createSendMessagePayload = { _, _ in .mock() }
viewModel = .mock(interactor: interactorMock, environment: env)

viewModel.gvaOptionAction(for: option)()

viewModel.interactor.state = .enqueueing
XCTAssertEqual(interactorMock.state, .enqueueing)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ class ChatViewModelTests: XCTestCase {
viewModelEnv.loadChatMessagesFromHistory = { true }
let viewModel = ChatViewModel.mock(interactor: interactor, environment: viewModelEnv)
viewModel.start()
viewModel.enqueue(mediaType: .audio)
XCTAssertEqual(calls, [.configureWithInteractor, .configureWithConfiguration])
}

Expand Down
3 changes: 2 additions & 1 deletion GliaWidgetsTests/Sources/InteractorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class InteractorTests: XCTestCase {
return
}
}

interactor.state = .enqueueing
interactor.enqueueForEngagement(
mediaType: .text,
success: {},
Expand Down Expand Up @@ -208,6 +208,7 @@ class InteractorTests: XCTestCase {
}
}

interactor.state = .enqueued(.mock)
interactor.enqueueForEngagement(
mediaType: .text,
success: {},
Expand Down

0 comments on commit a7f5e8e

Please sign in to comment.