Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: add is_team_member and user_type segmentations (WPB-14646) #3832

Merged
merged 2 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ private fun SelfQRCodeContent(
val context = LocalContext.current

BackHandler {
trackAnalyticsEvent(AnalyticsEvent.QrCode.Modal.Back)
trackAnalyticsEvent(
AnalyticsEvent.QrCode.Modal.Back(
isTeam = state.isTeamMember
)
)
onBackClick()
}

Expand All @@ -118,7 +122,11 @@ private fun SelfQRCodeContent(
WireCenterAlignedTopAppBar(
title = stringResource(id = R.string.user_profile_qr_code_title),
onNavigationPressed = {
trackAnalyticsEvent(AnalyticsEvent.QrCode.Modal.Back)
trackAnalyticsEvent(
AnalyticsEvent.QrCode.Modal.Back(
isTeam = state.isTeamMember
)
)
onBackClick()
},
elevation = 0.dp
Expand All @@ -127,26 +135,26 @@ private fun SelfQRCodeContent(
) { internalPadding ->
Column(
modifier =
Modifier
.fillMaxSize()
.background(colorsScheme().background)
.padding(internalPadding),
Modifier
.fillMaxSize()
.background(colorsScheme().background)
.padding(internalPadding),
horizontalAlignment = Alignment.CenterHorizontally
) {
VerticalSpace.x24()
Column(
modifier =
Modifier
.padding(horizontal = dimensions().spacing16x)
.clip(RoundedCornerShape(dimensions().spacing8x))
.fillMaxWidth()
.drawWithContent {
graphicsLayer.record {
[email protected]()
Modifier
.padding(horizontal = dimensions().spacing16x)
.clip(RoundedCornerShape(dimensions().spacing8x))
.fillMaxWidth()
.drawWithContent {
graphicsLayer.record {
[email protected]()
}
drawLayer(graphicsLayer)
}
drawLayer(graphicsLayer)
}
.background(Color.White),
.background(Color.White),
horizontalAlignment = Alignment.CenterHorizontally
) {
VerticalSpace.x16()
Expand All @@ -159,14 +167,14 @@ private fun SelfQRCodeContent(
Box(
contentAlignment = Alignment.Center,
modifier =
Modifier
.clip(CircleShape)
.border(
width = dimensions().spacing2x,
shape = CircleShape,
color = Color.White
)
.background(colorsScheme().primary)
Modifier
.clip(CircleShape)
.border(
width = dimensions().spacing2x,
shape = CircleShape,
color = Color.White
)
.background(colorsScheme().primary)
) {
Icon(
painter = painterResource(id = R.drawable.ic_launcher_foreground),
Expand Down Expand Up @@ -203,10 +211,14 @@ private fun SelfQRCodeContent(
color = colorsScheme().secondaryText
)
Spacer(modifier = Modifier.weight(1f))
ShareLinkButton(state.userAccountProfileLink, trackAnalyticsEvent)
ShareLinkButton(state.isTeamMember, state.userAccountProfileLink, trackAnalyticsEvent)
VerticalSpace.x8()
ShareQRCodeButton {
trackAnalyticsEvent(AnalyticsEvent.QrCode.Modal.ShareQrCode)
trackAnalyticsEvent(
AnalyticsEvent.QrCode.Modal.ShareQrCode(
isTeam = state.isTeamMember
)
)
coroutineScope.launch {
val bitmap = graphicsLayer.toImageBitmap()
val qrUri = shareQRAssetClick(bitmap.asAndroidBitmap())
Expand All @@ -222,32 +234,37 @@ private fun SelfQRCodeContent(
fun ShareQRCodeButton(shareQRAssetClick: () -> Unit) {
WirePrimaryButton(
modifier =
Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.background)
.padding(horizontal = dimensions().spacing16x)
.testTag("Share QR link"),
Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.background)
.padding(horizontal = dimensions().spacing16x)
.testTag("Share QR link"),
text = stringResource(R.string.user_profile_qr_code_share_image_link),
onClick = shareQRAssetClick
)
}

@Composable
private fun ShareLinkButton(
isTeamMember: Boolean,
selfProfileUrl: String,
trackAnalyticsEvent: (AnalyticsEvent.QrCode.Modal) -> Unit
) {
val context = LocalContext.current
WirePrimaryButton(
modifier =
Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.background)
.padding(horizontal = dimensions().spacing16x)
.testTag("Share link"),
Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.background)
.padding(horizontal = dimensions().spacing16x)
.testTag("Share link"),
text = stringResource(R.string.user_profile_qr_code_share_link),
onClick = {
trackAnalyticsEvent(AnalyticsEvent.QrCode.Modal.ShareProfileLink)
trackAnalyticsEvent(
AnalyticsEvent.QrCode.Modal.ShareProfileLink(
isTeam = isTeamMember
)
)
context.shareLinkToProfile(selfProfileUrl)
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ data class SelfQRCodeState(
val handle: String = "",
val userProfileLink: String = "",
val userAccountProfileLink: String = "",
val hasError: Boolean = false
val hasError: Boolean = false,
val isTeamMember: Boolean = false
)
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,18 @@ class SelfQRCodeViewModel @Inject constructor(
private val analyticsManager: AnonymousAnalyticsManager
) : ViewModel() {
private val selfQrCodeNavArgs: SelfQrCodeNavArgs = savedStateHandle.navArgs()
var selfQRCodeState by mutableStateOf(SelfQRCodeState(selfUserId, handle = selfQrCodeNavArgs.handle))
var selfQRCodeState by mutableStateOf(
SelfQRCodeState(
selfUserId,
handle = selfQrCodeNavArgs.handle,
isTeamMember = selfQrCodeNavArgs.isTeamMember
)
)
private set
private val cachePath: Path
get() = kaliumFileSystem.rootCachePath

init {
trackAnalyticsEvent(AnalyticsEvent.QrCode.Modal.Displayed)
viewModelScope.launch {
getServerLinks()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ import kotlinx.parcelize.Parcelize

@Parcelize
data class SelfQrCodeNavArgs(
val handle: String = ""
val handle: String = "",
val isTeamMember: Boolean
) : Parcelable
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,14 @@ fun SelfUserProfileScreen(
},
onQrCodeClick = {
viewModelSelf.trackQrCodeClick()
navigator.navigate(NavigationCommand(SelfQRCodeScreenDestination(viewModelSelf.userProfileState.userName)))
navigator.navigate(
NavigationCommand(
SelfQRCodeScreenDestination(
viewModelSelf.userProfileState.userName,
!viewModelSelf.userProfileState.teamName.isNullOrBlank()
)
)
)
},
onCreateAccount = {
viewModelSelf.sendPersonalToTeamMigrationEvent()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class SelfQRCodeViewModelTest {
coEvery { selfServerConfig.invoke() } returns SelfServerConfigUseCase.Result.Success(
serverLinks = newServerConfig(1).copy(links = ServerConfig.STAGING)
)
every { savedStateHandle.navArgs<SelfQrCodeNavArgs>() } returns SelfQrCodeNavArgs("handle")
every { savedStateHandle.navArgs<SelfQrCodeNavArgs>() } returns SelfQrCodeNavArgs("handle", false)
}

fun arrange() = this to SelfQRCodeViewModel(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_
import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CONVERSATION_SIZE
import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_CONVERSATION_TYPE
import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_END_REASON
import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_IS_TEAM_MEMBER
import com.wire.android.feature.analytics.model.AnalyticsEventConstants.IS_TEAM_MEMBER
import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_ENDED_UNIQUE_SCREEN_SHARE
import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_QUALITY_REVIEW_IGNORE_REASON
import com.wire.android.feature.analytics.model.AnalyticsEventConstants.CALLING_QUALITY_REVIEW_IGNORE_REASON_KEY
Expand Down Expand Up @@ -151,7 +151,7 @@ interface AnalyticsEvent {

override fun toSegmentation(): Map<String, Any> {
return mapOf(
CALLING_ENDED_IS_TEAM_MEMBER to metadata.isTeamMember,
IS_TEAM_MEMBER to metadata.isTeamMember,
CALLING_ENDED_CALL_SCREEN_SHARE to metadata.callDetails.screenShareDurationInSeconds,
CALLING_ENDED_UNIQUE_SCREEN_SHARE to metadata.callDetails.callScreenShareUniques,
CALLING_ENDED_CALL_DIRECTION to metadata.toCallDirection(),
Expand Down Expand Up @@ -257,39 +257,48 @@ interface AnalyticsEvent {
}

sealed class QrCode : AnalyticsEvent {
fun createSegmentationMap(
isTeam: Boolean
): Map<String, Any> {
val userType = if (isTeam) {
QR_CODE_SEGMENTATION_USER_TYPE_TEAM
} else {
QR_CODE_SEGMENTATION_USER_TYPE_PERSONAL
}

return mapOf(
AnalyticsEventConstants.QR_CODE_SEGMENTATION_USER_TYPE to userType,
IS_TEAM_MEMBER to isTeam,
)
}

data class Click(
val isTeam: Boolean
) : QrCode() {
override val key: String = AnalyticsEventConstants.QR_CODE_CLICK

override fun toSegmentation(): Map<String, Any> {
val userType = if (isTeam) {
QR_CODE_SEGMENTATION_USER_TYPE_TEAM
} else {
QR_CODE_SEGMENTATION_USER_TYPE_PERSONAL
}

return mapOf(
AnalyticsEventConstants.QR_CODE_SEGMENTATION_USER_TYPE to userType
)
}
override fun toSegmentation(): Map<String, Any> = createSegmentationMap(isTeam)
}

sealed class Modal : QrCode() {
data object Displayed : Modal() {
override val key: String = AnalyticsEventConstants.QR_CODE_MODAL
}

data object Back : Modal() {
data class Back(
val isTeam: Boolean
) : Modal() {
override val key: String = AnalyticsEventConstants.QR_CODE_MODAL_BACK
override fun toSegmentation(): Map<String, Any> = createSegmentationMap(isTeam)
}

data object ShareProfileLink : Modal() {
data class ShareProfileLink(
val isTeam: Boolean
) : Modal() {
override val key: String = AnalyticsEventConstants.QR_CODE_SHARE_PROFILE_LINK
override fun toSegmentation(): Map<String, Any> = createSegmentationMap(isTeam)
}

data object ShareQrCode : Modal() {
data class ShareQrCode(
val isTeam: Boolean
) : Modal() {
override val key: String = AnalyticsEventConstants.QR_CODE_SHARE_QR_CODE
override fun toSegmentation(): Map<String, Any> = createSegmentationMap(isTeam)
}
}
}
Expand Down Expand Up @@ -393,6 +402,8 @@ object AnalyticsEventConstants {
const val TEAM_IS_TEAM = "team_is_team"
const val APP_OPEN = "app.open"

const val IS_TEAM_MEMBER = "is_team_member"

/**
* Calling
*/
Expand All @@ -412,7 +423,6 @@ object AnalyticsEventConstants {
/**
* Call ended
*/
const val CALLING_ENDED_IS_TEAM_MEMBER = "is_team_member"
const val CALLING_ENDED_CALL_SCREEN_SHARE = "call_screen_share_duration"
const val CALLING_ENDED_UNIQUE_SCREEN_SHARE = "call_screen_share_unique"
const val CALLING_ENDED_CALL_DIRECTION = "call_direction"
Expand Down Expand Up @@ -455,7 +465,6 @@ object AnalyticsEventConstants {
* Qr code
*/
const val QR_CODE_CLICK = "ui.QR-click"
const val QR_CODE_MODAL = "ui.share.profile"
const val QR_CODE_MODAL_BACK = "user.back.share-profile"
const val QR_CODE_SHARE_PROFILE_LINK = "user.share-profile"
const val QR_CODE_SHARE_QR_CODE = "user.QR-code"
Expand Down
Loading