Rename Async to AsyncData
This commit is contained in:
parent
3b2882ce2f
commit
7b2341aec7
139 changed files with 745 additions and 745 deletions
|
|
@ -26,7 +26,7 @@ import kotlin.contracts.contract
|
|||
* Sealed type that allows to model an asynchronous operation.
|
||||
*/
|
||||
@Stable
|
||||
sealed interface Async<out T> {
|
||||
sealed interface AsyncData<out T> {
|
||||
|
||||
/**
|
||||
* Represents a failed operation.
|
||||
|
|
@ -38,7 +38,7 @@ sealed interface Async<out T> {
|
|||
data class Failure<out T>(
|
||||
val error: Throwable,
|
||||
val prevData: T? = null,
|
||||
) : Async<T>
|
||||
) : AsyncData<T>
|
||||
|
||||
/**
|
||||
* Represents an operation that is currently ongoing.
|
||||
|
|
@ -48,7 +48,7 @@ sealed interface Async<out T> {
|
|||
*/
|
||||
data class Loading<out T>(
|
||||
val prevData: T? = null,
|
||||
) : Async<T>
|
||||
) : AsyncData<T>
|
||||
|
||||
/**
|
||||
* Represents a successful operation.
|
||||
|
|
@ -58,12 +58,12 @@ sealed interface Async<out T> {
|
|||
*/
|
||||
data class Success<out T>(
|
||||
val data: T,
|
||||
) : Async<T>
|
||||
) : AsyncData<T>
|
||||
|
||||
/**
|
||||
* Represents an uninitialized operation (i.e. yet to be run).
|
||||
*/
|
||||
data object Uninitialized : Async<Nothing>
|
||||
data object Uninitialized : AsyncData<Nothing>
|
||||
|
||||
/**
|
||||
* Returns the data returned by the operation, or null otherwise.
|
||||
|
|
@ -94,7 +94,7 @@ sealed interface Async<out T> {
|
|||
fun isUninitialized(): Boolean = this == Uninitialized
|
||||
}
|
||||
|
||||
suspend inline fun <T> MutableState<Async<T>>.runCatchingUpdatingState(
|
||||
suspend inline fun <T> MutableState<AsyncData<T>>.runCatchingUpdatingState(
|
||||
errorTransform: (Throwable) -> Throwable = { it },
|
||||
block: () -> T,
|
||||
): Result<T> = runUpdatingState(
|
||||
|
|
@ -108,7 +108,7 @@ suspend inline fun <T> MutableState<Async<T>>.runCatchingUpdatingState(
|
|||
)
|
||||
|
||||
suspend inline fun <T> (suspend () -> T).runCatchingUpdatingState(
|
||||
state: MutableState<Async<T>>,
|
||||
state: MutableState<AsyncData<T>>,
|
||||
errorTransform: (Throwable) -> Throwable = { it },
|
||||
): Result<T> = runUpdatingState(
|
||||
state = state,
|
||||
|
|
@ -120,7 +120,7 @@ suspend inline fun <T> (suspend () -> T).runCatchingUpdatingState(
|
|||
},
|
||||
)
|
||||
|
||||
suspend inline fun <T> MutableState<Async<T>>.runUpdatingState(
|
||||
suspend inline fun <T> MutableState<AsyncData<T>>.runUpdatingState(
|
||||
errorTransform: (Throwable) -> Throwable = { it },
|
||||
resultBlock: () -> Result<T>,
|
||||
): Result<T> = runUpdatingState(
|
||||
|
|
@ -131,7 +131,7 @@ suspend inline fun <T> MutableState<Async<T>>.runUpdatingState(
|
|||
|
||||
/**
|
||||
* Calls the specified [Result]-returning function [resultBlock]
|
||||
* encapsulating its progress and return value into an [Async] while
|
||||
* encapsulating its progress and return value into an [AsyncData] while
|
||||
* posting its updates to the MutableState [state].
|
||||
*
|
||||
* @param T the type of data returned by the operation.
|
||||
|
|
@ -143,7 +143,7 @@ suspend inline fun <T> MutableState<Async<T>>.runUpdatingState(
|
|||
@OptIn(ExperimentalContracts::class)
|
||||
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
|
||||
suspend inline fun <T> runUpdatingState(
|
||||
state: MutableState<Async<T>>,
|
||||
state: MutableState<AsyncData<T>>,
|
||||
errorTransform: (Throwable) -> Throwable = { it },
|
||||
resultBlock: suspend () -> Result<T>,
|
||||
): Result<T> {
|
||||
|
|
@ -151,15 +151,15 @@ suspend inline fun <T> runUpdatingState(
|
|||
callsInPlace(resultBlock, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
val prevData = state.value.dataOrNull()
|
||||
state.value = Async.Loading(prevData = prevData)
|
||||
state.value = AsyncData.Loading(prevData = prevData)
|
||||
return resultBlock().fold(
|
||||
onSuccess = {
|
||||
state.value = Async.Success(it)
|
||||
state.value = AsyncData.Success(it)
|
||||
Result.success(it)
|
||||
},
|
||||
onFailure = {
|
||||
val error = errorTransform(it)
|
||||
state.value = Async.Failure(
|
||||
state.value = AsyncData.Failure(
|
||||
error = error,
|
||||
prevData = prevData,
|
||||
)
|
||||
|
|
@ -22,10 +22,10 @@ import kotlinx.coroutines.delay
|
|||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
class AsyncKtTest {
|
||||
class AsyncDataKtTest {
|
||||
@Test
|
||||
fun `updates state when block returns success`() = runTest {
|
||||
val state = TestableMutableState<Async<Int>>(Async.Uninitialized)
|
||||
val state = TestableMutableState<AsyncData<Int>>(AsyncData.Uninitialized)
|
||||
|
||||
val result = runUpdatingState(state) {
|
||||
delay(1)
|
||||
|
|
@ -35,15 +35,15 @@ class AsyncKtTest {
|
|||
assertThat(result.isSuccess).isTrue()
|
||||
assertThat(result.getOrNull()).isEqualTo(1)
|
||||
|
||||
assertThat(state.popFirst()).isEqualTo(Async.Uninitialized)
|
||||
assertThat(state.popFirst()).isEqualTo(Async.Loading(null))
|
||||
assertThat(state.popFirst()).isEqualTo(Async.Success(1))
|
||||
assertThat(state.popFirst()).isEqualTo(AsyncData.Uninitialized)
|
||||
assertThat(state.popFirst()).isEqualTo(AsyncData.Loading(null))
|
||||
assertThat(state.popFirst()).isEqualTo(AsyncData.Success(1))
|
||||
state.assertNoMoreValues()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `updates state when block returns failure`() = runTest {
|
||||
val state = TestableMutableState<Async<Int>>(Async.Uninitialized)
|
||||
val state = TestableMutableState<AsyncData<Int>>(AsyncData.Uninitialized)
|
||||
|
||||
val result = runUpdatingState(state) {
|
||||
delay(1)
|
||||
|
|
@ -53,15 +53,15 @@ class AsyncKtTest {
|
|||
assertThat(result.isFailure).isTrue()
|
||||
assertThat(result.exceptionOrNull()).isEqualTo(MyThrowable("hello"))
|
||||
|
||||
assertThat(state.popFirst()).isEqualTo(Async.Uninitialized)
|
||||
assertThat(state.popFirst()).isEqualTo(Async.Loading(null))
|
||||
assertThat(state.popFirst()).isEqualTo(Async.Failure<Int>(MyThrowable("hello")))
|
||||
assertThat(state.popFirst()).isEqualTo(AsyncData.Uninitialized)
|
||||
assertThat(state.popFirst()).isEqualTo(AsyncData.Loading(null))
|
||||
assertThat(state.popFirst()).isEqualTo(AsyncData.Failure<Int>(MyThrowable("hello")))
|
||||
state.assertNoMoreValues()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `updates state when block returns failure transforming the error`() = runTest {
|
||||
val state = TestableMutableState<Async<Int>>(Async.Uninitialized)
|
||||
val state = TestableMutableState<AsyncData<Int>>(AsyncData.Uninitialized)
|
||||
|
||||
val result = runUpdatingState(state, { MyThrowable(it.message + " world") }) {
|
||||
delay(1)
|
||||
|
|
@ -71,9 +71,9 @@ class AsyncKtTest {
|
|||
assertThat(result.isFailure).isTrue()
|
||||
assertThat(result.exceptionOrNull()).isEqualTo(MyThrowable("hello world"))
|
||||
|
||||
assertThat(state.popFirst()).isEqualTo(Async.Uninitialized)
|
||||
assertThat(state.popFirst()).isEqualTo(Async.Loading(null))
|
||||
assertThat(state.popFirst()).isEqualTo(Async.Failure<Int>(MyThrowable("hello world")))
|
||||
assertThat(state.popFirst()).isEqualTo(AsyncData.Uninitialized)
|
||||
assertThat(state.popFirst()).isEqualTo(AsyncData.Loading(null))
|
||||
assertThat(state.popFirst()).isEqualTo(AsyncData.Failure<Int>(MyThrowable("hello world")))
|
||||
state.assertNoMoreValues()
|
||||
}
|
||||
}
|
||||
|
|
@ -17,14 +17,14 @@
|
|||
package io.element.android.libraries.designsystem.components.async
|
||||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
|
||||
open class AsyncProvider : PreviewParameterProvider<Async<Unit>> {
|
||||
override val values: Sequence<Async<Unit>>
|
||||
open class AsyncProvider : PreviewParameterProvider<AsyncData<Unit>> {
|
||||
override val values: Sequence<AsyncData<Unit>>
|
||||
get() = sequenceOf(
|
||||
Async.Uninitialized,
|
||||
Async.Loading(),
|
||||
Async.Failure(Exception("An error occurred")),
|
||||
Async.Success(Unit),
|
||||
AsyncData.Uninitialized,
|
||||
AsyncData.Loading(),
|
||||
AsyncData.Failure(Exception("An error occurred")),
|
||||
AsyncData.Success(Unit),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ package io.element.android.libraries.designsystem.components.async
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.designsystem.components.ProgressDialog
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialogDefaults
|
||||
|
|
@ -36,7 +36,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
|||
*/
|
||||
@Composable
|
||||
fun <T> AsyncView(
|
||||
async: Async<T>,
|
||||
async: AsyncData<T>,
|
||||
onSuccess: (T) -> Unit,
|
||||
onErrorDismiss: () -> Unit,
|
||||
showProgressDialog: Boolean = true,
|
||||
|
|
@ -62,7 +62,7 @@ fun <T> AsyncView(
|
|||
|
||||
@Composable
|
||||
fun <T> AsyncView(
|
||||
async: Async<T>,
|
||||
async: AsyncData<T>,
|
||||
onSuccess: (T) -> Unit,
|
||||
onErrorDismiss: () -> Unit,
|
||||
progressDialog: @Composable () -> Unit = { AsyncViewDefaults.ProgressDialog() },
|
||||
|
|
@ -71,9 +71,9 @@ fun <T> AsyncView(
|
|||
onRetry: (() -> Unit)? = null,
|
||||
) {
|
||||
when (async) {
|
||||
Async.Uninitialized -> Unit
|
||||
is Async.Loading -> progressDialog()
|
||||
is Async.Failure -> {
|
||||
AsyncData.Uninitialized -> Unit
|
||||
is AsyncData.Loading -> progressDialog()
|
||||
is AsyncData.Failure -> {
|
||||
if (onRetry == null) {
|
||||
ErrorDialog(
|
||||
title = errorTitle(async.error),
|
||||
|
|
@ -89,7 +89,7 @@ fun <T> AsyncView(
|
|||
)
|
||||
}
|
||||
}
|
||||
is Async.Success -> {
|
||||
is AsyncData.Success -> {
|
||||
LaunchedEffect(async) {
|
||||
onSuccess(async.data)
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ object AsyncViewDefaults {
|
|||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun AsyncViewPreview(
|
||||
@PreviewParameter(AsyncProvider::class) async: Async<Unit>,
|
||||
@PreviewParameter(AsyncProvider::class) async: AsyncData<Unit>,
|
||||
) = ElementPreview {
|
||||
AsyncView(
|
||||
async = async,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import androidx.compose.runtime.setValue
|
|||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
||||
|
|
@ -64,8 +64,8 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
val mediaFile: MutableState<MediaFile?> = remember {
|
||||
mutableStateOf(null)
|
||||
}
|
||||
val localMedia: MutableState<Async<LocalMedia>> = remember {
|
||||
mutableStateOf(Async.Uninitialized)
|
||||
val localMedia: MutableState<AsyncData<LocalMedia>> = remember {
|
||||
mutableStateOf(AsyncData.Uninitialized)
|
||||
}
|
||||
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
|
||||
localMediaActions.Configure()
|
||||
|
|
@ -79,7 +79,7 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
fun handleEvents(mediaViewerEvents: MediaViewerEvents) {
|
||||
when (mediaViewerEvents) {
|
||||
MediaViewerEvents.RetryLoading -> loadMediaTrigger++
|
||||
MediaViewerEvents.ClearLoadingError -> localMedia.value = Async.Uninitialized
|
||||
MediaViewerEvents.ClearLoadingError -> localMedia.value = AsyncData.Uninitialized
|
||||
MediaViewerEvents.SaveOnDisk -> coroutineScope.saveOnDisk(localMedia.value)
|
||||
MediaViewerEvents.Share -> coroutineScope.share(localMedia.value)
|
||||
MediaViewerEvents.OpenWith -> coroutineScope.open(localMedia.value)
|
||||
|
|
@ -97,8 +97,8 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun CoroutineScope.downloadMedia(mediaFile: MutableState<MediaFile?>, localMedia: MutableState<Async<LocalMedia>>) = launch {
|
||||
localMedia.value = Async.Loading()
|
||||
private fun CoroutineScope.downloadMedia(mediaFile: MutableState<MediaFile?>, localMedia: MutableState<AsyncData<LocalMedia>>) = launch {
|
||||
localMedia.value = AsyncData.Loading()
|
||||
mediaLoader.downloadMediaFile(
|
||||
source = inputs.mediaSource,
|
||||
mimeType = inputs.mediaInfo.mimeType,
|
||||
|
|
@ -114,15 +114,15 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
.onSuccess {
|
||||
localMedia.value = Async.Success(it)
|
||||
localMedia.value = AsyncData.Success(it)
|
||||
}
|
||||
.onFailure {
|
||||
localMedia.value = Async.Failure(it)
|
||||
localMedia.value = AsyncData.Failure(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CoroutineScope.saveOnDisk(localMedia: Async<LocalMedia>) = launch {
|
||||
if (localMedia is Async.Success) {
|
||||
private fun CoroutineScope.saveOnDisk(localMedia: AsyncData<LocalMedia>) = launch {
|
||||
if (localMedia is AsyncData.Success) {
|
||||
localMediaActions.saveOnDisk(localMedia.data)
|
||||
.onSuccess {
|
||||
val snackbarMessage = SnackbarMessage(CommonStrings.common_file_saved_on_disk_android)
|
||||
|
|
@ -135,8 +135,8 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
} else Unit
|
||||
}
|
||||
|
||||
private fun CoroutineScope.share(localMedia: Async<LocalMedia>) = launch {
|
||||
if (localMedia is Async.Success) {
|
||||
private fun CoroutineScope.share(localMedia: AsyncData<LocalMedia>) = launch {
|
||||
if (localMedia is AsyncData.Success) {
|
||||
localMediaActions.share(localMedia.data)
|
||||
.onFailure {
|
||||
val snackbarMessage = SnackbarMessage(mediaActionsError(it))
|
||||
|
|
@ -145,8 +145,8 @@ class MediaViewerPresenter @AssistedInject constructor(
|
|||
} else Unit
|
||||
}
|
||||
|
||||
private fun CoroutineScope.open(localMedia: Async<LocalMedia>) = launch {
|
||||
if (localMedia is Async.Success) {
|
||||
private fun CoroutineScope.open(localMedia: AsyncData<LocalMedia>) = launch {
|
||||
if (localMedia is AsyncData.Success) {
|
||||
localMediaActions.open(localMedia.data)
|
||||
.onFailure {
|
||||
val snackbarMessage = SnackbarMessage(mediaActionsError(it))
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
package io.element.android.libraries.mediaviewer.api.viewer
|
||||
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
|
||||
import io.element.android.libraries.matrix.api.media.MediaSource
|
||||
import io.element.android.libraries.mediaviewer.api.local.LocalMedia
|
||||
|
|
@ -25,7 +25,7 @@ import io.element.android.libraries.mediaviewer.api.local.MediaInfo
|
|||
data class MediaViewerState(
|
||||
val mediaInfo: MediaInfo,
|
||||
val thumbnailSource: MediaSource?,
|
||||
val downloadedMedia: Async<LocalMedia>,
|
||||
val downloadedMedia: AsyncData<LocalMedia>,
|
||||
val snackbarMessage: SnackbarMessage?,
|
||||
val canDownload: Boolean,
|
||||
val canShare: Boolean,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package io.element.android.libraries.mediaviewer.api.viewer
|
|||
|
||||
import android.net.Uri
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.mediaviewer.api.local.LocalMedia
|
||||
import io.element.android.libraries.mediaviewer.api.local.MediaInfo
|
||||
import io.element.android.libraries.mediaviewer.api.local.aFileInfo
|
||||
|
|
@ -31,48 +31,48 @@ open class MediaViewerStateProvider : PreviewParameterProvider<MediaViewerState>
|
|||
override val values: Sequence<MediaViewerState>
|
||||
get() = sequenceOf(
|
||||
aMediaViewerState(),
|
||||
aMediaViewerState(Async.Loading()),
|
||||
aMediaViewerState(Async.Failure(IllegalStateException("error"))),
|
||||
aMediaViewerState(AsyncData.Loading()),
|
||||
aMediaViewerState(AsyncData.Failure(IllegalStateException("error"))),
|
||||
aMediaViewerState(
|
||||
Async.Success(
|
||||
AsyncData.Success(
|
||||
LocalMedia(Uri.EMPTY, anImageInfo())
|
||||
),
|
||||
anImageInfo(),
|
||||
),
|
||||
aMediaViewerState(
|
||||
Async.Success(
|
||||
AsyncData.Success(
|
||||
LocalMedia(Uri.EMPTY, aVideoInfo())
|
||||
),
|
||||
aVideoInfo(),
|
||||
),
|
||||
aMediaViewerState(
|
||||
Async.Success(
|
||||
AsyncData.Success(
|
||||
LocalMedia(Uri.EMPTY, aPdfInfo())
|
||||
),
|
||||
aPdfInfo(),
|
||||
),
|
||||
aMediaViewerState(
|
||||
Async.Loading(),
|
||||
AsyncData.Loading(),
|
||||
aFileInfo(),
|
||||
),
|
||||
aMediaViewerState(
|
||||
Async.Success(
|
||||
AsyncData.Success(
|
||||
LocalMedia(Uri.EMPTY, aFileInfo())
|
||||
),
|
||||
aFileInfo(),
|
||||
),
|
||||
aMediaViewerState(
|
||||
Async.Loading(),
|
||||
AsyncData.Loading(),
|
||||
anAudioInfo(),
|
||||
),
|
||||
aMediaViewerState(
|
||||
Async.Success(
|
||||
AsyncData.Success(
|
||||
LocalMedia(Uri.EMPTY, anAudioInfo())
|
||||
),
|
||||
anAudioInfo(),
|
||||
),
|
||||
aMediaViewerState(
|
||||
Async.Success(
|
||||
AsyncData.Success(
|
||||
LocalMedia(Uri.EMPTY, anImageInfo())
|
||||
),
|
||||
anImageInfo(),
|
||||
|
|
@ -83,7 +83,7 @@ open class MediaViewerStateProvider : PreviewParameterProvider<MediaViewerState>
|
|||
}
|
||||
|
||||
fun aMediaViewerState(
|
||||
downloadedMedia: Async<LocalMedia> = Async.Uninitialized,
|
||||
downloadedMedia: AsyncData<LocalMedia> = AsyncData.Uninitialized,
|
||||
mediaInfo: MediaInfo = anImageInfo(),
|
||||
canDownload: Boolean = true,
|
||||
canShare: Boolean = true,
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.AsyncImage
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||
import io.element.android.libraries.designsystem.components.button.BackButton
|
||||
import io.element.android.libraries.designsystem.components.dialogs.RetryDialog
|
||||
|
|
@ -93,7 +93,7 @@ fun MediaViewerView(
|
|||
modifier,
|
||||
topBar = {
|
||||
MediaViewerTopBar(
|
||||
actionsEnabled = state.downloadedMedia is Async.Success,
|
||||
actionsEnabled = state.downloadedMedia is AsyncData.Success,
|
||||
mimeType = state.mediaInfo.mimeType,
|
||||
onBackPressed = onBackPressed,
|
||||
canDownload = state.canDownload,
|
||||
|
|
@ -121,7 +121,7 @@ fun MediaViewerView(
|
|||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
if (state.downloadedMedia is Async.Failure) {
|
||||
if (state.downloadedMedia is AsyncData.Failure) {
|
||||
ErrorView(
|
||||
errorMessage = stringResource(id = CommonStrings.error_unknown),
|
||||
onRetry = ::onRetry,
|
||||
|
|
@ -144,7 +144,7 @@ fun MediaViewerView(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberShowProgress(downloadedMedia: Async<LocalMedia>): Boolean {
|
||||
private fun rememberShowProgress(downloadedMedia: AsyncData<LocalMedia>): Boolean {
|
||||
var showProgress by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import app.cash.molecule.RecompositionMode
|
|||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||
import io.element.android.libraries.matrix.test.media.FakeMediaLoader
|
||||
import io.element.android.libraries.matrix.test.media.aMediaSource
|
||||
|
|
@ -60,13 +60,13 @@ class MediaViewerPresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
var state = awaitItem()
|
||||
assertThat(state.downloadedMedia).isEqualTo(Async.Uninitialized)
|
||||
assertThat(state.downloadedMedia).isEqualTo(AsyncData.Uninitialized)
|
||||
assertThat(state.mediaInfo).isEqualTo(TESTED_MEDIA_INFO)
|
||||
state = awaitItem()
|
||||
assertThat(state.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
||||
assertThat(state.downloadedMedia).isInstanceOf(AsyncData.Loading::class.java)
|
||||
state = awaitItem()
|
||||
val successData = state.downloadedMedia.dataOrNull()
|
||||
assertThat(state.downloadedMedia).isInstanceOf(Async.Success::class.java)
|
||||
assertThat(state.downloadedMedia).isInstanceOf(AsyncData.Success::class.java)
|
||||
assertThat(successData).isNotNull()
|
||||
}
|
||||
}
|
||||
|
|
@ -81,15 +81,15 @@ class MediaViewerPresenterTest {
|
|||
presenter.present()
|
||||
}.test {
|
||||
var state = awaitItem()
|
||||
assertThat(state.downloadedMedia).isEqualTo(Async.Uninitialized)
|
||||
assertThat(state.downloadedMedia).isEqualTo(AsyncData.Uninitialized)
|
||||
state = awaitItem()
|
||||
assertThat(state.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
||||
assertThat(state.downloadedMedia).isInstanceOf(AsyncData.Loading::class.java)
|
||||
// no state changes while media is loading
|
||||
state.eventSink(MediaViewerEvents.OpenWith)
|
||||
state.eventSink(MediaViewerEvents.Share)
|
||||
state.eventSink(MediaViewerEvents.SaveOnDisk)
|
||||
state = awaitItem()
|
||||
assertThat(state.downloadedMedia).isInstanceOf(Async.Success::class.java)
|
||||
assertThat(state.downloadedMedia).isInstanceOf(AsyncData.Success::class.java)
|
||||
// Should succeed without change of state
|
||||
state.eventSink(MediaViewerEvents.OpenWith)
|
||||
// Should succeed without change of state
|
||||
|
|
@ -128,21 +128,21 @@ class MediaViewerPresenterTest {
|
|||
}.test {
|
||||
mediaLoader.shouldFail = true
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.downloadedMedia).isEqualTo(Async.Uninitialized)
|
||||
assertThat(initialState.downloadedMedia).isEqualTo(AsyncData.Uninitialized)
|
||||
assertThat(initialState.mediaInfo).isEqualTo(TESTED_MEDIA_INFO)
|
||||
val loadingState = awaitItem()
|
||||
assertThat(loadingState.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
||||
assertThat(loadingState.downloadedMedia).isInstanceOf(AsyncData.Loading::class.java)
|
||||
val failureState = awaitItem()
|
||||
assertThat(failureState.downloadedMedia).isInstanceOf(Async.Failure::class.java)
|
||||
assertThat(failureState.downloadedMedia).isInstanceOf(AsyncData.Failure::class.java)
|
||||
mediaLoader.shouldFail = false
|
||||
failureState.eventSink(MediaViewerEvents.RetryLoading)
|
||||
//There is one recomposition because of the retry mechanism
|
||||
skipItems(1)
|
||||
val retryLoadingState = awaitItem()
|
||||
assertThat(retryLoadingState.downloadedMedia).isInstanceOf(Async.Loading::class.java)
|
||||
assertThat(retryLoadingState.downloadedMedia).isInstanceOf(AsyncData.Loading::class.java)
|
||||
val successState = awaitItem()
|
||||
val successData = successState.downloadedMedia.dataOrNull()
|
||||
assertThat(successState.downloadedMedia).isInstanceOf(Async.Success::class.java)
|
||||
assertThat(successState.downloadedMedia).isInstanceOf(AsyncData.Success::class.java)
|
||||
assertThat(successData).isNotNull()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue