Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement EngagementLauncher logic #1055

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions GliaWidgets.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@
1AFB1E7825F8B26800CA460D /* ChatTextContentStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AFB1E7725F8B26800CA460D /* ChatTextContentStyle.swift */; };
215A25902CA44D8A0013023E /* Glia+EngagementLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 215A258F2CA44D8A0013023E /* Glia+EngagementLauncher.swift */; };
215A25932CA44D900013023E /* EngagementLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 215A25912CA44D900013023E /* EngagementLauncher.swift */; };
215A25982CABC7DF0013023E /* EngagementLauncherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 215A25972CABC7DF0013023E /* EngagementLauncherTests.swift */; };
215A259A2CAC19780013023E /* GliaTests+EngagementLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 215A25992CAC19780013023E /* GliaTests+EngagementLauncher.swift */; };
23D69155F4F4C5043173EF05 /* Pods_GliaWidgets.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F7A5CDD05FB57D55971AA68A /* Pods_GliaWidgets.framework */; };
3100D929296E946600DEC9CE /* SecureConversations.ConfirmationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3100D924296E946600DEC9CE /* SecureConversations.ConfirmationView.swift */; };
3100D92A296E946600DEC9CE /* Theme+SecureConversationsConfirmation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3100D925296E946600DEC9CE /* Theme+SecureConversationsConfirmation.swift */; };
Expand Down Expand Up @@ -1199,6 +1201,8 @@
1AFB1E7725F8B26800CA460D /* ChatTextContentStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTextContentStyle.swift; sourceTree = "<group>"; };
215A258F2CA44D8A0013023E /* Glia+EngagementLauncher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Glia+EngagementLauncher.swift"; sourceTree = "<group>"; };
215A25912CA44D900013023E /* EngagementLauncher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EngagementLauncher.swift; sourceTree = "<group>"; };
215A25972CABC7DF0013023E /* EngagementLauncherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EngagementLauncherTests.swift; sourceTree = "<group>"; };
215A25992CAC19780013023E /* GliaTests+EngagementLauncher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GliaTests+EngagementLauncher.swift"; sourceTree = "<group>"; };
235300A49A5836A51EB1C4E8 /* Pods-GliaWidgets.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GliaWidgets.release.xcconfig"; path = "Target Support Files/Pods-GliaWidgets/Pods-GliaWidgets.release.xcconfig"; sourceTree = "<group>"; };
2797F86D83B9055FAD6E596E /* Pods-SnapshotTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SnapshotTests.debug.xcconfig"; path = "Target Support Files/Pods-SnapshotTests/Pods-SnapshotTests.debug.xcconfig"; sourceTree = "<group>"; };
3100D924296E946600DEC9CE /* SecureConversations.ConfirmationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecureConversations.ConfirmationView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3204,6 +3208,14 @@
path = EngagementLauncher;
sourceTree = "<group>";
};
215A25962CABC7C50013023E /* EngagementLauncher */ = {
isa = PBXGroup;
children = (
215A25972CABC7DF0013023E /* EngagementLauncherTests.swift */,
);
path = EngagementLauncher;
sourceTree = "<group>";
};
3100D921296E943100DEC9CE /* Welcome */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -3472,6 +3484,7 @@
7512A57827BF9FB800319DF1 /* Sources */ = {
isa = PBXGroup;
children = (
215A25962CABC7C50013023E /* EngagementLauncher */,
C0D6C9FE2C106A0D00D4709B /* AlertManager */,
8418AD792BFB68C9007DE207 /* OnHoldOverlayVisualEffectView */,
8485704D2BEE39EB00CEBCC5 /* ChatView */,
Expand Down Expand Up @@ -4089,6 +4102,7 @@
7512A5A627C3926500319DF1 /* GliaTests.swift */,
846A5C4429F6BEFA0049B29F /* GliaTests+StartEngagement.swift */,
AFFA99812C57D658004A2825 /* GliaTests+RestoreEngagement.swift */,
215A25992CAC19780013023E /* GliaTests+EngagementLauncher.swift */,
);
path = Glia;
sourceTree = "<group>";
Expand Down Expand Up @@ -6350,6 +6364,7 @@
C03A8049292BC8DB00DDECA6 /* CallViewControllerTests.swift in Sources */,
84D5B9662A15204400807F92 /* QuickLookBased.Failing.swift in Sources */,
84602A772AEA5BEA0031E606 /* ProximityManager.Failing.swift in Sources */,
215A259A2CAC19780013023E /* GliaTests+EngagementLauncher.swift in Sources */,
31758EC62B5FC182007BBD9F /* SceneProvider.Mock.swift in Sources */,
753B05F82AFC1D750084611E /* SerialQueueTests.swift in Sources */,
31B278032B55BE670021DEC1 /* SecureConversations.WelcomeViewController.Mock.swift in Sources */,
Expand All @@ -6373,6 +6388,7 @@
AF1C19802B14FE9F00F8810F /* ConditionalCompilationClient.Failing.swift in Sources */,
84520BED2B19FD3000F97617 /* CallVisualizerTests+LO.swift in Sources */,
9A19927027D3BCAE00161AAE /* GCD.Failing.swift in Sources */,
215A25982CABC7DF0013023E /* EngagementLauncherTests.swift in Sources */,
3142696A29FFB712003DF62E /* Interactor.Failing.swift in Sources */,
8485704F2BEE3A0800CEBCC5 /* ChatViewTest.swift in Sources */,
8491AF602AA1EBB600CC3E72 /* TranscriptModelTests+URLs.swift in Sources */,
Expand Down
15 changes: 13 additions & 2 deletions GliaWidgets/Public/Glia/Glia+EngagementLauncher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,18 @@ extension Glia {
///
/// - Returns:
/// - `EngagementLauncher` instance.
public func getEngagementLauncher(queueIds: [String]?) -> EngagementLauncher {
.init(queueIds: queueIds)
public func getEngagementLauncher(queueIds: [String]?) throws -> EngagementLauncher {
igorkravchenko marked this conversation as resolved.
Show resolved Hide resolved
let parameters = try getEngagementParameters(in: queueIds ?? [])
return try EngagementLauncher { [weak self] engagementKind, sceneProvider in
try self?.resolveEngangementState(
engagementKind: engagementKind,
sceneProvider: sceneProvider,
configuration: parameters.configuration,
interactor: parameters.interactor,
features: parameters.features,
viewFactory: parameters.viewFactory,
ongoingEngagementMediaStreams: parameters.ongoingEngagementMediaStreams
)
}
}
}
99 changes: 71 additions & 28 deletions GliaWidgets/Public/Glia/Glia+StartEngagement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,40 +24,40 @@ extension Glia {
in queueIds: [String] = [],
sceneProvider: SceneProvider? = nil
) throws {
let parameters = try getEngagementParameters(in: queueIds)

try resolveEngangementState(
engagementKind: engagementKind,
sceneProvider: sceneProvider,
configuration: parameters.configuration,
interactor: parameters.interactor,
features: parameters.features,
viewFactory: parameters.viewFactory,
ongoingEngagementMediaStreams: parameters.ongoingEngagementMediaStreams
)
}

/// Set up and returns parameters needed to start or restore engagement
func getEngagementParameters(in queueIds: [String] = []) throws -> EngagementParameters {
// In order to align behaviour between platforms,
// `GliaError.engagementExists` is no longer thrown,
// instead engagement is getting restored.
guard let configuration = self.configuration else { throw GliaError.sdkIsNotConfigured }
guard let configuration else {
throw GliaError.sdkIsNotConfigured
}

guard let interactor else {
loggerPhase.logger.prefixed(Self.self).warning("Interactor is missing")
throw GliaError.sdkIsNotConfigured
}

// Interactor is initialized during configuration, which means that queueIds need
// to be set in interactor when startEngagement is called.
self.interactor?.setQueuesIds(queueIds)
interactor.setQueuesIds(queueIds)

// It is assumed that `features` to be provided from `configure` or via deprecated `startEngagement` method.
let features = self.features ?? []

if let engagement = environment.coreSdk.getCurrentEngagement() {
if engagement.source == .callVisualizer {
throw GliaError.callVisualizerEngagementExists
} else {
guard let interactor else {
loggerPhase.logger.prefixed(Self.self).warning("Interactor is missing")
return
}
if let rootCoordinator {
rootCoordinator.maximize()
} else {
self.restoreOngoingEngagement(
configuration: configuration,
currentEngagement: engagement,
interactor: interactor,
features: features,
maximize: true
)
}
return
}
}

// Apply company name to theme and get the modified theme
let modifiedTheme = applyCompanyName(using: configuration, theme: theme)

Expand All @@ -78,10 +78,44 @@ extension Glia {
ongoingEngagementMediaStreams = .init(audio: media.audio, video: nil)
}

guard let interactor else {
loggerPhase.logger.prefixed(Self.self).warning("Interactor is missing")
return
return EngagementParameters(
viewFactory: viewFactory,
interactor: interactor,
ongoingEngagementMediaStreams: ongoingEngagementMediaStreams,
features: features,
configuration: configuration
)
}

func resolveEngangementState(
engagementKind: EngagementKind,
sceneProvider: SceneProvider?,
configuration: Configuration,
interactor: Interactor,
features: Features,
viewFactory: ViewFactory,
ongoingEngagementMediaStreams: Engagement.Media?
) throws {
if let engagement = environment.coreSdk.getCurrentEngagement() {
if engagement.source == .callVisualizer {
throw GliaError.callVisualizerEngagementExists
} else {
if let rootCoordinator {
rootCoordinator.maximize()
} else {
self.restoreOngoingEngagement(
configuration: configuration,
currentEngagement: engagement,
interactor: interactor,
features: features,
maximize: true
)
}
loggerPhase.logger.prefixed(Self.self).info("Engagement was restored")
return
}
}

startRootCoordinator(
with: interactor,
viewFactory: viewFactory,
Expand Down Expand Up @@ -175,4 +209,13 @@ extension Glia {
onEvent?(.maximized)
}
}

/// The `EngagementParameters` encapsulates all parameters required to initiate or restore the coordinator
struct EngagementParameters {
igorkravchenko marked this conversation as resolved.
Show resolved Hide resolved
let viewFactory: ViewFactory
let interactor: Interactor
let ongoingEngagementMediaStreams: Engagement.Media?
let features: Features
let configuration: Configuration
}
}
29 changes: 13 additions & 16 deletions GliaWidgets/Sources/EngagementLauncher/EngagementLauncher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,47 @@ import GliaCoreSDK
/// `EngagementLauncher`class allows launching different types of engagements, such as chat,
/// audio calls, video calls, and secure messaging.
public final class EngagementLauncher {
private let queueIds: [String]?
typealias StartEngagementAction = (EngagementKind, SceneProvider?) throws -> Void

public init(queueIds: [String]?) {
self.queueIds = queueIds
private var startEngagement: StartEngagementAction

init(startEngagement: @escaping StartEngagementAction) rethrows {
self.startEngagement = startEngagement
}

/// Starts a chat.
///
/// - Parameters:
/// - sceneProvider: Used to provide `UIWindowScene` to the framework. Defaults to
/// the first active foreground scene.
public func startChat(sceneProvider: SceneProvider? = nil) {
startEngagement(of: .chat, sceneProvider: sceneProvider)
public func startChat(sceneProvider: SceneProvider? = nil) throws {
igorkravchenko marked this conversation as resolved.
Show resolved Hide resolved
try startEngagement(.chat, sceneProvider)
}

/// Starts a audio call.
///
/// - Parameters:
/// - sceneProvider: Used to provide `UIWindowScene` to the framework. Defaults to
/// the first active foreground scene.
public func startAudioCall(sceneProvider: SceneProvider? = nil) {
startEngagement(of: .audioCall, sceneProvider: sceneProvider)
public func startAudioCall(sceneProvider: SceneProvider? = nil) throws {
try startEngagement(.audioCall, sceneProvider)
igorkravchenko marked this conversation as resolved.
Show resolved Hide resolved
}

/// Starts a video call.
///
/// - Parameters:
/// - sceneProvider: Used to provide `UIWindowScene` to the framework. Defaults to
/// the first active foreground scene.
public func startVideoCall(sceneProvider: SceneProvider? = nil) {
startEngagement(of: .videoCall, sceneProvider: sceneProvider)
public func startVideoCall(sceneProvider: SceneProvider? = nil) throws {
igorkravchenko marked this conversation as resolved.
Show resolved Hide resolved
try startEngagement(.videoCall, sceneProvider)
}

/// Starts a secure messaging.
///
/// - Parameters:
/// - sceneProvider: Used to provide `UIWindowScene` to the framework. Defaults to
/// the first active foreground scene.
public func startSecureMessaging(sceneProvider: SceneProvider? = nil) {
startEngagement(of: .messaging(.welcome), sceneProvider: sceneProvider)
public func startSecureMessaging(sceneProvider: SceneProvider? = nil) throws {
try startEngagement(.messaging(.welcome), sceneProvider)
igorkravchenko marked this conversation as resolved.
Show resolved Hide resolved
}

private func startEngagement(
of engagementKind: EngagementKind,
sceneProvider: SceneProvider?
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import XCTest

@testable import GliaWidgets

final class EngagementLauncherTests: XCTestCase {

func test_startChat() throws {
var chatEngagement: EngagementKind?
var engagementLauncher = EngagementLauncher { engagementKind, _ in
igorkravchenko marked this conversation as resolved.
Show resolved Hide resolved
chatEngagement = engagementKind
}

try engagementLauncher.startChat()

XCTAssertEqual(chatEngagement, .chat)
}

func test_startAudioCall() throws {
var chatEngagement: EngagementKind?
var engagementLauncher = EngagementLauncher { engagementKind, _ in
chatEngagement = engagementKind
}

try engagementLauncher.startAudioCall()

XCTAssertEqual(chatEngagement, .audioCall)
}

func test_startVideoCall() throws {
var chatEngagement: EngagementKind?
var engagementLauncher = EngagementLauncher { engagementKind, _ in
chatEngagement = engagementKind
}

try engagementLauncher.startVideoCall()

XCTAssertEqual(chatEngagement, .videoCall)
}

func test_startSecureMessaging() throws {
var chatEngagement: EngagementKind?
var engagementLauncher = EngagementLauncher { engagementKind, _ in
chatEngagement = engagementKind
}

try engagementLauncher.startSecureMessaging()

XCTAssertEqual(chatEngagement, .messaging(.welcome))
}
}
Loading
Loading