From 9059f7d224ad9c4d8ed90776befd064761aad52e Mon Sep 17 00:00:00 2001 From: Cristhian Escobar Date: Sun, 25 Aug 2024 02:24:45 -0500 Subject: [PATCH] Analytics logged for screens loaded --- .../src/main/java/io/newm/HomeActivity.kt | 9 ++- .../src/main/java/io/newm/LoginActivity.kt | 4 +- .../main/java/io/newm/NewmAppComposable.kt | 6 +- .../screens/library/NFTLibraryScreenUi.kt | 69 ++++++++++++++----- .../screens/library/SongFilterBottomSheet.kt | 10 ++- .../library/screens/EmptyWalletScreen.kt | 4 +- .../library/screens/LinkWalletScreen.kt | 3 +- .../profile/ProfileBottomSheetLayout.kt | 8 +++ .../screens/profile/edit/ProfileEditUi.kt | 8 ++- .../io/newm/screens/profile/view/ProfileUi.kt | 17 ++++- android/core/ui-utils/build.gradle.kts | 1 + .../io/newm/core/ui/ConfirmationDialog.kt | 6 ++ .../java/io/newm/core/ui/utils/ErrorScreen.kt | 6 +- .../CreateAccountScreenPresenter.kt | 1 - .../ResetPasswordScreenPresenter.kt | 3 - .../resetpassword/ResetPasswordScreenUi.kt | 61 ++++++++++++---- .../login/screen/welcome/WelcomeScreenUi.kt | 15 +++- .../login/screen/ResetPasswordScreenTest.kt | 10 ++- 18 files changed, 182 insertions(+), 59 deletions(-) diff --git a/android/app-newm/src/main/java/io/newm/HomeActivity.kt b/android/app-newm/src/main/java/io/newm/HomeActivity.kt index f03cc5be..0e8315c5 100644 --- a/android/app-newm/src/main/java/io/newm/HomeActivity.kt +++ b/android/app-newm/src/main/java/io/newm/HomeActivity.kt @@ -80,21 +80,24 @@ class HomeActivity : ComponentActivity() { is Screen.UserAccount -> ui { state, modifier -> ProfileUi( state = state, - modifier = modifier + modifier = modifier, + eventLogger = eventLogger ) } is NFTLibrary -> ui { state, modifier -> NFTLibraryScreenUi( state = state, - modifier = modifier + modifier = modifier, + eventLogger = eventLogger ) } is Screen.EditProfile -> ui { state, modifier -> ProfileEditUi( state = state, - modifier = modifier + modifier = modifier, + eventLogger = eventLogger ) } diff --git a/android/app-newm/src/main/java/io/newm/LoginActivity.kt b/android/app-newm/src/main/java/io/newm/LoginActivity.kt index 98f4ad81..99463c48 100644 --- a/android/app-newm/src/main/java/io/newm/LoginActivity.kt +++ b/android/app-newm/src/main/java/io/newm/LoginActivity.kt @@ -83,7 +83,7 @@ class LoginActivity : ComponentActivity() { } is LoginLandingScreen -> ui { state, modifier -> - WelcomeScreenUi(modifier, state) + WelcomeScreenUi(modifier, state, eventLogger) } is LoginScreen -> ui { state, modifier -> @@ -91,7 +91,7 @@ class LoginActivity : ComponentActivity() { } is ResetPasswordScreen -> ui { state, modifier -> - ResetPasswordScreenUi().Content(state = state, modifier = modifier) + ResetPasswordScreenUi(eventLogger).Content(state = state, modifier = modifier) } else -> null diff --git a/android/app-newm/src/main/java/io/newm/NewmAppComposable.kt b/android/app-newm/src/main/java/io/newm/NewmAppComposable.kt index 6fe4db7c..5c774635 100644 --- a/android/app-newm/src/main/java/io/newm/NewmAppComposable.kt +++ b/android/app-newm/src/main/java/io/newm/NewmAppComposable.kt @@ -129,10 +129,6 @@ internal fun NewmApp( modifier = Modifier, sheetState = sheetState, sheetContent = { - LaunchedEffect(Unit) { - eventLogger.logPageLoad("Music Player") - } - MusicPlayerScreen( eventLogger = eventLogger, onNavigateUp = { @@ -155,7 +151,6 @@ internal fun NewmApp( MiniPlayer( modifier = Modifier.clickable { coroutineScope.launch { - eventLogger.logClickEvent("Mini Player") sheetState.show() } }, @@ -221,6 +216,7 @@ internal fun NewmBottomNavigation( selectedLabelColor = DarkPink, onClick = { eventLogger.logClickEvent("Account") + eventLogger.logPageLoad("Account") onNavigationSelected(Screen.UserAccount) }, ) diff --git a/android/app-newm/src/main/java/io/newm/screens/library/NFTLibraryScreenUi.kt b/android/app-newm/src/main/java/io/newm/screens/library/NFTLibraryScreenUi.kt index 5cb5a03e..e1c59ffa 100644 --- a/android/app-newm/src/main/java/io/newm/screens/library/NFTLibraryScreenUi.kt +++ b/android/app-newm/src/main/java/io/newm/screens/library/NFTLibraryScreenUi.kt @@ -32,6 +32,7 @@ import androidx.compose.material.rememberModalBottomSheetState import androidx.compose.material.rememberSwipeableState import androidx.compose.material.swipeable import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -72,6 +73,7 @@ import io.newm.screens.library.NFTLibraryEvent.PlaySong import io.newm.screens.library.screens.EmptyWalletScreen import io.newm.screens.library.screens.LinkWalletScreen import io.newm.screens.library.screens.ZeroSearchResults +import io.newm.shared.public.analytics.NewmAppEventLogger import io.newm.shared.public.models.NFTTrack import kotlinx.coroutines.launch import kotlin.math.roundToInt @@ -82,7 +84,8 @@ internal const val TAG_NFT_LIBRARY_SCREEN = "TAG_NFT_LIBRARY_SCREEN" @Composable fun NFTLibraryScreenUi( modifier: Modifier = Modifier, - state: NFTLibraryState + state: NFTLibraryState, + eventLogger: NewmAppEventLogger ) { Column( modifier = modifier @@ -91,22 +94,47 @@ fun NFTLibraryScreenUi( .testTag(TAG_NFT_LIBRARY_SCREEN), ) { when (state) { - NFTLibraryState.Loading -> LoadingScreen() + NFTLibraryState.Loading -> { + LaunchedEffect(Unit) { + eventLogger.logPageLoad("NFT Library Loading") + } + LoadingScreen() + } - is NFTLibraryState.LinkWallet -> LinkWalletScreen( - modifier = Modifier - .fillMaxSize() - .padding(horizontal = 16.dp), - ) { newmWalletConnectionId -> - val eventSink = state.onConnectWallet - eventSink(newmWalletConnectionId) + is NFTLibraryState.LinkWallet -> { + LaunchedEffect(Unit) { + eventLogger.logPageLoad("NFT Library Link Wallet") + } + LinkWalletScreen( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 16.dp), + ) { newmWalletConnectionId -> + val eventSink = state.onConnectWallet + eventSink(newmWalletConnectionId) + } + } + + NFTLibraryState.EmptyWallet -> { + LaunchedEffect(Unit) { + eventLogger.logPageLoad("NFT Library Empty Wallet") + } + EmptyWalletScreen(eventLogger) + } + + is NFTLibraryState.Error -> { + LaunchedEffect(Unit) { + eventLogger.logPageLoad("NFT Library Error Screen") + } + ErrorScreen(state.message) } - NFTLibraryState.EmptyWallet -> EmptyWalletScreen() - is NFTLibraryState.Error -> ErrorScreen(state.message) is NFTLibraryState.Content -> { val eventSink = state.eventSink + LaunchedEffect(Unit) { + eventLogger.logPageLoad("NFT Library Song List") + } Text( text = stringResource(id = R.string.title_nft_library), modifier = Modifier.padding(16.dp), @@ -129,7 +157,8 @@ fun NFTLibraryScreenUi( onDownloadSong = { trackId -> eventSink(OnDownloadTrack(trackId)) }, refresh = { eventSink(NFTLibraryEvent.OnRefresh) }, refreshing = state.refreshing, - onApplyFilters = { filters -> eventSink(OnApplyFilters(filters)) } + eventLogger = eventLogger, + onApplyFilters = { filters -> eventSink(OnApplyFilters(filters)) }, ) } } @@ -150,7 +179,8 @@ private fun NFTTracks( onDownloadSong: (String) -> Unit, refresh: () -> Unit, refreshing: Boolean, - onApplyFilters: (NFTLibraryFilters) -> Unit + eventLogger: NewmAppEventLogger, + onApplyFilters: (NFTLibraryFilters) -> Unit, ) { val scope = rememberCoroutineScope() val filterSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) @@ -219,7 +249,7 @@ private fun NFTTracks( modifier = Modifier.align(Alignment.TopCenter) ) - SongFilterBottomSheet(filterSheetState, filters, onApplyFilters) + SongFilterBottomSheet(filterSheetState, filters, onApplyFilters, eventLogger) } } @@ -257,7 +287,7 @@ private fun TrackRowItemWrapper( TrackRowItem( track = track, onClick = onPlaySong, - modifier = if(DOWNLOAD_UI_ENABLED) Modifier.offset { + modifier = if (DOWNLOAD_UI_ENABLED) Modifier.offset { IntOffset( x = -swipeableState.offset.value.roundToInt(), y = 0 @@ -340,7 +370,8 @@ fun PreviewNftLibrary() { ), refreshing = false, eventSink = {} - ) + ), + eventLogger = NewmAppEventLogger() ) } } @@ -350,7 +381,8 @@ fun PreviewNftLibrary() { fun PreviewNftLibraryLoading() { NewmTheme(darkTheme = true) { NFTLibraryScreenUi( - state = NFTLibraryState.Loading + state = NFTLibraryState.Loading, + eventLogger = NewmAppEventLogger() ) } } @@ -360,7 +392,8 @@ fun PreviewNftLibraryLoading() { fun PreviewNftLibraryEmptyWallet() { NewmTheme(darkTheme = true) { NFTLibraryScreenUi( - state = NFTLibraryState.EmptyWallet + state = NFTLibraryState.EmptyWallet, + eventLogger = NewmAppEventLogger() ) } } diff --git a/android/app-newm/src/main/java/io/newm/screens/library/SongFilterBottomSheet.kt b/android/app-newm/src/main/java/io/newm/screens/library/SongFilterBottomSheet.kt index b479d332..f366a849 100644 --- a/android/app-newm/src/main/java/io/newm/screens/library/SongFilterBottomSheet.kt +++ b/android/app-newm/src/main/java/io/newm/screens/library/SongFilterBottomSheet.kt @@ -19,6 +19,7 @@ import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -39,6 +40,7 @@ import io.newm.core.theme.Purple import io.newm.core.theme.White import io.newm.core.theme.inter import io.newm.core.ui.utils.iconGradient +import io.newm.shared.public.analytics.NewmAppEventLogger private val buttonGradient = @@ -49,12 +51,18 @@ private val buttonGradient = fun SongFilterBottomSheet( sheetState: ModalBottomSheetState, filters: NFTLibraryFilters, - onApplyFilters: (NFTLibraryFilters) -> Unit + onApplyFilters: (NFTLibraryFilters) -> Unit, + eventLogger: NewmAppEventLogger ) { LocalIsBottomBarVisible.current.value = sheetState.targetValue != ModalBottomSheetValue.Expanded ModalBottomSheetLayout( sheetState = sheetState, sheetContent = { + if (sheetState.targetValue == ModalBottomSheetValue.Expanded) { + LaunchedEffect(Unit) { + eventLogger.logPageLoad("NFT Library Filter") + } + } Box( modifier = Modifier .background(Black90) diff --git a/android/app-newm/src/main/java/io/newm/screens/library/screens/EmptyWalletScreen.kt b/android/app-newm/src/main/java/io/newm/screens/library/screens/EmptyWalletScreen.kt index 255c80f7..61a56064 100644 --- a/android/app-newm/src/main/java/io/newm/screens/library/screens/EmptyWalletScreen.kt +++ b/android/app-newm/src/main/java/io/newm/screens/library/screens/EmptyWalletScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -22,7 +23,7 @@ import io.newm.shared.public.analytics.NewmAppEventLogger private const val RECORD_STORE_URL = "https://recordstore.newm.io/" @Composable -fun EmptyWalletScreen() { +fun EmptyWalletScreen(eventLogger: NewmAppEventLogger) { val context = LocalContext.current Box( @@ -48,6 +49,7 @@ fun EmptyWalletScreen() { modifier = Modifier.padding(all = 16.dp), text = "Visit the Record Store", onClick = { + eventLogger.logClickEvent("Visit the Record Store") context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(RECORD_STORE_URL))) }, ) diff --git a/android/app-newm/src/main/java/io/newm/screens/library/screens/LinkWalletScreen.kt b/android/app-newm/src/main/java/io/newm/screens/library/screens/LinkWalletScreen.kt index ef0f5550..184b7dbd 100644 --- a/android/app-newm/src/main/java/io/newm/screens/library/screens/LinkWalletScreen.kt +++ b/android/app-newm/src/main/java/io/newm/screens/library/screens/LinkWalletScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext @@ -23,6 +24,7 @@ import io.newm.core.ui.permissions.rememberRequestPermissionIntent import io.newm.core.ui.wallet.ConnectWalletPanel import io.newm.feature.barcode.scanner.BarcodeScannerActivity import io.newm.screens.library.TAG_NFT_LIBRARY_SCREEN +import io.newm.shared.public.analytics.NewmAppEventLogger @Composable fun LinkWalletScreen( @@ -30,7 +32,6 @@ fun LinkWalletScreen( onConnectWallet: (String) -> Unit ) { val context = LocalContext.current - val launcher = rememberLauncherForActivityResult( contract = ActivityResultContracts.StartActivityForResult() ) { result: ActivityResult -> diff --git a/android/app-newm/src/main/java/io/newm/screens/profile/ProfileBottomSheetLayout.kt b/android/app-newm/src/main/java/io/newm/screens/profile/ProfileBottomSheetLayout.kt index 75947d93..aa143318 100644 --- a/android/app-newm/src/main/java/io/newm/screens/profile/ProfileBottomSheetLayout.kt +++ b/android/app-newm/src/main/java/io/newm/screens/profile/ProfileBottomSheetLayout.kt @@ -12,6 +12,7 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.ModalBottomSheetLayout import androidx.compose.material.ModalBottomSheetState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp @@ -20,12 +21,14 @@ import io.newm.core.theme.Black90 import io.newm.core.theme.Gray400 import io.newm.core.ui.buttons.PrimaryButton import io.newm.core.ui.buttons.SecondaryButton +import io.newm.shared.public.analytics.NewmAppEventLogger @OptIn(ExperimentalMaterialApi::class) @Composable fun ProfileBottomSheetLayout( modifier: Modifier = Modifier, sheetState: ModalBottomSheetState, + eventLogger: NewmAppEventLogger, onLogout: () -> Unit, onShowTermsAndConditions: () -> Unit, onShowPrivacyPolicy: () -> Unit, @@ -35,6 +38,11 @@ fun ProfileBottomSheetLayout( modifier = modifier, sheetState = sheetState, sheetContent = { + if(sheetState.isVisible) { + LaunchedEffect(Unit) { + eventLogger.logPageLoad("Account Options") + } + } Column( modifier = Modifier .fillMaxWidth() diff --git a/android/app-newm/src/main/java/io/newm/screens/profile/edit/ProfileEditUi.kt b/android/app-newm/src/main/java/io/newm/screens/profile/edit/ProfileEditUi.kt index 8f07d3d3..936aa5a5 100644 --- a/android/app-newm/src/main/java/io/newm/screens/profile/edit/ProfileEditUi.kt +++ b/android/app-newm/src/main/java/io/newm/screens/profile/edit/ProfileEditUi.kt @@ -43,6 +43,7 @@ import io.newm.screens.profile.ProfileForm import io.newm.screens.profile.ProfileHeader import io.newm.screens.profile.edit.ProfileEditUiState.Content import io.newm.screens.profile.edit.ProfileEditUiState.Loading +import io.newm.shared.public.analytics.NewmAppEventLogger import io.newm.shared.public.models.User import io.newm.shared.public.models.canEditName import io.newm.shared.public.models.mocks.mockUsers @@ -54,6 +55,7 @@ internal const val TAG_PROFILE_SCREEN = "TAG_PROFILE_SCREEN" fun ProfileEditUi( modifier: Modifier, state: ProfileEditUiState, + eventLogger: NewmAppEventLogger ) { when (state) { Loading -> LoadingScreen() @@ -61,6 +63,7 @@ fun ProfileEditUi( ProfileEditUiContent( modifier = modifier, state = state, + eventLogger = eventLogger ) } } @@ -71,6 +74,7 @@ fun ProfileEditUi( private fun ProfileEditUiContent( modifier: Modifier = Modifier, state: Content, + eventLogger: NewmAppEventLogger ) { val onEvent = state.eventSink val profile = state.profile @@ -81,6 +85,7 @@ private fun ProfileEditUiContent( ProfileBottomSheetLayout( modifier = modifier, sheetState = sheetState, + eventLogger = eventLogger, onLogout = { onEvent(OnLogout) }, onShowTermsAndConditions = { onEvent(OnShowTermsAndConditions) }, onShowPrivacyPolicy = { onEvent(OnShowPrivacyPolicy) } @@ -170,7 +175,8 @@ private fun ProfileScreenPreview() { confirmPasswordState = TextFieldState(), errorMessage = null, eventSink = {}, - ) + ), + eventLogger = NewmAppEventLogger() ) } } diff --git a/android/app-newm/src/main/java/io/newm/screens/profile/view/ProfileUi.kt b/android/app-newm/src/main/java/io/newm/screens/profile/view/ProfileUi.kt index 0d90d1d4..ecc2956b 100644 --- a/android/app-newm/src/main/java/io/newm/screens/profile/view/ProfileUi.kt +++ b/android/app-newm/src/main/java/io/newm/screens/profile/view/ProfileUi.kt @@ -70,6 +70,7 @@ import io.newm.screens.profile.OnShowTermsAndConditions import io.newm.screens.profile.ProfileAppBar import io.newm.screens.profile.ProfileBottomSheetLayout import io.newm.screens.profile.ProfileHeader +import io.newm.shared.public.analytics.NewmAppEventLogger import io.newm.shared.public.models.User import kotlinx.coroutines.launch @@ -111,6 +112,7 @@ private val disconnectWalletButtonTextGradient = fun ProfileUi( state: ProfileUiState, modifier: Modifier = Modifier, + eventLogger : NewmAppEventLogger ) { when (state) { ProfileUiState.Loading -> LoadingScreen() @@ -118,6 +120,7 @@ fun ProfileUi( ProfileUiContent( state = state, modifier = modifier, + eventLogger = eventLogger ) } } @@ -128,6 +131,7 @@ fun ProfileUi( private fun ProfileUiContent( state: ProfileUiState.Content, modifier: Modifier, + eventLogger: NewmAppEventLogger ) { val onEvent = state.eventSink val openWalletDialog: MutableState = remember { mutableStateOf(false) } @@ -139,6 +143,7 @@ private fun ProfileUiContent( ProfileBottomSheetLayout( modifier = modifier.fillMaxSize(), sheetState = sheetState, + eventLogger = eventLogger, onLogout = { onEvent(OnLogout) }, onShowTermsAndConditions = { onEvent(OnShowTermsAndConditions) }, onShowPrivacyPolicy = { onEvent(OnShowPrivacyPolicy) } @@ -169,10 +174,11 @@ private fun ProfileUiContent( WalletButton( openWalletDialog = openWalletDialog, isWalletConnected = state.isWalletConnected, + eventLogger = eventLogger, disconnectWallet = { onEvent(OnDisconnectWallet) } ) { newmWalletConnectionId -> onEvent(OnConnectWallet(newmWalletConnectionId)) } Spacer(Modifier.weight(1f)) - RecordStorePanel() + RecordStorePanel(eventLogger) Spacer(modifier = Modifier.height(16.dp)) } } @@ -180,7 +186,7 @@ private fun ProfileUiContent( } @Composable -fun RecordStorePanel() { +fun RecordStorePanel(eventLogger: NewmAppEventLogger) { val context = LocalContext.current Box( @@ -200,6 +206,8 @@ fun RecordStorePanel() { ProfileButton( labelResId = R.string.profile_visit_store, onClick = { + eventLogger.logPageLoad("Record Store") + eventLogger.logClickEvent("Visit the Record Store") context.startActivity( Intent( Intent.ACTION_VIEW, @@ -241,6 +249,7 @@ private fun ProfileButton( private fun WalletButton( openWalletDialog: MutableState, isWalletConnected: Boolean, + eventLogger: NewmAppEventLogger, disconnectWallet: () -> Unit, onConnectWalletClick: (String) -> Unit ) { @@ -280,6 +289,7 @@ private fun WalletButton( ConfirmationDialog( title = "Unlink Cardano Wallet", message = "Are you sure you want to disconnect your wallet?", + eventLogger = eventLogger, isOpen = openWalletDialog, onConfirm = { disconnectWallet() @@ -318,7 +328,8 @@ internal fun UserAccountScreenPreview( NewmTheme(darkTheme = true) { ProfileUi( state = state, - modifier = Modifier + modifier = Modifier, + eventLogger = NewmAppEventLogger() ) } } diff --git a/android/core/ui-utils/build.gradle.kts b/android/core/ui-utils/build.gradle.kts index 85129424..3f506ddf 100644 --- a/android/core/ui-utils/build.gradle.kts +++ b/android/core/ui-utils/build.gradle.kts @@ -32,4 +32,5 @@ dependencies { implementation(libs.androidx.material) implementation(libs.androidx.material.icons.extended) implementation(project(Modules.coreTheme)) + implementation(project(":shared")) } diff --git a/android/core/ui-utils/src/main/java/io/newm/core/ui/ConfirmationDialog.kt b/android/core/ui-utils/src/main/java/io/newm/core/ui/ConfirmationDialog.kt index 735bef3c..58eb7e3e 100644 --- a/android/core/ui-utils/src/main/java/io/newm/core/ui/ConfirmationDialog.kt +++ b/android/core/ui-utils/src/main/java/io/newm/core/ui/ConfirmationDialog.kt @@ -6,15 +6,18 @@ import androidx.compose.material.ButtonDefaults import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import io.newm.core.resources.R +import io.newm.shared.public.analytics.NewmAppEventLogger @Composable fun ConfirmationDialog( title: String, message: String, + eventLogger: NewmAppEventLogger, isOpen: MutableState, onConfirm: () -> Unit, onDismiss: () -> Unit, @@ -24,6 +27,9 @@ fun ConfirmationDialog( val confirmationText = stringResource(id = R.string.dialog_confirm) val cancelText = stringResource(id = R.string.dialog_cancel) if (isOpen.value) { + LaunchedEffect(Unit) { + eventLogger.logPageLoad("Logout Confirmation Dialog") + } AlertDialog( onDismissRequest = { // Update the isOpen state to false when the user clicks outside the dialog or presses the back button diff --git a/android/core/ui-utils/src/main/java/io/newm/core/ui/utils/ErrorScreen.kt b/android/core/ui-utils/src/main/java/io/newm/core/ui/utils/ErrorScreen.kt index cdb05faa..d420e5e8 100644 --- a/android/core/ui-utils/src/main/java/io/newm/core/ui/utils/ErrorScreen.kt +++ b/android/core/ui-utils/src/main/java/io/newm/core/ui/utils/ErrorScreen.kt @@ -3,13 +3,17 @@ package io.newm.core.ui.utils import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import io.newm.shared.public.analytics.NewmAppEventLogger @Composable -fun ErrorScreen(errorMessage: String) { +fun ErrorScreen( + errorMessage: String +) { Box( contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize() diff --git a/android/features/login/src/main/java/io/newm/feature/login/screen/createaccount/CreateAccountScreenPresenter.kt b/android/features/login/src/main/java/io/newm/feature/login/screen/createaccount/CreateAccountScreenPresenter.kt index 6f61b453..feca2571 100644 --- a/android/features/login/src/main/java/io/newm/feature/login/screen/createaccount/CreateAccountScreenPresenter.kt +++ b/android/features/login/src/main/java/io/newm/feature/login/screen/createaccount/CreateAccountScreenPresenter.kt @@ -50,7 +50,6 @@ class CreateAccountScreenPresenter( return when (step) { Step.EmailAndPassword -> { - eventLogger.logPageLoad("Create Account") EmailAndPasswordUiState( emailState = userEmail, passwordState = password, diff --git a/android/features/login/src/main/java/io/newm/feature/login/screen/resetpassword/ResetPasswordScreenPresenter.kt b/android/features/login/src/main/java/io/newm/feature/login/screen/resetpassword/ResetPasswordScreenPresenter.kt index 3848d95d..1b30ac1c 100644 --- a/android/features/login/src/main/java/io/newm/feature/login/screen/resetpassword/ResetPasswordScreenPresenter.kt +++ b/android/features/login/src/main/java/io/newm/feature/login/screen/resetpassword/ResetPasswordScreenPresenter.kt @@ -62,7 +62,6 @@ class ResetPasswordScreenPresenter( eventSink = { event -> when (event) { EnterEmailUiEvent.OnSubmit -> { - analyticsTracker.logPageLoad("Enter Email") analyticsTracker.logClickEvent("Continue") errorMessage = null isLoading = true @@ -102,7 +101,6 @@ class ResetPasswordScreenPresenter( } ResetPasswordStep.EnterVerificationCode -> { - analyticsTracker.logPageLoad("Enter Verification Code") ResetPasswordScreenUiState.EnterVerificationCode( code = authCode, errorMessage = errorMessage, @@ -120,7 +118,6 @@ class ResetPasswordScreenPresenter( } ResetPasswordStep.EnterNewPassword -> { - analyticsTracker.logPageLoad("Enter New Password") val submitEnabled = password.isValid && passwordConfirmation.isValid && !isLoading ResetPasswordScreenUiState.EnterNewPassword( diff --git a/android/features/login/src/main/java/io/newm/feature/login/screen/resetpassword/ResetPasswordScreenUi.kt b/android/features/login/src/main/java/io/newm/feature/login/screen/resetpassword/ResetPasswordScreenUi.kt index bfad05ea..26875413 100644 --- a/android/features/login/src/main/java/io/newm/feature/login/screen/resetpassword/ResetPasswordScreenUi.kt +++ b/android/features/login/src/main/java/io/newm/feature/login/screen/resetpassword/ResetPasswordScreenUi.kt @@ -13,6 +13,7 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi @@ -43,11 +44,12 @@ import io.newm.feature.login.screen.resetpassword.ResetPasswordScreenUiState.Ent import io.newm.feature.login.screen.resetpassword.ResetPasswordUiEvent.EnterEmailUiEvent import io.newm.feature.login.screen.resetpassword.ResetPasswordUiEvent.EnterNewPasswordUiEvent import io.newm.feature.login.screen.resetpassword.ResetPasswordUiEvent.EnterVerificationCodeUiEvent +import io.newm.shared.public.analytics.NewmAppEventLogger -class ResetPasswordScreenUi : Ui { +class ResetPasswordScreenUi(val eventLogger: NewmAppEventLogger) : Ui { @Composable override fun Content(state: ResetPasswordScreenUiState, modifier: Modifier) { - ResetPasswordScreenContent(modifier = modifier, state = state) + ResetPasswordScreenContent(modifier = modifier, state = state, eventLogger = eventLogger) } } @@ -55,14 +57,23 @@ class ResetPasswordScreenUi : Ui { internal fun ResetPasswordScreenContent( state: ResetPasswordScreenUiState, modifier: Modifier = Modifier, + eventLogger: NewmAppEventLogger ) { ToastSideEffect(message = state.errorMessage) Scaffold(modifier = modifier.fillMaxSize()) { padding -> when (state) { - is EnterEmail -> EnterEmailContent(state, modifier = Modifier.padding(padding)) - is EnterVerificationCode -> EnterCodeContent(state, modifier = Modifier.padding(padding)) - is EnterNewPassword -> SetNewPasswordContent(state, modifier = Modifier.padding(padding)) + is EnterEmail -> { + EnterEmailContent(state, modifier = Modifier.padding(padding), eventLogger) + } + + is EnterVerificationCode -> { + EnterCodeContent(state, modifier = Modifier.padding(padding), eventLogger) + } + + is EnterNewPassword -> { + SetNewPasswordContent(state, modifier = Modifier.padding(padding), eventLogger) + } } if (state.isLoading) { LinearProgressIndicator(modifier = Modifier.fillMaxWidth()) @@ -71,11 +82,18 @@ internal fun ResetPasswordScreenContent( } @Composable -private fun EnterEmailContent(state: EnterEmail, modifier: Modifier = Modifier) { +private fun EnterEmailContent( + state: EnterEmail, + modifier: Modifier = Modifier, + eventLogger: NewmAppEventLogger +) { val eventSink = state.eventSink val focusRequester = remember { FocusRequester() } val keyboardController = LocalSoftwareKeyboardController.current + LaunchedEffect(Unit) { + eventLogger.logPageLoad("Reset Password Enter Email") + } Column( modifier = modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally, @@ -120,9 +138,15 @@ private fun EnterEmailContent(state: EnterEmail, modifier: Modifier = Modifier) } @Composable -private fun EnterCodeContent(state: EnterVerificationCode, modifier: Modifier) { +private fun EnterCodeContent( + state: EnterVerificationCode, + modifier: Modifier, + eventLogger: NewmAppEventLogger +) { val eventSink = state.eventSink - + LaunchedEffect(Unit) { + eventLogger.logPageLoad("Reset Password Enter Code") + } EmailVerificationContent( modifier = modifier, verificationCode = state.code, @@ -132,13 +156,20 @@ private fun EnterCodeContent(state: EnterVerificationCode, modifier: Modifier) { ) } -@OptIn(ExperimentalComposeUiApi::class) @Composable -private fun SetNewPasswordContent(state: EnterNewPassword, modifier: Modifier = Modifier) { +private fun SetNewPasswordContent( + state: EnterNewPassword, + modifier: Modifier = Modifier, + eventLogger: NewmAppEventLogger +) { val onEvent = state.eventSink val focusRequester = remember { FocusRequester() } val keyboardController = LocalSoftwareKeyboardController.current + LaunchedEffect(Unit) { + eventLogger.logPageLoad("Reset Password Set New Password") + } + ToastSideEffect(message = state.errorMessage) Column( @@ -200,7 +231,8 @@ private fun PreviewEnterEmail() { isLoading = false, submitButtonEnabled = true, eventSink = {}, - ) + ), + eventLogger = NewmAppEventLogger() ) } } @@ -218,6 +250,7 @@ private fun PreviewVerificationCode() { submitButtonEnabled = true, eventSink = {}, ), + eventLogger = NewmAppEventLogger() ) } } @@ -235,7 +268,8 @@ private fun PreviewSetNewPassword() { isLoading = false, submitButtonEnabled = true, eventSink = {}, - ) + ), + eventLogger = NewmAppEventLogger() ) } } @@ -253,7 +287,8 @@ private fun PreviewLoading() { isLoading = true, submitButtonEnabled = true, eventSink = {}, - ) + ), + eventLogger = NewmAppEventLogger() ) } } diff --git a/android/features/login/src/main/java/io/newm/feature/login/screen/welcome/WelcomeScreenUi.kt b/android/features/login/src/main/java/io/newm/feature/login/screen/welcome/WelcomeScreenUi.kt index 737323c3..5a6c67dd 100644 --- a/android/features/login/src/main/java/io/newm/feature/login/screen/welcome/WelcomeScreenUi.kt +++ b/android/features/login/src/main/java/io/newm/feature/login/screen/welcome/WelcomeScreenUi.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.* import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -20,14 +21,20 @@ import io.newm.core.ui.buttons.SecondaryButton import io.newm.feature.login.screen.LoginPageMainImage import io.newm.feature.login.screen.welcome.WelcomeScreenUiEvent.CreateAccountClicked import io.newm.feature.login.screen.welcome.WelcomeScreenUiEvent.LoginClicked +import io.newm.shared.public.analytics.NewmAppEventLogger @Composable fun WelcomeScreenUi( modifier: Modifier = Modifier, - state: WelcomeScreenUiState + state: WelcomeScreenUiState, + eventLogger: NewmAppEventLogger ) { val onEvent = state.onEvent + LaunchedEffect(Unit) { + eventLogger.logPageLoad("Welcome Screen") + } + Box( modifier = modifier .fillMaxSize() @@ -82,7 +89,8 @@ fun WelcomeScreenUi( private fun DefaultLightWelcomePreview() { NewmTheme(darkTheme = false) { WelcomeScreenUi( - state = WelcomeScreenUiState(onEvent = {}) + state = WelcomeScreenUiState(onEvent = {}), + eventLogger = NewmAppEventLogger() ) } } @@ -92,7 +100,8 @@ private fun DefaultLightWelcomePreview() { private fun DefaultDarkWelcomePreview() { NewmTheme(darkTheme = true) { WelcomeScreenUi( - state = WelcomeScreenUiState(onEvent = {}) + state = WelcomeScreenUiState(onEvent = {}), + eventLogger = NewmAppEventLogger() ) } } diff --git a/android/features/login/src/test/kotlin/io/newm/feature/login/screen/ResetPasswordScreenTest.kt b/android/features/login/src/test/kotlin/io/newm/feature/login/screen/ResetPasswordScreenTest.kt index 7873076c..0c6bd2ae 100644 --- a/android/features/login/src/test/kotlin/io/newm/feature/login/screen/ResetPasswordScreenTest.kt +++ b/android/features/login/src/test/kotlin/io/newm/feature/login/screen/ResetPasswordScreenTest.kt @@ -9,6 +9,7 @@ import io.newm.feature.login.screen.resetpassword.ResetPasswordScreenContent import io.newm.feature.login.screen.resetpassword.ResetPasswordScreenUiState.EnterEmail import io.newm.feature.login.screen.resetpassword.ResetPasswordScreenUiState.EnterVerificationCode import io.newm.feature.login.screen.resetpassword.ResetPasswordScreenUiState.EnterNewPassword +import io.newm.shared.public.analytics.NewmAppEventLogger import org.junit.Test import org.junit.runner.RunWith @@ -27,7 +28,8 @@ class ResetPasswordScreenTest( isLoading = false, submitButtonEnabled = true, eventSink = {}, - ) + ), + eventLogger = NewmAppEventLogger() ) } } @@ -42,7 +44,8 @@ class ResetPasswordScreenTest( isLoading = false, submitButtonEnabled = true, eventSink = {}, - ) + ), + eventLogger = NewmAppEventLogger() ) } } @@ -58,7 +61,8 @@ class ResetPasswordScreenTest( isLoading = false, submitButtonEnabled = true, eventSink = {}, - ) + ), + eventLogger = NewmAppEventLogger() ) } }