From 7b795477789b572c63a205139624792982e18ebe Mon Sep 17 00:00:00 2001 From: AnirudhBhat Date: Wed, 19 Mar 2025 08:19:34 +0530 Subject: [PATCH 1/5] Add logic to play Cha-Ching sound on successful payment (Card and Cash) --- .../android/ui/woopos/home/WooPosHomeViewModel.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt index 80118d44f45..68abca2149b 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt @@ -3,6 +3,7 @@ package com.woocommerce.android.ui.woopos.home import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.woocommerce.android.AppPrefsWrapper import com.woocommerce.android.ui.woopos.home.ChildToParentEvent.NavigationEvent import com.woocommerce.android.ui.woopos.home.ParentToChildrenEvent.OrderSuccessfullyPaid.PaymentMethod import com.woocommerce.android.ui.woopos.home.WooPosHomeState.ExitConfirmationDialog @@ -14,6 +15,7 @@ import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsEvent.Eve import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsTracker import com.woocommerce.android.viewmodel.getStateFlow import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow @@ -42,6 +44,9 @@ class WooPosHomeViewModel @Inject constructor( private val _toastEvent = MutableSharedFlow() val toastEvent: SharedFlow = _toastEvent + private val _playChaChingEvent = MutableSharedFlow(replay = 1) + val playChaChingEvent: SharedFlow = _playChaChingEvent + private val _navigationEvent = MutableSharedFlow() val navigationEvent: SharedFlow = _navigationEvent @@ -214,10 +219,18 @@ class WooPosHomeViewModel @Inject constructor( wooPosItemsNavigator.sendNavigationEvent( WooPosItemsNavigator.WooPosItemsScreenNavigationEvent.NavigateBackToItemListScreen ) + _playChaChingEvent.emit("Cha-Ching") } _state.value = _state.value.copy( screenPositionState = ScreenPositionState.Checkout.FullScreenTotals ) sendEventToChildren(ParentToChildrenEvent.OrderSuccessfullyPaid(paymentMethod)) } + + @OptIn(ExperimentalCoroutinesApi::class) + fun clearChaChingEvent() { + viewModelScope.launch { + _playChaChingEvent.resetReplayCache() + } + } } From f838f9b8c5e49b117b80d11389ad153b13740418 Mon Sep 17 00:00:00 2001 From: AnirudhBhat Date: Wed, 19 Mar 2025 08:19:54 +0530 Subject: [PATCH 2/5] Add logic to play Cha-Ching sound on successful payment (Card and Cash) in WooPosHomeScreen --- .../ui/woopos/home/WooPosHomeScreen.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeScreen.kt index 99757707544..a1fd1e2ed78 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeScreen.kt @@ -1,5 +1,9 @@ package com.woocommerce.android.ui.woopos.home +import android.content.ContentResolver +import android.content.Context +import android.media.MediaPlayer +import android.net.Uri import androidx.activity.compose.BackHandler import androidx.compose.animation.core.animateDpAsState import androidx.compose.animation.core.spring @@ -26,6 +30,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import com.woocommerce.android.R import com.woocommerce.android.ui.woopos.common.composeui.WooPosPreview import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosExitConfirmationDialog import com.woocommerce.android.ui.woopos.common.composeui.designsystem.WooPosSpacing @@ -41,6 +46,7 @@ import com.woocommerce.android.ui.woopos.home.toolbar.PreviewWooPosFloatingToolb import com.woocommerce.android.ui.woopos.home.toolbar.WooPosFloatingToolbar import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsScreen import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsScreenPreview +import kotlinx.coroutines.flow.collectLatest import org.wordpress.android.util.ToastUtils @Composable @@ -67,12 +73,29 @@ fun WooPosHomeScreen( } } + LaunchedEffect(Unit) { + viewModel.playChaChingEvent.collectLatest { + playChaChingSound(context) + viewModel.clearChaChingEvent() + } + } + WooPosHomeScreen( state = state, onHomeUIEvent = { viewModel.onUIEvent(it) }, ) } +fun playChaChingSound(context: Context) { + val chaChingUri = + Uri.parse( + ContentResolver.SCHEME_ANDROID_RESOURCE + + "://" + context.packageName + "/" + R.raw.cha_ching + ) + val mp = MediaPlayer.create(context, chaChingUri) + mp.start() +} + @Composable private fun WooPosHomeScreen( state: WooPosHomeState, From 6964f3864d880081ce75f71b5611c37ebed3edd2 Mon Sep 17 00:00:00 2001 From: AnirudhBhat Date: Wed, 19 Mar 2025 08:39:40 +0530 Subject: [PATCH 3/5] Add test to verify cha ching event is emitted when cash payment is complete --- .../ui/woopos/home/WooPosHomeViewModelTest.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt index 6aa5e55b0c1..4cac01c30f8 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt @@ -15,6 +15,9 @@ import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsTracker import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat import org.junit.Rule @@ -454,6 +457,26 @@ class WooPosHomeViewModelTest { analyticsTracker.track(BackToCartTapped) } + @Test + fun `given state is Checkout, when OnPaymentCompletedViaCash event passed, then cha ching event is emitted`() = runTest { + // GIVEN + val events = MutableSharedFlow() + whenever(childrenToParentEventReceiver.events).thenReturn(events) + val viewModel = createViewModel() + val emittedValues = mutableListOf() + val job = launch { + viewModel.playChaChingEvent.toList(emittedValues) + } + + // WHEN + viewModel.onUIEvent(WooPosHomeUIEvent.OnPaymentCompletedViaCash) + + // THEN + advanceUntilIdle() + assertTrue(emittedValues.contains("Cha-Ching")) + job.cancel() + } + private fun createViewModel() = WooPosHomeViewModel( childrenToParentEventReceiver, parentToChildrenEventSender, From b9432ce7e79764ea3341883226cf91fb4617a336 Mon Sep 17 00:00:00 2001 From: AnirudhBhat Date: Wed, 19 Mar 2025 08:42:35 +0530 Subject: [PATCH 4/5] Add test to verify cha ching event is emitted when card payment is complete --- .../ui/woopos/home/WooPosHomeViewModelTest.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt index 4cac01c30f8..1d08c4416b2 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModelTest.kt @@ -477,6 +477,24 @@ class WooPosHomeViewModelTest { job.cancel() } + @Test + fun `given state is Checkout, when OrderSuccessfullyPaidByCard event passed, then cha ching event is emitted`() = runTest { + // GIVEN + whenever(childrenToParentEventReceiver.events).thenReturn( + flowOf(ChildToParentEvent.OrderSuccessfullyPaidByCard) + ) + val viewModel = createViewModel() + val emittedValues = mutableListOf() + val job = launch { + viewModel.playChaChingEvent.toList(emittedValues) + } + + // THEN + advanceUntilIdle() + assertTrue(emittedValues.contains("Cha-Ching")) + job.cancel() + } + private fun createViewModel() = WooPosHomeViewModel( childrenToParentEventReceiver, parentToChildrenEventSender, From 188eb4e8e1acb7a0d6bdc30f2c22c8cbb88f2b49 Mon Sep 17 00:00:00 2001 From: AnirudhBhat Date: Wed, 19 Mar 2025 08:43:21 +0530 Subject: [PATCH 5/5] Remove unused imports --- .../woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt index 68abca2149b..6c49d3fd077 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/WooPosHomeViewModel.kt @@ -3,7 +3,6 @@ package com.woocommerce.android.ui.woopos.home import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.woocommerce.android.AppPrefsWrapper import com.woocommerce.android.ui.woopos.home.ChildToParentEvent.NavigationEvent import com.woocommerce.android.ui.woopos.home.ParentToChildrenEvent.OrderSuccessfullyPaid.PaymentMethod import com.woocommerce.android.ui.woopos.home.WooPosHomeState.ExitConfirmationDialog