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, 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..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 @@ -14,6 +14,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 +43,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 +218,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() + } + } } 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..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 @@ -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,44 @@ 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() + } + + @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,