Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import com.google.jetpackcamera.feature.postcapture.ui.PostCaptureLayout
import com.google.jetpackcamera.feature.postcapture.ui.SaveCurrentMediaButton
import com.google.jetpackcamera.feature.postcapture.ui.ShareCurrentMediaButton
import com.google.jetpackcamera.feature.postcapture.utils.MediaSharing
import com.google.jetpackcamera.ui.components.capture.SnackBarController
import com.google.jetpackcamera.ui.components.capture.TestableSnackbar
import com.google.jetpackcamera.ui.uistate.SnackBarUiState
import com.google.jetpackcamera.ui.uistate.postcapture.DeleteButtonUiState
Expand Down Expand Up @@ -73,8 +74,8 @@ fun PostCaptureScreen(
onSaveMedia = viewModel::saveCurrentMedia,
onShareCurrentMedia = viewModel::onShareCurrentMedia,
onLoadVideo = viewModel::loadCurrentVideo,
onSnackBarResult = viewModel::onSnackBarResult,
snackBarUiState = snackBarUiState
snackBarUiState = snackBarUiState,
snackBarController = viewModel.snackBarController
)
}

Expand All @@ -87,8 +88,8 @@ fun PostCaptureComponent(
onShareCurrentMedia: () -> Unit,
onDeleteMedia: (onSuccessCallback: () -> Unit) -> Unit,
onLoadVideo: () -> Unit,
onSnackBarResult: (String) -> Unit,
snackBarUiState: SnackBarUiState = SnackBarUiState.Disabled
snackBarUiState: SnackBarUiState = SnackBarUiState.Disabled,
snackBarController: SnackBarController? = null
) {
when (uiState) {
PostCaptureUiState.Loading -> {
Expand Down Expand Up @@ -139,12 +140,14 @@ fun PostCaptureComponent(
if (snackBarUiState is SnackBarUiState.Enabled) {
val snackBarData = snackBarUiState.snackBarQueue.peek()
if (snackBarData != null) {
TestableSnackbar(
modifier = modifier.testTag(snackBarData.testTag),
snackbarToShow = snackBarData,
snackbarHostState = snackbarHostState,
onSnackbarResult = onSnackBarResult
)
snackBarController?.let {
TestableSnackbar(
modifier = modifier.testTag(snackBarData.testTag),
snackbarToShow = snackBarData,
snackbarHostState = snackbarHostState,
snackBarController = snackBarController
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,18 @@ import com.google.jetpackcamera.feature.postcapture.ui.SNACKBAR_POST_CAPTURE_IMA
import com.google.jetpackcamera.feature.postcapture.ui.SNACKBAR_POST_CAPTURE_VIDEO_DELETE_FAILURE
import com.google.jetpackcamera.feature.postcapture.ui.SNACKBAR_POST_CAPTURE_VIDEO_SAVE_FAILURE
import com.google.jetpackcamera.feature.postcapture.ui.SNACKBAR_POST_CAPTURE_VIDEO_SAVE_SUCCESS
import com.google.jetpackcamera.ui.components.capture.SnackBarController
import com.google.jetpackcamera.ui.components.capture.SnackBarControllerImpl
import com.google.jetpackcamera.ui.uistate.SnackBarUiState
import com.google.jetpackcamera.ui.uistate.SnackbarData
import com.google.jetpackcamera.ui.uistate.postcapture.DeleteButtonUiState
import com.google.jetpackcamera.ui.uistate.postcapture.MediaViewerUiState
import com.google.jetpackcamera.ui.uistate.postcapture.PostCaptureUiState
import com.google.jetpackcamera.ui.uistate.postcapture.ShareButtonUiState
import com.google.jetpackcamera.ui.uistateadapter.from
import com.google.jetpackcamera.ui.uistateadapter.postcapture.from
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import java.util.LinkedList
import javax.inject.Inject
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.async
import kotlinx.coroutines.channels.Channel
Expand Down Expand Up @@ -111,8 +110,10 @@ class PostCaptureViewModel @Inject constructor(
MutableStateFlow(SnackBarUiState.Enabled())
val snackBarUiState: StateFlow<SnackBarUiState.Enabled> =
_snackBarUiState.asStateFlow()
private val snackBarCount = atomic(0)

val snackBarController: SnackBarController = SnackBarControllerImpl(
snackBarUiState = _snackBarUiState,
coroutineContext = viewModelScope.coroutineContext
)
private var player: ExoPlayer? = null

private val playerState = MutableStateFlow<PlayerState>(PlayerState.Unavailable)
Expand Down Expand Up @@ -302,7 +303,7 @@ class PostCaptureViewModel @Inject constructor(
*/

private suspend fun saveMedia(mediaDescriptor: MediaDescriptor.Content) {
val cookieInt = snackBarCount.incrementAndGet()
val cookieInt = snackBarController.incrementAndGetSnackBarCount()
val cookie = "MediaSave-$cookieInt"
val result: Uri?
try {
Expand All @@ -321,7 +322,7 @@ class PostCaptureViewModel @Inject constructor(
SNACKBAR_POST_CAPTURE_VIDEO_SAVE_SUCCESS
}

addSnackBarData(
snackBarController.addSnackBarData(
SnackbarData(
cookie = cookie,
stringResource = stringResource,
Expand All @@ -343,7 +344,7 @@ class PostCaptureViewModel @Inject constructor(
SNACKBAR_POST_CAPTURE_VIDEO_SAVE_FAILURE
}

addSnackBarData(
snackBarController.addSnackBarData(
SnackbarData(
cookie = cookie,
stringResource = stringResource,
Expand All @@ -364,7 +365,7 @@ class PostCaptureViewModel @Inject constructor(
SNACKBAR_POST_CAPTURE_VIDEO_SAVE_FAILURE
}

addSnackBarData(
snackBarController.addSnackBarData(
SnackbarData(
cookie = cookie,
stringResource = stringResource,
Expand All @@ -388,9 +389,9 @@ class PostCaptureViewModel @Inject constructor(
false
}
if (!result) {
val cookieInt = snackBarCount.incrementAndGet()
val cookieInt = snackBarController.incrementAndGetSnackBarCount()
val cookie = "MediaDelete-$cookieInt"
addSnackBarData(
snackBarController.addSnackBarData(
SnackbarData(
cookie = cookie,
stringResource = when (mediaDescriptor) {
Expand Down Expand Up @@ -426,39 +427,6 @@ class PostCaptureViewModel @Inject constructor(
}
}
}

// snackbar interaction
private fun addSnackBarData(snackBarData: SnackbarData) {
viewModelScope.launch {
_snackBarUiState.update { old ->
val newQueue = LinkedList(old.snackBarQueue)

newQueue.add(snackBarData)
Log.d(TAG, "SnackBar added. Queue size: ${newQueue.size}")
old.copy(
snackBarQueue = newQueue
)
}
}
}

fun onSnackBarResult(cookie: String) {
viewModelScope.launch {
_snackBarUiState.update { state ->
val newQueue = LinkedList(state.snackBarQueue)
val snackBarData = newQueue.poll()
if (snackBarData != null && snackBarData.cookie == cookie) {
// If the latest snackBar had a result, then clear snackBarToShow
Log.d(TAG, "SnackBar removed. Queue size: ${newQueue.size}")
state.copy(
snackBarQueue = newQueue
)
} else {
state
}
}
}
}
}

sealed interface PlayerState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ internal class PostCaptureViewModelTest {
val cookie = snackBarUiState.snackBarQueue.first().cookie

// When
viewModel.onSnackBarResult(cookie)
viewModel.snackBarController.onSnackBarResult(cookie)
advanceUntilIdle()

// Then
Expand All @@ -367,7 +367,7 @@ internal class PostCaptureViewModelTest {
advanceUntilIdle()

// When
viewModel.onSnackBarResult("incorrect_cookie")
viewModel.snackBarController.onSnackBarResult("incorrect_cookie")
advanceUntilIdle()

// Then
Expand All @@ -382,7 +382,7 @@ internal class PostCaptureViewModelTest {
assertThat(snackBarUiState.snackBarQueue).isEmpty()

// When
viewModel.onSnackBarResult("any_cookie")
viewModel.snackBarController.onSnackBarResult("any_cookie")
advanceUntilIdle()

// Then
Expand Down
Loading
Loading