Async API improvements "v2" (#672)

* Async API improvements "v2"

**NB: This PR actually changes only 3 files in `libraries/architecture/`. All the other changes are automated refactors to fix the calling code.**

This is a proposal for improvements to our `Async` type as discussed in: https://github.com/vector-im/element-x-android/pull/598/files#r1230664392 and in other chats.

Please bear in mind it is just a proposal, I'd love to hear your feedback about it, especially when it comes to naming: I've tried to make parameter and function names use a terminology similar to what we find in the Kotlin stdlib and its `Result` type.

I'm inclined to like more the non-extension flavours of the new `run*` APIs, though I'd also like your feedback about what API shape you prefer.

### Summary of the changes:
#### Functional
- Adds `exceptionOrNull()` API to complement the existing `dataOrNull()` API.
- Adds `isFailure()`, `isLoading()`, `isSuccess()` and `isUninitialized()` courtesy APIs.
- Renames `executeResult()` to `runUpdatingState()`:
	- Becomes the base API to which all the other similarly named APIs call into.
	- Makes it inline.
	- Adds contract.
	- Passes over any `prevData` to newre Async states.
	- Passes through the `block`s return value.
	- Adds unit tests.
- Renames `execute` to `runCatchingUpdatingState()` and makes it just call into `runUpdatingState()`
- Adds extension function overloads to the `run*` functions to accept `MutableState` as receiver

#### Cosmetics
- Reorders classes and methods in alphabetic order.
- Reorder parameter names to mimic conventions in Kotlin stdlib.
- Adds docstrings where useful.

* Use `fold()`

* rename pop to popFirst

* Add docstrings

* Please Detekt

* Rename exception to error.

* Please detekt

* Update existing usages.
This commit is contained in:
Marco Romano 2023-06-27 13:37:23 +02:00 committed by GitHub
parent 01ea66e60e
commit 316d57d1b6
25 changed files with 286 additions and 75 deletions

View file

@ -30,7 +30,7 @@ import io.element.android.features.createroom.impl.CreateRoomConfig
import io.element.android.features.createroom.impl.CreateRoomDataStore
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.execute
import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.core.mimetype.MimeTypes
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
@ -131,7 +131,7 @@ class ConfigureRoomPresenter @Inject constructor(
dataStore.clearCachedData()
analyticsService.capture(CreatedRoom(isDM = false))
}
}.execute(createRoomAction)
}.runCatchingUpdatingState(createRoomAction)
}
private suspend fun uploadAvatar(avatarUri: Uri): String {

View file

@ -84,7 +84,7 @@ fun ConfigureRoomView(
if (state.createRoomAction is Async.Success) {
LaunchedEffect(state.createRoomAction) {
onRoomCreated(state.createRoomAction.state)
onRoomCreated(state.createRoomAction.data)
}
}

View file

@ -28,7 +28,7 @@ import io.element.android.features.createroom.impl.userlist.UserListPresenter
import io.element.android.features.createroom.impl.userlist.UserListPresenterArgs
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.architecture.execute
import io.element.android.libraries.architecture.runCatchingUpdatingState
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId
@ -95,6 +95,6 @@ class CreateRoomRootPresenter @Inject constructor(
suspend {
matrixClient.createDM(user.userId).getOrThrow()
.also { analyticsService.capture(CreatedRoom(isDM = true)) }
}.execute(startDmAction)
}.runCatchingUpdatingState(startDmAction)
}
}

View file

@ -69,7 +69,7 @@ fun CreateRoomRootView(
) {
if (state.startDmAction is Async.Success) {
LaunchedEffect(state.startDmAction) {
onOpenDM(state.startDmAction.state)
onOpenDM(state.startDmAction.data)
}
}