Skip to content

Commit

Permalink
Implement EngagementLauncher logic
Browse files Browse the repository at this point in the history
  • Loading branch information
ykyivskyi-gl authored and github-review-helper committed Oct 2, 2024
1 parent 69175f6 commit 724c729
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 46 deletions.
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 {
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 {
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 {
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)
}

/// 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 {
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)
}

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
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

0 comments on commit 724c729

Please sign in to comment.