mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 15:26:40 +00:00
Make AnalyticsService mockable via `AnalyticsServiceProtocol (#5599)
* Create AnalyticsServiceProtocol and conform AnalyticsService * Replace AnalyticsService properties and arguments with AnalyticsServiceProtocol * Inline AnalyticsServiceMock replacing old mock * handle more complex AnalyticsServiceMock callsites * move documentation from AnalyticsService to AnalyticsServiceProtocol
This commit is contained in:
@@ -22,7 +22,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
||||
private let targetConfiguration: Target.ConfigurationResult
|
||||
private let appMediator: AppMediator
|
||||
private let appSettings: AppSettings
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
private let appDelegate: AppDelegate
|
||||
@@ -946,7 +946,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
|
||||
}
|
||||
}
|
||||
|
||||
private static func setupSentry(bugReportService: BugReportServiceProtocol, appSettings: AppSettings, analytics: AnalyticsService) {
|
||||
private static func setupSentry(bugReportService: BugReportServiceProtocol, appSettings: AppSettings, analytics: AnalyticsServiceProtocol) {
|
||||
guard let bugReportSentryURL = appSettings.bugReportSentryURL else { return }
|
||||
|
||||
let options: Options = .init()
|
||||
|
||||
@@ -36,7 +36,7 @@ struct CommonFlowParameters {
|
||||
let appMediator: AppMediatorProtocol
|
||||
let appSettings: AppSettings
|
||||
let appHooks: AppHooks
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let notificationManager: NotificationManagerProtocol
|
||||
let stateMachineFactory: StateMachineFactoryProtocol
|
||||
|
||||
@@ -23,7 +23,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private let appMediator: AppMediatorProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let appHooks: AppHooks
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
enum State: StateType {
|
||||
@@ -109,7 +109,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
|
||||
appMediator: AppMediatorProtocol,
|
||||
appSettings: AppSettings,
|
||||
appHooks: AppHooks,
|
||||
analytics: AnalyticsService,
|
||||
analytics: AnalyticsServiceProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.authenticationService = authenticationService
|
||||
self.bugReportService = bugReportService
|
||||
|
||||
@@ -19,7 +19,7 @@ enum OnboardingFlowCoordinatorAction {
|
||||
class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private let userSession: UserSessionProtocol
|
||||
private let appLockService: AppLockServiceProtocol
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
private let appMediator: AppMediatorProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let appHooks: AppHooks
|
||||
|
||||
@@ -20,7 +20,7 @@ struct RoomRolesAndPermissionsFlowCoordinatorParameters {
|
||||
let mediaProvider: MediaProviderProtocol
|
||||
let navigationStackCoordinator: NavigationStackCoordinator
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
}
|
||||
|
||||
class RoomRolesAndPermissionsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
@@ -28,7 +28,7 @@ class RoomRolesAndPermissionsFlowCoordinator: FlowCoordinatorProtocol {
|
||||
private let navigationStackCoordinator: NavigationStackCoordinator
|
||||
private let mediaProvider: MediaProviderProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
|
||||
enum State: StateType {
|
||||
/// The state machine hasn't started.
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// Copyright 2026 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
extension AnalyticsService {
|
||||
static func mock(_ clientOverride: AnalyticsClientProtocol? = nil, settings: AppSettings? = nil) -> AnalyticsService {
|
||||
let client: AnalyticsClientProtocol
|
||||
if let clientOverride {
|
||||
client = clientOverride
|
||||
} else {
|
||||
let mockClient = AnalyticsClientMock()
|
||||
mockClient.isRunning = false
|
||||
client = mockClient
|
||||
}
|
||||
|
||||
return .init(client: client, appSettings: settings ?? AppSettings())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Copyright 2026 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
extension AnalyticsServiceMock {
|
||||
static func `default`() -> AnalyticsServiceMock {
|
||||
let mock = AnalyticsServiceMock()
|
||||
mock.isEnabled = false
|
||||
mock.shouldShowAnalyticsPrompt = false
|
||||
mock.signpost = Signposter()
|
||||
return mock
|
||||
}
|
||||
}
|
||||
@@ -256,6 +256,761 @@ class AnalyticsClientMock: AnalyticsClientProtocol, @unchecked Sendable {
|
||||
updateUserPropertiesClosure?(event)
|
||||
}
|
||||
}
|
||||
class AnalyticsServiceMock: AnalyticsServiceProtocol, @unchecked Sendable {
|
||||
var signpost: Signposter {
|
||||
get { return underlyingSignpost }
|
||||
set(value) { underlyingSignpost = value }
|
||||
}
|
||||
var underlyingSignpost: Signposter!
|
||||
var shouldShowAnalyticsPrompt: Bool {
|
||||
get { return underlyingShouldShowAnalyticsPrompt }
|
||||
set(value) { underlyingShouldShowAnalyticsPrompt = value }
|
||||
}
|
||||
var underlyingShouldShowAnalyticsPrompt: Bool!
|
||||
var isEnabled: Bool {
|
||||
get { return underlyingIsEnabled }
|
||||
set(value) { underlyingIsEnabled = value }
|
||||
}
|
||||
var underlyingIsEnabled: Bool!
|
||||
|
||||
//MARK: - optIn
|
||||
|
||||
var optInUnderlyingCallsCount = 0
|
||||
var optInCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return optInUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = optInUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
optInUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
optInUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var optInCalled: Bool {
|
||||
return optInCallsCount > 0
|
||||
}
|
||||
var optInClosure: (() -> Void)?
|
||||
|
||||
func optIn() {
|
||||
optInCallsCount += 1
|
||||
optInClosure?()
|
||||
}
|
||||
//MARK: - optOut
|
||||
|
||||
var optOutUnderlyingCallsCount = 0
|
||||
var optOutCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return optOutUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = optOutUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
optOutUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
optOutUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var optOutCalled: Bool {
|
||||
return optOutCallsCount > 0
|
||||
}
|
||||
var optOutClosure: (() -> Void)?
|
||||
|
||||
func optOut() {
|
||||
optOutCallsCount += 1
|
||||
optOutClosure?()
|
||||
}
|
||||
//MARK: - startIfEnabled
|
||||
|
||||
var startIfEnabledUnderlyingCallsCount = 0
|
||||
var startIfEnabledCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return startIfEnabledUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = startIfEnabledUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
startIfEnabledUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
startIfEnabledUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var startIfEnabledCalled: Bool {
|
||||
return startIfEnabledCallsCount > 0
|
||||
}
|
||||
var startIfEnabledClosure: (() -> Void)?
|
||||
|
||||
func startIfEnabled() {
|
||||
startIfEnabledCallsCount += 1
|
||||
startIfEnabledClosure?()
|
||||
}
|
||||
//MARK: - reset
|
||||
|
||||
var resetUnderlyingCallsCount = 0
|
||||
var resetCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return resetUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = resetUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
resetUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
resetUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var resetCalled: Bool {
|
||||
return resetCallsCount > 0
|
||||
}
|
||||
var resetClosure: (() -> Void)?
|
||||
|
||||
func reset() {
|
||||
resetCallsCount += 1
|
||||
resetClosure?()
|
||||
}
|
||||
//MARK: - resetConsentState
|
||||
|
||||
var resetConsentStateUnderlyingCallsCount = 0
|
||||
var resetConsentStateCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return resetConsentStateUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = resetConsentStateUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
resetConsentStateUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
resetConsentStateUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var resetConsentStateCalled: Bool {
|
||||
return resetConsentStateCallsCount > 0
|
||||
}
|
||||
var resetConsentStateClosure: (() -> Void)?
|
||||
|
||||
func resetConsentState() {
|
||||
resetConsentStateCallsCount += 1
|
||||
resetConsentStateClosure?()
|
||||
}
|
||||
//MARK: - track
|
||||
|
||||
var trackScreenDurationUnderlyingCallsCount = 0
|
||||
var trackScreenDurationCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackScreenDurationUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackScreenDurationUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackScreenDurationUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackScreenDurationUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackScreenDurationCalled: Bool {
|
||||
return trackScreenDurationCallsCount > 0
|
||||
}
|
||||
var trackScreenDurationReceivedArguments: (screen: AnalyticsEvent.MobileScreen.ScreenName, milliseconds: Int?)?
|
||||
var trackScreenDurationReceivedInvocations: [(screen: AnalyticsEvent.MobileScreen.ScreenName, milliseconds: Int?)] = []
|
||||
var trackScreenDurationClosure: ((AnalyticsEvent.MobileScreen.ScreenName, Int?) -> Void)?
|
||||
|
||||
func track(screen: AnalyticsEvent.MobileScreen.ScreenName, duration milliseconds: Int?) {
|
||||
trackScreenDurationCallsCount += 1
|
||||
trackScreenDurationReceivedArguments = (screen: screen, milliseconds: milliseconds)
|
||||
DispatchQueue.main.async {
|
||||
self.trackScreenDurationReceivedInvocations.append((screen: screen, milliseconds: milliseconds))
|
||||
}
|
||||
trackScreenDurationClosure?(screen, milliseconds)
|
||||
}
|
||||
//MARK: - trackInteraction
|
||||
|
||||
var trackInteractionIndexNameUnderlyingCallsCount = 0
|
||||
var trackInteractionIndexNameCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackInteractionIndexNameUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackInteractionIndexNameUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackInteractionIndexNameUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackInteractionIndexNameUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackInteractionIndexNameCalled: Bool {
|
||||
return trackInteractionIndexNameCallsCount > 0
|
||||
}
|
||||
var trackInteractionIndexNameReceivedArguments: (index: Int?, name: AnalyticsEvent.Interaction.Name)?
|
||||
var trackInteractionIndexNameReceivedInvocations: [(index: Int?, name: AnalyticsEvent.Interaction.Name)] = []
|
||||
var trackInteractionIndexNameClosure: ((Int?, AnalyticsEvent.Interaction.Name) -> Void)?
|
||||
|
||||
func trackInteraction(index: Int?, name: AnalyticsEvent.Interaction.Name) {
|
||||
trackInteractionIndexNameCallsCount += 1
|
||||
trackInteractionIndexNameReceivedArguments = (index: index, name: name)
|
||||
DispatchQueue.main.async {
|
||||
self.trackInteractionIndexNameReceivedInvocations.append((index: index, name: name))
|
||||
}
|
||||
trackInteractionIndexNameClosure?(index, name)
|
||||
}
|
||||
//MARK: - trackError
|
||||
|
||||
var trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserUnderlyingCallsCount = 0
|
||||
var trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserCalled: Bool {
|
||||
return trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserCallsCount > 0
|
||||
}
|
||||
var trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserReceivedArguments: (context: String?, domain: AnalyticsEvent.Error.Domain, name: AnalyticsEvent.Error.Name, timeToDecryptMillis: Int?, eventLocalAgeMillis: Int?, isFederated: Bool?, isMatrixDotOrg: Bool?, userTrustsOwnIdentity: Bool?, wasVisibleToUser: Bool?)?
|
||||
var trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserReceivedInvocations: [(context: String?, domain: AnalyticsEvent.Error.Domain, name: AnalyticsEvent.Error.Name, timeToDecryptMillis: Int?, eventLocalAgeMillis: Int?, isFederated: Bool?, isMatrixDotOrg: Bool?, userTrustsOwnIdentity: Bool?, wasVisibleToUser: Bool?)] = []
|
||||
var trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserClosure: ((String?, AnalyticsEvent.Error.Domain, AnalyticsEvent.Error.Name, Int?, Int?, Bool?, Bool?, Bool?, Bool?) -> Void)?
|
||||
|
||||
func trackError(context: String?, domain: AnalyticsEvent.Error.Domain, name: AnalyticsEvent.Error.Name, timeToDecryptMillis: Int?, eventLocalAgeMillis: Int?, isFederated: Bool?, isMatrixDotOrg: Bool?, userTrustsOwnIdentity: Bool?, wasVisibleToUser: Bool?) {
|
||||
trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserCallsCount += 1
|
||||
trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserReceivedArguments = (context: context, domain: domain, name: name, timeToDecryptMillis: timeToDecryptMillis, eventLocalAgeMillis: eventLocalAgeMillis, isFederated: isFederated, isMatrixDotOrg: isMatrixDotOrg, userTrustsOwnIdentity: userTrustsOwnIdentity, wasVisibleToUser: wasVisibleToUser)
|
||||
DispatchQueue.main.async {
|
||||
self.trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserReceivedInvocations.append((context: context, domain: domain, name: name, timeToDecryptMillis: timeToDecryptMillis, eventLocalAgeMillis: eventLocalAgeMillis, isFederated: isFederated, isMatrixDotOrg: isMatrixDotOrg, userTrustsOwnIdentity: userTrustsOwnIdentity, wasVisibleToUser: wasVisibleToUser))
|
||||
}
|
||||
trackErrorContextDomainNameTimeToDecryptMillisEventLocalAgeMillisIsFederatedIsMatrixDotOrgUserTrustsOwnIdentityWasVisibleToUserClosure?(context, domain, name, timeToDecryptMillis, eventLocalAgeMillis, isFederated, isMatrixDotOrg, userTrustsOwnIdentity, wasVisibleToUser)
|
||||
}
|
||||
//MARK: - trackCreatedRoom
|
||||
|
||||
var trackCreatedRoomIsDMUnderlyingCallsCount = 0
|
||||
var trackCreatedRoomIsDMCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackCreatedRoomIsDMUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackCreatedRoomIsDMUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackCreatedRoomIsDMUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackCreatedRoomIsDMUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackCreatedRoomIsDMCalled: Bool {
|
||||
return trackCreatedRoomIsDMCallsCount > 0
|
||||
}
|
||||
var trackCreatedRoomIsDMReceivedIsDM: Bool?
|
||||
var trackCreatedRoomIsDMReceivedInvocations: [Bool] = []
|
||||
var trackCreatedRoomIsDMClosure: ((Bool) -> Void)?
|
||||
|
||||
func trackCreatedRoom(isDM: Bool) {
|
||||
trackCreatedRoomIsDMCallsCount += 1
|
||||
trackCreatedRoomIsDMReceivedIsDM = isDM
|
||||
DispatchQueue.main.async {
|
||||
self.trackCreatedRoomIsDMReceivedInvocations.append(isDM)
|
||||
}
|
||||
trackCreatedRoomIsDMClosure?(isDM)
|
||||
}
|
||||
//MARK: - trackComposer
|
||||
|
||||
var trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadUnderlyingCallsCount = 0
|
||||
var trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadCalled: Bool {
|
||||
return trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadCallsCount > 0
|
||||
}
|
||||
var trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadReceivedArguments: (inThread: Bool, isEditing: Bool, isReply: Bool, messageType: AnalyticsEvent.Composer.MessageType, startsThread: Bool?)?
|
||||
var trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadReceivedInvocations: [(inThread: Bool, isEditing: Bool, isReply: Bool, messageType: AnalyticsEvent.Composer.MessageType, startsThread: Bool?)] = []
|
||||
var trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadClosure: ((Bool, Bool, Bool, AnalyticsEvent.Composer.MessageType, Bool?) -> Void)?
|
||||
|
||||
func trackComposer(inThread: Bool, isEditing: Bool, isReply: Bool, messageType: AnalyticsEvent.Composer.MessageType, startsThread: Bool?) {
|
||||
trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadCallsCount += 1
|
||||
trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadReceivedArguments = (inThread: inThread, isEditing: isEditing, isReply: isReply, messageType: messageType, startsThread: startsThread)
|
||||
DispatchQueue.main.async {
|
||||
self.trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadReceivedInvocations.append((inThread: inThread, isEditing: isEditing, isReply: isReply, messageType: messageType, startsThread: startsThread))
|
||||
}
|
||||
trackComposerInThreadIsEditingIsReplyMessageTypeStartsThreadClosure?(inThread, isEditing, isReply, messageType, startsThread)
|
||||
}
|
||||
//MARK: - trackViewRoom
|
||||
|
||||
var trackViewRoomIsDMIsSpaceUnderlyingCallsCount = 0
|
||||
var trackViewRoomIsDMIsSpaceCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackViewRoomIsDMIsSpaceUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackViewRoomIsDMIsSpaceUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackViewRoomIsDMIsSpaceUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackViewRoomIsDMIsSpaceUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackViewRoomIsDMIsSpaceCalled: Bool {
|
||||
return trackViewRoomIsDMIsSpaceCallsCount > 0
|
||||
}
|
||||
var trackViewRoomIsDMIsSpaceReceivedArguments: (isDM: Bool, isSpace: Bool)?
|
||||
var trackViewRoomIsDMIsSpaceReceivedInvocations: [(isDM: Bool, isSpace: Bool)] = []
|
||||
var trackViewRoomIsDMIsSpaceClosure: ((Bool, Bool) -> Void)?
|
||||
|
||||
func trackViewRoom(isDM: Bool, isSpace: Bool) {
|
||||
trackViewRoomIsDMIsSpaceCallsCount += 1
|
||||
trackViewRoomIsDMIsSpaceReceivedArguments = (isDM: isDM, isSpace: isSpace)
|
||||
DispatchQueue.main.async {
|
||||
self.trackViewRoomIsDMIsSpaceReceivedInvocations.append((isDM: isDM, isSpace: isSpace))
|
||||
}
|
||||
trackViewRoomIsDMIsSpaceClosure?(isDM, isSpace)
|
||||
}
|
||||
//MARK: - trackJoinedRoom
|
||||
|
||||
var trackJoinedRoomIsDMIsSpaceActiveMemberCountUnderlyingCallsCount = 0
|
||||
var trackJoinedRoomIsDMIsSpaceActiveMemberCountCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackJoinedRoomIsDMIsSpaceActiveMemberCountUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackJoinedRoomIsDMIsSpaceActiveMemberCountUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackJoinedRoomIsDMIsSpaceActiveMemberCountUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackJoinedRoomIsDMIsSpaceActiveMemberCountUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackJoinedRoomIsDMIsSpaceActiveMemberCountCalled: Bool {
|
||||
return trackJoinedRoomIsDMIsSpaceActiveMemberCountCallsCount > 0
|
||||
}
|
||||
var trackJoinedRoomIsDMIsSpaceActiveMemberCountReceivedArguments: (isDM: Bool, isSpace: Bool, activeMemberCount: UInt)?
|
||||
var trackJoinedRoomIsDMIsSpaceActiveMemberCountReceivedInvocations: [(isDM: Bool, isSpace: Bool, activeMemberCount: UInt)] = []
|
||||
var trackJoinedRoomIsDMIsSpaceActiveMemberCountClosure: ((Bool, Bool, UInt) -> Void)?
|
||||
|
||||
func trackJoinedRoom(isDM: Bool, isSpace: Bool, activeMemberCount: UInt) {
|
||||
trackJoinedRoomIsDMIsSpaceActiveMemberCountCallsCount += 1
|
||||
trackJoinedRoomIsDMIsSpaceActiveMemberCountReceivedArguments = (isDM: isDM, isSpace: isSpace, activeMemberCount: activeMemberCount)
|
||||
DispatchQueue.main.async {
|
||||
self.trackJoinedRoomIsDMIsSpaceActiveMemberCountReceivedInvocations.append((isDM: isDM, isSpace: isSpace, activeMemberCount: activeMemberCount))
|
||||
}
|
||||
trackJoinedRoomIsDMIsSpaceActiveMemberCountClosure?(isDM, isSpace, activeMemberCount)
|
||||
}
|
||||
//MARK: - trackPollCreated
|
||||
|
||||
var trackPollCreatedIsUndisclosedNumberOfAnswersUnderlyingCallsCount = 0
|
||||
var trackPollCreatedIsUndisclosedNumberOfAnswersCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackPollCreatedIsUndisclosedNumberOfAnswersUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackPollCreatedIsUndisclosedNumberOfAnswersUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackPollCreatedIsUndisclosedNumberOfAnswersUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackPollCreatedIsUndisclosedNumberOfAnswersUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackPollCreatedIsUndisclosedNumberOfAnswersCalled: Bool {
|
||||
return trackPollCreatedIsUndisclosedNumberOfAnswersCallsCount > 0
|
||||
}
|
||||
var trackPollCreatedIsUndisclosedNumberOfAnswersReceivedArguments: (isUndisclosed: Bool, numberOfAnswers: Int)?
|
||||
var trackPollCreatedIsUndisclosedNumberOfAnswersReceivedInvocations: [(isUndisclosed: Bool, numberOfAnswers: Int)] = []
|
||||
var trackPollCreatedIsUndisclosedNumberOfAnswersClosure: ((Bool, Int) -> Void)?
|
||||
|
||||
func trackPollCreated(isUndisclosed: Bool, numberOfAnswers: Int) {
|
||||
trackPollCreatedIsUndisclosedNumberOfAnswersCallsCount += 1
|
||||
trackPollCreatedIsUndisclosedNumberOfAnswersReceivedArguments = (isUndisclosed: isUndisclosed, numberOfAnswers: numberOfAnswers)
|
||||
DispatchQueue.main.async {
|
||||
self.trackPollCreatedIsUndisclosedNumberOfAnswersReceivedInvocations.append((isUndisclosed: isUndisclosed, numberOfAnswers: numberOfAnswers))
|
||||
}
|
||||
trackPollCreatedIsUndisclosedNumberOfAnswersClosure?(isUndisclosed, numberOfAnswers)
|
||||
}
|
||||
//MARK: - trackPollVote
|
||||
|
||||
var trackPollVoteUnderlyingCallsCount = 0
|
||||
var trackPollVoteCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackPollVoteUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackPollVoteUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackPollVoteUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackPollVoteUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackPollVoteCalled: Bool {
|
||||
return trackPollVoteCallsCount > 0
|
||||
}
|
||||
var trackPollVoteClosure: (() -> Void)?
|
||||
|
||||
func trackPollVote() {
|
||||
trackPollVoteCallsCount += 1
|
||||
trackPollVoteClosure?()
|
||||
}
|
||||
//MARK: - trackPollEnd
|
||||
|
||||
var trackPollEndUnderlyingCallsCount = 0
|
||||
var trackPollEndCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackPollEndUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackPollEndUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackPollEndUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackPollEndUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackPollEndCalled: Bool {
|
||||
return trackPollEndCallsCount > 0
|
||||
}
|
||||
var trackPollEndClosure: (() -> Void)?
|
||||
|
||||
func trackPollEnd() {
|
||||
trackPollEndCallsCount += 1
|
||||
trackPollEndClosure?()
|
||||
}
|
||||
//MARK: - trackRoomModeration
|
||||
|
||||
var trackRoomModerationActionRoleUnderlyingCallsCount = 0
|
||||
var trackRoomModerationActionRoleCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackRoomModerationActionRoleUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackRoomModerationActionRoleUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackRoomModerationActionRoleUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackRoomModerationActionRoleUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackRoomModerationActionRoleCalled: Bool {
|
||||
return trackRoomModerationActionRoleCallsCount > 0
|
||||
}
|
||||
var trackRoomModerationActionRoleReceivedArguments: (action: AnalyticsEvent.RoomModeration.Action, role: RoomRole?)?
|
||||
var trackRoomModerationActionRoleReceivedInvocations: [(action: AnalyticsEvent.RoomModeration.Action, role: RoomRole?)] = []
|
||||
var trackRoomModerationActionRoleClosure: ((AnalyticsEvent.RoomModeration.Action, RoomRole?) -> Void)?
|
||||
|
||||
func trackRoomModeration(action: AnalyticsEvent.RoomModeration.Action, role: RoomRole?) {
|
||||
trackRoomModerationActionRoleCallsCount += 1
|
||||
trackRoomModerationActionRoleReceivedArguments = (action: action, role: role)
|
||||
DispatchQueue.main.async {
|
||||
self.trackRoomModerationActionRoleReceivedInvocations.append((action: action, role: role))
|
||||
}
|
||||
trackRoomModerationActionRoleClosure?(action, role)
|
||||
}
|
||||
//MARK: - trackSessionSecurityState
|
||||
|
||||
var trackSessionSecurityStateUnderlyingCallsCount = 0
|
||||
var trackSessionSecurityStateCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackSessionSecurityStateUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackSessionSecurityStateUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackSessionSecurityStateUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackSessionSecurityStateUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackSessionSecurityStateCalled: Bool {
|
||||
return trackSessionSecurityStateCallsCount > 0
|
||||
}
|
||||
var trackSessionSecurityStateReceivedState: SessionSecurityState?
|
||||
var trackSessionSecurityStateReceivedInvocations: [SessionSecurityState] = []
|
||||
var trackSessionSecurityStateClosure: ((SessionSecurityState) -> Void)?
|
||||
|
||||
func trackSessionSecurityState(_ state: SessionSecurityState) {
|
||||
trackSessionSecurityStateCallsCount += 1
|
||||
trackSessionSecurityStateReceivedState = state
|
||||
DispatchQueue.main.async {
|
||||
self.trackSessionSecurityStateReceivedInvocations.append(state)
|
||||
}
|
||||
trackSessionSecurityStateClosure?(state)
|
||||
}
|
||||
//MARK: - updateUserProperties
|
||||
|
||||
var updateUserPropertiesUnderlyingCallsCount = 0
|
||||
var updateUserPropertiesCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return updateUserPropertiesUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = updateUserPropertiesUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
updateUserPropertiesUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
updateUserPropertiesUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var updateUserPropertiesCalled: Bool {
|
||||
return updateUserPropertiesCallsCount > 0
|
||||
}
|
||||
var updateUserPropertiesReceivedUserProperties: AnalyticsEvent.UserProperties?
|
||||
var updateUserPropertiesReceivedInvocations: [AnalyticsEvent.UserProperties] = []
|
||||
var updateUserPropertiesClosure: ((AnalyticsEvent.UserProperties) -> Void)?
|
||||
|
||||
func updateUserProperties(_ userProperties: AnalyticsEvent.UserProperties) {
|
||||
updateUserPropertiesCallsCount += 1
|
||||
updateUserPropertiesReceivedUserProperties = userProperties
|
||||
DispatchQueue.main.async {
|
||||
self.updateUserPropertiesReceivedInvocations.append(userProperties)
|
||||
}
|
||||
updateUserPropertiesClosure?(userProperties)
|
||||
}
|
||||
//MARK: - trackPinUnpinEvent
|
||||
|
||||
var trackPinUnpinEventUnderlyingCallsCount = 0
|
||||
var trackPinUnpinEventCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return trackPinUnpinEventUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = trackPinUnpinEventUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
}
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
trackPinUnpinEventUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
trackPinUnpinEventUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var trackPinUnpinEventCalled: Bool {
|
||||
return trackPinUnpinEventCallsCount > 0
|
||||
}
|
||||
var trackPinUnpinEventReceivedEvent: AnalyticsEvent.PinUnpinAction?
|
||||
var trackPinUnpinEventReceivedInvocations: [AnalyticsEvent.PinUnpinAction] = []
|
||||
var trackPinUnpinEventClosure: ((AnalyticsEvent.PinUnpinAction) -> Void)?
|
||||
|
||||
func trackPinUnpinEvent(_ event: AnalyticsEvent.PinUnpinAction) {
|
||||
trackPinUnpinEventCallsCount += 1
|
||||
trackPinUnpinEventReceivedEvent = event
|
||||
DispatchQueue.main.async {
|
||||
self.trackPinUnpinEventReceivedInvocations.append(event)
|
||||
}
|
||||
trackPinUnpinEventClosure?(event)
|
||||
}
|
||||
}
|
||||
class AppLockServiceMock: AppLockServiceProtocol, @unchecked Sendable {
|
||||
var isMandatory: Bool {
|
||||
get { return underlyingIsMandatory }
|
||||
|
||||
@@ -16,7 +16,7 @@ struct LoginScreenCoordinatorParameters {
|
||||
let loginHint: String?
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let appSettings: AppSettings
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
}
|
||||
|
||||
enum LoginScreenCoordinatorAction {
|
||||
|
||||
@@ -15,7 +15,7 @@ class LoginScreenViewModel: LoginScreenViewModelType, LoginScreenViewModelProtoc
|
||||
private let authenticationService: AuthenticationServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
|
||||
private var actionsSubject: PassthroughSubject<LoginScreenViewModelAction, Never> = .init()
|
||||
var actions: AnyPublisher<LoginScreenViewModelAction, Never> {
|
||||
@@ -26,7 +26,7 @@ class LoginScreenViewModel: LoginScreenViewModelType, LoginScreenViewModelProtoc
|
||||
loginHint: String?,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
appSettings: AppSettings,
|
||||
analytics: AnalyticsService) {
|
||||
analytics: AnalyticsServiceProtocol) {
|
||||
self.authenticationService = authenticationService
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.appSettings = appSettings
|
||||
|
||||
@@ -158,14 +158,11 @@ struct LoginScreen_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
Task { await authenticationService.configure(for: homeserverAddress, flow: .login) }
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
let viewModel = LoginScreenViewModel(authenticationService: authenticationService,
|
||||
loginHint: nil,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: appSettings,
|
||||
analytics: analytics)
|
||||
appSettings: AppSettings(),
|
||||
analytics: AnalyticsServiceMock.default())
|
||||
|
||||
if withCredentials {
|
||||
viewModel.context.username = "alice"
|
||||
|
||||
@@ -16,7 +16,7 @@ struct CallScreenCoordinatorParameters {
|
||||
let allowPictureInPicture: Bool
|
||||
let appSettings: AppSettings
|
||||
let appHooks: AppHooks
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
}
|
||||
|
||||
enum CallScreenCoordinatorAction {
|
||||
|
||||
@@ -18,7 +18,7 @@ class CallScreenViewModel: CallScreenViewModelType, CallScreenViewModelProtocol
|
||||
private let configuration: ElementCallConfiguration
|
||||
private let isPictureInPictureAllowed: Bool
|
||||
private let appSettings: AppSettings
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
|
||||
private let widgetDriver: ElementCallWidgetDriverProtocol
|
||||
|
||||
@@ -41,7 +41,7 @@ class CallScreenViewModel: CallScreenViewModelType, CallScreenViewModelProtocol
|
||||
allowPictureInPicture: Bool,
|
||||
appHooks: AppHooks,
|
||||
appSettings: AppSettings,
|
||||
analyticsService: AnalyticsService) {
|
||||
analyticsService: AnalyticsServiceProtocol) {
|
||||
self.elementCallService = elementCallService
|
||||
self.configuration = configuration
|
||||
self.appSettings = appSettings
|
||||
|
||||
@@ -364,9 +364,6 @@ struct CallScreen_Previews: PreviewProvider {
|
||||
|
||||
roomProxy.elementCallWidgetDriverDeviceIDReturnValue = widgetDriver
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return CallScreenViewModel(elementCallService: ElementCallServiceMock(.init()),
|
||||
configuration: .init(roomProxy: roomProxy,
|
||||
clientProxy: clientProxy,
|
||||
@@ -377,8 +374,8 @@ struct CallScreen_Previews: PreviewProvider {
|
||||
colorScheme: .light),
|
||||
allowPictureInPicture: false,
|
||||
appHooks: AppHooks(),
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics)
|
||||
appSettings: AppSettings(),
|
||||
analyticsService: AnalyticsServiceMock.default())
|
||||
}()
|
||||
|
||||
static var previews: some View {
|
||||
|
||||
@@ -14,7 +14,7 @@ struct PollFormScreenCoordinatorParameters {
|
||||
/// The max number of allowed options, if no value provided the default value of the view model will be used.
|
||||
var maxNumberOfOptions: Int?
|
||||
let timelineController: TimelineControllerProtocol
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ typealias PollFormScreenViewModelType = StateStoreViewModelV2<PollFormScreenView
|
||||
|
||||
class PollFormScreenViewModel: PollFormScreenViewModelType, PollFormScreenViewModelProtocol {
|
||||
private let timelineController: TimelineControllerProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
private var actionsSubject: PassthroughSubject<PollFormScreenViewModelAction, Never> = .init()
|
||||
@@ -24,7 +24,7 @@ class PollFormScreenViewModel: PollFormScreenViewModelType, PollFormScreenViewMo
|
||||
init(mode: PollFormMode,
|
||||
maxNumberOfOptions: Int? = nil,
|
||||
timelineController: TimelineControllerProtocol,
|
||||
analytics: AnalyticsService,
|
||||
analytics: AnalyticsServiceProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.timelineController = timelineController
|
||||
self.analytics = analytics
|
||||
|
||||
@@ -227,7 +227,7 @@ struct PollFormScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static func makeViewModel(mode: PollFormMode) -> PollFormScreenViewModel {
|
||||
PollFormScreenViewModel(mode: mode,
|
||||
timelineController: MockTimelineController(),
|
||||
analytics: .mock(),
|
||||
analytics: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ struct CreateRoomScreenCoordinatorParameters {
|
||||
let userSession: UserSessionProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let appSettings: AppSettings
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
}
|
||||
|
||||
enum CreateRoomScreenCoordinatorAction {
|
||||
|
||||
@@ -15,7 +15,7 @@ typealias CreateRoomScreenViewModelType = StateStoreViewModel<CreateRoomScreenVi
|
||||
class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreenViewModelProtocol {
|
||||
private let userSession: UserSessionProtocol
|
||||
private let mediaUploadingPreprocessor: MediaUploadingPreprocessor
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
private var syncNameAndAlias = true
|
||||
@@ -31,7 +31,7 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
|
||||
spaceSelectionMode: CreateRoomScreenSpaceSelectionMode,
|
||||
shouldShowCancelButton: Bool,
|
||||
userSession: UserSessionProtocol,
|
||||
analytics: AnalyticsService,
|
||||
analytics: AnalyticsServiceProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
appSettings: AppSettings) {
|
||||
self.userSession = userSession
|
||||
|
||||
@@ -461,7 +461,7 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
|
||||
spaceSelectionMode: selectionMode,
|
||||
shouldShowCancelButton: isSpace,
|
||||
userSession: userSession,
|
||||
analytics: .mock(settings: appSettings),
|
||||
analytics: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
appSettings: appSettings)
|
||||
}
|
||||
|
||||
@@ -68,13 +68,11 @@ struct CreateRoomSpaceSelectionSheet_Previews: PreviewProvider, TestablePreview
|
||||
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return CreateRoomScreenViewModel(isSpace: false,
|
||||
spaceSelectionMode: .editableSpacesList(preSelectedSpace: nil),
|
||||
shouldShowCancelButton: false,
|
||||
userSession: userSession,
|
||||
analytics: analytics,
|
||||
analytics: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
appSettings: appSettings)
|
||||
}()
|
||||
|
||||
@@ -14,7 +14,7 @@ struct HomeScreenCoordinatorParameters {
|
||||
let bugReportService: BugReportServiceProtocol
|
||||
let selectedRoomPublisher: CurrentValuePublisher<String?, Never>
|
||||
let appSettings: AppSettings
|
||||
let analyticsService: AnalyticsService
|
||||
let analyticsService: AnalyticsServiceProtocol
|
||||
let notificationManager: NotificationManagerProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ typealias HomeScreenViewModelType = StateStoreViewModel<HomeScreenViewState, Hom
|
||||
class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol {
|
||||
private let userSession: UserSessionProtocol
|
||||
private let spaceFilterSubject: CurrentValueSubject<SpaceServiceFilter?, Never>
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let notificationManager: NotificationManagerProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
@@ -32,7 +32,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
init(userSession: UserSessionProtocol,
|
||||
selectedRoomPublisher: CurrentValuePublisher<String?, Never>,
|
||||
appSettings: AppSettings,
|
||||
analyticsService: AnalyticsService,
|
||||
analyticsService: AnalyticsServiceProtocol,
|
||||
notificationManager: NotificationManagerProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.userSession = userSession
|
||||
|
||||
@@ -222,13 +222,10 @@ struct HomeScreen_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
appSettings: AppSettings(),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
notificationManager: NotificationManagerMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default)
|
||||
}
|
||||
|
||||
@@ -143,13 +143,10 @@ struct HomeScreenEmptyStateView_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = {
|
||||
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@user:example.com",
|
||||
roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded([])))))))
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
appSettings: AppSettings(),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
notificationManager: NotificationManagerMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default)
|
||||
}()
|
||||
|
||||
@@ -200,13 +200,10 @@ struct HomeScreenInviteCell_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
appSettings: AppSettings(),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
notificationManager: NotificationManagerMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default)
|
||||
}
|
||||
|
||||
@@ -132,13 +132,10 @@ struct HomeScreenKnockedCell_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
appSettings: AppSettings(),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
notificationManager: NotificationManagerMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default)
|
||||
}
|
||||
|
||||
+2
-5
@@ -121,13 +121,10 @@ struct HomeScreenRecoveryKeyConfirmationBanner_Previews: PreviewProvider, Testab
|
||||
|
||||
let userSession = UserSessionMock(.init(clientProxy: clientProxy))
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
appSettings: AppSettings(),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
notificationManager: NotificationManagerMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default)
|
||||
}
|
||||
|
||||
@@ -253,13 +253,10 @@ struct HomeScreenRoomCell_Previews: PreviewProvider, TestablePreview {
|
||||
static func makeViewModel(roomSummaryProvider: RoomSummaryProviderProtocol) -> HomeScreenViewModel {
|
||||
let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "John Doe", roomSummaryProvider: roomSummaryProvider))))
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return HomeScreenViewModel(userSession: userSession,
|
||||
selectedRoomPublisher: CurrentValueSubject<String?, Never>(nil).asCurrentValuePublisher(),
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
appSettings: AppSettings(),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
notificationManager: NotificationManagerMock(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ struct LocationSharingScreenCoordinatorParameters {
|
||||
let timelineController: TimelineControllerProtocol
|
||||
let liveLocationManager: LiveLocationManagerProtocol
|
||||
let appMediator: AppMediatorProtocol
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let mediaProvider: MediaProviderProtocol
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class LocationSharingScreenViewModel: LocationSharingScreenViewModelType, Locati
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let timelineController: TimelineControllerProtocol
|
||||
private let liveLocationManager: LiveLocationManagerProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let notificationCenter: NotificationCenter
|
||||
|
||||
@@ -36,7 +36,7 @@ class LocationSharingScreenViewModel: LocationSharingScreenViewModelType, Locati
|
||||
roomProxy: JoinedRoomProxyProtocol,
|
||||
timelineController: TimelineControllerProtocol,
|
||||
liveLocationManager: LiveLocationManagerProtocol,
|
||||
analytics: AnalyticsService,
|
||||
analytics: AnalyticsServiceProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
notificationCenter: NotificationCenter = .default) {
|
||||
@@ -389,15 +389,12 @@ extension LocationSharingScreenViewModel {
|
||||
let roomProxy = JoinedRoomProxyMock(.init(members: .allMembers, ownUserID: RoomMemberProxyMock.mockMe.userID))
|
||||
roomProxy.makeLiveLocationServiceReturnValue = liveLocationServiceMock
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return LocationSharingScreenViewModel(interactionMode: interactionMode,
|
||||
mapURLBuilder: appSettings.mapTilerConfiguration,
|
||||
mapURLBuilder: AppSettings().mapTilerConfiguration,
|
||||
roomProxy: roomProxy,
|
||||
timelineController: MockTimelineController(),
|
||||
liveLocationManager: LiveLocationManagerMock(),
|
||||
analytics: analytics,
|
||||
analytics: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()))
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ typealias ManageRoomMemberSheetViewModelType = StateStoreViewModelV2<ManageRoomM
|
||||
class ManageRoomMemberSheetViewModel: ManageRoomMemberSheetViewModelType, ManageRoomMemberSheetViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
|
||||
private var actionsSubject: PassthroughSubject<ManageRoomMemberSheetViewModelAction, Never> = .init()
|
||||
|
||||
@@ -27,7 +27,7 @@ class ManageRoomMemberSheetViewModel: ManageRoomMemberSheetViewModelType, Manage
|
||||
permissions: ManageRoomMemberPermissions,
|
||||
roomProxy: JoinedRoomProxyProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
analyticsService: AnalyticsService,
|
||||
analyticsService: AnalyticsServiceProtocol,
|
||||
mediaProvider: MediaProviderProtocol) {
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.roomProxy = roomProxy
|
||||
|
||||
@@ -120,7 +120,7 @@ private extension ManageRoomMemberSheetViewModel {
|
||||
ownPowerLevel: powerLevel),
|
||||
roomProxy: JoinedRoomProxyMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
analyticsService: .mock(),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()))
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ struct MediaEventsTimelineScreenCoordinatorParameters {
|
||||
let mediaPlayerProvider: MediaPlayerProviderProtocol
|
||||
let appMediator: AppMediatorProtocol
|
||||
let appSettings: AppSettings
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
let emojiProvider: EmojiProviderProtocol
|
||||
let linkMetadataProvider: LinkMetadataProviderProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
+1
-3
@@ -311,8 +311,6 @@ struct MediaEventsTimelineScreen_Previews: PreviewProvider, TestablePreview {
|
||||
}
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return TimelineViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Preview room")),
|
||||
timelineController: timelineController,
|
||||
userSession: UserSessionMock(.init()),
|
||||
@@ -320,7 +318,7 @@ struct MediaEventsTimelineScreen_Previews: PreviewProvider, TestablePreview {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ enum AnalyticsPromptScreenCoordinatorAction {
|
||||
}
|
||||
|
||||
final class AnalyticsPromptScreenCoordinator: CoordinatorProtocol {
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private var viewModel: AnalyticsPromptScreenViewModelProtocol
|
||||
private let actionsSubject: PassthroughSubject<AnalyticsPromptScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
@@ -23,7 +23,7 @@ final class AnalyticsPromptScreenCoordinator: CoordinatorProtocol {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(analytics: AnalyticsService, termsURL: URL?) {
|
||||
init(analytics: AnalyticsServiceProtocol, termsURL: URL?) {
|
||||
self.analytics = analytics
|
||||
viewModel = AnalyticsPromptScreenViewModel(termsURL: termsURL)
|
||||
}
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ struct PinnedEventsTimelineScreenCoordinatorParameters {
|
||||
let mediaPlayerProvider: MediaPlayerProviderProtocol
|
||||
let appMediator: AppMediatorProtocol
|
||||
let appSettings: AppSettings
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
let emojiProvider: EmojiProviderProtocol
|
||||
let linkMetadataProvider: LinkMetadataProviderProtocol
|
||||
let timelineControllerFactory: TimelineControllerFactoryProtocol
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ class PinnedEventsTimelineScreenViewModel: PinnedEventsTimelineScreenViewModelTy
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
|
||||
private let actionsSubject: PassthroughSubject<PinnedEventsTimelineScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<PinnedEventsTimelineScreenViewModelAction, Never> {
|
||||
@@ -25,7 +25,7 @@ class PinnedEventsTimelineScreenViewModel: PinnedEventsTimelineScreenViewModelTy
|
||||
init(roomProxy: JoinedRoomProxyProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
appSettings: AppSettings,
|
||||
analyticsService: AnalyticsService) {
|
||||
analyticsService: AnalyticsServiceProtocol) {
|
||||
self.roomProxy = roomProxy
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.appSettings = appSettings
|
||||
|
||||
+2
-4
@@ -69,15 +69,13 @@ struct PinnedEventsTimelineScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = PinnedEventsTimelineScreenViewModel(roomProxy: JoinedRoomProxyMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appSettings: AppSettings(),
|
||||
analyticsService: .mock())
|
||||
analyticsService: AnalyticsServiceMock.default())
|
||||
|
||||
static let emptyTimelineViewModel: TimelineViewModel = {
|
||||
let timelineController = MockTimelineController(timelineKind: .pinned)
|
||||
timelineController.timelineItems = []
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return TimelineViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Preview room")),
|
||||
timelineController: timelineController,
|
||||
userSession: UserSessionMock(.init()),
|
||||
@@ -85,7 +83,7 @@ struct PinnedEventsTimelineScreen_Previews: PreviewProvider, TestablePreview {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ struct RoomChangePermissionsScreenCoordinatorParameters {
|
||||
let permissions: RoomPermissions
|
||||
let roomProxy: JoinedRoomProxyProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
}
|
||||
|
||||
enum RoomChangePermissionsScreenCoordinatorAction {
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ typealias RoomChangePermissionsScreenViewModelType = StateStoreViewModelV2<RoomC
|
||||
class RoomChangePermissionsScreenViewModel: RoomChangePermissionsScreenViewModelType, RoomChangePermissionsScreenViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
|
||||
private var actionsSubject: PassthroughSubject<RoomChangePermissionsScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<RoomChangePermissionsScreenViewModelAction, Never> {
|
||||
@@ -26,7 +26,7 @@ class RoomChangePermissionsScreenViewModel: RoomChangePermissionsScreenViewModel
|
||||
ownPowerLevel: RoomPowerLevel,
|
||||
roomProxy: JoinedRoomProxyProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
analytics: AnalyticsService) {
|
||||
analytics: AnalyticsServiceProtocol) {
|
||||
self.roomProxy = roomProxy
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.analytics = analytics
|
||||
|
||||
+1
-1
@@ -91,6 +91,6 @@ struct RoomChangePermissionsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
ownPowerLevel: ownPowerLevel,
|
||||
roomProxy: JoinedRoomProxyMock(.init(isSpace: isSpace)),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
analytics: .mock())
|
||||
analytics: AnalyticsServiceMock.default())
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ struct RoomChangeRolesScreenCoordinatorParameters {
|
||||
let roomProxy: JoinedRoomProxyProtocol
|
||||
let mediaProvider: MediaProviderProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
}
|
||||
|
||||
enum RoomChangeRolesScreenCoordinatorAction {
|
||||
|
||||
@@ -14,7 +14,7 @@ typealias RoomChangeRolesScreenViewModelType = StateStoreViewModelV2<RoomChangeR
|
||||
class RoomChangeRolesScreenViewModel: RoomChangeRolesScreenViewModelType, RoomChangeRolesScreenViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
|
||||
private let actionsSubject: PassthroughSubject<RoomChangeRolesScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<RoomChangeRolesScreenViewModelAction, Never> {
|
||||
@@ -25,7 +25,7 @@ class RoomChangeRolesScreenViewModel: RoomChangeRolesScreenViewModelType, RoomCh
|
||||
roomProxy: JoinedRoomProxyProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
analytics: AnalyticsService) {
|
||||
analytics: AnalyticsServiceProtocol) {
|
||||
guard mode != .user || mode != .creator else { fatalError("Invalid screen configuration: \(mode)") }
|
||||
|
||||
self.roomProxy = roomProxy
|
||||
|
||||
@@ -151,6 +151,6 @@ struct RoomChangeRolesScreen_Previews: PreviewProvider, TestablePreview {
|
||||
roomProxy: JoinedRoomProxyMock(.init(members: members)),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
analytics: .mock())
|
||||
analytics: AnalyticsServiceMock.default())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import SwiftUI
|
||||
struct RoomDetailsScreenCoordinatorParameters {
|
||||
let roomProxy: JoinedRoomProxyProtocol
|
||||
let userSession: UserSessionProtocol
|
||||
let analyticsService: AnalyticsService
|
||||
let analyticsService: AnalyticsServiceProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let notificationSettings: NotificationSettingsProxyProtocol
|
||||
let attributedStringBuilder: AttributedStringBuilderProtocol
|
||||
|
||||
@@ -14,7 +14,7 @@ typealias RoomDetailsScreenViewModelType = StateStoreViewModelV2<RoomDetailsScre
|
||||
class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScreenViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let userSession: UserSessionProtocol
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let notificationSettingsProxy: NotificationSettingsProxyProtocol
|
||||
private let attributedStringBuilder: AttributedStringBuilderProtocol
|
||||
@@ -46,7 +46,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
|
||||
|
||||
init(roomProxy: JoinedRoomProxyProtocol,
|
||||
userSession: UserSessionProtocol,
|
||||
analyticsService: AnalyticsService,
|
||||
analyticsService: AnalyticsServiceProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
notificationSettingsProxy: NotificationSettingsProxyProtocol,
|
||||
attributedStringBuilder: AttributedStringBuilderProtocol,
|
||||
|
||||
@@ -418,16 +418,13 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
let notificationSettingsProxy = NotificationSettingsProxyMock(with: notificationSettingsProxyMockConfiguration)
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return .init(roomProxy: roomProxy,
|
||||
userSession: UserSessionMock(.init()),
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
notificationSettingsProxy: notificationSettingsProxy,
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appSettings: appSettings)
|
||||
appSettings: AppSettings())
|
||||
}
|
||||
|
||||
private static func makeSimpleRoomViewModel() -> RoomDetailsScreenViewModel {
|
||||
@@ -449,16 +446,13 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
let notificationSettingsProxy = NotificationSettingsProxyMock(with: .init())
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return .init(roomProxy: roomProxy,
|
||||
userSession: UserSessionMock(.init()),
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
notificationSettingsProxy: notificationSettingsProxy,
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appSettings: appSettings)
|
||||
appSettings: AppSettings())
|
||||
}
|
||||
|
||||
private static func makeDMViewModel(verificationState: UserIdentityVerificationState) -> RoomDetailsScreenViewModel {
|
||||
@@ -490,15 +484,12 @@ struct RoomDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
let notificationSettingsProxy = NotificationSettingsProxyMock(with: .init())
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return .init(roomProxy: roomProxy,
|
||||
userSession: UserSessionMock(.init(clientProxy: clientProxyMock)),
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
notificationSettingsProxy: notificationSettingsProxy,
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appSettings: appSettings)
|
||||
appSettings: AppSettings())
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ struct RoomMemberDetailsScreenCoordinatorParameters {
|
||||
let roomProxy: JoinedRoomProxyProtocol
|
||||
let userSession: UserSessionProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
let appSettings: AppSettings
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let userSession: UserSessionProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private let appSettings: AppSettings
|
||||
|
||||
private var actionsSubject: PassthroughSubject<RoomMemberDetailsScreenViewModelAction, Never> = .init()
|
||||
@@ -30,7 +30,7 @@ class RoomMemberDetailsScreenViewModel: RoomMemberDetailsScreenViewModelType, Ro
|
||||
roomProxy: JoinedRoomProxyProtocol,
|
||||
userSession: UserSessionProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
analytics: AnalyticsService,
|
||||
analytics: AnalyticsServiceProtocol,
|
||||
appSettings: AppSettings) {
|
||||
self.roomProxy = roomProxy
|
||||
self.userSession = userSession
|
||||
|
||||
@@ -236,14 +236,11 @@ struct RoomMemberDetailsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
clientProxyMock.directRoomForUserIDReturnValue = .success("roomID")
|
||||
}
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return RoomMemberDetailsScreenViewModel(userID: member.userID,
|
||||
roomProxy: roomProxyMock,
|
||||
userSession: UserSessionMock(.init(clientProxy: clientProxyMock)),
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
analytics: analytics,
|
||||
appSettings: appSettings)
|
||||
analytics: AnalyticsServiceMock.default(),
|
||||
appSettings: AppSettings())
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ struct RoomMembersListScreenCoordinatorParameters {
|
||||
let userSession: UserSessionProtocol
|
||||
let roomProxy: JoinedRoomProxyProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
}
|
||||
|
||||
enum RoomMembersListScreenCoordinatorAction {
|
||||
|
||||
@@ -15,7 +15,7 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe
|
||||
private let userSession: UserSessionProtocol
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
|
||||
private var members: [RoomMemberProxyProtocol] = []
|
||||
private var currentUserProxy: RoomMemberProxyProtocol?
|
||||
@@ -30,7 +30,7 @@ class RoomMembersListScreenViewModel: RoomMembersListScreenViewModelType, RoomMe
|
||||
userSession: UserSessionProtocol,
|
||||
roomProxy: JoinedRoomProxyProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
analytics: AnalyticsService) {
|
||||
analytics: AnalyticsServiceProtocol) {
|
||||
self.userSession = userSession
|
||||
self.roomProxy = roomProxy
|
||||
self.userIndicatorController = userIndicatorController
|
||||
|
||||
@@ -262,6 +262,6 @@ struct RoomMembersListScreen_Previews: PreviewProvider, TestablePreview {
|
||||
ownUserID: ownUserID,
|
||||
powerLevelsConfiguration: .init(canUserInvite: false))),
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
analytics: .mock())
|
||||
analytics: AnalyticsServiceMock.default())
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -132,7 +132,7 @@ struct RoomMembersListMemberCell_Previews: PreviewProvider, TestablePreview {
|
||||
static let viewModel = RoomMembersListScreenViewModel(userSession: UserSessionMock(.init()),
|
||||
roomProxy: JoinedRoomProxyMock(.init(name: "Some room", members: [])),
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
analytics: .mock())
|
||||
analytics: AnalyticsServiceMock.default())
|
||||
static var previews: some View {
|
||||
VStack(spacing: 0) {
|
||||
Section("Invited/Joined") {
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import SwiftUI
|
||||
struct RoomRolesAndPermissionsScreenCoordinatorParameters {
|
||||
let roomProxy: JoinedRoomProxyProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
}
|
||||
|
||||
enum RoomRolesAndPermissionsScreenCoordinatorAction {
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ typealias RoomRolesAndPermissionsScreenViewModelType = StateStoreViewModelV2<Roo
|
||||
class RoomRolesAndPermissionsScreenViewModel: RoomRolesAndPermissionsScreenViewModelType, RoomRolesAndPermissionsScreenViewModelProtocol {
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private var ownUser: RoomMemberDetails?
|
||||
|
||||
private var actionsSubject: PassthroughSubject<RoomRolesAndPermissionsScreenViewModelAction, Never> = .init()
|
||||
@@ -22,7 +22,7 @@ class RoomRolesAndPermissionsScreenViewModel: RoomRolesAndPermissionsScreenViewM
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(initialPermissions: RoomPermissions? = nil, roomProxy: JoinedRoomProxyProtocol, userIndicatorController: UserIndicatorControllerProtocol, analytics: AnalyticsService) {
|
||||
init(initialPermissions: RoomPermissions? = nil, roomProxy: JoinedRoomProxyProtocol, userIndicatorController: UserIndicatorControllerProtocol, analytics: AnalyticsServiceProtocol) {
|
||||
self.roomProxy = roomProxy
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.analytics = analytics
|
||||
|
||||
+2
-2
@@ -121,12 +121,12 @@ struct RoomRolesAndPermissionsScreen_Previews: PreviewProvider, TestablePreview
|
||||
static let viewModel = RoomRolesAndPermissionsScreenViewModel(initialPermissions: RoomPermissions(powerLevels: .mock),
|
||||
roomProxy: JoinedRoomProxyMock(.init(members: .allMembersAsAdmin)),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
analytics: .mock())
|
||||
analytics: AnalyticsServiceMock.default())
|
||||
|
||||
static let creatorViewModel = RoomRolesAndPermissionsScreenViewModel(initialPermissions: RoomPermissions(powerLevels: .mock),
|
||||
roomProxy: JoinedRoomProxyMock(.init(members: .allMembersAsCreator)),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
analytics: .mock())
|
||||
analytics: AnalyticsServiceMock.default())
|
||||
static var previews: some View {
|
||||
ElementNavigationStack {
|
||||
RoomRolesAndPermissionsScreen(context: viewModel.context)
|
||||
|
||||
@@ -20,7 +20,7 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
||||
private let wysiwygViewModel: WysiwygComposerViewModel
|
||||
private let completionSuggestionService: CompletionSuggestionServiceProtocol
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
private let draftService: ComposerDraftServiceProtocol
|
||||
private var identityPinningViolations = [String: RoomMemberProxyProtocol]()
|
||||
|
||||
@@ -52,7 +52,7 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
mentionDisplayHelper: MentionDisplayHelper,
|
||||
appSettings: AppSettings,
|
||||
analyticsService: AnalyticsService,
|
||||
analyticsService: AnalyticsServiceProtocol,
|
||||
composerDraftService: ComposerDraftServiceProtocol) {
|
||||
self.initialText = initialText
|
||||
self.wysiwygViewModel = wysiwygViewModel
|
||||
@@ -820,17 +820,14 @@ extension ComposerToolbarViewModel {
|
||||
roomProxy.identityStatusChangesPublisher = .init([.init(userId: RoomMemberProxyMock.mockAlice.userID, changedTo: .verificationViolation)])
|
||||
}
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
let wysiwygViewModel = WysiwygComposerViewModel()
|
||||
let viewModel = ComposerToolbarViewModel(roomProxy: roomProxy,
|
||||
wysiwygViewModel: wysiwygViewModel,
|
||||
completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init(suggestions: suggestions)),
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
mentionDisplayHelper: ComposerMentionDisplayHelper.mock,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
appSettings: AppSettings(),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
composerDraftService: ComposerDraftServiceMock(.init()))
|
||||
viewModel.state.bindings.composerFocused = focused
|
||||
viewModel.state.bindings.plainComposerText = NSAttributedString(string: message)
|
||||
|
||||
@@ -89,7 +89,7 @@ struct RoomAttachmentPicker_Previews: PreviewProvider, TestablePreview {
|
||||
mediaProvider: MediaProviderMock(configuration: .init()),
|
||||
mentionDisplayHelper: ComposerMentionDisplayHelper.mock,
|
||||
appSettings: appSettings,
|
||||
analyticsService: .mock(settings: appSettings),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
composerDraftService: ComposerDraftServiceMock(.init()))
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ struct RoomScreenCoordinatorParameters {
|
||||
let appMediator: AppMediatorProtocol
|
||||
let appSettings: AppSettings
|
||||
let appHooks: AppHooks
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
let composerDraftService: ComposerDraftServiceProtocol
|
||||
let timelineControllerFactory: TimelineControllerFactoryProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
@@ -18,7 +18,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
private let clientProxy: ClientProxyProtocol
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
private var initialSelectedPinnedEventID: String?
|
||||
@@ -56,7 +56,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
ongoingCallRoomIDPublisher: CurrentValuePublisher<String?, Never>,
|
||||
appSettings: AppSettings,
|
||||
appHooks: AppHooks,
|
||||
analyticsService: AnalyticsService,
|
||||
analyticsService: AnalyticsServiceProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
clientProxy = userSession.clientProxy
|
||||
self.roomProxy = roomProxy
|
||||
@@ -457,17 +457,14 @@ extension RoomScreenViewModel {
|
||||
static func mock(roomProxyMock: JoinedRoomProxyMock,
|
||||
clientProxyMock: ClientProxyMock = ClientProxyMock(.init()),
|
||||
appHooks: AppHooks = AppHooks()) -> RoomScreenViewModel {
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return RoomScreenViewModel(userSession: UserSessionMock(.init(clientProxy: clientProxyMock)),
|
||||
roomProxy: roomProxyMock,
|
||||
initialSelectedPinnedEventID: nil,
|
||||
ongoingCallRoomIDPublisher: .init(.init(nil)),
|
||||
appSettings: appSettings,
|
||||
appHooks: appHooks,
|
||||
analyticsService: analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock.default)
|
||||
RoomScreenViewModel(userSession: UserSessionMock(.init(clientProxy: clientProxyMock)),
|
||||
roomProxy: roomProxyMock,
|
||||
initialSelectedPinnedEventID: nil,
|
||||
ongoingCallRoomIDPublisher: .init(.init(nil)),
|
||||
appSettings: AppSettings(),
|
||||
appHooks: appHooks,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -258,8 +258,6 @@ struct RoomScreen_Previews: PreviewProvider, TestablePreview {
|
||||
let roomViewModel = RoomScreenViewModel.mock(roomProxyMock: roomProxyMock)
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
let timelineViewModel = TimelineViewModel(roomProxy: roomProxyMock,
|
||||
timelineController: MockTimelineController(),
|
||||
userSession: UserSessionMock(.init()),
|
||||
@@ -267,7 +265,7 @@ struct RoomScreen_Previews: PreviewProvider, TestablePreview {
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import SwiftUI
|
||||
|
||||
struct AdvancedSettingsScreenCoordinatorParameters {
|
||||
let appSettings: AppSettings
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
let clientProxy: ClientProxyProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
}
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ import SwiftUI
|
||||
typealias AdvancedSettingsScreenViewModelType = StateStoreViewModelV2<AdvancedSettingsScreenViewState, AdvancedSettingsScreenViewAction>
|
||||
|
||||
class AdvancedSettingsScreenViewModel: AdvancedSettingsScreenViewModelType, AdvancedSettingsScreenViewModelProtocol {
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private let clientProxy: ClientProxyProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
@@ -20,7 +20,7 @@ class AdvancedSettingsScreenViewModel: AdvancedSettingsScreenViewModelType, Adva
|
||||
private var hideInviteAvatarsTask: Task<Void, Never>?
|
||||
|
||||
init(advancedSettings: AdvancedSettingsProtocol,
|
||||
analytics: AnalyticsService,
|
||||
analytics: AnalyticsServiceProtocol,
|
||||
clientProxy: ClientProxyProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.analytics = analytics
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ struct AdvancedSettingsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
AppSettings.resetAllSettings()
|
||||
let appSettings = AppSettings()
|
||||
return AdvancedSettingsScreenViewModel(advancedSettings: appSettings,
|
||||
analytics: .mock(settings: appSettings),
|
||||
analytics: AnalyticsServiceMock.default(),
|
||||
clientProxy: ClientProxyMock(.init()),
|
||||
userIndicatorController: UserIndicatorControllerMock.default)
|
||||
}()
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import SwiftUI
|
||||
|
||||
struct AnalyticsSettingsScreenCoordinatorParameters {
|
||||
let appSettings: AppSettings
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
}
|
||||
|
||||
final class AnalyticsSettingsScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
+2
-2
@@ -12,9 +12,9 @@ import SwiftUI
|
||||
typealias AnalyticsSettingsScreenViewModelType = StateStoreViewModelV2<AnalyticsSettingsScreenViewState, AnalyticsSettingsScreenViewAction>
|
||||
|
||||
class AnalyticsSettingsScreenViewModel: AnalyticsSettingsScreenViewModelType, AnalyticsSettingsScreenViewModelProtocol {
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
|
||||
init(appSettings: AppSettings, analytics: AnalyticsService) {
|
||||
init(appSettings: AppSettings, analytics: AnalyticsServiceProtocol) {
|
||||
self.analytics = analytics
|
||||
|
||||
let strings = AnalyticsSettingsScreenStrings(termsURL: appSettings.analyticsTermsURL)
|
||||
|
||||
+1
-2
@@ -40,9 +40,8 @@ struct AnalyticsSettingsScreen: View {
|
||||
struct AnalyticsSettingsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static var previews: some View {
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
let viewModel = AnalyticsSettingsScreenViewModel(appSettings: appSettings,
|
||||
analytics: analytics)
|
||||
analytics: AnalyticsServiceMock.default())
|
||||
AnalyticsSettingsScreen(context: viewModel.context)
|
||||
}
|
||||
}
|
||||
|
||||
+11
-14
@@ -126,20 +126,17 @@ struct SpaceSettingsScreen_Previews: PreviewProvider, TestablePreview {
|
||||
static let userViewModel = makeViewModel(members: .allMembers)
|
||||
|
||||
static func makeViewModel(members: [RoomMemberProxyMock]) -> RoomDetailsScreenViewModel {
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return RoomDetailsScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Space",
|
||||
avatarURL: .mockMXCAvatar,
|
||||
isSpace: true,
|
||||
canonicalAlias: "#space:matrix.org",
|
||||
members: members)),
|
||||
userSession: UserSessionMock(.init()),
|
||||
analyticsService: analytics,
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()),
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appSettings: appSettings)
|
||||
RoomDetailsScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Space",
|
||||
avatarURL: .mockMXCAvatar,
|
||||
isSpace: true,
|
||||
canonicalAlias: "#space:matrix.org",
|
||||
members: members)),
|
||||
userSession: UserSessionMock(.init()),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
notificationSettingsProxy: NotificationSettingsProxyMock(with: NotificationSettingsProxyMockConfiguration()),
|
||||
attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()),
|
||||
appSettings: AppSettings())
|
||||
}
|
||||
|
||||
static var previews: some View {
|
||||
|
||||
@@ -14,7 +14,7 @@ struct StartChatScreenCoordinatorParameters {
|
||||
let userDiscoveryService: UserDiscoveryServiceProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let appSettings: AppSettings
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
}
|
||||
|
||||
enum StartChatScreenCoordinatorAction {
|
||||
|
||||
@@ -14,7 +14,7 @@ typealias StartChatScreenViewModelType = StateStoreViewModel<StartChatScreenView
|
||||
|
||||
class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenViewModelProtocol {
|
||||
private let userSession: UserSessionProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let userDiscoveryService: UserDiscoveryServiceProtocol
|
||||
private let appSettings: AppSettings
|
||||
@@ -27,7 +27,7 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
|
||||
}
|
||||
|
||||
init(userSession: UserSessionProtocol,
|
||||
analytics: AnalyticsService,
|
||||
analytics: AnalyticsServiceProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
userDiscoveryService: UserDiscoveryServiceProtocol,
|
||||
appSettings: AppSettings) {
|
||||
|
||||
@@ -83,14 +83,11 @@ struct JoinRoomByAddressView_Previews: PreviewProvider, TestablePreview {
|
||||
let userDiscoveryService = UserDiscoveryServiceMock()
|
||||
userDiscoveryService.searchProfilesWithReturnValue = .success([.mockAlice])
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return StartChatScreenViewModel(userSession: userSession,
|
||||
analytics: analytics,
|
||||
analytics: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
userDiscoveryService: userDiscoveryService,
|
||||
appSettings: appSettings)
|
||||
appSettings: AppSettings())
|
||||
}()
|
||||
|
||||
static var previews: some View {
|
||||
|
||||
@@ -159,7 +159,7 @@ struct StartChatScreen_Previews: PreviewProvider, TestablePreview {
|
||||
let userDiscoveryService = UserDiscoveryServiceMock()
|
||||
userDiscoveryService.searchProfilesWithReturnValue = .success([.mockAlice])
|
||||
return StartChatScreenViewModel(userSession: userSession,
|
||||
analytics: .mock(settings: appSettings),
|
||||
analytics: AnalyticsServiceMock.default(),
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
userDiscoveryService: userDiscoveryService,
|
||||
appSettings: appSettings)
|
||||
|
||||
@@ -22,7 +22,7 @@ struct ThreadTimelineScreenCoordinatorParameters {
|
||||
let completionSuggestionService: CompletionSuggestionServiceProtocol
|
||||
let appMediator: AppMediatorProtocol
|
||||
let appSettings: AppSettings
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
let composerDraftService: ComposerDraftServiceProtocol
|
||||
let timelineControllerFactory: TimelineControllerFactoryProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
@@ -41,7 +41,7 @@ class TimelineInteractionHandler {
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let appMediator: AppMediatorProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
private let emojiProvider: EmojiProviderProtocol
|
||||
private let linkMetadataProvider: LinkMetadataProviderProtocol
|
||||
private let timelineControllerFactory: TimelineControllerFactoryProtocol
|
||||
@@ -68,7 +68,7 @@ class TimelineInteractionHandler {
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
appMediator: AppMediatorProtocol,
|
||||
appSettings: AppSettings,
|
||||
analyticsService: AnalyticsService,
|
||||
analyticsService: AnalyticsServiceProtocol,
|
||||
emojiProvider: EmojiProviderProtocol,
|
||||
linkMetadataProvider: LinkMetadataProviderProtocol,
|
||||
timelineControllerFactory: TimelineControllerFactoryProtocol) {
|
||||
|
||||
@@ -29,7 +29,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let appMediator: AppMediatorProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
private let emojiProvider: EmojiProviderProtocol
|
||||
private let timelineControllerFactory: TimelineControllerFactoryProtocol
|
||||
|
||||
@@ -55,7 +55,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
appMediator: AppMediatorProtocol,
|
||||
appSettings: AppSettings,
|
||||
analyticsService: AnalyticsService,
|
||||
analyticsService: AnalyticsServiceProtocol,
|
||||
emojiProvider: EmojiProviderProtocol,
|
||||
linkMetadataProvider: LinkMetadataProviderProtocol,
|
||||
timelineControllerFactory: TimelineControllerFactoryProtocol) {
|
||||
@@ -1059,8 +1059,6 @@ extension TimelineViewModel {
|
||||
let roomProxy = JoinedRoomProxyMock(.init(name: "Preview room", predecessor: hasPredecessor ? .init(roomId: UUID().uuidString) : nil))
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return TimelineViewModel(roomProxy: roomProxy,
|
||||
focussedEventID: nil,
|
||||
timelineController: timelineController ?? MockTimelineController(timelineKind: timelineKind),
|
||||
@@ -1069,7 +1067,7 @@ extension TimelineViewModel {
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
@@ -46,7 +46,6 @@ struct ReadReceiptsSummaryView_Previews: PreviewProvider, TestablePreview {
|
||||
let roomProxyMock = JoinedRoomProxyMock(.init(name: "Room", members: members))
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return TimelineViewModel(roomProxy: roomProxyMock,
|
||||
timelineController: MockTimelineController(),
|
||||
@@ -55,7 +54,7 @@ struct ReadReceiptsSummaryView_Previews: PreviewProvider, TestablePreview {
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
@@ -346,7 +346,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
analyticsService: .mock(settings: appSettings),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
@@ -365,7 +365,7 @@ struct TimelineItemBubbledStylerView_Previews: PreviewProvider, TestablePreview
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
analyticsService: .mock(settings: appSettings),
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
@@ -81,8 +81,6 @@ struct TimelineReadReceiptsView_Previews: PreviewProvider, TestablePreview {
|
||||
|
||||
static let viewModel = {
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return TimelineViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Test", members: members)),
|
||||
timelineController: MockTimelineController(),
|
||||
userSession: UserSessionMock(.init()),
|
||||
@@ -90,7 +88,7 @@ struct TimelineReadReceiptsView_Previews: PreviewProvider, TestablePreview {
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
+1
-3
@@ -91,8 +91,6 @@ struct HighlightedTimelineItemTimeline_Previews: PreviewProvider {
|
||||
static let composerViewModel = ComposerToolbarViewModel.mock()
|
||||
static let timelineViewModel = {
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return TimelineViewModel(roomProxy: roomProxyMock,
|
||||
focussedEventID: focussedEventID,
|
||||
timelineController: MockTimelineController(),
|
||||
@@ -101,7 +99,7 @@ struct HighlightedTimelineItemTimeline_Previews: PreviewProvider {
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
@@ -148,8 +148,6 @@ struct TimelineView_Previews: PreviewProvider { // Not testable as this preview
|
||||
static let composerViewModel = ComposerToolbarViewModel.mock()
|
||||
static let timelineViewModel = {
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return TimelineViewModel(roomProxy: roomProxyMock,
|
||||
timelineController: MockTimelineController(),
|
||||
userSession: UserSessionMock(.init()),
|
||||
@@ -157,7 +155,7 @@ struct TimelineView_Previews: PreviewProvider { // Not testable as this preview
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
appMediator: AppMediatorMock.default,
|
||||
appSettings: appSettings,
|
||||
analyticsService: analytics,
|
||||
analyticsService: AnalyticsServiceMock.default(),
|
||||
emojiProvider: EmojiProvider(appSettings: appSettings),
|
||||
linkMetadataProvider: LinkMetadataProvider(),
|
||||
timelineControllerFactory: TimelineControllerFactoryMock(.init()))
|
||||
|
||||
@@ -14,7 +14,7 @@ struct UserProfileScreenCoordinatorParameters {
|
||||
let isPresentedModally: Bool
|
||||
let userSession: UserSessionProtocol
|
||||
let userIndicatorController: UserIndicatorControllerProtocol
|
||||
let analytics: AnalyticsService
|
||||
let analytics: AnalyticsServiceProtocol
|
||||
let appSettings: AppSettings
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ typealias UserProfileScreenViewModelType = StateStoreViewModelV2<UserProfileScre
|
||||
class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScreenViewModelProtocol {
|
||||
private let userSession: UserSessionProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private let appSettings: AppSettings
|
||||
|
||||
private var actionsSubject: PassthroughSubject<UserProfileScreenViewModelAction, Never> = .init()
|
||||
@@ -27,7 +27,7 @@ class UserProfileScreenViewModel: UserProfileScreenViewModelType, UserProfileScr
|
||||
isPresentedModally: Bool,
|
||||
userSession: UserSessionProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol,
|
||||
analytics: AnalyticsService,
|
||||
analytics: AnalyticsServiceProtocol,
|
||||
appSettings: AppSettings) {
|
||||
self.userSession = userSession
|
||||
self.userIndicatorController = userIndicatorController
|
||||
|
||||
@@ -143,14 +143,11 @@ struct UserProfileScreen_Previews: PreviewProvider, TestablePreview {
|
||||
clientProxyMock.directRoomForUserIDReturnValue = .success("roomID")
|
||||
}
|
||||
|
||||
let appSettings = AppSettings()
|
||||
let analytics = AnalyticsService.mock(settings: appSettings)
|
||||
|
||||
return UserProfileScreenViewModel(userID: userID,
|
||||
isPresentedModally: false,
|
||||
userSession: UserSessionMock(.init(clientProxy: clientProxyMock)),
|
||||
userIndicatorController: UserIndicatorControllerMock.default,
|
||||
analytics: analytics,
|
||||
appSettings: appSettings)
|
||||
analytics: AnalyticsServiceMock.default(),
|
||||
appSettings: AppSettings())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,26 +10,11 @@ import AnalyticsEvents
|
||||
import Combine
|
||||
import PostHog
|
||||
|
||||
/// A class responsible for managing a variety of analytics clients
|
||||
/// and sending events through these clients.
|
||||
///
|
||||
/// Events may include user activity, or app health data such as crashes,
|
||||
/// non-fatal issues and performance. `Analytics` class serves as a façade
|
||||
/// to all these use cases.
|
||||
///
|
||||
/// ## Creating Analytics Events
|
||||
///
|
||||
/// Events are managed in a shared repo for all Element clients https://github.com/matrix-org/matrix-analytics-events
|
||||
/// To add a new event create a PR to that repo with the new/updated schema. Once merged
|
||||
/// into `main`, update the AnalyticsEvents Swift package in `project.yml`.
|
||||
///
|
||||
class AnalyticsService {
|
||||
class AnalyticsService: AnalyticsServiceProtocol {
|
||||
/// The analytics client to send events with.
|
||||
private let client: AnalyticsClientProtocol
|
||||
private let appSettings: AppSettings
|
||||
|
||||
/// A signpost client for performance testing the app. This client doesn't respect the
|
||||
/// `isRunning` state or behave any differently when `start`/`reset` are called.
|
||||
let signpost = Signposter()
|
||||
|
||||
init(client: AnalyticsClientProtocol, appSettings: AppSettings) {
|
||||
@@ -37,7 +22,6 @@ class AnalyticsService {
|
||||
self.appSettings = appSettings
|
||||
}
|
||||
|
||||
/// Whether to show the user the analytics opt in prompt.
|
||||
var shouldShowAnalyticsPrompt: Bool {
|
||||
// Only show the prompt once, and when analytics are enabled in BuildSettings.
|
||||
appSettings.analyticsConsentState == .unknown && appSettings.canPromptForAnalytics
|
||||
@@ -47,13 +31,11 @@ class AnalyticsService {
|
||||
appSettings.analyticsConsentState == .optedIn
|
||||
}
|
||||
|
||||
/// Opts in to analytics tracking with the supplied user session.
|
||||
func optIn() {
|
||||
appSettings.analyticsConsentState = .optedIn
|
||||
startIfEnabled()
|
||||
}
|
||||
|
||||
/// Stops analytics tracking and calls `reset` to clear any IDs and event queues.
|
||||
func optOut() {
|
||||
appSettings.analyticsConsentState = .optedOut
|
||||
|
||||
@@ -64,7 +46,6 @@ class AnalyticsService {
|
||||
MXLog.info("Stopped.")
|
||||
}
|
||||
|
||||
/// Starts the analytics client if the user has opted in, otherwise does nothing.
|
||||
func startIfEnabled() {
|
||||
guard isEnabled, !client.isRunning, let configuration = appSettings.analyticsConfiguration else { return }
|
||||
|
||||
@@ -76,16 +57,11 @@ class AnalyticsService {
|
||||
MXLog.info("Started.")
|
||||
}
|
||||
|
||||
/// Resets the any IDs and event queues in the analytics client. This method should
|
||||
/// be called on sign-out to maintain opt-in status, whilst ensuring the next
|
||||
/// account used isn't associated with the previous one.
|
||||
/// Note: **MUST** be called before stopping PostHog or the reset is ignored.
|
||||
func reset() {
|
||||
client.reset()
|
||||
MXLog.info("Reset.")
|
||||
}
|
||||
|
||||
/// Reset the consent state for analytics
|
||||
func resetConsentState() {
|
||||
MXLog.warning("Resetting consent state for analytics.")
|
||||
appSettings.analyticsConsentState = .unknown
|
||||
@@ -104,9 +80,6 @@ class AnalyticsService {
|
||||
// MARK: - Public tracking methods
|
||||
|
||||
extension AnalyticsService {
|
||||
/// Track the presentation of a screen
|
||||
/// - Parameter screen: The screen that was shown
|
||||
/// - Parameter duration: An optional value representing how long the screen was shown for in milliseconds.
|
||||
func track(screen: AnalyticsEvent.MobileScreen.ScreenName, duration milliseconds: Int? = nil) {
|
||||
MXLog.debug("\(screen)")
|
||||
let event = AnalyticsEvent.MobileScreen(durationMs: milliseconds, screenName: screen)
|
||||
@@ -117,12 +90,6 @@ extension AnalyticsService {
|
||||
capture(event: AnalyticsEvent.Interaction(index: index, interactionType: .Touch, name: name))
|
||||
}
|
||||
|
||||
/// Track the presentation of a screen
|
||||
/// - Parameter context: To provide additional context or description for the error
|
||||
/// - Parameter domain: The domain to which the error belongs to.
|
||||
/// - Parameter name: The name of the error
|
||||
/// - Parameter timeToDecryptMillis: The time it took to decrypt the event in milliseconds, needs to be used only to track UTD errors, otherwise if the error is nort related to UTD it should be nil.
|
||||
/// Can be found in `UnableToDecryptInfo`. In case the `UnableToDecryptInfo` contains the value as nil, pass it as `-1`
|
||||
func trackError(context: String?, domain: AnalyticsEvent.Error.Domain,
|
||||
name: AnalyticsEvent.Error.Name,
|
||||
timeToDecryptMillis: Int? = nil,
|
||||
@@ -145,19 +112,10 @@ extension AnalyticsService {
|
||||
wasVisibleToUser: wasVisibleToUser))
|
||||
}
|
||||
|
||||
/// Track the creation of a room
|
||||
/// - Parameter isDM: true if the created room is a direct message, false otherwise
|
||||
func trackCreatedRoom(isDM: Bool) {
|
||||
capture(event: AnalyticsEvent.CreatedRoom(isDM: isDM))
|
||||
}
|
||||
|
||||
/// Track the composer
|
||||
/// - Parameters:
|
||||
/// - inThread: whether the composer is used in a Thread
|
||||
/// - isEditing: whether the composer is used to edit a message
|
||||
/// - isReply: whether the composer is used to reply a message
|
||||
/// - messageType: the type of the message
|
||||
/// - startsThread: whether the composer is used to start a new thread
|
||||
func trackComposer(inThread: Bool,
|
||||
isEditing: Bool,
|
||||
isReply: Bool,
|
||||
@@ -170,19 +128,10 @@ extension AnalyticsService {
|
||||
startsThread: startsThread))
|
||||
}
|
||||
|
||||
/// Track the presentation of a room
|
||||
/// - Parameters:
|
||||
/// - isDM: whether the room is a direct message
|
||||
/// - isSpace: whether the room is a space
|
||||
func trackViewRoom(isDM: Bool, isSpace: Bool) {
|
||||
capture(event: AnalyticsEvent.ViewRoom(activeSpace: nil, isDM: isDM, isSpace: isSpace, trigger: nil, viaKeyboard: nil))
|
||||
}
|
||||
|
||||
/// Track the action of joining a room
|
||||
/// - Parameters:
|
||||
/// - isDM: whether the room is a direct message
|
||||
/// - isSpace: whether the room is a space
|
||||
/// - activeMemberCount: the number of active members in the room
|
||||
func trackJoinedRoom(isDM: Bool, isSpace: Bool, activeMemberCount: UInt) {
|
||||
guard let roomSize = AnalyticsEvent.JoinedRoom.RoomSize(memberCount: activeMemberCount) else {
|
||||
MXLog.error("invalid room size")
|
||||
@@ -191,27 +140,20 @@ extension AnalyticsService {
|
||||
capture(event: AnalyticsEvent.JoinedRoom(isDM: isDM, isSpace: isSpace, roomSize: roomSize, trigger: nil))
|
||||
}
|
||||
|
||||
/// Track the action of creating a poll
|
||||
/// - Parameters:
|
||||
/// - isUndisclosed: whether the poll is undisclosed
|
||||
/// - numberOfAnswers: the number of options in the poll
|
||||
func trackPollCreated(isUndisclosed: Bool, numberOfAnswers: Int) {
|
||||
capture(event: AnalyticsEvent.PollCreation(action: .Create,
|
||||
isUndisclosed: isUndisclosed,
|
||||
numberOfAnswers: numberOfAnswers))
|
||||
}
|
||||
|
||||
/// Track the action of voting on a poll
|
||||
func trackPollVote() {
|
||||
capture(event: AnalyticsEvent.PollVote(doNotUse: nil))
|
||||
}
|
||||
|
||||
/// Track the action of ending a poll
|
||||
func trackPollEnd() {
|
||||
capture(event: AnalyticsEvent.PollEnd(doNotUse: nil))
|
||||
}
|
||||
|
||||
/// Track a room moderation action.
|
||||
func trackRoomModeration(action: AnalyticsEvent.RoomModeration.Action, role: RoomRole?) {
|
||||
let role = role.map(AnalyticsEvent.RoomModeration.Role.init)
|
||||
capture(event: AnalyticsEvent.RoomModeration(action: action, role: role))
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
//
|
||||
// Copyright 2026 Element Creations Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import AnalyticsEvents
|
||||
|
||||
/// A service responsible for managing analytics clients and sending events through them.
|
||||
///
|
||||
/// Events may include user activity, or app health data such as crashes,
|
||||
/// non-fatal issues and performance.
|
||||
///
|
||||
/// ## Creating Analytics Events
|
||||
///
|
||||
/// Events are managed in a shared repo for all Element clients https://github.com/matrix-org/matrix-analytics-events
|
||||
/// To add a new event create a PR to that repo with the new/updated schema. Once merged
|
||||
/// into `main`, update the AnalyticsEvents Swift package in `project.yml`.
|
||||
protocol AnalyticsServiceProtocol: AnyObject {
|
||||
/// A signpost client for performance testing the app. This client doesn't respect the
|
||||
/// `isRunning` state or behave any differently when `start`/`reset` are called.
|
||||
var signpost: Signposter { get }
|
||||
|
||||
/// Whether to show the user the analytics opt in prompt.
|
||||
var shouldShowAnalyticsPrompt: Bool { get }
|
||||
|
||||
/// Whether analytics tracking is currently enabled.
|
||||
var isEnabled: Bool { get }
|
||||
|
||||
/// Opts in to analytics tracking.
|
||||
func optIn()
|
||||
|
||||
/// Stops analytics tracking and calls `reset` to clear any IDs and event queues.
|
||||
func optOut()
|
||||
|
||||
/// Starts the analytics client if the user has opted in, otherwise does nothing.
|
||||
func startIfEnabled()
|
||||
|
||||
/// Resets any IDs and event queues in the analytics client. This method should
|
||||
/// be called on sign-out to maintain opt-in status, whilst ensuring the next
|
||||
/// account used isn't associated with the previous one.
|
||||
/// Note: **MUST** be called before stopping PostHog or the reset is ignored.
|
||||
func reset()
|
||||
|
||||
/// Resets the consent state for analytics.
|
||||
func resetConsentState()
|
||||
|
||||
/// Track the presentation of a screen.
|
||||
/// - Parameter screen: The screen that was shown.
|
||||
/// - Parameter milliseconds: An optional value representing how long the screen was shown for in milliseconds.
|
||||
func track(screen: AnalyticsEvent.MobileScreen.ScreenName, duration milliseconds: Int?)
|
||||
func trackInteraction(index: Int?, name: AnalyticsEvent.Interaction.Name)
|
||||
|
||||
/// Track an analytics error event.
|
||||
/// - Parameter context: Additional context or description for the error.
|
||||
/// - Parameter domain: The domain to which the error belongs.
|
||||
/// - Parameter name: The name of the error.
|
||||
/// - Parameter timeToDecryptMillis: The time it took to decrypt the event in milliseconds. Only used for UTD errors; pass `nil` otherwise.
|
||||
/// Can be found in `UnableToDecryptInfo`. If `UnableToDecryptInfo` contains `nil` for this value, pass `-1`.
|
||||
func trackError(context: String?, domain: AnalyticsEvent.Error.Domain,
|
||||
name: AnalyticsEvent.Error.Name,
|
||||
timeToDecryptMillis: Int?,
|
||||
eventLocalAgeMillis: Int?,
|
||||
isFederated: Bool?,
|
||||
isMatrixDotOrg: Bool?,
|
||||
userTrustsOwnIdentity: Bool?,
|
||||
wasVisibleToUser: Bool?)
|
||||
|
||||
/// Track the creation of a room.
|
||||
/// - Parameter isDM: `true` if the created room is a direct message, `false` otherwise.
|
||||
func trackCreatedRoom(isDM: Bool)
|
||||
|
||||
/// Track the composer.
|
||||
/// - Parameters:
|
||||
/// - inThread: Whether the composer is used in a thread.
|
||||
/// - isEditing: Whether the composer is used to edit a message.
|
||||
/// - isReply: Whether the composer is used to reply to a message.
|
||||
/// - messageType: The type of the message.
|
||||
/// - startsThread: Whether the composer is used to start a new thread.
|
||||
func trackComposer(inThread: Bool,
|
||||
isEditing: Bool,
|
||||
isReply: Bool,
|
||||
messageType: AnalyticsEvent.Composer.MessageType,
|
||||
startsThread: Bool?)
|
||||
|
||||
/// Track the presentation of a room.
|
||||
/// - Parameters:
|
||||
/// - isDM: Whether the room is a direct message.
|
||||
/// - isSpace: Whether the room is a space.
|
||||
func trackViewRoom(isDM: Bool, isSpace: Bool)
|
||||
|
||||
/// Track the action of joining a room.
|
||||
/// - Parameters:
|
||||
/// - isDM: Whether the room is a direct message.
|
||||
/// - isSpace: Whether the room is a space.
|
||||
/// - activeMemberCount: The number of active members in the room.
|
||||
func trackJoinedRoom(isDM: Bool, isSpace: Bool, activeMemberCount: UInt)
|
||||
|
||||
/// Track the action of creating a poll.
|
||||
/// - Parameters:
|
||||
/// - isUndisclosed: Whether the poll is undisclosed.
|
||||
/// - numberOfAnswers: The number of options in the poll.
|
||||
func trackPollCreated(isUndisclosed: Bool, numberOfAnswers: Int)
|
||||
|
||||
/// Track the action of voting on a poll.
|
||||
func trackPollVote()
|
||||
|
||||
/// Track the action of ending a poll.
|
||||
func trackPollEnd()
|
||||
|
||||
/// Track a room moderation action.
|
||||
func trackRoomModeration(action: AnalyticsEvent.RoomModeration.Action, role: RoomRole?)
|
||||
func trackSessionSecurityState(_ state: SessionSecurityState)
|
||||
func updateUserProperties(_ userProperties: AnalyticsEvent.UserProperties)
|
||||
func trackPinUnpinEvent(_ event: AnalyticsEvent.PinUnpinAction)
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
extension AnalyticsServiceProtocol {
|
||||
func track(screen: AnalyticsEvent.MobileScreen.ScreenName) {
|
||||
track(screen: screen, duration: nil)
|
||||
}
|
||||
|
||||
func trackInteraction(name: AnalyticsEvent.Interaction.Name) {
|
||||
trackInteraction(index: nil, name: name)
|
||||
}
|
||||
|
||||
@_disfavoredOverload // make sure this doesn't cause infinite recursion
|
||||
func trackError(context: String?,
|
||||
domain: AnalyticsEvent.Error.Domain,
|
||||
name: AnalyticsEvent.Error.Name,
|
||||
timeToDecryptMillis: Int? = nil,
|
||||
eventLocalAgeMillis: Int? = nil,
|
||||
isFederated: Bool? = nil,
|
||||
isMatrixDotOrg: Bool? = nil,
|
||||
userTrustsOwnIdentity: Bool? = nil,
|
||||
wasVisibleToUser: Bool? = nil) {
|
||||
trackError(context: context,
|
||||
domain: domain,
|
||||
name: name,
|
||||
timeToDecryptMillis: timeToDecryptMillis,
|
||||
eventLocalAgeMillis: eventLocalAgeMillis,
|
||||
isFederated: isFederated,
|
||||
isMatrixDotOrg: isMatrixDotOrg,
|
||||
userTrustsOwnIdentity: userTrustsOwnIdentity,
|
||||
wasVisibleToUser: wasVisibleToUser)
|
||||
}
|
||||
|
||||
func trackComposer(inThread: Bool,
|
||||
isEditing: Bool,
|
||||
isReply: Bool,
|
||||
startsThread: Bool?) {
|
||||
trackComposer(inThread: inThread,
|
||||
isEditing: isEditing,
|
||||
isReply: isReply,
|
||||
messageType: .Text,
|
||||
startsThread: startsThread)
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,5 @@
|
||||
import SwiftUI
|
||||
|
||||
extension EnvironmentValues {
|
||||
@Entry var analyticsService: AnalyticsService?
|
||||
@Entry var analyticsService: AnalyticsServiceProtocol?
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class ClientProxy: ClientProxyProtocol {
|
||||
private let client: ClientProtocol
|
||||
private let networkMonitor: NetworkMonitorProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
|
||||
let mediaLoader: MediaLoaderProtocol
|
||||
private let clientQueue: DispatchQueue
|
||||
@@ -202,7 +202,7 @@ class ClientProxy: ClientProxyProtocol {
|
||||
init(client: ClientProtocol,
|
||||
networkMonitor: NetworkMonitorProtocol,
|
||||
appSettings: AppSettings,
|
||||
analyticsService: AnalyticsService) async throws {
|
||||
analyticsService: AnalyticsServiceProtocol) async throws {
|
||||
self.client = client
|
||||
self.networkMonitor = networkMonitor
|
||||
self.appSettings = appSettings
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
import Foundation
|
||||
|
||||
class PollInteractionHandler: PollInteractionHandlerProtocol {
|
||||
let analyticsService: AnalyticsService
|
||||
let analyticsService: AnalyticsServiceProtocol
|
||||
let timelineController: TimelineControllerProtocol
|
||||
|
||||
init(analyticsService: AnalyticsService, timelineController: TimelineControllerProtocol) {
|
||||
init(analyticsService: AnalyticsServiceProtocol, timelineController: TimelineControllerProtocol) {
|
||||
self.analyticsService = analyticsService
|
||||
self.timelineController = timelineController
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
|
||||
private let roomListService: RoomListServiceProtocol
|
||||
private let room: RoomProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
private let eventStringBuilder: RoomEventStringBuilder
|
||||
|
||||
// periphery:ignore - required for instance retention in the rust codebase
|
||||
@@ -79,7 +79,7 @@ class JoinedRoomProxy: JoinedRoomProxyProtocol {
|
||||
init(roomListService: RoomListServiceProtocol,
|
||||
room: RoomProtocol,
|
||||
appSettings: AppSettings,
|
||||
analyticsService: AnalyticsService,
|
||||
analyticsService: AnalyticsServiceProtocol,
|
||||
eventStringBuilder: RoomEventStringBuilder) async throws {
|
||||
self.roomListService = roomListService
|
||||
self.room = room
|
||||
|
||||
@@ -12,7 +12,7 @@ import MatrixRustSDK
|
||||
class UserSessionStore: UserSessionStoreProtocol {
|
||||
private let keychainController: KeychainControllerProtocol
|
||||
private let appSettings: AppSettings
|
||||
private let analyticsService: AnalyticsService
|
||||
private let analyticsService: AnalyticsServiceProtocol
|
||||
private let networkMonitor: NetworkMonitorProtocol
|
||||
private let appHooks: AppHooks
|
||||
|
||||
@@ -32,7 +32,7 @@ class UserSessionStore: UserSessionStoreProtocol {
|
||||
|
||||
init(keychainController: KeychainControllerProtocol,
|
||||
appSettings: AppSettings,
|
||||
analyticsService: AnalyticsService,
|
||||
analyticsService: AnalyticsServiceProtocol,
|
||||
appHooks: AppHooks,
|
||||
networkMonitor: NetworkMonitorProtocol) {
|
||||
self.keychainController = keychainController
|
||||
|
||||
@@ -13,7 +13,7 @@ import UIKit
|
||||
|
||||
class UITestsAppCoordinator: AppCoordinatorProtocol, SecureWindowManagerDelegate {
|
||||
private let appSettings: AppSettings
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
private let navigationRootCoordinator: NavigationRootCoordinator
|
||||
@@ -42,7 +42,7 @@ class UITestsAppCoordinator: AppCoordinatorProtocol, SecureWindowManagerDelegate
|
||||
let analyticsClient = AnalyticsClientMock()
|
||||
analyticsClient.isRunning = false
|
||||
|
||||
analytics = .mock(analyticsClient, settings: appSettings)
|
||||
analytics = AnalyticsServiceMock.default()
|
||||
userIndicatorController = UserIndicatorController()
|
||||
|
||||
windowManager.delegate = self
|
||||
@@ -115,7 +115,7 @@ class MockScreen: Identifiable {
|
||||
let navigationRootCoordinator: NavigationRootCoordinator
|
||||
|
||||
private let appSettings: AppSettings
|
||||
private let analytics: AnalyticsService
|
||||
private let analytics: AnalyticsServiceProtocol
|
||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||
|
||||
private var client: UITestsSignalling.Client?
|
||||
@@ -127,7 +127,7 @@ class MockScreen: Identifiable {
|
||||
windowManager: SecureWindowManagerProtocol,
|
||||
navigationRootCoordinator: NavigationRootCoordinator,
|
||||
appSettings: AppSettings,
|
||||
analytics: AnalyticsService,
|
||||
analytics: AnalyticsServiceProtocol,
|
||||
userIndicatorController: UserIndicatorControllerProtocol) {
|
||||
self.id = id
|
||||
self.windowManager = windowManager
|
||||
|
||||
Reference in New Issue
Block a user