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

Isolate pending interaction logic in separate model #1137

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
12 changes: 12 additions & 0 deletions GliaWidgets.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,9 @@
AFBBF5782851C391004993B3 /* Glia.Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFBBF5772851C391004993B3 /* Glia.Deprecated.swift */; };
AFC40C1C29965F0F001B4C53 /* SecureConversations.ChatWithTranscriptModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFC40C1B29965F0F001B4C53 /* SecureConversations.ChatWithTranscriptModel.swift */; };
AFC7ABB82C2D93A0006F15AA /* Glia+RestoreEngagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFC7ABB72C2D93A0006F15AA /* Glia+RestoreEngagement.swift */; };
AFCDA7242CF8EC2C006E339B /* SecureConversations.PendingInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCDA7232CF8EC2C006E339B /* SecureConversations.PendingInteraction.swift */; };
AFCDA7262CFA250A006E339B /* SecureConversations.PendingInteractionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCDA7252CFA250A006E339B /* SecureConversations.PendingInteractionTests.swift */; };
AFCDA7282CFA2ACB006E339B /* SecureConversations.PendingInteraction.Failing.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCDA7272CFA2ACB006E339B /* SecureConversations.PendingInteraction.Failing.swift */; };
AFCF8A5A2A02A97100B7ABB3 /* ChatItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCF8A592A02A97100B7ABB3 /* ChatItemTests.swift */; };
AFCF8A5C2A02AB3000B7ABB3 /* OutgoingMessage.Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFCF8A5B2A02AB3000B7ABB3 /* OutgoingMessage.Mock.swift */; };
AFD3C52C2A472B7500BC37A9 /* VisitorInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFD3C52B2A472B7500BC37A9 /* VisitorInfoModel.swift */; };
Expand Down Expand Up @@ -1782,6 +1785,9 @@
AFBBF5772851C391004993B3 /* Glia.Deprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Glia.Deprecated.swift; sourceTree = "<group>"; };
AFC40C1B29965F0F001B4C53 /* SecureConversations.ChatWithTranscriptModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureConversations.ChatWithTranscriptModel.swift; sourceTree = "<group>"; };
AFC7ABB72C2D93A0006F15AA /* Glia+RestoreEngagement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Glia+RestoreEngagement.swift"; sourceTree = "<group>"; };
AFCDA7232CF8EC2C006E339B /* SecureConversations.PendingInteraction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureConversations.PendingInteraction.swift; sourceTree = "<group>"; };
AFCDA7252CFA250A006E339B /* SecureConversations.PendingInteractionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureConversations.PendingInteractionTests.swift; sourceTree = "<group>"; };
AFCDA7272CFA2ACB006E339B /* SecureConversations.PendingInteraction.Failing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureConversations.PendingInteraction.Failing.swift; sourceTree = "<group>"; };
AFCF8A592A02A97100B7ABB3 /* ChatItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemTests.swift; sourceTree = "<group>"; };
AFCF8A5B2A02AB3000B7ABB3 /* OutgoingMessage.Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutgoingMessage.Mock.swift; sourceTree = "<group>"; };
AFD3C52B2A472B7500BC37A9 /* VisitorInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisitorInfoModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3492,6 +3498,7 @@
AF10ED8C29BA210500E85309 /* SecureConversations.MessagesWithUnreadCountLoader.swift */,
C0D6CA142C184F1900D4709B /* SecureConversations.MessagesWithUnreadCountLoader.Environment.swift */,
3115D45B29A4FD3F00D99561 /* SecureConversations.Availability.swift */,
AFCDA7232CF8EC2C006E339B /* SecureConversations.PendingInteraction.swift */,
);
path = SecureConversations;
sourceTree = "<group>";
Expand Down Expand Up @@ -4759,6 +4766,8 @@
AF29811129E42F3C0005BD55 /* AvailabilityTests.swift */,
AF29810F29E06E830005BD55 /* Availability.Environment.Failing.swift */,
3197F7AC29E6A5C8008EE9F7 /* SecureConversations.FileUploadListView.Mock.swift */,
AFCDA7252CFA250A006E339B /* SecureConversations.PendingInteractionTests.swift */,
AFCDA7272CFA2ACB006E339B /* SecureConversations.PendingInteraction.Failing.swift */,
);
path = SecureConversations;
sourceTree = "<group>";
Expand Down Expand Up @@ -6150,6 +6159,7 @@
AF6291132B0813B000D3D76B /* SwiftBased.Mock.swift in Sources */,
1AC7A74F2582571100567FF8 /* Interactor.swift in Sources */,
AF552EDD2BEE954500FD5653 /* FlipCameraButtonStyle.swift in Sources */,
AFCDA7242CF8EC2C006E339B /* SecureConversations.PendingInteraction.swift in Sources */,
84C24CFC2B8354A80089A388 /* ProcessInfoHandling.Live.swift in Sources */,
AFB6A0792CCBF3B700A1ED9A /* MediaTypeItemStyle.Loading.swift in Sources */,
845E2F72283D068000C04D56 /* HeaderStyle.Accessibility.swift in Sources */,
Expand Down Expand Up @@ -6681,6 +6691,7 @@
7512A57727BE8A6700319DF1 /* InteractorTests.swift in Sources */,
31CCE3E92BCE8F3A00F92535 /* CallVisualizer.VideoCallCoordinator.Environment.Mock.swift in Sources */,
AF29811529E6D76A0005BD55 /* FileDownloadTests.swift in Sources */,
AFCDA7262CFA250A006E339B /* SecureConversations.PendingInteractionTests.swift in Sources */,
C096B40B297EBDE400F0C552 /* VisitorCodeTests.swift in Sources */,
31FF0DD12B5A89A600834AFB /* CallCoordinator.Environment.Mock.swift in Sources */,
9ACC25D427B474E800BC5335 /* Glia.Environment.Failing.swift in Sources */,
Expand Down Expand Up @@ -6742,6 +6753,7 @@
EB7A1508286D98000035AC62 /* FileUploader.Environment.Failing.swift in Sources */,
AF993B3D2C8F5E7000DC5E69 /* EngagementCoordinatorCallTests.swift in Sources */,
AF2355A229C9EC7E007D9896 /* IdCollectionTests.swift in Sources */,
AFCDA7282CFA2ACB006E339B /* SecureConversations.PendingInteraction.Failing.swift in Sources */,
8491AF572AA0964800CC3E72 /* ChatItem.Kind.Mock.swift in Sources */,
84C24CFF2B8357BB0089A388 /* ProcessInfoHandling.Failing.swift in Sources */,
AFFA99822C57D658004A2825 /* GliaTests+RestoreEngagement.swift in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion GliaWidgets/Public/Glia/Glia+EngagementSetup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ extension Glia {
) {
let engagementLaunching: EngagementCoordinator.EngagementLaunching

switch (hasPendingInteraction, engagementKind) {
switch (pendingInteraction.hasPendingInteraction, engagementKind) {
case (false, _):
// if there is no pending Secure Conversation, open regular flow.
engagementLaunching = .direct(kind: engagementKind)
Expand Down
3 changes: 2 additions & 1 deletion GliaWidgets/Public/Glia/Glia+EntryWidget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ extension Glia {
log: loggerPhase.logger,
isAuthenticated: environment.isAuthenticated,
hasPendingInteraction: { [weak self] in
self?.hasPendingInteraction ?? false
guard let self else { return false }
return pendingInteraction.hasPendingInteraction
}
)
)
Expand Down
15 changes: 2 additions & 13 deletions GliaWidgets/Public/Glia/Glia.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,19 +135,7 @@
//
// Currently it's used to know if we have to force a visitor to SecureMessaging screen,
// once they try to start an engagement with media type other than `messaging`.
var hasPendingInteraction: Bool {
var pendingConversationExists = false
environment.coreSdk.pendingSecureConversationStatusUpdates { hasPendingConversationResult in
pendingConversationExists = (try? hasPendingConversationResult.get()) ?? false
}

var unreadMessageCount = 0
environment.coreSdk.getSecureUnreadMessageCount {
unreadMessageCount = (try? $0.get()) ?? 0
}

return unreadMessageCount > 0 || pendingConversationExists
}
let pendingInteraction: SecureConversations.PendingInteraction

init(environment: Environment) {
self.environment = environment
Expand Down Expand Up @@ -191,6 +179,7 @@
viewFactory: viewFactory
)
)
pendingInteraction = .init(environment: .init(with: environment.coreSdk))
}

/// Setup SDK using specific engagement configuration without starting the engagement.
Expand All @@ -207,7 +196,7 @@
/// - `GliaError.configuringDuringEngagementIsNotAllowed`
/// - `ConfigurationError`
///
public func configure(

Check warning on line 199 in GliaWidgets/Public/Glia/Glia.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Function Body Length Violation: Function body should span 60 lines or less excluding comments and whitespace: currently spans 63 lines (function_body_length)
with configuration: Configuration,
theme: Theme = Theme(),
uiConfig: RemoteConfiguration? = nil,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import Combine

extension SecureConversations {
final class PendingInteraction: ObservableObject {
@Published private(set) var pendingStatus = false
@Published private(set) var unreadMessageCount = 0
@Published private(set) var hasPendingInteraction = false
private let environment: Environment
private(set) var pendingStatusCancellationToken: String?
private(set) var unreadMessageCountCancellationToken: String?

init(environment: Environment) {
self.environment = environment
self.pendingStatusCancellationToken = environment.observePendingSecureConversationsStatus { [weak self] result in
guard let self else { return }
// At this point it is enough to know if there is a pending conversation,
// so no need to handle error.
pendingStatus = (try? result.get()) ?? false
}
self.unreadMessageCountCancellationToken = environment.observeSecureConversationsUnreadMessageCount { [weak self] result in
guard let self else { return }
// At this point it is enough to know if there is an unread message count,
// so no need to handle error.
unreadMessageCount = (try? result.get()) ?? 0
}

$pendingStatus.combineLatest($unreadMessageCount)
.map { hasPending, unreadCount in
hasPending || unreadCount > 0
}
.assign(to: &$hasPendingInteraction)
}

deinit {
if let unreadMessageCountCancellationToken {
environment.unsubscribeFromUnreadCount(unreadMessageCountCancellationToken)
}

if let pendingStatusCancellationToken {
environment.unsubscribeFromPendingStatus(pendingStatusCancellationToken)
}
}
}
}

extension SecureConversations.PendingInteraction {
struct Environment {
var observePendingSecureConversationsStatus: CoreSdkClient.ObservePendingSecureConversationStatus
var observeSecureConversationsUnreadMessageCount: CoreSdkClient.SubscribeForUnreadSCMessageCount
var unsubscribeFromUnreadCount: CoreSdkClient.UnsubscribeFromUnreadCount
var unsubscribeFromPendingStatus: CoreSdkClient.UnsubscribeFromPendingSCStatus
}
}

extension SecureConversations.PendingInteraction.Environment {
init(with client: CoreSdkClient) {
self.observePendingSecureConversationsStatus = client.observePendingSecureConversationStatus
self.observeSecureConversationsUnreadMessageCount = client.subscribeForUnreadSCMessageCount
self.unsubscribeFromPendingStatus = client.unsubscribeFromPendingSecureConversationStatus
self.unsubscribeFromUnreadCount = client.unsubscribeFromUnreadCount
}
}

#if DEBUG
extension SecureConversations.PendingInteraction.Environment {
static let mock = Self(
observePendingSecureConversationsStatus: { _ in nil },
observeSecureConversationsUnreadMessageCount: { _ in nil },
unsubscribeFromUnreadCount: { _ in },
unsubscribeFromPendingStatus: { _ in }
)
}

extension SecureConversations.PendingInteraction {
static func mock(environment: Environment = .mock) -> Self {
.init(environment: environment)
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ extension EngagementCoordinator.Environment {
flipCameraButtonStyle: .nop,
alertManager: .mock(),
queuesMonitor: .mock(),
pendingSecureConversationStatusUpdates: { $0(.success(false)) },
pendingSecureConversationStatus: { $0(.success(false)) },
createEntryWidget: { _ in .mock() },
dismissManager: .init { _, _, _ in }
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ extension EngagementCoordinator {
var flipCameraButtonStyle: FlipCameraButtonStyle
var alertManager: AlertManager
var queuesMonitor: QueuesMonitor
var pendingSecureConversationStatusUpdates: CoreSdkClient.PendingSecureConversationStatusUpdates
var pendingSecureConversationStatus: CoreSdkClient.PendingSecureConversationStatus
var createEntryWidget: EntryWidgetBuilder
var dismissManager: GliaPresenter.DismissManager
}
Expand Down Expand Up @@ -103,7 +103,7 @@ extension EngagementCoordinator.Environment {
flipCameraButtonStyle: viewFactory.theme.call.flipCameraButtonStyle,
alertManager: alertManager,
queuesMonitor: queuesMonitor,
pendingSecureConversationStatusUpdates: environment.coreSdk.pendingSecureConversationStatusUpdates,
pendingSecureConversationStatus: environment.coreSdk.pendingSecureConversationStatus,
createEntryWidget: createEntryWidget,
dismissManager: environment.dismissManager
)
Expand Down
16 changes: 14 additions & 2 deletions GliaWidgets/Sources/CoreSDKClient/CoreSDKClient.Interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,21 @@ struct CoreSdkClient {

var subscribeForUnreadSCMessageCount: SubscribeForUnreadSCMessageCount

typealias PendingSecureConversationStatusUpdates = (_ callback: @escaping (Result<Bool, Error>) -> Void) -> Void
typealias PendingSecureConversationStatus = (_ callback: @escaping (Result<Bool, Error>) -> Void) -> Void

var pendingSecureConversationStatusUpdates: PendingSecureConversationStatusUpdates
var pendingSecureConversationStatus: PendingSecureConversationStatus

typealias ObservePendingSecureConversationStatus = (_ callback: @escaping (Result<Bool, Error>) -> Void) -> String?

var observePendingSecureConversationStatus: ObservePendingSecureConversationStatus

typealias UnsubscribeFromPendingSCStatus = (String) -> Void

var unsubscribeFromPendingSecureConversationStatus: UnsubscribeFromPendingSCStatus

typealias UnsubscribeFromUnreadCount = (String) -> Void

var unsubscribeFromUnreadCount: UnsubscribeFromUnreadCount
}

extension CoreSdkClient {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ extension CoreSdkClient {
subscribeForQueuesUpdates: GliaCore.sharedInstance.subscribeForQueuesUpdates(forQueues:completion:),
unsubscribeFromUpdates: GliaCore.sharedInstance.unsubscribeFromUpdates(queueCallbackId:onError:),
subscribeForUnreadSCMessageCount: GliaCore.sharedInstance.secureConversations.subscribeToUnreadMessageCount(completion:),
pendingSecureConversationStatusUpdates: GliaCore.sharedInstance.secureConversations.pendingSecureConversationStatus
pendingSecureConversationStatus: GliaCore.sharedInstance.secureConversations.pendingSecureConversationStatus,
observePendingSecureConversationStatus: GliaCore.sharedInstance.secureConversations.subscribeToPendingSecureConversationStatus,
unsubscribeFromPendingSecureConversationStatus: {
GliaCore.sharedInstance.secureConversations.unsubscribeFromPendingSecureConversationStatus($0)
},
unsubscribeFromUnreadCount: GliaCore.sharedInstance.secureConversations.unsubscribeFromUnreadMessageCount
)
}()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ extension CoreSdkClient {
subscribeForQueuesUpdates: { _, _ in UUID.mock.uuidString },
unsubscribeFromUpdates: { _, _ in },
subscribeForUnreadSCMessageCount: { _ in UUID.mock.uuidString },
pendingSecureConversationStatusUpdates: { $0(.success(false)) }
pendingSecureConversationStatus: { $0(.success(false)) },
observePendingSecureConversationStatus: { _ in nil },
unsubscribeFromPendingSecureConversationStatus: { _ in },
unsubscribeFromUnreadCount: { _ in }
)
}

Expand Down
24 changes: 24 additions & 0 deletions GliaWidgetsTests/CallVisualizer/CallVisualizerTests+LO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ extension CallVisualizerTests {
gliaEnv.snackBar.present = { _, _, _, _, _, _, _ in
calls.append(.presentSnackBar)
}
gliaEnv.coreSdk.subscribeForUnreadSCMessageCount = { _ in nil }
gliaEnv.coreSdk.observePendingSecureConversationStatus = { _ in nil }
gliaEnv.coreSdk.unsubscribeFromPendingSecureConversationStatus = { _ in }
gliaEnv.coreSdk.unsubscribeFromUnreadCount = { _ in }
let sdk = Glia(environment: gliaEnv)
try sdk.configure(with: .mock(), theme: .mock(), completion: { _ in })

Expand Down Expand Up @@ -66,6 +70,10 @@ extension CallVisualizerTests {
gliaEnv.snackBar.present = { _, _, _, _, _, _, _ in
calls.append(.presentSnackBar)
}
gliaEnv.coreSdk.subscribeForUnreadSCMessageCount = { _ in nil }
gliaEnv.coreSdk.observePendingSecureConversationStatus = { _ in nil }
gliaEnv.coreSdk.unsubscribeFromPendingSecureConversationStatus = { _ in }
gliaEnv.coreSdk.unsubscribeFromUnreadCount = { _ in }
let sdk = Glia(environment: gliaEnv)
try sdk.configure(with: .mock(), theme: .mock(), completion: { _ in })

Expand Down Expand Up @@ -102,6 +110,10 @@ extension CallVisualizerTests {
gliaEnv.snackBar.present = { _, _, _, _, _, _, _ in
calls.append(.presentSnackBar)
}
gliaEnv.coreSdk.subscribeForUnreadSCMessageCount = { _ in nil }
gliaEnv.coreSdk.observePendingSecureConversationStatus = { _ in nil }
gliaEnv.coreSdk.unsubscribeFromPendingSecureConversationStatus = { _ in }
gliaEnv.coreSdk.unsubscribeFromUnreadCount = { _ in }
let sdk = Glia(environment: gliaEnv)
try sdk.configure(with: .mock(), theme: .mock(), completion: { _ in })

Expand Down Expand Up @@ -132,6 +144,10 @@ extension CallVisualizerTests {
gliaEnv.callVisualizerPresenter = .init(presenter: { nil })
gliaEnv.gcd.mainQueue.asyncIfNeeded = { $0() }
gliaEnv.coreSDKConfigurator.configureWithInteractor = { _ in }
gliaEnv.coreSdk.subscribeForUnreadSCMessageCount = { _ in nil }
gliaEnv.coreSdk.observePendingSecureConversationStatus = { _ in nil }
gliaEnv.coreSdk.unsubscribeFromPendingSecureConversationStatus = { _ in }
gliaEnv.coreSdk.unsubscribeFromUnreadCount = { _ in }
let sdk = Glia(environment: gliaEnv)
sdk.environment.coreSDKConfigurator.configureWithConfiguration = { _, completion in
sdk.environment.coreSdk.getCurrentEngagement = {
Expand Down Expand Up @@ -165,6 +181,10 @@ extension CallVisualizerTests {
gliaEnv.callVisualizerPresenter = .init(presenter: { nil })
gliaEnv.gcd.mainQueue.asyncIfNeeded = { $0() }
gliaEnv.coreSDKConfigurator.configureWithInteractor = { _ in }
gliaEnv.coreSdk.subscribeForUnreadSCMessageCount = { _ in nil }
gliaEnv.coreSdk.observePendingSecureConversationStatus = { _ in nil }
gliaEnv.coreSdk.unsubscribeFromPendingSecureConversationStatus = { _ in }
gliaEnv.coreSdk.unsubscribeFromUnreadCount = { _ in }
let sdk = Glia(environment: gliaEnv)
sdk.environment.coreSDKConfigurator.configureWithConfiguration = { _, completion in
sdk.environment.coreSdk.getCurrentEngagement = {
Expand Down Expand Up @@ -198,6 +218,10 @@ extension CallVisualizerTests {
gliaEnv.callVisualizerPresenter = .init(presenter: { nil })
gliaEnv.gcd.mainQueue.asyncIfNeeded = { $0() }
gliaEnv.coreSDKConfigurator.configureWithInteractor = { _ in }
gliaEnv.coreSdk.subscribeForUnreadSCMessageCount = { _ in nil }
gliaEnv.coreSdk.observePendingSecureConversationStatus = { _ in nil }
gliaEnv.coreSdk.unsubscribeFromPendingSecureConversationStatus = { _ in }
gliaEnv.coreSdk.unsubscribeFromUnreadCount = { _ in }
let sdk = Glia(environment: gliaEnv)
sdk.environment.coreSDKConfigurator.configureWithConfiguration = { _, completion in
sdk.environment.coreSdk.getCurrentEngagement = {
Expand Down
Loading
Loading