From 8016286fcb70b21284d8f8848d8cbfbb6551ae87 Mon Sep 17 00:00:00 2001 From: Boris Safonov Date: Thu, 20 Feb 2025 10:36:11 +0200 Subject: [PATCH 1/6] fix: UI issues for newly created group --- .../messages/item/MessageContainerItem.kt | 16 ---------------- .../messages/item/SystemMessageItem.kt | 2 +- app/src/main/res/values/strings.xml | 2 +- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/MessageContainerItem.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/MessageContainerItem.kt index 4e2e58e7ea7..e5c4789c3a2 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/MessageContainerItem.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/MessageContainerItem.kt @@ -109,20 +109,4 @@ fun MessageContainerItem( ) } } - if (message.messageContent is UIMessageContent.SystemMessage.ConversationMessageCreated) { - Row( - Modifier - .background(colorsScheme().background) - .height(dimensions().spacing24x) - .fillMaxWidth() - ) { - Text( - modifier = Modifier - .padding(start = dimensions().spacing56x) - .align(Alignment.CenterVertically), - style = MaterialTheme.wireTypography.title03, - text = (message.messageContent as UIMessageContent.SystemMessage.ConversationMessageCreated).date - ) - } - } } diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItem.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItem.kt index 914aed7af53..bc6fb70553b 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItem.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/SystemMessageItem.kt @@ -75,7 +75,7 @@ fun SystemMessageItem( fullAvatarOuterPadding = dimensions().avatarClickablePadding, leading = { SystemMessageItemLeading( - modifier = Modifier.padding(end = dimensions().avatarClickablePadding), + modifier = Modifier.padding(end = dimensions().spacing16x), messageContent = message.messageContent ) }, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 572258175d4..e9ab48ff0df 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -749,7 +749,7 @@ This user is no longer available The conversation is using an encryption protocol that is - not supported by this device. Some devices from the involve users might need updating. + not supported by this device. Some devices from the involved users might need updating. Read receipts are %1$s %1$s turned read receipts %2$s for everyone From 64c7eaefc7cbd11ee7529aee318c588d21ba01bf Mon Sep 17 00:00:00 2001 From: Boris Safonov Date: Thu, 20 Feb 2025 11:12:23 +0200 Subject: [PATCH 2/6] Code style fix --- .../messages/item/MessageContainerItem.kt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/MessageContainerItem.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/MessageContainerItem.kt index e5c4789c3a2..13db0a792fa 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/MessageContainerItem.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/messages/item/MessageContainerItem.kt @@ -17,27 +17,17 @@ */ package com.wire.android.ui.home.conversations.messages.item -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import com.wire.android.media.audiomessage.AudioSpeed import com.wire.android.media.audiomessage.AudioState import com.wire.android.ui.common.colorsScheme -import com.wire.android.ui.common.dimensions import com.wire.android.ui.home.conversations.SelfDeletionTimerHelper import com.wire.android.ui.home.conversations.info.ConversationDetailsData import com.wire.android.ui.home.conversations.model.UIMessage -import com.wire.android.ui.home.conversations.model.UIMessageContent import com.wire.android.ui.home.conversations.rememberSelfDeletionTimer -import com.wire.android.ui.theme.wireTypography import com.wire.kalium.logic.data.asset.AssetTransferStatus @Suppress("ComplexMethod") From 9ab33d34026ccf2fa5fa8f9dda9fb7be12376c82 Mon Sep 17 00:00:00 2001 From: Boris Safonov Date: Tue, 25 Feb 2025 17:20:28 +0200 Subject: [PATCH 3/6] feat: New user properties for Analytics --- .../com/wire/android/WireApplication.kt | 4 +- .../ObserveCurrentSessionAnalyticsUseCase.kt | 49 ++++++++++++------- ...serveCurrentSessionAnalyticsUseCaseTest.kt | 2 +- .../AnonymousAnalyticsManagerImpl.kt | 11 +++-- .../AnonymousAnalyticsRecorderImpl.kt | 30 ++++++++---- .../AnonymousAnalyticsManagerTest.kt | 9 +++- .../analytics/AnonymousAnalyticsRecorder.kt | 5 +- .../AnonymousAnalyticsRecorderStub.kt | 5 +- .../feature/analytics/model/AnalyticsEvent.kt | 4 ++ .../analytics/model/AnalyticsResult.kt | 10 +++- kalium | 2 +- 11 files changed, 89 insertions(+), 42 deletions(-) diff --git a/app/src/main/kotlin/com/wire/android/WireApplication.kt b/app/src/main/kotlin/com/wire/android/WireApplication.kt index ff2706d7fd3..f6b68f2977f 100644 --- a/app/src/main/kotlin/com/wire/android/WireApplication.kt +++ b/app/src/main/kotlin/com/wire/android/WireApplication.kt @@ -217,8 +217,8 @@ class WireApplication : BaseApp() { val analyticsResultFlow = ObserveCurrentSessionAnalyticsUseCase( currentSessionFlow = coreLogic.get().getGlobalScope().session.currentSessionFlow(), - isUserTeamMember = { - coreLogic.get().getSessionScope(it).team.isSelfATeamMember() + getAnalyticsContactsData = { + coreLogic.get().getSessionScope(it).getAnalyticsContactsData() }, observeAnalyticsTrackingIdentifierStatusFlow = { coreLogic.get().getSessionScope(it).observeAnalyticsTrackingIdentifierStatus() diff --git a/app/src/main/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCase.kt b/app/src/main/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCase.kt index 4cada52b9e9..c65a1a57f64 100644 --- a/app/src/main/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCase.kt +++ b/app/src/main/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCase.kt @@ -18,10 +18,12 @@ package com.wire.android.analytics import com.wire.android.datastore.UserDataStoreProvider +import com.wire.android.feature.analytics.model.AnalyticsProfileProperties import com.wire.android.feature.analytics.model.AnalyticsResult import com.wire.kalium.logic.configuration.server.ServerConfig import com.wire.kalium.logic.data.analytics.AnalyticsIdentifierResult import com.wire.kalium.logic.data.user.UserId +import com.wire.kalium.logic.feature.analytics.AnalyticsContactsData import com.wire.kalium.logic.feature.analytics.AnalyticsIdentifierManager import com.wire.kalium.logic.feature.session.CurrentSessionResult import com.wire.kalium.logic.feature.user.SelfServerConfigUseCase @@ -47,7 +49,7 @@ interface ObserveCurrentSessionAnalyticsUseCase { @Suppress("FunctionNaming", "LongParameterList") fun ObserveCurrentSessionAnalyticsUseCase( currentSessionFlow: Flow, - isUserTeamMember: suspend (UserId) -> Boolean, + getAnalyticsContactsData: suspend (UserId) -> AnalyticsContactsData, observeAnalyticsTrackingIdentifierStatusFlow: suspend (UserId) -> Flow, analyticsIdentifierManagerProvider: (UserId) -> AnalyticsIdentifierManager, userDataStoreProvider: UserDataStoreProvider, @@ -56,12 +58,10 @@ fun ObserveCurrentSessionAnalyticsUseCase( private var previousAnalyticsResult: AnalyticsIdentifierResult? = null - override fun invoke(): Flow> = - currentSessionFlow + override fun invoke(): Flow> = currentSessionFlow .flatMapLatest { if (it is CurrentSessionResult.Success && it.accountInfo.isValid()) { val userId = it.accountInfo.userId - val isTeamMember = isUserTeamMember(userId) val analyticsIdentifierManager = analyticsIdentifierManagerProvider(userId) combine( @@ -74,35 +74,48 @@ fun ObserveCurrentSessionAnalyticsUseCase( currentResult?.identifier != previousResult?.identifier }, userDataStoreProvider.getOrCreate(userId).isAnonymousUsageDataEnabled() - ) { identifierResult, enabled -> - previousAnalyticsResult = identifierResult + ) { analyticsIdentifierResult, enabled -> + previousAnalyticsResult = analyticsIdentifierResult val isProdBackend = when (val serverConfig = currentBackend(userId)) { is SelfServerConfigUseCase.Result.Success -> serverConfig.serverLinks.links.api == ServerConfig.PRODUCTION.api || serverConfig.serverLinks.links.api == ServerConfig.STAGING.api + is SelfServerConfigUseCase.Result.Failure -> false } - if (enabled && isProdBackend) { - AnalyticsResult( - identifierResult = identifierResult, - isTeamMember = isTeamMember, - manager = analyticsIdentifierManager - ) + val analyticsContactsData = getAnalyticsContactsData(userId) + + val identifierResult = if (enabled && isProdBackend) { + analyticsIdentifierResult } else { - AnalyticsResult( - identifierResult = AnalyticsIdentifierResult.Disabled, - isTeamMember = isTeamMember, - manager = analyticsIdentifierManager - ) + AnalyticsIdentifierResult.Disabled } + + AnalyticsResult( + identifierResult = identifierResult, + profileProperties = AnalyticsProfileProperties( + isTeamMember = analyticsContactsData.isTeamMember, + teamId = analyticsContactsData.teamId, + contactsAmount = analyticsContactsData.contactsSize, + teamMembersAmount = analyticsContactsData.teamSize, + isEnterprise = analyticsContactsData.isEnterprise + ), + manager = analyticsIdentifierManager + ) } } else { flowOf( AnalyticsResult( identifierResult = AnalyticsIdentifierResult.Disabled, - isTeamMember = false, + profileProperties = AnalyticsProfileProperties( + isTeamMember = false, + teamId = null, + contactsAmount = null, + teamMembersAmount = null, + isEnterprise = null + ), manager = null ) ) diff --git a/app/src/test/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCaseTest.kt b/app/src/test/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCaseTest.kt index 5e10cd61760..c51cc3cf58d 100644 --- a/app/src/test/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCaseTest.kt +++ b/app/src/test/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCaseTest.kt @@ -265,7 +265,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { var useCase: ObserveCurrentSessionAnalyticsUseCase = ObserveCurrentSessionAnalyticsUseCase( currentSessionFlow = currentSessionChannel.receiveAsFlow(), - isUserTeamMember = isTeamMember, + getAnalyticsContactsData = isTeamMember, observeAnalyticsTrackingIdentifierStatusFlow = { analyticsTrackingIdentifierStatusChannel.receiveAsFlow() }, diff --git a/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerImpl.kt b/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerImpl.kt index 60c1100911f..c1b339015e4 100644 --- a/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerImpl.kt +++ b/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerImpl.kt @@ -23,6 +23,7 @@ import android.util.Log import com.wire.android.feature.analytics.handler.AnalyticsMigrationHandler import com.wire.android.feature.analytics.handler.AnalyticsPropagationHandler import com.wire.android.feature.analytics.model.AnalyticsEvent +import com.wire.android.feature.analytics.model.AnalyticsProfileProperties import com.wire.android.feature.analytics.model.AnalyticsResult import com.wire.android.feature.analytics.model.AnalyticsSettings import com.wire.kalium.logic.data.analytics.AnalyticsIdentifierResult @@ -76,7 +77,7 @@ object AnonymousAnalyticsManagerImpl : AnonymousAnalyticsManager { handleTrackingIdentifier( analyticsIdentifierResult = analyticsResult.identifierResult, - isTeamMember = analyticsResult.isTeamMember, + analyticsProfileProperties = analyticsResult.profileProperties, propagateIdentifier = { analyticsResult.manager?.let { propagationHandler.propagate(it, result.identifier) } }, @@ -133,7 +134,7 @@ object AnonymousAnalyticsManagerImpl : AnonymousAnalyticsManager { private suspend fun handleTrackingIdentifier( analyticsIdentifierResult: AnalyticsIdentifierResult, - isTeamMember: Boolean, + analyticsProfileProperties: AnalyticsProfileProperties, propagateIdentifier: suspend () -> Unit, migrationComplete: suspend () -> Unit ) { @@ -142,7 +143,7 @@ object AnonymousAnalyticsManagerImpl : AnonymousAnalyticsManager { anonymousAnalyticsRecorder?.setTrackingIdentifierWithoutMerge( identifier = analyticsIdentifierResult.identifier, shouldPropagateIdentifier = true, - isTeamMember = isTeamMember, + analyticsProfileProperties = analyticsProfileProperties, propagateIdentifier = propagateIdentifier ) } @@ -151,7 +152,7 @@ object AnonymousAnalyticsManagerImpl : AnonymousAnalyticsManager { anonymousAnalyticsRecorder?.setTrackingIdentifierWithoutMerge( identifier = analyticsIdentifierResult.identifier, shouldPropagateIdentifier = false, - isTeamMember = isTeamMember, + analyticsProfileProperties = analyticsProfileProperties, propagateIdentifier = {} ) } @@ -159,7 +160,7 @@ object AnonymousAnalyticsManagerImpl : AnonymousAnalyticsManager { is AnalyticsIdentifierResult.MigrationIdentifier -> { anonymousAnalyticsRecorder?.setTrackingIdentifierWithMerge( identifier = analyticsIdentifierResult.identifier, - isTeamMember = isTeamMember, + analyticsProfileProperties = analyticsProfileProperties, migrationComplete = migrationComplete ) } diff --git a/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt b/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt index 038181b76c1..f6c8854e6a3 100644 --- a/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt +++ b/core/analytics-enabled/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderImpl.kt @@ -28,6 +28,7 @@ import com.wire.android.feature.analytics.model.AnalyticsEventConstants.APP_NAME import com.wire.android.feature.analytics.model.AnalyticsEventConstants.APP_VERSION import com.wire.android.feature.analytics.model.AnalyticsEventConstants.DEVICE_MODEL import com.wire.android.feature.analytics.model.AnalyticsEventConstants.OS_VERSION +import com.wire.android.feature.analytics.model.AnalyticsProfileProperties import com.wire.android.feature.analytics.model.AnalyticsSettings import ly.count.android.sdk.Countly import ly.count.android.sdk.CountlyConfig @@ -101,7 +102,7 @@ class AnonymousAnalyticsRecorderImpl( override suspend fun setTrackingIdentifierWithMerge( identifier: String, - isTeamMember: Boolean, + analyticsProfileProperties: AnalyticsProfileProperties, migrationComplete: suspend () -> Unit ) { wrapCountlyRequest { @@ -110,31 +111,42 @@ class AnonymousAnalyticsRecorderImpl( migrationComplete() } - setUserProfileProperties(isTeamMember = isTeamMember) + setUserProfileProperties(profileProperties = analyticsProfileProperties) } override suspend fun setTrackingIdentifierWithoutMerge( identifier: String, shouldPropagateIdentifier: Boolean, - isTeamMember: Boolean, + analyticsProfileProperties: AnalyticsProfileProperties, propagateIdentifier: suspend () -> Unit ) { wrapCountlyRequest { Countly.sharedInstance()?.deviceId()?.changeWithoutMerge(identifier) } - setUserProfileProperties(isTeamMember = isTeamMember) + setUserProfileProperties(profileProperties = analyticsProfileProperties) if (shouldPropagateIdentifier) { propagateIdentifier() } } - private fun setUserProfileProperties(isTeamMember: Boolean) = wrapCountlyRequest { - Countly.sharedInstance()?.userProfile()?.setProperty( - AnalyticsEventConstants.TEAM_IS_TEAM, - isTeamMember - ) + private fun setUserProfileProperties(profileProperties: AnalyticsProfileProperties) = wrapCountlyRequest { + Countly.sharedInstance()?.userProfile()?.apply { + setProperty(AnalyticsEventConstants.TEAM_IS_TEAM, profileProperties.isTeamMember) + profileProperties.teamId?.let { + setProperty(AnalyticsEventConstants.TEAM_TEAM_ID, it) + } + profileProperties.teamMembersAmount?.let { + setProperty(AnalyticsEventConstants.TEAM_TEAM_SIZE, it) + } + profileProperties.isEnterprise?.let { + setProperty(AnalyticsEventConstants.TEAM_IS_ENTERPRISE, it) + } + profileProperties.contactsAmount?.let { + setProperty(AnalyticsEventConstants.USER_CONTACTS, it) + } + } Countly.sharedInstance()?.userProfile()?.save() } diff --git a/core/analytics-enabled/src/test/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerTest.kt b/core/analytics-enabled/src/test/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerTest.kt index 691810ab5a3..a67cf191878 100644 --- a/core/analytics-enabled/src/test/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerTest.kt +++ b/core/analytics-enabled/src/test/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsManagerTest.kt @@ -22,6 +22,7 @@ import android.content.Context import com.wire.android.feature.analytics.handler.AnalyticsMigrationHandler import com.wire.android.feature.analytics.handler.AnalyticsPropagationHandler import com.wire.android.feature.analytics.model.AnalyticsEvent +import com.wire.android.feature.analytics.model.AnalyticsProfileProperties import com.wire.android.feature.analytics.model.AnalyticsResult import com.wire.android.feature.analytics.model.AnalyticsSettings import com.wire.kalium.logic.data.analytics.AnalyticsIdentifierResult @@ -450,7 +451,13 @@ class AnonymousAnalyticsManagerTest { private fun dummyManager() = object : DummyManager {} val existingIdentifierResult = AnalyticsResult( identifierResult = AnalyticsIdentifierResult.ExistingIdentifier(CURRENT_IDENTIFIER), - isTeamMember = true, + profileProperties = AnalyticsProfileProperties( + isTeamMember = true, + teamId = null, + contactsAmount = null, + teamMembersAmount = null, + isEnterprise = null + ), manager = dummyManager() ) val disabledIdentifierResult = existingIdentifierResult.copy( diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorder.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorder.kt index db193e0dd09..3151b4da4ec 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorder.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorder.kt @@ -20,6 +20,7 @@ package com.wire.android.feature.analytics import android.app.Activity import android.content.Context import com.wire.android.feature.analytics.model.AnalyticsEvent +import com.wire.android.feature.analytics.model.AnalyticsProfileProperties import com.wire.android.feature.analytics.model.AnalyticsSettings interface AnonymousAnalyticsRecorder { @@ -38,14 +39,14 @@ interface AnonymousAnalyticsRecorder { suspend fun setTrackingIdentifierWithMerge( identifier: String, - isTeamMember: Boolean, + analyticsProfileProperties: AnalyticsProfileProperties, migrationComplete: suspend () -> Unit ) suspend fun setTrackingIdentifierWithoutMerge( identifier: String, shouldPropagateIdentifier: Boolean, - isTeamMember: Boolean, + analyticsProfileProperties: AnalyticsProfileProperties, propagateIdentifier: suspend () -> Unit ) diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderStub.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderStub.kt index a60ed0fc44d..d2efd8ad3a1 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderStub.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/AnonymousAnalyticsRecorderStub.kt @@ -20,6 +20,7 @@ package com.wire.android.feature.analytics import android.app.Activity import android.content.Context import com.wire.android.feature.analytics.model.AnalyticsEvent +import com.wire.android.feature.analytics.model.AnalyticsProfileProperties import com.wire.android.feature.analytics.model.AnalyticsSettings open class AnonymousAnalyticsRecorderStub : AnonymousAnalyticsRecorder { @@ -35,14 +36,14 @@ open class AnonymousAnalyticsRecorderStub : AnonymousAnalyticsRecorder { override suspend fun setTrackingIdentifierWithMerge( identifier: String, - isTeamMember: Boolean, + analyticsProfileProperties: AnalyticsProfileProperties, migrationComplete: suspend () -> Unit ) = Unit override suspend fun setTrackingIdentifierWithoutMerge( identifier: String, shouldPropagateIdentifier: Boolean, - isTeamMember: Boolean, + analyticsProfileProperties: AnalyticsProfileProperties, propagateIdentifier: suspend () -> Unit ) = Unit diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt index e969175bb5b..11f1956d8e4 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsEvent.kt @@ -374,6 +374,10 @@ object AnalyticsEventConstants { const val APP_OPEN = "app.open" const val IS_TEAM_MEMBER = "is_team_member" + const val TEAM_IS_ENTERPRISE = "team_is_enterprise" + const val TEAM_TEAM_ID = "team_team_id" + const val TEAM_TEAM_SIZE = "team_team_size" + const val USER_CONTACTS = "user_contacts" /** * Calling diff --git a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsResult.kt b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsResult.kt index fc13fd16492..b3ac73b06c0 100644 --- a/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsResult.kt +++ b/core/analytics/src/main/kotlin/com/wire/android/feature/analytics/model/AnalyticsResult.kt @@ -21,6 +21,14 @@ import com.wire.kalium.logic.data.analytics.AnalyticsIdentifierResult data class AnalyticsResult( val identifierResult: AnalyticsIdentifierResult, - val isTeamMember: Boolean, + val profileProperties: AnalyticsProfileProperties, val manager: T? ) + +data class AnalyticsProfileProperties( + val isTeamMember: Boolean, + val teamId: String?, + val contactsAmount: Int?, + val teamMembersAmount: Int?, + val isEnterprise: Boolean? +) diff --git a/kalium b/kalium index 7c462ea8667..fa3ef824c12 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit 7c462ea8667fbb0ff791b005e68dc7c6fba1ee09 +Subproject commit fa3ef824c1284de127691ddbefdedaf4c34c8ac6 From 301c9a209f1d215c70c64adbbc2fadfe37e2f001 Mon Sep 17 00:00:00 2001 From: Boris Safonov Date: Wed, 26 Feb 2025 11:13:39 +0200 Subject: [PATCH 4/6] Updated kalium --- kalium | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kalium b/kalium index fa3ef824c12..389894b9342 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit fa3ef824c1284de127691ddbefdedaf4c34c8ac6 +Subproject commit 389894b9342afd1a77e3550b2f9f57ae2c29c372 From adac1b6ff9a354cd73d0d7c15a7f96563f9a537a Mon Sep 17 00:00:00 2001 From: Boris Safonov Date: Wed, 26 Feb 2025 11:15:11 +0200 Subject: [PATCH 5/6] Updated kalium --- kalium | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kalium b/kalium index 389894b9342..96cfab54bf4 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit 389894b9342afd1a77e3550b2f9f57ae2c29c372 +Subproject commit 96cfab54bf45905c8240a59e42b0bb2320e3ddbc From fcaf42bb6fad56c4e58c7c1de4d5e33e06e1424f Mon Sep 17 00:00:00 2001 From: Boris Safonov Date: Wed, 26 Feb 2025 15:40:19 +0200 Subject: [PATCH 6/6] Fixed tests --- ...serveCurrentSessionAnalyticsUseCaseTest.kt | 65 +++++++++++++------ 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/app/src/test/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCaseTest.kt b/app/src/test/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCaseTest.kt index c51cc3cf58d..70da43e1c54 100644 --- a/app/src/test/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCaseTest.kt +++ b/app/src/test/kotlin/com/wire/android/analytics/ObserveCurrentSessionAnalyticsUseCaseTest.kt @@ -21,6 +21,7 @@ import app.cash.turbine.test import com.wire.android.assertIs import com.wire.android.datastore.UserDataStore import com.wire.android.datastore.UserDataStoreProvider +import com.wire.android.feature.analytics.model.AnalyticsProfileProperties import com.wire.android.framework.TestUser import com.wire.kalium.common.error.CoreFailure import com.wire.kalium.logic.configuration.server.CommonApiVersionType @@ -28,6 +29,7 @@ import com.wire.kalium.logic.configuration.server.ServerConfig import com.wire.kalium.logic.data.analytics.AnalyticsIdentifierResult import com.wire.kalium.logic.data.auth.AccountInfo import com.wire.kalium.logic.data.user.UserId +import com.wire.kalium.logic.feature.analytics.AnalyticsContactsData import com.wire.kalium.logic.feature.analytics.AnalyticsIdentifierManager import com.wire.kalium.logic.feature.session.CurrentSessionResult import com.wire.kalium.logic.feature.user.SelfServerConfigUseCase @@ -56,7 +58,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { // then val item = awaitItem() assertIs(item.identifierResult) - assertEquals(false, item.isTeamMember) + assertEquals(false, item.profileProperties.isTeamMember) assertEquals(null, item.manager) } } @@ -68,7 +70,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { .withIsAnonymousUsageDataEnabled(true) .apply { setCurrentSession(CurrentSessionResult.Success(AccountInfo.Valid(TestUser.SELF_USER.id))) - setIsTeamMember(TestUser.SELF_USER.id) + setAnalyticsContactsData(TestUser.SELF_USER.id, Arrangement.ANALYTICS_CONTACTS_DATA) setObservingTrackingIdentifierStatus(AnalyticsIdentifierResult.ExistingIdentifier(Arrangement.CURRENT_TRACKING_IDENTIFIER)) setSelfServerConfig(Arrangement.SERVER_CONFIG_PRODUCTION) }.arrange() @@ -78,7 +80,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { // then val item = awaitItem() assertIs(item.identifierResult) - assertEquals(true, item.isTeamMember) + assertAnalyticsProfileProperties(Arrangement.ANALYTICS_CONTACTS_DATA, item.profileProperties) } } @@ -89,7 +91,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { .withIsAnonymousUsageDataEnabled(true) .apply { setCurrentSession(CurrentSessionResult.Success(AccountInfo.Valid(TestUser.SELF_USER.id))) - setIsTeamMember(TestUser.SELF_USER.id) + setAnalyticsContactsData(TestUser.SELF_USER.id, Arrangement.ANALYTICS_CONTACTS_DATA) setObservingTrackingIdentifierStatus(AnalyticsIdentifierResult.ExistingIdentifier(Arrangement.CURRENT_TRACKING_IDENTIFIER)) setSelfServerConfig(Arrangement.SERVER_CONFIG_STAGING) }.arrange() @@ -99,7 +101,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { // then val item = awaitItem() assertIs(item.identifierResult) - assertEquals(true, item.isTeamMember) + assertAnalyticsProfileProperties(Arrangement.ANALYTICS_CONTACTS_DATA, item.profileProperties) } } @@ -111,7 +113,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { .withIsAnonymousUsageDataEnabled(false) .apply { setCurrentSession(CurrentSessionResult.Success(AccountInfo.Valid(TestUser.SELF_USER.id))) - setIsTeamMember(TestUser.SELF_USER.id) + setAnalyticsContactsData(TestUser.SELF_USER.id, Arrangement.ANALYTICS_CONTACTS_DATA) setObservingTrackingIdentifierStatus( AnalyticsIdentifierResult.ExistingIdentifier(Arrangement.CURRENT_TRACKING_IDENTIFIER) ) @@ -123,7 +125,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { // then val item = awaitItem() assertIs(item.identifierResult) - assertEquals(true, item.isTeamMember) + assertAnalyticsProfileProperties(Arrangement.ANALYTICS_CONTACTS_DATA, item.profileProperties) assertEquals(true, item.manager != null) } } @@ -136,7 +138,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { .withIsAnonymousUsageDataEnabled(true) .apply { setCurrentSession(CurrentSessionResult.Success(AccountInfo.Valid(TestUser.SELF_USER.id))) - setIsTeamMember(TestUser.SELF_USER.id) + setAnalyticsContactsData(TestUser.SELF_USER.id, Arrangement.ANALYTICS_CONTACTS_DATA) setObservingTrackingIdentifierStatus( AnalyticsIdentifierResult.ExistingIdentifier(Arrangement.CURRENT_TRACKING_IDENTIFIER) ) @@ -152,7 +154,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { // then val item = awaitItem() assertIs(item.identifierResult) - assertEquals(true, item.isTeamMember) + assertAnalyticsProfileProperties(Arrangement.ANALYTICS_CONTACTS_DATA, item.profileProperties) assertEquals(true, item.manager != null) } } @@ -165,7 +167,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { .withIsAnonymousUsageDataEnabled(true) .apply { setCurrentSession(CurrentSessionResult.Success(AccountInfo.Valid(TestUser.SELF_USER.id))) - setIsTeamMember(TestUser.SELF_USER.id) + setAnalyticsContactsData(TestUser.SELF_USER.id, Arrangement.ANALYTICS_CONTACTS_DATA) setObservingTrackingIdentifierStatus( AnalyticsIdentifierResult.ExistingIdentifier(Arrangement.CURRENT_TRACKING_IDENTIFIER) ) @@ -177,7 +179,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { // then val item = awaitItem() assertIs(item.identifierResult) - assertEquals(true, item.isTeamMember) + assertAnalyticsProfileProperties(Arrangement.ANALYTICS_CONTACTS_DATA, item.profileProperties) assertEquals(true, item.manager != null) } } @@ -189,7 +191,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { .withIsAnonymousUsageDataEnabled(true) .apply { setCurrentSession(CurrentSessionResult.Success(AccountInfo.Valid(TestUser.SELF_USER.id))) - setIsTeamMember(TestUser.SELF_USER.id) + setAnalyticsContactsData(TestUser.SELF_USER.id, Arrangement.ANALYTICS_CONTACTS_DATA) setObservingTrackingIdentifierStatus(AnalyticsIdentifierResult.ExistingIdentifier(Arrangement.CURRENT_TRACKING_IDENTIFIER)) setSelfServerConfig(Arrangement.SERVER_CONFIG_PRODUCTION) }.arrange() @@ -199,7 +201,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { // then val item = awaitItem() assertIs(item.identifierResult) - assertEquals(true, item.isTeamMember) + assertAnalyticsProfileProperties(Arrangement.ANALYTICS_CONTACTS_DATA, item.profileProperties) // when changing user arrangement.setCurrentSession(CurrentSessionResult.Success(AccountInfo.Valid(TestUser.OTHER_USER.id))) @@ -212,10 +214,17 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { // then val nextItem = awaitItem() assertIs(nextItem.identifierResult) - assertEquals(false, nextItem.isTeamMember) } } + private fun assertAnalyticsProfileProperties(expected: AnalyticsContactsData, actual: AnalyticsProfileProperties) { + assertEquals(expected.teamId, actual.teamId) + assertEquals(expected.isTeamMember, actual.isTeamMember) + assertEquals(expected.isEnterprise, actual.isEnterprise) + assertEquals(expected.contactsSize, actual.contactsAmount) + assertEquals(expected.teamSize, actual.teamMembersAmount) + } + private class Arrangement { @MockK @@ -233,9 +242,11 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { private val selfServerConfigChannel = Channel(Channel.UNLIMITED) - private val teamMembers = mutableSetOf() + private var analyticsContactsData: MutableMap = mutableMapOf() - private val isTeamMember: (UserId) -> Boolean = { teamMembers.contains(it) } + private val getAnalyticsContactsData: (UserId) -> AnalyticsContactsData = { + analyticsContactsData.getOrDefault(it, ANALYTICS_CONTACTS_DATA_DEFAULT) + } init { // Tests setup @@ -246,8 +257,8 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { currentSessionChannel.send(result) } - fun setIsTeamMember(userId: UserId) { - teamMembers.add(userId) + fun setAnalyticsContactsData(userId: UserId, data: AnalyticsContactsData) { + analyticsContactsData[userId] = data } suspend fun setObservingTrackingIdentifierStatus(result: AnalyticsIdentifierResult) { @@ -265,7 +276,7 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { var useCase: ObserveCurrentSessionAnalyticsUseCase = ObserveCurrentSessionAnalyticsUseCase( currentSessionFlow = currentSessionChannel.receiveAsFlow(), - getAnalyticsContactsData = isTeamMember, + getAnalyticsContactsData = getAnalyticsContactsData, observeAnalyticsTrackingIdentifierStatusFlow = { analyticsTrackingIdentifierStatusChannel.receiveAsFlow() }, @@ -301,6 +312,22 @@ class ObserveCurrentSessionAnalyticsUseCaseTest { links = ServerConfig.STAGING ) ) + + val ANALYTICS_CONTACTS_DATA = AnalyticsContactsData( + teamId = "teamId", + contactsSize = 12, + teamSize = 13, + isEnterprise = true, + isTeamMember = true + ) + + val ANALYTICS_CONTACTS_DATA_DEFAULT = AnalyticsContactsData( + teamId = null, + contactsSize = null, + teamSize = null, + isEnterprise = null, + isTeamMember = false + ) } } }