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

[Woo POS] Play Cha-Ching sound on successful payment #13808

Draft
wants to merge 5 commits into
base: trunk
Choose a base branch
from
Draft
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
@@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -42,6 +43,9 @@ class WooPosHomeViewModel @Inject constructor(
private val _toastEvent = MutableSharedFlow<String>()
val toastEvent: SharedFlow<String> = _toastEvent

private val _playChaChingEvent = MutableSharedFlow<String>(replay = 1)
val playChaChingEvent: SharedFlow<String> = _playChaChingEvent

private val _navigationEvent = MutableSharedFlow<NavigationEvent>()
val navigationEvent: SharedFlow<NavigationEvent> = _navigationEvent

Expand Down Expand Up @@ -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()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<ChildToParentEvent>()
whenever(childrenToParentEventReceiver.events).thenReturn(events)
val viewModel = createViewModel()
val emittedValues = mutableListOf<String>()
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<String>()
val job = launch {
viewModel.playChaChingEvent.toList(emittedValues)
}

// THEN
advanceUntilIdle()
assertTrue(emittedValues.contains("Cha-Ching"))
job.cancel()
}

private fun createViewModel() = WooPosHomeViewModel(
childrenToParentEventReceiver,
parentToChildrenEventSender,
Expand Down