Introduce AsyncAction with a Confirmation state and use it for logout action

<!-- Please read [CONTRIBUTING.md](https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md) before submitting your pull request -->

## Type of change

- [ ] Feature
- [x] Bugfix
- [ ] Technical
- [ ] Other :

## Content

<!-- Describe shortly what has been changed -->
Add `AsyncAction` similar to `Async` but to be used for action triggered by the user.
It also contain an `Confirming` class, which can optionally by used.

## Motivation and context

<!-- Provide link to the corresponding issue if applicable or explain the context -->

Attempt to fix #2165, by updating the state only once when a confirmation is needed from the user.

## Screenshots / GIFs

<!--
We have screenshot tests in the project, so attaching screenshots to a PR is not mandatory, as far as there
is a Composable Preview covering the changes. In this case, the change will appear in the file diff.
Note that all the UI composables should be covered by a Composable Preview.

Providing a video of the change is still very useful for the reviewer and for the history of the project.

You can use a table like this to show screenshots comparison.
Uncomment this markdown table below and edit the last line `|||`:
|copy screenshot of before here|copy screenshot of after here|

|Before|After|
|-|-|
|||
 -->

## Tests

<!-- Explain how you tested your development -->

- Step 1
- Step 2
- Step ...

## Tested devices

- [ ] Physical
- [ ] Emulator
- OS version(s):

## Checklist

<!-- Depending on the Pull Request content, it can be acceptable if some of the following checkboxes stay unchecked. -->

- [ ] Changes have been tested on an Android device or Android emulator with API 23
- [ ] UI change has been tested on both light and dark themes
- [ ] Accessibility has been taken into account. See https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#accessibility
- [ ] Pull request is based on the develop branch
- [ ] Pull request includes a new file under ./changelog.d. See https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#changelog
- [ ] Pull request includes screenshots or videos if containing UI changes
- [ ] Pull request includes a [sign off](https://matrix-org.github.io/synapse/latest/development/contributing_guide.html#sign-off)
- [ ] You've made a self review of your PR

Fix flaky test `present - logout then confirm`
We have a flaky test on CI: `present - logout then confirm`, which fails from time to time in release mode, for instance here: https://github.com/element-hq/element-x-android/actions/runs/7410156372/job/20161825022?pr=2164

Extract of `element-x-android/features/logout/impl/build/reports/tests/testReleaseUnitTest/index.html`:

<img width="1388" alt="image" src="https://github.com/element-hq/element-x-android/assets/3940906/53f5e80a-7e47-4542-b1cb-5dc17d989bd0">

```
expected instance of: io.element.android.libraries.architecture.Async$Success
but was instance of : io.element.android.libraries.architecture.Async$Loading
with value          : Loading(prevData=null)
	at app//io.element.android.features.logout.impl.LogoutPresenterTest$present - logout then confirm$1$2.invokeSuspend(LogoutPresenterTest.kt:149)
```

Not reproduced locally, both in debug and release mode.

diff --git a/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenPresenter.kt b/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenPresenter.kt
index 6883ebeb61f..d43557c6b19 100644
--- a/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenPresenter.kt
+++ b/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenPresenter.kt
@@ -34,7 +34,7 @@ import io.element.android.features.call.data.WidgetMessage
 import io.element.android.features.call.utils.CallWidgetProvider
 import io.element.android.features.call.utils.WidgetMessageInterceptor
 import io.element.android.features.call.utils.WidgetMessageSerializer
-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.architecture.runCatchingUpdatingState
 import io.element.android.libraries.core.coroutine.CoroutineDispatchers
@@ -75,7 +75,7 @@ class CallScreenPresenter @AssistedInject constructor(
     @Composable
     override fun present(): CallScreenState {
         val coroutineScope = rememberCoroutineScope()
-        val urlState = remember { mutableStateOf<Async<String>>(Async.Uninitialized) }
+        val urlState = remember { mutableStateOf<AsyncData<String>>(AsyncData.Uninitialized) }
         val callWidgetDriver = remember { mutableStateOf<MatrixWidgetDriver?>(null) }
         val messageInterceptor = remember { mutableStateOf<WidgetMessageInterceptor?>(null) }
         var isJoinedCall by rememberSaveable { mutableStateOf(false) }
@@ -154,7 +154,7 @@ class CallScreenPresenter @AssistedInject constructor(

     private fun CoroutineScope.loadUrl(
         inputs: CallType,
-        urlState: MutableState<Async<String>>,
+        urlState: MutableState<AsyncData<String>>,
         callWidgetDriver: MutableState<MatrixWidgetDriver?>,
     ) = launch {
         urlState.runCatchingUpdatingState {
diff --git a/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenState.kt b/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenState.kt
index 12cd7612ae6..76926bfb9f3 100644
--- a/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenState.kt
+++ b/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenState.kt
@@ -16,10 +16,10 @@

 package io.element.android.features.call.ui

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 data class CallScreenState(
-    val urlState: Async<String>,
+    val urlState: AsyncData<String>,
     val userAgent: String,
     val isInWidgetMode: Boolean,
     val eventSink: (CallScreenEvents) -> Unit,
diff --git a/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenView.kt b/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenView.kt
index f2c8a0cb935..c28bacf88a4 100644
--- a/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenView.kt
+++ b/features/call/src/main/kotlin/io/element/android/features/call/ui/CallScreenView.kt
@@ -36,7 +36,7 @@ import androidx.compose.ui.viewinterop.AndroidView
 import io.element.android.compound.tokens.generated.CompoundIcons
 import io.element.android.features.call.R
 import io.element.android.features.call.utils.WebViewWidgetMessageInterceptor
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.preview.ElementPreview
 import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@@ -96,7 +96,7 @@ internal fun CallScreenView(

 @Composable
 private fun CallWebView(
-    url: Async<String>,
+    url: AsyncData<String>,
     userAgent: String,
     onPermissionsRequested: (PermissionRequest) -> Unit,
     onWebViewCreated: (WebView) -> Unit,
@@ -116,7 +116,7 @@ private fun CallWebView(
                 }
             },
             update = { webView ->
-                if (url is Async.Success && webView.url != url.data) {
+                if (url is AsyncData.Success && webView.url != url.data) {
                     webView.loadUrl(url.data)
                 }
             },
@@ -161,7 +161,7 @@ internal fun CallScreenViewPreview() {
     ElementPreview {
         CallScreenView(
             state = CallScreenState(
-                urlState = Async.Success("https://call.element.io/some-actual-call?with=parameters"),
+                urlState = AsyncData.Success("https://call.element.io/some-actual-call?with=parameters"),
                 isInWidgetMode = false,
                 userAgent = "",
                 eventSink = {},
diff --git a/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/StartDMAction.kt b/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/StartDMAction.kt
index ef95f15dce2..baacfa79dca 100644
--- a/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/StartDMAction.kt
+++ b/features/createroom/api/src/main/kotlin/io/element/android/features/createroom/api/StartDMAction.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.createroom.api

 import androidx.compose.runtime.MutableState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.core.RoomId
 import io.element.android.libraries.matrix.api.core.UserId

@@ -27,5 +27,5 @@ interface StartDMAction {
      * @param userId The user to start a DM with.
      * @param actionState The state to update with the result of the action.
      */
-    suspend fun execute(userId: UserId, actionState: MutableState<Async<RoomId>>)
+    suspend fun execute(userId: UserId, actionState: MutableState<AsyncAction<RoomId>>)
 }
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultStartDMAction.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultStartDMAction.kt
index 7145ac671e8..c941c419584 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultStartDMAction.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/DefaultStartDMAction.kt
@@ -20,7 +20,7 @@ import androidx.compose.runtime.MutableState
 import com.squareup.anvil.annotations.ContributesBinding
 import im.vector.app.features.analytics.plan.CreatedRoom
 import io.element.android.features.createroom.api.StartDMAction
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.di.SessionScope
 import io.element.android.libraries.matrix.api.MatrixClient
 import io.element.android.libraries.matrix.api.core.RoomId
@@ -36,17 +36,17 @@ class DefaultStartDMAction @Inject constructor(
     private val analyticsService: AnalyticsService,
 ) : StartDMAction {

-    override suspend fun execute(userId: UserId, actionState: MutableState<Async<RoomId>>) {
-        actionState.value = Async.Loading()
+    override suspend fun execute(userId: UserId, actionState: MutableState<AsyncAction<RoomId>>) {
+        actionState.value = AsyncAction.Loading
         when (val result = matrixClient.startDM(userId)) {
             is StartDMResult.Success -> {
                 if (result.isNew) {
                     analyticsService.capture(CreatedRoom(isDM = true))
                 }
-                actionState.value = Async.Success(result.roomId)
+                actionState.value = AsyncAction.Success(result.roomId)
             }
             is StartDMResult.Failure -> {
-                actionState.value = Async.Failure(result.throwable)
+                actionState.value = AsyncAction.Failure(result.throwable)
             }
         }
     }
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt
index 4cefa82a31d..6e077c6e508 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt
@@ -29,7 +29,7 @@ import androidx.compose.runtime.rememberCoroutineScope
 import im.vector.app.features.analytics.plan.CreatedRoom
 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.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.architecture.runCatchingUpdatingState
 import io.element.android.libraries.core.mimetype.MimeTypes
@@ -91,10 +91,10 @@ class ConfigureRoomPresenter @Inject constructor(
         }

         val localCoroutineScope = rememberCoroutineScope()
-        val createRoomAction: MutableState<Async<RoomId>> = remember { mutableStateOf(Async.Uninitialized) }
+        val createRoomAction: MutableState<AsyncAction<RoomId>> = remember { mutableStateOf(AsyncAction.Uninitialized) }

         fun createRoom(config: CreateRoomConfig) {
-            createRoomAction.value = Async.Uninitialized
+            createRoomAction.value = AsyncAction.Uninitialized
             localCoroutineScope.createRoom(config, createRoomAction)
         }

@@ -118,7 +118,7 @@ class ConfigureRoomPresenter @Inject constructor(
                     }
                 }

-                ConfigureRoomEvents.CancelCreateRoom -> createRoomAction.value = Async.Uninitialized
+                ConfigureRoomEvents.CancelCreateRoom -> createRoomAction.value = AsyncAction.Uninitialized
             }
         }

@@ -133,7 +133,7 @@ class ConfigureRoomPresenter @Inject constructor(

     private fun CoroutineScope.createRoom(
         config: CreateRoomConfig,
-        createRoomAction: MutableState<Async<RoomId>>
+        createRoomAction: MutableState<AsyncAction<RoomId>>
     ) = launch {
         suspend {
             val avatarUrl = config.avatarUri?.let { uploadAvatar(it) }
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt
index 7e16cedaa73..f275a0e217b 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt
@@ -16,17 +16,17 @@

 package io.element.android.features.createroom.impl.configureroom

-import io.element.android.libraries.matrix.ui.media.AvatarAction
 import io.element.android.features.createroom.impl.CreateRoomConfig
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.core.RoomId
+import io.element.android.libraries.matrix.ui.media.AvatarAction
 import io.element.android.libraries.permissions.api.PermissionsState
 import kotlinx.collections.immutable.ImmutableList

 data class ConfigureRoomState(
     val config: CreateRoomConfig,
     val avatarActions: ImmutableList<AvatarAction>,
-    val createRoomAction: Async<RoomId>,
+    val createRoomAction: AsyncAction<RoomId>,
     val cameraPermissionState: PermissionsState,
     val eventSink: (ConfigureRoomEvents) -> Unit
 ) {
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt
index eafbe6915bd..1065f746e0b 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt
@@ -19,7 +19,7 @@ package io.element.android.features.createroom.impl.configureroom
 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
 import io.element.android.features.createroom.impl.CreateRoomConfig
 import io.element.android.features.createroom.impl.userlist.aListOfSelectedUsers
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.permissions.api.aPermissionsState
 import kotlinx.collections.immutable.persistentListOf

@@ -41,7 +41,7 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomSt
 fun aConfigureRoomState() = ConfigureRoomState(
     config = CreateRoomConfig(),
     avatarActions = persistentListOf(),
-    createRoomAction = Async.Uninitialized,
+    createRoomAction = AsyncAction.Uninitialized,
     cameraPermissionState = aPermissionsState(showDialog = false),
     eventSink = { },
 )
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt
index f979239b4ca..c3887ecba64 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt
@@ -49,7 +49,8 @@ import io.element.android.compound.theme.ElementTheme
 import io.element.android.features.createroom.impl.R
 import io.element.android.features.createroom.impl.components.RoomPrivacyOption
 import io.element.android.libraries.designsystem.components.LabelledTextField
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
+import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.preview.ElementPreview
 import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@@ -148,9 +149,13 @@ fun ConfigureRoomView(
         onActionSelected = { state.eventSink(ConfigureRoomEvents.HandleAvatarAction(it)) }
     )

-    AsyncView(
+    AsyncActionView(
         async = state.createRoomAction,
-        progressText = stringResource(CommonStrings.common_creating_room),
+        progressDialog = {
+            AsyncActionViewDefaults.ProgressDialog(
+                progressText = stringResource(CommonStrings.common_creating_room),
+            )
+        },
         onSuccess = { onRoomCreated(it) },
         errorMessage = { stringResource(R.string.screen_create_room_error_creating_room) },
         onRetry = { state.eventSink(ConfigureRoomEvents.CreateRoom(state.config)) },
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt
index 9b60924ca46..50f5a14c44b 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenter.kt
@@ -26,7 +26,7 @@ import io.element.android.features.createroom.impl.userlist.SelectionMode
 import io.element.android.features.createroom.impl.userlist.UserListDataStore
 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.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.core.meta.BuildMeta
 import io.element.android.libraries.matrix.api.core.RoomId
@@ -55,14 +55,14 @@ class CreateRoomRootPresenter @Inject constructor(
         val userListState = presenter.present()

         val localCoroutineScope = rememberCoroutineScope()
-        val startDmActionState: MutableState<Async<RoomId>> = remember { mutableStateOf(Async.Uninitialized) }
+        val startDmActionState: MutableState<AsyncAction<RoomId>> = remember { mutableStateOf(AsyncAction.Uninitialized) }

         fun handleEvents(event: CreateRoomRootEvents) {
             when (event) {
                 is CreateRoomRootEvents.StartDM -> localCoroutineScope.launch {
                     startDMAction.execute(event.matrixUser.userId, startDmActionState)
                 }
-                CreateRoomRootEvents.CancelStartDM -> startDmActionState.value = Async.Uninitialized
+                CreateRoomRootEvents.CancelStartDM -> startDmActionState.value = AsyncAction.Uninitialized
             }
         }

diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt
index 02f64a6c862..185c08c1311 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootState.kt
@@ -17,12 +17,12 @@
 package io.element.android.features.createroom.impl.root

 import io.element.android.features.createroom.impl.userlist.UserListState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.core.RoomId

 data class CreateRoomRootState(
     val applicationName: String,
     val userListState: UserListState,
-    val startDmAction: Async<RoomId>,
+    val startDmAction: AsyncAction<RoomId>,
     val eventSink: (CreateRoomRootEvents) -> Unit,
 )
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt
index 7a3bf6ef03c..59980b75611 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootStateProvider.kt
@@ -18,8 +18,8 @@ package io.element.android.features.createroom.impl.root

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
 import io.element.android.features.createroom.impl.userlist.aUserListState
+import io.element.android.libraries.architecture.AsyncAction

-import io.element.android.libraries.architecture.Async
 import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
 import io.element.android.libraries.matrix.ui.components.aMatrixUser
 import io.element.android.libraries.usersearch.api.UserSearchResult
@@ -30,7 +30,7 @@ open class CreateRoomRootStateProvider : PreviewParameterProvider<CreateRoomRoot
         get() = sequenceOf(
             aCreateRoomRootState(),
             aCreateRoomRootState().copy(
-                startDmAction = Async.Loading(),
+                startDmAction = AsyncAction.Loading,
                 userListState = aMatrixUser().let {
                     aUserListState().copy(
                         searchQuery = it.userId.value,
@@ -41,7 +41,7 @@ open class CreateRoomRootStateProvider : PreviewParameterProvider<CreateRoomRoot
                 }
             ),
             aCreateRoomRootState().copy(
-                startDmAction = Async.Failure(Throwable("error")),
+                startDmAction = AsyncAction.Failure(Throwable("error")),
                 userListState = aMatrixUser().let {
                     aUserListState().copy(
                         searchQuery = it.userId.value,
@@ -57,6 +57,6 @@ open class CreateRoomRootStateProvider : PreviewParameterProvider<CreateRoomRoot
 fun aCreateRoomRootState() = CreateRoomRootState(
     eventSink = {},
     applicationName = "Element X Preview",
-    startDmAction = Async.Uninitialized,
+    startDmAction = AsyncAction.Uninitialized,
     userListState = aUserListState(),
 )
diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt
index 0acf9d23430..59decf9129f 100644
--- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt
+++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootView.kt
@@ -38,7 +38,8 @@ import io.element.android.compound.theme.ElementTheme
 import io.element.android.compound.tokens.generated.CompoundIcons
 import io.element.android.features.createroom.impl.R
 import io.element.android.features.createroom.impl.components.UserListView
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
+import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.icons.CompoundDrawables
 import io.element.android.libraries.designsystem.preview.ElementPreview
@@ -93,9 +94,13 @@ fun CreateRoomRootView(
         }
     }

-    AsyncView(
+    AsyncActionView(
         async = state.startDmAction,
-        progressText = stringResource(CommonStrings.common_starting_chat),
+        progressDialog = {
+            AsyncActionViewDefaults.ProgressDialog(
+                progressText = stringResource(CommonStrings.common_starting_chat),
+            )
+        },
         onSuccess = { onOpenDM(it) },
         errorMessage = { stringResource(R.string.screen_start_chat_error_starting_chat) },
         onRetry = {
diff --git a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt
index 8bc752d6293..403f312a224 100644
--- a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt
+++ b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListPresenter.kt
@@ -29,7 +29,7 @@ import im.vector.app.features.analytics.plan.JoinedRoom
 import io.element.android.features.invitelist.api.SeenInvitesStore
 import io.element.android.features.invitelist.impl.model.InviteListInviteSummary
 import io.element.android.features.invitelist.impl.model.InviteSender
-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.architecture.runCatchingUpdatingState
 import io.element.android.libraries.designsystem.components.avatar.AvatarData
@@ -77,14 +77,14 @@ class InviteListPresenter @Inject constructor(
         }

         val localCoroutineScope = rememberCoroutineScope()
-        val acceptedAction: MutableState<Async<RoomId>> = remember { mutableStateOf(Async.Uninitialized) }
-        val declinedAction: MutableState<Async<Unit>> = remember { mutableStateOf(Async.Uninitialized) }
+        val acceptedAction: MutableState<AsyncData<RoomId>> = remember { mutableStateOf(AsyncData.Uninitialized) }
+        val declinedAction: MutableState<AsyncData<Unit>> = remember { mutableStateOf(AsyncData.Uninitialized) }
         val decliningInvite: MutableState<InviteListInviteSummary?> = remember { mutableStateOf(null) }

         fun handleEvent(event: InviteListEvents) {
             when (event) {
                 is InviteListEvents.AcceptInvite -> {
-                    acceptedAction.value = Async.Uninitialized
+                    acceptedAction.value = AsyncData.Uninitialized
                     localCoroutineScope.acceptInvite(event.invite.roomId, acceptedAction)
                 }

@@ -93,7 +93,7 @@ class InviteListPresenter @Inject constructor(
                 }

                 is InviteListEvents.ConfirmDeclineInvite -> {
-                    declinedAction.value = Async.Uninitialized
+                    declinedAction.value = AsyncData.Uninitialized
                     decliningInvite.value?.let {
                         localCoroutineScope.declineInvite(it.roomId, declinedAction)
                     }
@@ -105,11 +105,11 @@ class InviteListPresenter @Inject constructor(
                 }

                 is InviteListEvents.DismissAcceptError -> {
-                    acceptedAction.value = Async.Uninitialized
+                    acceptedAction.value = AsyncData.Uninitialized
                 }

                 is InviteListEvents.DismissDeclineError -> {
-                    declinedAction.value = Async.Uninitialized
+                    declinedAction.value = AsyncData.Uninitialized
                 }
             }
         }
@@ -137,7 +137,7 @@ class InviteListPresenter @Inject constructor(
         )
     }

-    private fun CoroutineScope.acceptInvite(roomId: RoomId, acceptedAction: MutableState<Async<RoomId>>) = launch {
+    private fun CoroutineScope.acceptInvite(roomId: RoomId, acceptedAction: MutableState<AsyncData<RoomId>>) = launch {
         suspend {
             client.getRoom(roomId)?.use {
                 it.join().getOrThrow()
@@ -148,7 +148,7 @@ class InviteListPresenter @Inject constructor(
         }.runCatchingUpdatingState(acceptedAction)
     }

-    private fun CoroutineScope.declineInvite(roomId: RoomId, declinedAction: MutableState<Async<Unit>>) = launch {
+    private fun CoroutineScope.declineInvite(roomId: RoomId, declinedAction: MutableState<AsyncData<Unit>>) = launch {
         suspend {
             client.getRoom(roomId)?.use {
                 it.leave().getOrThrow()
diff --git a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListState.kt b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListState.kt
index 43644cd6aaa..b576861475c 100644
--- a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListState.kt
+++ b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListState.kt
@@ -18,7 +18,7 @@ package io.element.android.features.invitelist.impl

 import androidx.compose.runtime.Immutable
 import io.element.android.features.invitelist.impl.model.InviteListInviteSummary
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.core.RoomId
 import kotlinx.collections.immutable.ImmutableList

@@ -26,8 +26,8 @@ import kotlinx.collections.immutable.ImmutableList
 data class InviteListState(
     val inviteList: ImmutableList<InviteListInviteSummary>,
     val declineConfirmationDialog: InviteDeclineConfirmationDialog,
-    val acceptedAction: Async<RoomId>,
-    val declinedAction: Async<Unit>,
+    val acceptedAction: AsyncData<RoomId>,
+    val declinedAction: AsyncData<Unit>,
     val eventSink: (InviteListEvents) -> Unit
 )

diff --git a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListStateProvider.kt b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListStateProvider.kt
index f187398689c..e61bd9ff934 100644
--- a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListStateProvider.kt
+++ b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListStateProvider.kt
@@ -19,7 +19,7 @@ package io.element.android.features.invitelist.impl
 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
 import io.element.android.features.invitelist.impl.model.InviteListInviteSummary
 import io.element.android.features.invitelist.impl.model.InviteSender
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.core.RoomId
 import io.element.android.libraries.matrix.api.core.UserId
 import kotlinx.collections.immutable.ImmutableList
@@ -32,16 +32,16 @@ open class InviteListStateProvider : PreviewParameterProvider<InviteListState> {
             aInviteListState().copy(inviteList = persistentListOf()),
             aInviteListState().copy(declineConfirmationDialog = InviteDeclineConfirmationDialog.Visible(true, "Alice")),
             aInviteListState().copy(declineConfirmationDialog = InviteDeclineConfirmationDialog.Visible(false, "Some Room")),
-            aInviteListState().copy(acceptedAction = Async.Failure(Throwable("Whoops"))),
-            aInviteListState().copy(declinedAction = Async.Failure(Throwable("Whoops"))),
+            aInviteListState().copy(acceptedAction = AsyncData.Failure(Throwable("Whoops"))),
+            aInviteListState().copy(declinedAction = AsyncData.Failure(Throwable("Whoops"))),
         )
 }

 internal fun aInviteListState() = InviteListState(
     inviteList = aInviteListInviteSummaryList(),
     declineConfirmationDialog = InviteDeclineConfirmationDialog.Hidden,
-    acceptedAction = Async.Uninitialized,
-    declinedAction = Async.Uninitialized,
+    acceptedAction = AsyncData.Uninitialized,
+    declinedAction = AsyncData.Uninitialized,
     eventSink = {},
 )

diff --git a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt
index c831024448e..3a804de7bcf 100644
--- a/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt
+++ b/features/invitelist/impl/src/main/kotlin/io/element/android/features/invitelist/impl/InviteListView.kt
@@ -35,7 +35,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
 import androidx.compose.ui.unit.dp
 import io.element.android.compound.theme.ElementTheme
 import io.element.android.features.invitelist.impl.components.InviteSummaryRow
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
 import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
@@ -56,7 +56,7 @@ fun InviteListView(
     onInviteAccepted: (RoomId) -> Unit,
     modifier: Modifier = Modifier,
 ) {
-    if (state.acceptedAction is Async.Success) {
+    if (state.acceptedAction is AsyncData.Success) {
         LaunchedEffect(state.acceptedAction) {
             onInviteAccepted(state.acceptedAction.data)
         }
@@ -89,7 +89,7 @@ fun InviteListView(
         )
     }

-    if (state.acceptedAction is Async.Failure) {
+    if (state.acceptedAction is AsyncData.Failure) {
         ErrorDialog(
             content = stringResource(CommonStrings.error_unknown),
             title = stringResource(CommonStrings.common_error),
@@ -98,7 +98,7 @@ fun InviteListView(
         )
     }

-    if (state.declinedAction is Async.Failure) {
+    if (state.declinedAction is AsyncData.Failure) {
         ErrorDialog(
             content = stringResource(CommonStrings.error_unknown),
             title = stringResource(CommonStrings.common_error),
diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockPresenter.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockPresenter.kt
index 1b5ce800852..5fe7fdddde1 100644
--- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockPresenter.kt
+++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockPresenter.kt
@@ -29,7 +29,7 @@ import io.element.android.features.lockscreen.impl.biometric.BiometricUnlockMana
 import io.element.android.features.lockscreen.impl.pin.PinCodeManager
 import io.element.android.features.lockscreen.impl.pin.model.PinEntry
 import io.element.android.features.lockscreen.impl.unlock.keypad.PinKeypadModel
-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.architecture.runCatchingUpdatingState
 import io.element.android.libraries.core.bool.orFalse
@@ -49,11 +49,11 @@ class PinUnlockPresenter @Inject constructor(
     @Composable
     override fun present(): PinUnlockState {
         val pinEntryState = remember {
-            mutableStateOf<Async<PinEntry>>(Async.Uninitialized)
+            mutableStateOf<AsyncData<PinEntry>>(AsyncData.Uninitialized)
         }
         val pinEntry by pinEntryState
         var remainingAttempts by remember {
-            mutableStateOf<Async<Int>>(Async.Uninitialized)
+            mutableStateOf<AsyncData<Int>>(AsyncData.Uninitialized)
         }
         var showWrongPinTitle by rememberSaveable {
             mutableStateOf(false)
@@ -62,7 +62,7 @@ class PinUnlockPresenter @Inject constructor(
             mutableStateOf(false)
         }
         val signOutAction = remember {
-            mutableStateOf<Async<String?>>(Async.Uninitialized)
+            mutableStateOf<AsyncData<String?>>(AsyncData.Uninitialized)
         }
         var biometricUnlockResult by remember {
             mutableStateOf<BiometricUnlock.AuthenticationResult?>(null)
@@ -91,7 +91,7 @@ class PinUnlockPresenter @Inject constructor(
                 }
             }
             val remainingAttemptsNumber = pinCodeManager.getRemainingPinCodeAttemptsNumber()
-            remainingAttempts = Async.Success(remainingAttemptsNumber)
+            remainingAttempts = AsyncData.Success(remainingAttemptsNumber)
             if (remainingAttemptsNumber == 0) {
                 showSignOutPrompt = true
             }
@@ -139,46 +139,46 @@ class PinUnlockPresenter @Inject constructor(
         )
     }

-    private fun Async<PinEntry>.isComplete(): Boolean {
+    private fun AsyncData<PinEntry>.isComplete(): Boolean {
         return dataOrNull()?.isComplete().orFalse()
     }

-    private fun Async<PinEntry>.toText(): String {
+    private fun AsyncData<PinEntry>.toText(): String {
         return dataOrNull()?.toText() ?: ""
     }

-    private fun Async<PinEntry>.clear(): Async<PinEntry> {
+    private fun AsyncData<PinEntry>.clear(): AsyncData<PinEntry> {
         return when (this) {
-            is Async.Success -> Async.Success(data.clear())
+            is AsyncData.Success -> AsyncData.Success(data.clear())
             else -> this
         }
     }

-    private fun Async<PinEntry>.process(pinKeypadModel: PinKeypadModel): Async<PinEntry> {
+    private fun AsyncData<PinEntry>.process(pinKeypadModel: PinKeypadModel): AsyncData<PinEntry> {
         return when (this) {
-            is Async.Success -> {
+            is AsyncData.Success -> {
                 val pinEntry = when (pinKeypadModel) {
                     PinKeypadModel.Back -> data.deleteLast()
                     is PinKeypadModel.Number -> data.addDigit(pinKeypadModel.number)
                     PinKeypadModel.Empty -> data
                 }
-                Async.Success(pinEntry)
+                AsyncData.Success(pinEntry)
             }
             else -> this
         }
     }

-    private fun Async<PinEntry>.process(pinEntryAsText: String): Async<PinEntry> {
+    private fun AsyncData<PinEntry>.process(pinEntryAsText: String): AsyncData<PinEntry> {
         return when (this) {
-            is Async.Success -> {
+            is AsyncData.Success -> {
                 val pinEntry = data.fillWith(pinEntryAsText)
-                Async.Success(pinEntry)
+                AsyncData.Success(pinEntry)
             }
             else -> this
         }
     }

-    private fun CoroutineScope.signOut(signOutAction: MutableState<Async<String?>>) = launch {
+    private fun CoroutineScope.signOut(signOutAction: MutableState<AsyncData<String?>>) = launch {
         suspend {
             matrixClient.logout(ignoreSdkError = true)
         }.runCatchingUpdatingState(signOutAction)
diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockState.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockState.kt
index 006234270c9..ae381f70317 100644
--- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockState.kt
+++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockState.kt
@@ -19,21 +19,21 @@ package io.element.android.features.lockscreen.impl.unlock
 import io.element.android.features.lockscreen.impl.biometric.BiometricUnlock
 import io.element.android.features.lockscreen.impl.biometric.BiometricUnlockError
 import io.element.android.features.lockscreen.impl.pin.model.PinEntry
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 data class PinUnlockState(
-    val pinEntry: Async<PinEntry>,
+    val pinEntry: AsyncData<PinEntry>,
     val showWrongPinTitle: Boolean,
-    val remainingAttempts: Async<Int>,
+    val remainingAttempts: AsyncData<Int>,
     val showSignOutPrompt: Boolean,
-    val signOutAction: Async<String?>,
+    val signOutAction: AsyncData<String?>,
     val showBiometricUnlock: Boolean,
     val isUnlocked: Boolean,
     val biometricUnlockResult: BiometricUnlock.AuthenticationResult?,
     val eventSink: (PinUnlockEvents) -> Unit
 ) {
     val isSignOutPromptCancellable = when (remainingAttempts) {
-        is Async.Success -> remainingAttempts.data > 0
+        is AsyncData.Success -> remainingAttempts.data > 0
         else -> true
     }

diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockStateProvider.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockStateProvider.kt
index 02da0e03501..151c3079ee5 100644
--- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockStateProvider.kt
+++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockStateProvider.kt
@@ -19,7 +19,7 @@ package io.element.android.features.lockscreen.impl.unlock
 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
 import io.element.android.features.lockscreen.impl.biometric.BiometricUnlock
 import io.element.android.features.lockscreen.impl.pin.model.PinEntry
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 open class PinUnlockStateProvider : PreviewParameterProvider<PinUnlockState> {
     override val values: Sequence<PinUnlockState>
@@ -30,7 +30,7 @@ open class PinUnlockStateProvider : PreviewParameterProvider<PinUnlockState> {
             aPinUnlockState(showSignOutPrompt = true),
             aPinUnlockState(showBiometricUnlock = false),
             aPinUnlockState(showSignOutPrompt = true, remainingAttempts = 0),
-            aPinUnlockState(signOutAction = Async.Loading()),
+            aPinUnlockState(signOutAction = AsyncData.Loading()),
         )
 }

@@ -42,11 +42,11 @@ fun aPinUnlockState(
     showBiometricUnlock: Boolean = true,
     biometricUnlockResult: BiometricUnlock.AuthenticationResult? = null,
     isUnlocked: Boolean = false,
-    signOutAction: Async<String?> = Async.Uninitialized,
+    signOutAction: AsyncData<String?> = AsyncData.Uninitialized,
 ) = PinUnlockState(
-    pinEntry = Async.Success(pinEntry),
+    pinEntry = AsyncData.Success(pinEntry),
     showWrongPinTitle = showWrongPinTitle,
-    remainingAttempts = Async.Success(remainingAttempts),
+    remainingAttempts = AsyncData.Success(remainingAttempts),
     showSignOutPrompt = showSignOutPrompt,
     showBiometricUnlock = showBiometricUnlock,
     signOutAction = signOutAction,
diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockView.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockView.kt
index 325a41c3935..6c9fd2bb6eb 100644
--- a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockView.kt
+++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockView.kt
@@ -56,7 +56,7 @@ import io.element.android.features.lockscreen.impl.components.PinEntryTextField
 import io.element.android.features.lockscreen.impl.pin.model.PinDigit
 import io.element.android.features.lockscreen.impl.pin.model.PinEntry
 import io.element.android.features.lockscreen.impl.unlock.keypad.PinKeypad
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtom
 import io.element.android.libraries.designsystem.components.ProgressDialog
 import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
@@ -92,7 +92,7 @@ fun PinUnlockView(
                 onDismiss = { state.eventSink(PinUnlockEvents.ClearSignOutPrompt) },
             )
         }
-        if (state.signOutAction is Async.Loading) {
+        if (state.signOutAction is AsyncData.Loading) {
             ProgressDialog(text = stringResource(id = R.string.screen_signout_in_progress_dialog_content))
         }
         if (state.showBiometricUnlockError) {
@@ -335,7 +335,7 @@ private fun PinUnlockHeader(
             style = ElementTheme.typography.fontBodyMdRegular,
             color = subtitleColor,
         )
-        if (!isInAppUnlock && state.pinEntry is Async.Success) {
+        if (!isInAppUnlock && state.pinEntry is AsyncData.Success) {
             Spacer(Modifier.height(24.dp))
             PinDotsRow(state.pinEntry.data)
         }
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt
index 726e2412539..f360afbae2f 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenter.kt
@@ -24,7 +24,7 @@ import androidx.compose.runtime.rememberCoroutineScope
 import io.element.android.features.login.impl.accountprovider.AccountProvider
 import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
 import io.element.android.features.login.impl.error.ChangeServerError
-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.architecture.runCatchingUpdatingState
 import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
@@ -41,14 +41,14 @@ class ChangeServerPresenter @Inject constructor(
     override fun present(): ChangeServerState {
         val localCoroutineScope = rememberCoroutineScope()

-        val changeServerAction: MutableState<Async<Unit>> = remember {
-            mutableStateOf(Async.Uninitialized)
+        val changeServerAction: MutableState<AsyncData<Unit>> = remember {
+            mutableStateOf(AsyncData.Uninitialized)
         }

         fun handleEvents(event: ChangeServerEvents) {
             when (event) {
                 is ChangeServerEvents.ChangeServer -> localCoroutineScope.changeServer(event.accountProvider, changeServerAction)
-                ChangeServerEvents.ClearError -> changeServerAction.value = Async.Uninitialized
+                ChangeServerEvents.ClearError -> changeServerAction.value = AsyncData.Uninitialized
             }
         }

@@ -60,7 +60,7 @@ class ChangeServerPresenter @Inject constructor(

     private fun CoroutineScope.changeServer(
         data: AccountProvider,
-        changeServerAction: MutableState<Async<Unit>>,
+        changeServerAction: MutableState<AsyncData<Unit>>,
     ) = launch {
         suspend {
             authenticationService.setHomeserver(data.url).map {
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerState.kt
index e49fa1f2fe4..c5c8ba5417a 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerState.kt
@@ -16,9 +16,9 @@

 package io.element.android.features.login.impl.changeserver

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 data class ChangeServerState(
-    val changeServerAction: Async<Unit>,
+    val changeServerAction: AsyncData<Unit>,
     val eventSink: (ChangeServerEvents) -> Unit
 )
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerStateProvider.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerStateProvider.kt
index 90c2bff4553..014c3352ce7 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerStateProvider.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerStateProvider.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.login.impl.changeserver

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 open class ChangeServerStateProvider : PreviewParameterProvider<ChangeServerState> {
     override val values: Sequence<ChangeServerState>
@@ -27,6 +27,6 @@ open class ChangeServerStateProvider : PreviewParameterProvider<ChangeServerStat
 }

 fun aChangeServerState() = ChangeServerState(
-    changeServerAction = Async.Uninitialized,
+    changeServerAction = AsyncData.Uninitialized,
     eventSink = {}
 )
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt
index 3dd24091619..c0fe52dacda 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerView.kt
@@ -22,7 +22,7 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.tooling.preview.PreviewParameter
 import io.element.android.features.login.impl.dialogs.SlidingSyncNotSupportedDialog
 import io.element.android.features.login.impl.error.ChangeServerError
-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.preview.ElementPreview
@@ -37,7 +37,7 @@ fun ChangeServerView(
 ) {
     val eventSink = state.eventSink
     when (state.changeServerAction) {
-        is Async.Failure -> {
+        is AsyncData.Failure -> {
             when (val error = state.changeServerAction.error) {
                 is ChangeServerError.Error -> {
                     ErrorDialog(
@@ -60,11 +60,11 @@ fun ChangeServerView(
                 }
             }
         }
-        is Async.Loading -> ProgressDialog()
-        is Async.Success -> LaunchedEffect(state.changeServerAction) {
+        is AsyncData.Loading -> ProgressDialog()
+        is AsyncData.Success -> LaunchedEffect(state.changeServerAction) {
             onDone()
         }
-        Async.Uninitialized -> Unit
+        AsyncData.Uninitialized -> Unit
     }
 }

diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenter.kt
index 66926b3734b..0a6d999871a 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenter.kt
@@ -26,7 +26,7 @@ import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import io.element.android.features.login.api.oidc.OidcAction
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
 import io.element.android.libraries.matrix.api.auth.OidcDetails
@@ -44,33 +44,33 @@ class OidcPresenter @AssistedInject constructor(

     @Composable
     override fun present(): OidcState {
-        var requestState: Async<Unit> by remember {
-            mutableStateOf(Async.Uninitialized)
+        var requestState: AsyncAction<Unit> by remember {
+            mutableStateOf(AsyncAction.Uninitialized)
         }
         val localCoroutineScope = rememberCoroutineScope()

         fun handleCancel() {
-            requestState = Async.Loading()
+            requestState = AsyncAction.Loading
             localCoroutineScope.launch {
                 authenticationService.cancelOidcLogin()
                     .fold(
                         onSuccess = {
                             // Then go back
-                            requestState = Async.Success(Unit)
+                            requestState = AsyncAction.Success(Unit)
                         },
                         onFailure = {
-                            requestState = Async.Failure(it)
+                            requestState = AsyncAction.Failure(it)
                         }
                     )
             }
         }

         fun handleSuccess(url: String) {
-            requestState = Async.Loading()
+            requestState = AsyncAction.Loading
             localCoroutineScope.launch {
                 authenticationService.loginWithOidc(url)
                     .onFailure {
-                        requestState = Async.Failure(it)
+                        requestState = AsyncAction.Failure(it)
                     }
                 // On success, the node tree will be updated, there is nothing to do
             }
@@ -87,7 +87,7 @@ class OidcPresenter @AssistedInject constructor(
             when (event) {
                 OidcEvents.Cancel -> handleCancel()
                 is OidcEvents.OidcActionEvent -> handleAction(event.oidcAction)
-                OidcEvents.ClearError -> requestState = Async.Uninitialized
+                OidcEvents.ClearError -> requestState = AsyncAction.Uninitialized
             }
         }

diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcState.kt
index fc9507a89de..dc4f26d51e6 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcState.kt
@@ -16,11 +16,11 @@

 package io.element.android.features.login.impl.oidc.webview

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.auth.OidcDetails

 data class OidcState(
     val oidcDetails: OidcDetails,
-    val requestState: Async<Unit>,
+    val requestState: AsyncAction<Unit>,
     val eventSink: (OidcEvents) -> Unit
 )
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcStateProvider.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcStateProvider.kt
index 80878cf8f85..5d446574628 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcStateProvider.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcStateProvider.kt
@@ -17,20 +17,20 @@
 package io.element.android.features.login.impl.oidc.webview

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.auth.OidcDetails

 open class OidcStateProvider : PreviewParameterProvider<OidcState> {
     override val values: Sequence<OidcState>
         get() = sequenceOf(
             aOidcState(),
-            aOidcState().copy(requestState = Async.Loading()),
+            aOidcState().copy(requestState = AsyncAction.Loading),
         )
 }

 fun aOidcState() = OidcState(
     oidcDetails = aOidcDetails(),
-    requestState = Async.Uninitialized,
+    requestState = AsyncAction.Uninitialized,
     eventSink = {}
 )

diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt
index 66e3b31496c..fb86ae18a57 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/oidc/webview/OidcView.kt
@@ -30,7 +30,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
 import androidx.compose.ui.viewinterop.AndroidView
 import io.element.android.features.login.impl.oidc.OidcUrlParser
 import io.element.android.libraries.core.bool.orFalse
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.preview.ElementPreview
 import io.element.android.libraries.designsystem.preview.PreviewsDayNight

@@ -76,7 +76,7 @@ fun OidcView(
             }
         )

-        AsyncView(
+        AsyncActionView(
             async = state.requestState,
             onSuccess = { onNavigateBack() },
             onErrorDismiss = { state.eventSink(OidcEvents.ClearError) }
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt
index 21896e44081..82c11047a30 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenter.kt
@@ -32,7 +32,7 @@ import io.element.android.features.login.impl.DefaultLoginUserStory
 import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
 import io.element.android.features.login.impl.error.ChangeServerError
 import io.element.android.features.login.impl.oidc.customtab.DefaultOidcActionFlow
-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.architecture.runCatchingUpdatingState
 import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
@@ -61,8 +61,8 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(
         val accountProvider by accountProviderDataSource.flow().collectAsState()
         val localCoroutineScope = rememberCoroutineScope()

-        val loginFlowAction: MutableState<Async<LoginFlow>> = remember {
-            mutableStateOf(Async.Uninitialized)
+        val loginFlowAction: MutableState<AsyncData<LoginFlow>> = remember {
+            mutableStateOf(AsyncData.Uninitialized)
         }

         LaunchedEffect(Unit) {
@@ -78,7 +78,7 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(
                 ConfirmAccountProviderEvents.Continue -> {
                     localCoroutineScope.submit(accountProvider.url, loginFlowAction)
                 }
-                ConfirmAccountProviderEvents.ClearError -> loginFlowAction.value = Async.Uninitialized
+                ConfirmAccountProviderEvents.ClearError -> loginFlowAction.value = AsyncData.Uninitialized
             }
         }

@@ -92,7 +92,7 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(

     private fun CoroutineScope.submit(
         homeserverUrl: String,
-        loginFlowAction: MutableState<Async<LoginFlow>>,
+        loginFlowAction: MutableState<AsyncData<LoginFlow>>,
     ) = launch {
         suspend {
             authenticationService.setHomeserver(homeserverUrl).map {
@@ -111,17 +111,17 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(

     private suspend fun onOidcAction(
         oidcAction: OidcAction,
-        loginFlowAction: MutableState<Async<LoginFlow>>,
+        loginFlowAction: MutableState<AsyncData<LoginFlow>>,
     ) {
-        loginFlowAction.value = Async.Loading()
+        loginFlowAction.value = AsyncData.Loading()
         when (oidcAction) {
             OidcAction.GoBack -> {
                 authenticationService.cancelOidcLogin()
                     .onSuccess {
-                        loginFlowAction.value = Async.Uninitialized
+                        loginFlowAction.value = AsyncData.Uninitialized
                     }
                     .onFailure { failure ->
-                        loginFlowAction.value = Async.Failure(failure)
+                        loginFlowAction.value = AsyncData.Failure(failure)
                     }
             }
             is OidcAction.Success -> {
@@ -130,7 +130,7 @@ class ConfirmAccountProviderPresenter @AssistedInject constructor(
                         defaultLoginUserStory.setLoginFlowIsDone(true)
                     }
                     .onFailure { failure ->
-                        loginFlowAction.value = Async.Failure(failure)
+                        loginFlowAction.value = AsyncData.Failure(failure)
                     }
             }
         }
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderState.kt
index 2fcb57af94b..2074b7b5ce0 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderState.kt
@@ -17,17 +17,17 @@
 package io.element.android.features.login.impl.screens.confirmaccountprovider

 import io.element.android.features.login.impl.accountprovider.AccountProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.auth.OidcDetails

 // Do not use default value, so no member get forgotten in the presenters.
 data class ConfirmAccountProviderState(
     val accountProvider: AccountProvider,
     val isAccountCreation: Boolean,
-    val loginFlow: Async<LoginFlow>,
+    val loginFlow: AsyncData<LoginFlow>,
     val eventSink: (ConfirmAccountProviderEvents) -> Unit
 ) {
-    val submitEnabled: Boolean get() = accountProvider.url.isNotEmpty() && (loginFlow is Async.Uninitialized || loginFlow is Async.Loading)
+    val submitEnabled: Boolean get() = accountProvider.url.isNotEmpty() && (loginFlow is AsyncData.Uninitialized || loginFlow is AsyncData.Loading)
 }

 sealed interface LoginFlow {
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderStateProvider.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderStateProvider.kt
index d5f98f5716a..3f7bf892782 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderStateProvider.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderStateProvider.kt
@@ -18,7 +18,7 @@ package io.element.android.features.login.impl.screens.confirmaccountprovider

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
 import io.element.android.features.login.impl.accountprovider.anAccountProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 open class ConfirmAccountProviderStateProvider : PreviewParameterProvider<ConfirmAccountProviderState> {
     override val values: Sequence<ConfirmAccountProviderState>
@@ -31,6 +31,6 @@ open class ConfirmAccountProviderStateProvider : PreviewParameterProvider<Confir
 fun aConfirmAccountProviderState() = ConfirmAccountProviderState(
     accountProvider = anAccountProvider(),
     isAccountCreation = false,
-    loginFlow = Async.Uninitialized,
+    loginFlow = AsyncData.Uninitialized,
     eventSink = {}
 )
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt
index 22508dd3d6b..dc4e7f3b7b2 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderView.kt
@@ -31,7 +31,7 @@ import androidx.compose.ui.unit.dp
 import io.element.android.features.login.impl.R
 import io.element.android.features.login.impl.dialogs.SlidingSyncNotSupportedDialog
 import io.element.android.features.login.impl.error.ChangeServerError
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
 import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
 import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
@@ -56,7 +56,7 @@ fun ConfirmAccountProviderView(
 ) {
     val isLoading by remember(state.loginFlow) {
         derivedStateOf {
-            state.loginFlow is Async.Loading
+            state.loginFlow is AsyncData.Loading
         }
     }
     val eventSink = state.eventSink
@@ -107,7 +107,7 @@ fun ConfirmAccountProviderView(
         }
     ) {
         when (state.loginFlow) {
-            is Async.Failure -> {
+            is AsyncData.Failure -> {
                 when (val error = state.loginFlow.error) {
                     is ChangeServerError.Error -> {
                         ErrorDialog(
@@ -127,14 +127,14 @@ fun ConfirmAccountProviderView(
                     }
                 }
             }
-            is Async.Loading -> Unit // The Continue button shows the loading state
-            is Async.Success -> {
+            is AsyncData.Loading -> Unit // The Continue button shows the loading state
+            is AsyncData.Success -> {
                 when (val loginFlowState = state.loginFlow.data) {
                     is LoginFlow.OidcFlow -> onOidcDetails(loginFlowState.oidcDetails)
                     LoginFlow.PasswordLogin -> onLoginPasswordNeeded()
                 }
             }
-            Async.Uninitialized -> Unit
+            AsyncData.Uninitialized -> Unit
         }
     }
 }
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenter.kt
index b2ea5fb985c..9d7bfde0fa9 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenter.kt
@@ -26,7 +26,7 @@ import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.saveable.rememberSaveable
 import io.element.android.features.login.impl.DefaultLoginUserStory
 import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
-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.matrix.api.auth.MatrixAuthenticationService
 import io.element.android.libraries.matrix.api.core.SessionId
@@ -43,8 +43,8 @@ class LoginPasswordPresenter @Inject constructor(
     @Composable
     override fun present(): LoginPasswordState {
         val localCoroutineScope = rememberCoroutineScope()
-        val loginAction: MutableState<Async<SessionId>> = remember {
-            mutableStateOf(Async.Uninitialized)
+        val loginAction: MutableState<AsyncData<SessionId>> = remember {
+            mutableStateOf(AsyncData.Uninitialized)
         }

         val formState = rememberSaveable {
@@ -63,7 +63,7 @@ class LoginPasswordPresenter @Inject constructor(
                 LoginPasswordEvents.Submit -> {
                     localCoroutineScope.submit(formState.value, loginAction)
                 }
-                LoginPasswordEvents.ClearError -> loginAction.value = Async.Uninitialized
+                LoginPasswordEvents.ClearError -> loginAction.value = AsyncData.Uninitialized
             }
         }

@@ -75,16 +75,16 @@ class LoginPasswordPresenter @Inject constructor(
         )
     }

-    private fun CoroutineScope.submit(formState: LoginFormState, loggedInState: MutableState<Async<SessionId>>) = launch {
-        loggedInState.value = Async.Loading()
+    private fun CoroutineScope.submit(formState: LoginFormState, loggedInState: MutableState<AsyncData<SessionId>>) = launch {
+        loggedInState.value = AsyncData.Loading()
         authenticationService.login(formState.login.trim(), formState.password)
             .onSuccess { sessionId ->
                 // We will not navigate to the WaitList screen, so the login user story is done
                 defaultLoginUserStory.setLoginFlowIsDone(true)
-                loggedInState.value = Async.Success(sessionId)
+                loggedInState.value = AsyncData.Success(sessionId)
             }
             .onFailure { failure ->
-                loggedInState.value = Async.Failure(failure)
+                loggedInState.value = AsyncData.Failure(failure)
             }
     }

diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordState.kt
index cf4e0d8ee59..d17c44a6716 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordState.kt
@@ -18,18 +18,18 @@ package io.element.android.features.login.impl.screens.loginpassword

 import android.os.Parcelable
 import io.element.android.features.login.impl.accountprovider.AccountProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.core.SessionId
 import kotlinx.parcelize.Parcelize

 data class LoginPasswordState(
     val accountProvider: AccountProvider,
     val formState: LoginFormState,
-    val loginAction: Async<SessionId>,
+    val loginAction: AsyncData<SessionId>,
     val eventSink: (LoginPasswordEvents) -> Unit
 ) {
     val submitEnabled: Boolean
-        get() = loginAction !is Async.Failure &&
+        get() = loginAction !is AsyncData.Failure &&
             formState.login.isNotEmpty() &&
             formState.password.isNotEmpty()
 }
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordStateProvider.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordStateProvider.kt
index b4f5a846915..9b501ac238a 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordStateProvider.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordStateProvider.kt
@@ -18,22 +18,22 @@ package io.element.android.features.login.impl.screens.loginpassword

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
 import io.element.android.features.login.impl.accountprovider.anAccountProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 open class LoginPasswordStateProvider : PreviewParameterProvider<LoginPasswordState> {
     override val values: Sequence<LoginPasswordState>
         get() = sequenceOf(
             aLoginPasswordState(),
             // Loading
-            aLoginPasswordState().copy(loginAction = Async.Loading()),
+            aLoginPasswordState().copy(loginAction = AsyncData.Loading()),
             // Error
-            aLoginPasswordState().copy(loginAction = Async.Failure(Exception("An error occurred"))),
+            aLoginPasswordState().copy(loginAction = AsyncData.Failure(Exception("An error occurred"))),
         )
 }

 fun aLoginPasswordState() = LoginPasswordState(
     accountProvider = anAccountProvider(),
     formState = LoginFormState.Default,
-    loginAction = Async.Uninitialized,
+    loginAction = AsyncData.Uninitialized,
     eventSink = {}
 )
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt
index 9a5735fe106..b49fe6cf00d 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordView.kt
@@ -54,7 +54,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons
 import io.element.android.features.login.impl.R
 import io.element.android.features.login.impl.error.isWaitListError
 import io.element.android.features.login.impl.error.loginError
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
@@ -84,7 +84,7 @@ fun LoginPasswordView(
 ) {
     val isLoading by remember(state.loginAction) {
         derivedStateOf {
-            state.loginAction is Async.Loading
+            state.loginAction is AsyncData.Loading
         }
     }
     val focusManager = LocalFocusManager.current
@@ -148,7 +148,7 @@ fun LoginPasswordView(
             )
             Spacer(modifier = Modifier.height(60.dp))

-            if (state.loginAction is Async.Failure) {
+            if (state.loginAction is AsyncData.Failure) {
                 when {
                     state.loginAction.error.isWaitListError() -> {
                         onWaitListError(state.formState)
@@ -224,7 +224,7 @@ private fun LoginForm(
         )

         var passwordVisible by remember { mutableStateOf(false) }
-        if (state.loginAction is Async.Loading) {
+        if (state.loginAction is AsyncData.Loading) {
             // Ensure password is hidden when user submits the form
             passwordVisible = false
         }
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenter.kt
index 1d8271e3947..247624316d2 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenter.kt
@@ -27,7 +27,7 @@ import androidx.compose.runtime.setValue
 import io.element.android.features.login.impl.changeserver.ChangeServerPresenter
 import io.element.android.features.login.impl.resolver.HomeserverData
 import io.element.android.features.login.impl.resolver.HomeserverResolver
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.architecture.Presenter
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.delay
@@ -46,8 +46,8 @@ class SearchAccountProviderPresenter @Inject constructor(
         }
         val changeServerState = changeServerPresenter.present()

-        val data: MutableState<Async<List<HomeserverData>>> = remember {
-            mutableStateOf(Async.Uninitialized)
+        val data: MutableState<AsyncData<List<HomeserverData>>> = remember {
+            mutableStateOf(AsyncData.Uninitialized)
         }

         LaunchedEffect(userInput) {
@@ -70,16 +70,16 @@ class SearchAccountProviderPresenter @Inject constructor(
         )
     }

-    private fun CoroutineScope.onUserInput(userInput: String, data: MutableState<Async<List<HomeserverData>>>) = launch {
-        data.value = Async.Uninitialized
+    private fun CoroutineScope.onUserInput(userInput: String, data: MutableState<AsyncData<List<HomeserverData>>>) = launch {
+        data.value = AsyncData.Uninitialized
         // Debounce
         delay(300)
-        data.value = Async.Loading()
+        data.value = AsyncData.Loading()
         homeserverResolver.resolve(userInput).collect {
-            data.value = Async.Success(it)
+            data.value = AsyncData.Success(it)
         }
-        if (data.value !is Async.Success) {
-            data.value = Async.Uninitialized
+        if (data.value !is AsyncData.Success) {
+            data.value = AsyncData.Uninitialized
         }
     }
 }
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderState.kt
index 15859afde1d..825befa356f 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderState.kt
@@ -18,12 +18,12 @@ package io.element.android.features.login.impl.screens.searchaccountprovider

 import io.element.android.features.login.impl.changeserver.ChangeServerState
 import io.element.android.features.login.impl.resolver.HomeserverData
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 // Do not use default value, so no member get forgotten in the presenters.
 data class SearchAccountProviderState(
     val userInput: String,
-    val userInputResult: Async<List<HomeserverData>>,
+    val userInputResult: AsyncData<List<HomeserverData>>,
     val changeServerState: ChangeServerState,
     val eventSink: (SearchAccountProviderEvents) -> Unit
 )
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderStateProvider.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderStateProvider.kt
index 50b24b39649..2df65afee4c 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderStateProvider.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderStateProvider.kt
@@ -20,20 +20,20 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
 import io.element.android.appconfig.AuthenticationConfig
 import io.element.android.features.login.impl.changeserver.aChangeServerState
 import io.element.android.features.login.impl.resolver.HomeserverData
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 open class SearchAccountProviderStateProvider : PreviewParameterProvider<SearchAccountProviderState> {
     override val values: Sequence<SearchAccountProviderState>
         get() = sequenceOf(
             aSearchAccountProviderState(),
-            aSearchAccountProviderState(userInputResult = Async.Success(aHomeserverDataList())),
+            aSearchAccountProviderState(userInputResult = AsyncData.Success(aHomeserverDataList())),
             // Add other state here
         )
 }

 fun aSearchAccountProviderState(
     userInput: String = "",
-    userInputResult: Async<List<HomeserverData>> = Async.Uninitialized,
+    userInputResult: AsyncData<List<HomeserverData>> = AsyncData.Uninitialized,
 ) = SearchAccountProviderState(
     userInput = userInput,
     userInputResult = userInputResult,
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt
index 09e8661b771..245c874ae2a 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderView.kt
@@ -55,7 +55,7 @@ import io.element.android.features.login.impl.accountprovider.AccountProviderVie
 import io.element.android.features.login.impl.changeserver.ChangeServerEvents
 import io.element.android.features.login.impl.changeserver.ChangeServerView
 import io.element.android.features.login.impl.resolver.HomeserverData
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.components.form.textFieldState
@@ -152,10 +152,10 @@ fun SearchAccountProviderView(
                 }

                 when (state.userInputResult) {
-                    is Async.Failure -> {
+                    is AsyncData.Failure -> {
                         // Ignore errors (let the user type more chars)
                     }
-                    is Async.Loading -> {
+                    is AsyncData.Loading -> {
                         item {
                             Box(
                                 modifier = Modifier
@@ -167,7 +167,7 @@ fun SearchAccountProviderView(
                             }
                         }
                     }
-                    is Async.Success -> {
+                    is AsyncData.Success -> {
                         items(state.userInputResult.data) { homeserverData ->
                             val item = homeserverData.toAccountProvider()
                             AccountProviderView(
@@ -178,7 +178,7 @@ fun SearchAccountProviderView(
                             )
                         }
                     }
-                    Async.Uninitialized -> Unit
+                    AsyncData.Uninitialized -> Unit
                 }
                 item {
                     Spacer(Modifier.height(32.dp))
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenter.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenter.kt
index 039986343be..7432111b227 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenter.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenter.kt
@@ -27,7 +27,7 @@ import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import io.element.android.features.login.impl.DefaultLoginUserStory
 import io.element.android.features.login.impl.screens.loginpassword.LoginFormState
-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.core.meta.BuildMeta
 import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
@@ -55,8 +55,8 @@ class WaitListPresenter @AssistedInject constructor(
             authenticationService.getHomeserverDetails().value?.url ?: "server"
         }

-        val loginAction: MutableState<Async<SessionId>> = remember {
-            mutableStateOf(Async.Uninitialized)
+        val loginAction: MutableState<AsyncData<SessionId>> = remember {
+            mutableStateOf(AsyncData.Uninitialized)
         }

         val attemptNumber = remember { mutableIntStateOf(0) }
@@ -70,7 +70,7 @@ class WaitListPresenter @AssistedInject constructor(
                         coroutineScope.loginAttempt(formState, loginAction)
                     }
                 }
-                WaitListEvents.ClearError -> loginAction.value = Async.Uninitialized
+                WaitListEvents.ClearError -> loginAction.value = AsyncData.Uninitialized
                 WaitListEvents.Continue -> defaultLoginUserStory.setLoginFlowIsDone(true)
             }
         }
@@ -83,15 +83,15 @@ class WaitListPresenter @AssistedInject constructor(
         )
     }

-    private fun CoroutineScope.loginAttempt(formState: LoginFormState, loggedInState: MutableState<Async<SessionId>>) = launch {
+    private fun CoroutineScope.loginAttempt(formState: LoginFormState, loggedInState: MutableState<AsyncData<SessionId>>) = launch {
         Timber.w("Attempt to login...")
-        loggedInState.value = Async.Loading()
+        loggedInState.value = AsyncData.Loading()
         authenticationService.login(formState.login.trim(), formState.password)
             .onSuccess { sessionId ->
-                loggedInState.value = Async.Success(sessionId)
+                loggedInState.value = AsyncData.Success(sessionId)
             }
             .onFailure { failure ->
-                loggedInState.value = Async.Failure(failure)
+                loggedInState.value = AsyncData.Failure(failure)
             }
     }
 }
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListState.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListState.kt
index f50de7e194b..fc85f6637a4 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListState.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListState.kt
@@ -16,13 +16,13 @@

 package io.element.android.features.login.impl.screens.waitlistscreen

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.core.SessionId

 // Do not use default value, so no member get forgotten in the presenters.
 data class WaitListState(
     val appName: String,
     val serverName: String,
-    val loginAction: Async<SessionId>,
+    val loginAction: AsyncData<SessionId>,
     val eventSink: (WaitListEvents) -> Unit
 )
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListStateProvider.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListStateProvider.kt
index 94a38fa406f..61550a230d2 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListStateProvider.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListStateProvider.kt
@@ -17,17 +17,17 @@
 package io.element.android.features.login.impl.screens.waitlistscreen

 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.matrix.api.core.SessionId

 open class WaitListStateProvider : PreviewParameterProvider<WaitListState> {
     override val values: Sequence<WaitListState>
         get() = sequenceOf(
-            aWaitListState(loginAction = Async.Uninitialized),
-            aWaitListState(loginAction = Async.Loading()),
-            aWaitListState(loginAction = Async.Failure(Throwable("error"))),
-            aWaitListState(loginAction = Async.Failure(Throwable(message = "IO_ELEMENT_X_WAIT_LIST"))),
-            aWaitListState(loginAction = Async.Success(SessionId("@alice:element.io"))),
+            aWaitListState(loginAction = AsyncData.Uninitialized),
+            aWaitListState(loginAction = AsyncData.Loading()),
+            aWaitListState(loginAction = AsyncData.Failure(Throwable("error"))),
+            aWaitListState(loginAction = AsyncData.Failure(Throwable(message = "IO_ELEMENT_X_WAIT_LIST"))),
+            aWaitListState(loginAction = AsyncData.Success(SessionId("@alice:element.io"))),
             // Add other state here
         )
 }
@@ -35,7 +35,7 @@ open class WaitListStateProvider : PreviewParameterProvider<WaitListState> {
 fun aWaitListState(
     appName: String = "Element X",
     serverName: String = "server.org",
-    loginAction: Async<SessionId> = Async.Uninitialized,
+    loginAction: AsyncData<SessionId> = AsyncData.Uninitialized,
 ) = WaitListState(
     appName = appName,
     serverName = serverName,
diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListView.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListView.kt
index 0e40a4827a1..e56d1b5bca4 100644
--- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListView.kt
+++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListView.kt
@@ -33,7 +33,7 @@ import androidx.lifecycle.Lifecycle
 import io.element.android.features.login.impl.R
 import io.element.android.features.login.impl.error.isWaitListError
 import io.element.android.features.login.impl.error.loginError
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.atomic.pages.SunsetPage
 import io.element.android.libraries.designsystem.components.dialogs.RetryDialog
 import io.element.android.libraries.designsystem.preview.ElementPreview
@@ -89,12 +89,12 @@ private fun WaitListContent(
     ) {
         val title = stringResource(
             when (state.loginAction) {
-                is Async.Success -> R.string.screen_waitlist_title_success
+                is AsyncData.Success -> R.string.screen_waitlist_title_success
                 else -> R.string.screen_waitlist_title
             }
         )
         val subtitle = when (state.loginAction) {
-            is Async.Success -> stringResource(
+            is AsyncData.Success -> stringResource(
                 id = R.string.screen_waitlist_message_success,
                 state.appName,
             )
@@ -122,7 +122,7 @@ private fun OverallContent(
     modifier: Modifier = Modifier,
 ) {
     Box(modifier = modifier.fillMaxSize()) {
-        if (state.loginAction !is Async.Success) {
+        if (state.loginAction !is AsyncData.Success) {
             CompositionLocalProvider(LocalContentColor provides Color.Black) {
                 TextButton(
                     text = stringResource(CommonStrings.action_cancel),
@@ -130,7 +130,7 @@ private fun OverallContent(
                 )
             }
         }
-        if (state.loginAction is Async.Success) {
+        if (state.loginAction is AsyncData.Success) {
             Button(
                 text = stringResource(id = CommonStrings.action_continue),
                 onClick = { state.eventSink.invoke(WaitListEvents.Continue) },
diff --git a/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutState.kt b/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutState.kt
index 71e97a856df..e5b6af99e47 100644
--- a/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutState.kt
+++ b/features/logout/api/src/main/kotlin/io/element/android/features/logout/api/direct/DirectLogoutState.kt
@@ -16,11 +16,10 @@

 package io.element.android.features.logout.api.direct

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction

 data class DirectLogoutState(
     val canDoDirectSignOut: Boolean,
-    val showConfirmationDialog: Boolean,
-    val logoutAction: Async<String?>,
+    val logoutAction: AsyncAction<String?>,
     val eventSink: (DirectLogoutEvents) -> Unit,
 )
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutPresenter.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutPresenter.kt
index b8d8772104d..165987900c1 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutPresenter.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutPresenter.kt
@@ -25,7 +25,8 @@ import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.setValue
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.architecture.runCatchingUpdatingState
 import io.element.android.libraries.core.bool.orTrue
@@ -50,8 +51,8 @@ class LogoutPresenter @Inject constructor(
     @Composable
     override fun present(): LogoutState {
         val localCoroutineScope = rememberCoroutineScope()
-        val logoutAction: MutableState<Async<String?>> = remember {
-            mutableStateOf(Async.Uninitialized)
+        val logoutAction: MutableState<AsyncAction<String?>> = remember {
+            mutableStateOf(AsyncAction.Uninitialized)
         }

         val secureStorageFlag by featureFlagService.isFeatureEnabledFlow(FeatureFlags.SecureStorage)
@@ -66,7 +67,6 @@ class LogoutPresenter @Inject constructor(
         }
             .collectAsState(initial = BackupUploadState.Unknown)

-        var showLogoutDialog by remember { mutableStateOf(false) }
         var isLastSession by remember { mutableStateOf(false) }
         LaunchedEffect(Unit) {
             isLastSession = encryptionService.isLastDevice().getOrNull() ?: false
@@ -75,8 +75,8 @@ class LogoutPresenter @Inject constructor(
         val backupState by encryptionService.backupStateStateFlow.collectAsState()
         val recoveryState by encryptionService.recoveryStateStateFlow.collectAsState()

-        val doesBackupExistOnServerAction: MutableState<Async<Boolean>> = remember {
-            mutableStateOf(Async.Uninitialized)
+        val doesBackupExistOnServerAction: MutableState<AsyncData<Boolean>> = remember {
+            mutableStateOf(AsyncData.Uninitialized)
         }

         LaunchedEffect(backupState) {
@@ -88,16 +88,14 @@ class LogoutPresenter @Inject constructor(
         fun handleEvents(event: LogoutEvents) {
             when (event) {
                 is LogoutEvents.Logout -> {
-                    if (showLogoutDialog || event.ignoreSdkError) {
-                        showLogoutDialog = false
+                    if (logoutAction.value.isConfirming() || event.ignoreSdkError) {
                         localCoroutineScope.logout(logoutAction, event.ignoreSdkError)
                     } else {
-                        showLogoutDialog = true
+                        logoutAction.value = AsyncAction.Confirming
                     }
                 }
                 LogoutEvents.CloseDialogs -> {
-                    logoutAction.value = Async.Uninitialized
-                    showLogoutDialog = false
+                    logoutAction.value = AsyncAction.Uninitialized
                 }
             }
         }
@@ -108,20 +106,19 @@ class LogoutPresenter @Inject constructor(
             doesBackupExistOnServer = doesBackupExistOnServerAction.value.dataOrNull().orTrue(),
             recoveryState = recoveryState,
             backupUploadState = backupUploadState,
-            showConfirmationDialog = showLogoutDialog,
             logoutAction = logoutAction.value,
             eventSink = ::handleEvents
         )
     }

-    private fun CoroutineScope.getKeyBackupStatus(action: MutableState<Async<Boolean>>) = launch {
+    private fun CoroutineScope.getKeyBackupStatus(action: MutableState<AsyncData<Boolean>>) = launch {
         suspend {
             encryptionService.doesBackupExistOnServer().getOrThrow()
         }.runCatchingUpdatingState(action)
     }

     private fun CoroutineScope.logout(
-        logoutAction: MutableState<Async<String?>>,
+        logoutAction: MutableState<AsyncAction<String?>>,
         ignoreSdkError: Boolean,
     ) = launch {
         suspend {
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutState.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutState.kt
index abade32b963..6da9df8e727 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutState.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutState.kt
@@ -16,7 +16,7 @@

 package io.element.android.features.logout.impl

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.encryption.BackupState
 import io.element.android.libraries.matrix.api.encryption.BackupUploadState
 import io.element.android.libraries.matrix.api.encryption.RecoveryState
@@ -27,7 +27,6 @@ data class LogoutState(
     val doesBackupExistOnServer: Boolean,
     val recoveryState: RecoveryState,
     val backupUploadState: BackupUploadState,
-    val showConfirmationDialog: Boolean,
-    val logoutAction: Async<String?>,
+    val logoutAction: AsyncAction<String?>,
     val eventSink: (LogoutEvents) -> Unit,
 )
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutStateProvider.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutStateProvider.kt
index 8c9482105d9..33c60a851f2 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutStateProvider.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutStateProvider.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.logout.impl

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.encryption.BackupState
 import io.element.android.libraries.matrix.api.encryption.BackupUploadState
 import io.element.android.libraries.matrix.api.encryption.RecoveryState
@@ -30,9 +30,9 @@ open class LogoutStateProvider : PreviewParameterProvider<LogoutState> {
             aLogoutState(isLastSession = true),
             aLogoutState(isLastSession = false, backupUploadState = BackupUploadState.Uploading(66, 200)),
             aLogoutState(isLastSession = true, backupUploadState = BackupUploadState.Done),
-            aLogoutState(showConfirmationDialog = true),
-            aLogoutState(logoutAction = Async.Loading()),
-            aLogoutState(logoutAction = Async.Failure(Exception("Failed to logout"))),
+            aLogoutState(logoutAction = AsyncAction.Confirming),
+            aLogoutState(logoutAction = AsyncAction.Loading),
+            aLogoutState(logoutAction = AsyncAction.Failure(Exception("Failed to logout"))),
             aLogoutState(backupUploadState = BackupUploadState.SteadyException(SteadyStateException.Connection("No network"))),
             // Last session no recovery
             aLogoutState(isLastSession = true, recoveryState = RecoveryState.DISABLED),
@@ -47,15 +47,13 @@ fun aLogoutState(
     doesBackupExistOnServer: Boolean = true,
     recoveryState: RecoveryState = RecoveryState.ENABLED,
     backupUploadState: BackupUploadState = BackupUploadState.Unknown,
-    showConfirmationDialog: Boolean = false,
-    logoutAction: Async<String?> = Async.Uninitialized,
+    logoutAction: AsyncAction<String?> = AsyncAction.Uninitialized,
 ) = LogoutState(
     isLastSession = isLastSession,
     backupState = backupState,
     doesBackupExistOnServer = doesBackupExistOnServer,
     recoveryState = recoveryState,
     backupUploadState = backupUploadState,
-    showConfirmationDialog = showConfirmationDialog,
     logoutAction = logoutAction,
     eventSink = {}
 )
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutView.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutView.kt
index e025f4825a5..ecec90cf06e 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutView.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/LogoutView.kt
@@ -32,8 +32,7 @@ import androidx.compose.ui.unit.dp
 import io.element.android.compound.theme.ElementTheme
 import io.element.android.features.logout.impl.tools.isBackingUp
 import io.element.android.features.logout.impl.ui.LogoutActionDialog
-import io.element.android.features.logout.impl.ui.LogoutConfirmationDialog
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage
 import io.element.android.libraries.designsystem.preview.ElementPreview
 import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@@ -79,20 +78,11 @@ fun LogoutView(
         },
     )

-    // Log out confirmation dialog
-    if (state.showConfirmationDialog) {
-        LogoutConfirmationDialog(
-            onSubmitClicked = {
-                eventSink(LogoutEvents.Logout(ignoreSdkError = false))
-            },
-            onDismiss = {
-                eventSink(LogoutEvents.CloseDialogs)
-            }
-        )
-    }
-
     LogoutActionDialog(
         state.logoutAction,
+        onConfirmClicked = {
+            eventSink(LogoutEvents.Logout(ignoreSdkError = false))
+        },
         onForceLogoutClicked = {
             eventSink(LogoutEvents.Logout(ignoreSdkError = true))
         },
@@ -148,13 +138,13 @@ private fun ColumnScope.Buttons(
         )
     }
     val signOutSubmitRes = when {
-        logoutAction is Async.Loading -> R.string.screen_signout_in_progress_dialog_content
+        logoutAction is AsyncAction.Loading -> R.string.screen_signout_in_progress_dialog_content
         state.backupUploadState.isBackingUp() -> CommonStrings.action_signout_anyway
         else -> CommonStrings.action_signout
     }
     Button(
         text = stringResource(id = signOutSubmitRes),
-        showProgress = logoutAction is Async.Loading,
+        showProgress = logoutAction is AsyncAction.Loading,
         destructive = true,
         modifier = Modifier
             .fillMaxWidth()
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutPresenter.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutPresenter.kt
index 70827e8ab0e..8ee46b63ac5 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutPresenter.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutPresenter.kt
@@ -30,7 +30,7 @@ import io.element.android.features.logout.api.direct.DirectLogoutEvents
 import io.element.android.features.logout.api.direct.DirectLogoutPresenter
 import io.element.android.features.logout.api.direct.DirectLogoutState
 import io.element.android.features.logout.impl.tools.isBackingUp
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.architecture.runCatchingUpdatingState
 import io.element.android.libraries.di.SessionScope
 import io.element.android.libraries.featureflag.api.FeatureFlagService
@@ -54,8 +54,8 @@ class DefaultDirectLogoutPresenter @Inject constructor(
     override fun present(): DirectLogoutState {
         val localCoroutineScope = rememberCoroutineScope()

-        val logoutAction: MutableState<Async<String?>> = remember {
-            mutableStateOf(Async.Uninitialized)
+        val logoutAction: MutableState<AsyncAction<String?>> = remember {
+            mutableStateOf(AsyncAction.Uninitialized)
         }

         val secureStorageFlag by featureFlagService.isFeatureEnabledFlow(FeatureFlags.SecureStorage)
@@ -70,7 +70,6 @@ class DefaultDirectLogoutPresenter @Inject constructor(
         }
             .collectAsState(initial = BackupUploadState.Unknown)

-        var showLogoutDialog by remember { mutableStateOf(false) }
         var isLastSession by remember { mutableStateOf(false) }
         LaunchedEffect(Unit) {
             isLastSession = encryptionService.isLastDevice().getOrNull() ?: false
@@ -79,16 +78,14 @@ class DefaultDirectLogoutPresenter @Inject constructor(
         fun handleEvents(event: DirectLogoutEvents) {
             when (event) {
                 is DirectLogoutEvents.Logout -> {
-                    if (showLogoutDialog || event.ignoreSdkError) {
-                        showLogoutDialog = false
+                    if (logoutAction.value.isConfirming() || event.ignoreSdkError) {
                         localCoroutineScope.logout(logoutAction, event.ignoreSdkError)
                     } else {
-                        showLogoutDialog = true
+                        logoutAction.value = AsyncAction.Confirming
                     }
                 }
                 DirectLogoutEvents.CloseDialogs -> {
-                    logoutAction.value = Async.Uninitialized
-                    showLogoutDialog = false
+                    logoutAction.value = AsyncAction.Uninitialized
                 }
             }
         }
@@ -96,14 +93,13 @@ class DefaultDirectLogoutPresenter @Inject constructor(
         return DirectLogoutState(
             canDoDirectSignOut = !isLastSession &&
                 !backupUploadState.isBackingUp(),
-            showConfirmationDialog = showLogoutDialog,
             logoutAction = logoutAction.value,
             eventSink = ::handleEvents
         )
     }

     private fun CoroutineScope.logout(
-        logoutAction: MutableState<Async<String?>>,
+        logoutAction: MutableState<AsyncAction<String?>>,
         ignoreSdkError: Boolean,
     ) = launch {
         suspend {
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutView.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutView.kt
index bd00975864d..f646d86c9e9 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutView.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutView.kt
@@ -22,7 +22,6 @@ import io.element.android.features.logout.api.direct.DirectLogoutEvents
 import io.element.android.features.logout.api.direct.DirectLogoutState
 import io.element.android.features.logout.api.direct.DirectLogoutView
 import io.element.android.features.logout.impl.ui.LogoutActionDialog
-import io.element.android.features.logout.impl.ui.LogoutConfirmationDialog
 import io.element.android.libraries.di.SessionScope
 import javax.inject.Inject

@@ -34,20 +33,11 @@ class DefaultDirectLogoutView @Inject constructor() : DirectLogoutView {
         onSuccessLogout: (logoutUrlResult: String?) -> Unit,
     ) {
         val eventSink = state.eventSink
-        // Log out confirmation dialog
-        if (state.showConfirmationDialog) {
-            LogoutConfirmationDialog(
-                onSubmitClicked = {
-                    eventSink(DirectLogoutEvents.Logout(ignoreSdkError = false))
-                },
-                onDismiss = {
-                    eventSink(DirectLogoutEvents.CloseDialogs)
-                }
-            )
-        }
-
         LogoutActionDialog(
             state.logoutAction,
+            onConfirmClicked = {
+                eventSink(DirectLogoutEvents.Logout(ignoreSdkError = false))
+            },
             onForceLogoutClicked = {
                 eventSink(DirectLogoutEvents.Logout(ignoreSdkError = true))
             },
diff --git a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/ui/LogoutActionDialog.kt b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/ui/LogoutActionDialog.kt
index 9baad1d1f3e..6a1891fd238 100644
--- a/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/ui/LogoutActionDialog.kt
+++ b/features/logout/impl/src/main/kotlin/io/element/android/features/logout/impl/ui/LogoutActionDialog.kt
@@ -20,22 +20,30 @@ import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.ui.res.stringResource
 import io.element.android.features.logout.impl.R
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.designsystem.components.ProgressDialog
 import io.element.android.libraries.designsystem.components.dialogs.RetryDialog
 import io.element.android.libraries.ui.strings.CommonStrings

 @Composable
 fun LogoutActionDialog(
-    state: Async<String?>,
+    state: AsyncAction<String?>,
+    onConfirmClicked: () -> Unit,
     onForceLogoutClicked: () -> Unit,
-    onDismissError: () -> Unit,
+    onDismissError: () -> Unit, // TODO Rename
     onSuccessLogout: (String?) -> Unit,
 ) {
     when (state) {
-        is Async.Loading ->
+        AsyncAction.Uninitialized ->
+            Unit
+        AsyncAction.Confirming ->
+            LogoutConfirmationDialog(
+                onSubmitClicked = onConfirmClicked,
+                onDismiss = onDismissError
+            )
+        is AsyncAction.Loading ->
             ProgressDialog(text = stringResource(id = R.string.screen_signout_in_progress_dialog_content))
-        is Async.Failure ->
+        is AsyncAction.Failure ->
             RetryDialog(
                 title = stringResource(id = CommonStrings.dialog_title_error),
                 content = stringResource(id = CommonStrings.error_unknown),
@@ -43,9 +51,7 @@ fun LogoutActionDialog(
                 onRetry = onForceLogoutClicked,
                 onDismiss = onDismissError,
             )
-        Async.Uninitialized ->
-            Unit
-        is Async.Success ->
+        is AsyncAction.Success ->
             LaunchedEffect(state) {
                 onSuccessLogout(state.data)
             }
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt
index f8682cbd494..c02455d6d38 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt
@@ -65,7 +65,7 @@ import io.element.android.features.networkmonitor.api.NetworkMonitor
 import io.element.android.features.networkmonitor.api.NetworkStatus
 import io.element.android.features.preferences.api.store.PreferencesStore
 import io.element.android.libraries.androidutils.clipboard.ClipboardHelper
-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.core.coroutine.CoroutineDispatchers
 import io.element.android.libraries.core.meta.BuildMeta
@@ -141,11 +141,11 @@ class MessagesPresenter @AssistedInject constructor(
         val userHasPermissionToSendMessage by room.canSendMessageAsState(type = MessageEventType.ROOM_MESSAGE, updateKey = syncUpdateFlow.value)
         val userHasPermissionToRedact by room.canRedactAsState(updateKey = syncUpdateFlow.value)
         val userHasPermissionToSendReaction by room.canSendMessageAsState(type = MessageEventType.REACTION_SENT, updateKey = syncUpdateFlow.value)
-        val roomName: Async<String> by remember {
-            derivedStateOf { roomInfo?.name?.let { Async.Success(it) } ?: Async.Uninitialized }
+        val roomName: AsyncData<String> by remember {
+            derivedStateOf { roomInfo?.name?.let { AsyncData.Success(it) } ?: AsyncData.Uninitialized }
         }
-        val roomAvatar: Async<AvatarData> by remember {
-            derivedStateOf { roomInfo?.avatarData()?.let { Async.Success(it) } ?: Async.Uninitialized }
+        val roomAvatar: AsyncData<AvatarData> by remember {
+            derivedStateOf { roomInfo?.avatarData()?.let { AsyncData.Success(it) } ?: AsyncData.Uninitialized }
         }

         var hasDismissedInviteDialog by rememberSaveable {
@@ -162,7 +162,7 @@ class MessagesPresenter @AssistedInject constructor(
             }
         }

-        val inviteProgress = remember { mutableStateOf<Async<Unit>>(Async.Uninitialized) }
+        val inviteProgress = remember { mutableStateOf<AsyncData<Unit>>(AsyncData.Uninitialized) }
         var showReinvitePrompt by remember { mutableStateOf(false) }
         LaunchedEffect(hasDismissedInviteDialog, composerState.hasFocus, syncUpdateFlow) {
             withContext(dispatchers.io) {
@@ -279,8 +279,8 @@ class MessagesPresenter @AssistedInject constructor(
             .onFailure { Timber.e(it) }
     }

-    private fun CoroutineScope.reinviteOtherUser(inviteProgress: MutableState<Async<Unit>>) = launch(dispatchers.io) {
-        inviteProgress.value = Async.Loading()
+    private fun CoroutineScope.reinviteOtherUser(inviteProgress: MutableState<AsyncData<Unit>>) = launch(dispatchers.io) {
+        inviteProgress.value = AsyncData.Loading()
         runCatching {
             room.updateMembers()

@@ -296,10 +296,10 @@ class MessagesPresenter @AssistedInject constructor(
             }.getOrThrow()
         }.fold(
             onSuccess = {
-                inviteProgress.value = Async.Success(Unit)
+                inviteProgress.value = AsyncData.Success(Unit)
             },
             onFailure = {
-                inviteProgress.value = Async.Failure(it)
+                inviteProgress.value = AsyncData.Failure(it)
             }
         )
     }
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt
index c7ef5f320fb..c1965356078 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesState.kt
@@ -25,7 +25,7 @@ import io.element.android.features.messages.impl.timeline.components.reactionsum
 import io.element.android.features.messages.impl.timeline.components.receipt.bottomsheet.ReadReceiptBottomSheetState
 import io.element.android.features.messages.impl.timeline.components.retrysendmenu.RetrySendMenuState
 import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.components.avatar.AvatarData
 import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
 import io.element.android.libraries.matrix.api.core.RoomId
@@ -33,8 +33,8 @@ import io.element.android.libraries.matrix.api.core.RoomId
 @Immutable
 data class MessagesState(
     val roomId: RoomId,
-    val roomName: Async<String>,
-    val roomAvatar: Async<AvatarData>,
+    val roomName: AsyncData<String>,
+    val roomAvatar: AsyncData<AvatarData>,
     val userHasPermissionToSendMessage: Boolean,
     val userHasPermissionToRedact: Boolean,
     val userHasPermissionToSendReaction: Boolean,
@@ -48,7 +48,7 @@ data class MessagesState(
     val readReceiptBottomSheetState: ReadReceiptBottomSheetState,
     val hasNetworkConnection: Boolean,
     val snackbarMessage: SnackbarMessage?,
-    val inviteProgress: Async<Unit>,
+    val inviteProgress: AsyncData<Unit>,
     val showReinvitePrompt: Boolean,
     val enableTextFormatting: Boolean,
     val enableVoiceMessages: Boolean,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt
index 2984e4e0876..8fc7466f95d 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesStateProvider.kt
@@ -29,7 +29,7 @@ import io.element.android.features.messages.impl.timeline.components.retrysendme
 import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent
 import io.element.android.features.messages.impl.voicemessages.composer.aVoiceMessageComposerState
 import io.element.android.features.messages.impl.voicemessages.composer.aVoiceMessagePreviewState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.components.avatar.AvatarData
 import io.element.android.libraries.designsystem.components.avatar.AvatarSize
 import io.element.android.libraries.matrix.api.core.RoomId
@@ -47,8 +47,8 @@ open class MessagesStateProvider : PreviewParameterProvider<MessagesState> {
             aMessagesState().copy(userHasPermissionToSendMessage = false),
             aMessagesState().copy(showReinvitePrompt = true),
             aMessagesState().copy(
-                roomName = Async.Uninitialized,
-                roomAvatar = Async.Uninitialized,
+                roomName = AsyncData.Uninitialized,
+                roomAvatar = AsyncData.Uninitialized,
             ),
             aMessagesState().copy(composerState = aMessageComposerState().copy(showTextFormatting = true)),
             aMessagesState().copy(
@@ -83,8 +83,8 @@ open class MessagesStateProvider : PreviewParameterProvider<MessagesState> {

 fun aMessagesState() = MessagesState(
     roomId = RoomId("!id:domain"),
-    roomName = Async.Success("Room name"),
-    roomAvatar = Async.Success(AvatarData("!id:domain", "Room name", size = AvatarSize.TimelineRoom)),
+    roomName = AsyncData.Success("Room name"),
+    roomAvatar = AsyncData.Success(AvatarData("!id:domain", "Room name", size = AvatarSize.TimelineRoom)),
     userHasPermissionToSendMessage = true,
     userHasPermissionToRedact = false,
     userHasPermissionToSendReaction = true,
@@ -117,7 +117,7 @@ fun aMessagesState() = MessagesState(
     ),
     hasNetworkConnection = true,
     snackbarMessage = null,
-    inviteProgress = Async.Uninitialized,
+    inviteProgress = AsyncData.Uninitialized,
     showReinvitePrompt = false,
     enableTextFormatting = true,
     enableVoiceMessages = true,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenter.kt
index f61f0f7b524..604b6520473 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenter.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenter.kt
@@ -25,7 +25,7 @@ import androidx.compose.runtime.remember
 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.matrix.api.core.EventId
 import io.element.android.libraries.matrix.api.core.RoomId
@@ -48,7 +48,7 @@ class ForwardMessagesPresenter @AssistedInject constructor(
         fun create(eventId: String): ForwardMessagesPresenter
     }

-    private val forwardingActionState: MutableState<Async<ImmutableList<RoomId>>> = mutableStateOf(Async.Uninitialized)
+    private val forwardingActionState: MutableState<AsyncData<ImmutableList<RoomId>>> = mutableStateOf(AsyncData.Uninitialized)

     fun onRoomSelected(roomIds: List<RoomId>) {
         matrixCoroutineScope.forwardEvent(eventId, roomIds.toPersistentList(), forwardingActionState)
@@ -62,13 +62,13 @@ class ForwardMessagesPresenter @AssistedInject constructor(

         fun handleEvents(event: ForwardMessagesEvents) {
             when (event) {
-                ForwardMessagesEvents.ClearError -> forwardingActionState.value = Async.Uninitialized
+                ForwardMessagesEvents.ClearError -> forwardingActionState.value = AsyncData.Uninitialized
             }
         }

         return ForwardMessagesState(
             isForwarding = forwardingActionState.value.isLoading(),
-            error = (forwardingActionState.value as? Async.Failure)?.error,
+            error = (forwardingActionState.value as? AsyncData.Failure)?.error,
             forwardingSucceeded = forwardingSucceeded,
             eventSink = { handleEvents(it) }
         )
@@ -77,12 +77,12 @@ class ForwardMessagesPresenter @AssistedInject constructor(
     private fun CoroutineScope.forwardEvent(
         eventId: EventId,
         roomIds: ImmutableList<RoomId>,
-        isForwardMessagesState: MutableState<Async<ImmutableList<RoomId>>>,
+        isForwardMessagesState: MutableState<AsyncData<ImmutableList<RoomId>>>,
     ) = launch {
-        isForwardMessagesState.value = Async.Loading()
+        isForwardMessagesState.value = AsyncData.Loading()
         room.forwardEvent(eventId, roomIds).fold(
-            { isForwardMessagesState.value = Async.Success(roomIds) },
-            { isForwardMessagesState.value = Async.Failure(it) }
+            { isForwardMessagesState.value = AsyncData.Success(roomIds) },
+            { isForwardMessagesState.value = AsyncData.Failure(it) }
         )
     }
 }
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenter.kt
index d474e3d25f2..a7040d50e4c 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenter.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenter.kt
@@ -27,7 +27,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.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.architecture.runUpdatingState
 import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
@@ -60,14 +60,14 @@ class ReportMessagePresenter @AssistedInject constructor(
         val coroutineScope = rememberCoroutineScope()
         var reason by rememberSaveable { mutableStateOf("") }
         var blockUser by rememberSaveable { mutableStateOf(false) }
-        var result: MutableState<Async<Unit>> = remember { mutableStateOf(Async.Uninitialized) }
+        var result: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }

         fun handleEvents(event: ReportMessageEvents) {
             when (event) {
                 is ReportMessageEvents.UpdateReason -> reason = event.reason
                 ReportMessageEvents.ToggleBlockUser -> blockUser = !blockUser
                 ReportMessageEvents.Report -> coroutineScope.report(inputs.eventId, inputs.senderId, reason, blockUser, result)
-                ReportMessageEvents.ClearError -> result.value = Async.Uninitialized
+                ReportMessageEvents.ClearError -> result.value = AsyncAction.Uninitialized
             }
         }

@@ -84,7 +84,7 @@ class ReportMessagePresenter @AssistedInject constructor(
         userId: UserId,
         reason: String,
         blockUser: Boolean,
-        result: MutableState<Async<Unit>>,
+        result: MutableState<AsyncAction<Unit>>,
     ) = launch {
         result.runUpdatingState {
             val userIdToBlock = userId.takeIf { blockUser }
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageState.kt
index 809668c88f5..71afa430318 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageState.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageState.kt
@@ -16,11 +16,11 @@

 package io.element.android.features.messages.impl.report

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction

 data class ReportMessageState(
     val reason: String,
     val blockUser: Boolean,
-    val result: Async<Unit>,
+    val result: AsyncAction<Unit>,
     val eventSink: (ReportMessageEvents) -> Unit
 )
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt
index de5e787a3dd..52f0948264c 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageStateProvider.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.messages.impl.report

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction

 open class ReportMessageStateProvider : PreviewParameterProvider<ReportMessageState> {
     override val values: Sequence<ReportMessageState>
@@ -25,9 +25,9 @@ open class ReportMessageStateProvider : PreviewParameterProvider<ReportMessageSt
             aReportMessageState(),
             aReportMessageState(reason = "This user is making the chat very toxic."),
             aReportMessageState(reason = "This user is making the chat very toxic.", blockUser = true),
-            aReportMessageState(reason = "This user is making the chat very toxic.", blockUser = true, result = Async.Loading()),
-            aReportMessageState(reason = "This user is making the chat very toxic.", blockUser = true, result = Async.Failure(Throwable("error"))),
-            aReportMessageState(reason = "This user is making the chat very toxic.", blockUser = true, result = Async.Success(Unit)),
+            aReportMessageState(reason = "This user is making the chat very toxic.", blockUser = true, result = AsyncAction.Loading),
+            aReportMessageState(reason = "This user is making the chat very toxic.", blockUser = true, result = AsyncAction.Failure(Throwable("error"))),
+            aReportMessageState(reason = "This user is making the chat very toxic.", blockUser = true, result = AsyncAction.Success(Unit)),
             // Add other states here
         )
 }
@@ -35,7 +35,7 @@ open class ReportMessageStateProvider : PreviewParameterProvider<ReportMessageSt
 fun aReportMessageState(
     reason: String = "",
     blockUser: Boolean = false,
-    result: Async<Unit> = Async.Uninitialized,
+    result: AsyncAction<Unit> = AsyncAction.Uninitialized,
 ) = ReportMessageState(
     reason = reason,
     blockUser = blockUser,
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt
index 6642ad4b55b..2207c817506 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/report/ReportMessageView.kt
@@ -41,8 +41,8 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
 import androidx.compose.ui.unit.dp
 import io.element.android.compound.theme.ElementTheme
 import io.element.android.features.messages.impl.R
-import io.element.android.libraries.architecture.Async
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.architecture.AsyncAction
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.preview.ElementPreview
 import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@@ -62,10 +62,10 @@ fun ReportMessageView(
     modifier: Modifier = Modifier,
 ) {
     val focusManager = LocalFocusManager.current
-    val isSending = state.result is Async.Loading
-    AsyncView(
+    val isSending = state.result is AsyncAction.Loading
+    AsyncActionView(
         async = state.result,
-        showProgressDialog = false,
+        progressDialog = {},
         onSuccess = { onBackClicked() },
         errorMessage = { stringResource(CommonStrings.error_unknown) },
         onErrorDismiss = { state.eventSink(ReportMessageEvents.ClearError) }
diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt
index fa6632308ae..dfe8e92a01c 100644
--- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt
+++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt
@@ -33,7 +33,7 @@ import io.element.android.features.messages.impl.timeline.di.TimelineItemEventCo
 import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactory
 import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
 import io.element.android.features.messages.impl.voicemessages.VoiceMessageException
-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.architecture.runUpdatingState
 import io.element.android.libraries.di.RoomScope
@@ -71,7 +71,7 @@ class VoiceMessagePresenter @AssistedInject constructor(
         body = content.body,
     )

-    private val play = mutableStateOf<Async<Unit>>(Async.Uninitialized)
+    private val play = mutableStateOf<AsyncData<Unit>>(AsyncData.Uninitialized)

     @Composable
     override fun present(): VoiceMessageState {
@@ -91,8 +91,8 @@ class VoiceMessagePresenter @AssistedInject constructor(
                 when {
                     content.eventId == null -> VoiceMessageState.Button.Disabled
                     playerState.isPlaying -> VoiceMessageState.Button.Pause
-                    play.value is Async.Loading -> VoiceMessageState.Button.Downloading
-                    play.value is Async.Failure -> VoiceMessageState.Button.Retry
+                    play.value is AsyncData.Loading -> VoiceMessageState.Button.Downloading
+                    play.value is AsyncData.Failure -> VoiceMessageState.Button.Retry
                     else -> VoiceMessageState.Button.Play
                 }
             }
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt
index df0ea43ce94..3c8ca8dc3b1 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenter.kt
@@ -32,7 +32,7 @@ import io.element.android.features.preferences.api.store.PreferencesStore
 import io.element.android.features.preferences.impl.tasks.ClearCacheUseCase
 import io.element.android.features.preferences.impl.tasks.ComputeCacheSizeUseCase
 import io.element.android.features.rageshake.api.preferences.RageshakePreferencesPresenter
-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.architecture.runCatchingUpdatingState
 import io.element.android.libraries.core.bool.orFalse
@@ -65,10 +65,10 @@ class DeveloperSettingsPresenter @Inject constructor(
             mutableStateMapOf<String, Boolean>()
         }
         val cacheSize = remember {
-            mutableStateOf<Async<String>>(Async.Uninitialized)
+            mutableStateOf<AsyncData<String>>(AsyncData.Uninitialized)
         }
         val clearCacheAction = remember {
-            mutableStateOf<Async<Unit>>(Async.Uninitialized)
+            mutableStateOf<AsyncData<Unit>>(AsyncData.Uninitialized)
         }
         val customElementCallBaseUrl by preferencesStore
             .getCustomElementCallBaseUrlFlow()
@@ -154,13 +154,13 @@ class DeveloperSettingsPresenter @Inject constructor(
         }
     }

-    private fun CoroutineScope.computeCacheSize(cacheSize: MutableState<Async<String>>) = launch {
+    private fun CoroutineScope.computeCacheSize(cacheSize: MutableState<AsyncData<String>>) = launch {
         suspend {
             computeCacheSizeUseCase()
         }.runCatchingUpdatingState(cacheSize)
     }

-    private fun CoroutineScope.clearCache(clearCacheAction: MutableState<Async<Unit>>) = launch {
+    private fun CoroutineScope.clearCache(clearCacheAction: MutableState<AsyncData<Unit>>) = launch {
         suspend {
             clearCacheUseCase()
         }.runCatchingUpdatingState(clearCacheAction)
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt
index d49e94b3090..9a128236869 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsState.kt
@@ -17,15 +17,15 @@
 package io.element.android.features.preferences.impl.developer

 import io.element.android.features.rageshake.api.preferences.RageshakePreferencesState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.featureflag.ui.model.FeatureUiModel
 import kotlinx.collections.immutable.ImmutableList

 data class DeveloperSettingsState(
     val features: ImmutableList<FeatureUiModel>,
-    val cacheSize: Async<String>,
+    val cacheSize: AsyncData<String>,
     val rageshakeState: RageshakePreferencesState,
-    val clearCacheAction: Async<Unit>,
+    val clearCacheAction: AsyncData<Unit>,
     val customElementCallBaseUrlState: CustomElementCallBaseUrlState,
     val eventSink: (DeveloperSettingsEvents) -> Unit
 )
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt
index 719b736c09c..e4643182f47 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsStateProvider.kt
@@ -18,14 +18,14 @@ package io.element.android.features.preferences.impl.developer

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
 import io.element.android.features.rageshake.api.preferences.aRageshakePreferencesState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.featureflag.ui.model.aFeatureUiModelList

 open class DeveloperSettingsStateProvider : PreviewParameterProvider<DeveloperSettingsState> {
     override val values: Sequence<DeveloperSettingsState>
         get() = sequenceOf(
             aDeveloperSettingsState(),
-            aDeveloperSettingsState().copy(clearCacheAction = Async.Loading()),
+            aDeveloperSettingsState().copy(clearCacheAction = AsyncData.Loading()),
             aDeveloperSettingsState().copy(
                 customElementCallBaseUrlState = CustomElementCallBaseUrlState(
                     baseUrl = "https://call.element.ahoy",
@@ -39,8 +39,8 @@ open class DeveloperSettingsStateProvider : PreviewParameterProvider<DeveloperSe
 fun aDeveloperSettingsState() = DeveloperSettingsState(
     features = aFeatureUiModelList(),
     rageshakeState = aRageshakePreferencesState(),
-    cacheSize = Async.Success("1.2 MB"),
-    clearCacheAction = Async.Uninitialized,
+    cacheSize = AsyncData.Success("1.2 MB"),
+    clearCacheAction = AsyncData.Uninitialized,
     customElementCallBaseUrlState = CustomElementCallBaseUrlState(baseUrl = null, defaultUrl = "https://call.element.io", validator = { true }),
     eventSink = {}
 )
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt
index 6252be1e5c4..7083b9f88bc 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsPresenter.kt
@@ -23,7 +23,7 @@ import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.architecture.runCatchingUpdatingState
 import io.element.android.libraries.matrix.api.MatrixClient
@@ -52,7 +52,7 @@ class NotificationSettingsPresenter @Inject constructor(
         val systemNotificationsEnabled: MutableState<Boolean> = remember {
             mutableStateOf(systemNotificationsEnabledProvider.notificationsEnabled())
         }
-        val changeNotificationSettingAction: MutableState<Async<Unit>> = remember { mutableStateOf(Async.Uninitialized) }
+        val changeNotificationSettingAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }

         val localCoroutineScope = rememberCoroutineScope()
         val appNotificationsEnabled = userPushStore
@@ -87,7 +87,7 @@ class NotificationSettingsPresenter @Inject constructor(
                 NotificationSettingsEvents.RefreshSystemNotificationsEnabled -> {
                     systemNotificationsEnabled.value = systemNotificationsEnabledProvider.notificationsEnabled()
                 }
-                NotificationSettingsEvents.ClearNotificationChangeError -> changeNotificationSettingAction.value = Async.Uninitialized
+                NotificationSettingsEvents.ClearNotificationChangeError -> changeNotificationSettingAction.value = AsyncAction.Uninitialized
             }
         }

@@ -119,7 +119,7 @@ class NotificationSettingsPresenter @Inject constructor(
         val oneToOneDefaultMode = notificationSettingsService.getDefaultRoomNotificationMode(isEncrypted = false, isOneToOne = true).getOrThrow()
         val encryptedOneToOneDefaultMode = notificationSettingsService.getDefaultRoomNotificationMode(isEncrypted = true, isOneToOne = true).getOrThrow()

-        if(groupDefaultMode != encryptedGroupDefaultMode || oneToOneDefaultMode != encryptedOneToOneDefaultMode) {
+        if (groupDefaultMode != encryptedGroupDefaultMode || oneToOneDefaultMode != encryptedOneToOneDefaultMode) {
             target.value = NotificationSettingsState.MatrixSettings.Invalid(fixFailed = false)
             return@launch
         }
@@ -168,19 +168,19 @@ class NotificationSettingsPresenter @Inject constructor(
         )
     }

-    private fun CoroutineScope.setAtRoomNotificationsEnabled(enabled: Boolean, action: MutableState<Async<Unit>>) = launch {
+    private fun CoroutineScope.setAtRoomNotificationsEnabled(enabled: Boolean, action: MutableState<AsyncAction<Unit>>) = launch {
         suspend {
             notificationSettingsService.setRoomMentionEnabled(enabled).getOrThrow()
         }.runCatchingUpdatingState(action)
     }

-    private fun CoroutineScope.setCallNotificationsEnabled(enabled: Boolean, action: MutableState<Async<Unit>>) = launch {
+    private fun CoroutineScope.setCallNotificationsEnabled(enabled: Boolean, action: MutableState<AsyncAction<Unit>>) = launch {
         suspend {
             notificationSettingsService.setCallEnabled(enabled).getOrThrow()
         }.runCatchingUpdatingState(action)
     }

-    private fun CoroutineScope.setInviteForMeNotificationsEnabled(enabled: Boolean, action: MutableState<Async<Unit>>) = launch {
+    private fun CoroutineScope.setInviteForMeNotificationsEnabled(enabled: Boolean, action: MutableState<AsyncAction<Unit>>) = launch {
         suspend {
             notificationSettingsService.setInviteForMeEnabled(enabled).getOrThrow()
         }.runCatchingUpdatingState(action)
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsState.kt
index 581f0e84758..6999acb1035 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsState.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsState.kt
@@ -17,18 +17,18 @@
 package io.element.android.features.preferences.impl.notifications

 import androidx.compose.runtime.Immutable
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.room.RoomNotificationMode

 @Immutable
 data class NotificationSettingsState(
     val matrixSettings: MatrixSettings,
     val appSettings: AppSettings,
-    val changeNotificationSettingAction: Async<Unit>,
+    val changeNotificationSettingAction: AsyncAction<Unit>,
     val eventSink: (NotificationSettingsEvents) -> Unit,
 ) {
     sealed interface MatrixSettings {
-        data object Uninitialized :  MatrixSettings
+        data object Uninitialized : MatrixSettings
         data class Valid(
             val atRoomNotificationsEnabled: Boolean,
             val callNotificationsEnabled: Boolean,
@@ -39,7 +39,7 @@ data class NotificationSettingsState(

         data class Invalid(
             val fixFailed: Boolean
-        ) :  MatrixSettings
+        ) : MatrixSettings
     }

     data class AppSettings(
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt
index f121a2fe600..2dc0c021454 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsStateProvider.kt
@@ -17,20 +17,20 @@
 package io.element.android.features.preferences.impl.notifications

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.room.RoomNotificationMode

 open class NotificationSettingsStateProvider : PreviewParameterProvider<NotificationSettingsState> {
     override val values: Sequence<NotificationSettingsState>
         get() = sequenceOf(
             aNotificationSettingsState(),
-            aNotificationSettingsState(changeNotificationSettingAction = Async.Loading(Unit)),
-            aNotificationSettingsState(changeNotificationSettingAction = Async.Failure(Throwable("error"))),
+            aNotificationSettingsState(changeNotificationSettingAction = AsyncAction.Loading),
+            aNotificationSettingsState(changeNotificationSettingAction = AsyncAction.Failure(Throwable("error"))),
         )
 }

 fun aNotificationSettingsState(
-    changeNotificationSettingAction: Async<Unit> = Async.Uninitialized,
+    changeNotificationSettingAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
 ) = NotificationSettingsState(
     matrixSettings = NotificationSettingsState.MatrixSettings.Valid(
         atRoomNotificationsEnabled = true,
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt
index f1066b2e9d2..da8d79be50c 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/NotificationSettingsView.kt
@@ -27,7 +27,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons
 import io.element.android.features.preferences.impl.R
 import io.element.android.libraries.androidutils.system.startNotificationSettingsIntent
 import io.element.android.libraries.designsystem.atomic.molecules.DialogLikeBannerMolecule
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
 import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
 import io.element.android.libraries.designsystem.components.preferences.PreferencePage
@@ -80,7 +80,7 @@ fun NotificationSettingsView(
                 onInviteForMeNotificationsChanged = { state.eventSink(NotificationSettingsEvents.SetInviteForMeNotificationsEnabled(it)) },
             )
         }
-        AsyncView(
+        AsyncActionView(
             async = state.changeNotificationSettingAction,
             errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) },
             onErrorDismiss = { state.eventSink(NotificationSettingsEvents.ClearNotificationChangeError) },
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt
index 7617e68dd6f..04accef4eab 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingPresenter.kt
@@ -27,7 +27,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.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.architecture.runCatchingUpdatingState
 import io.element.android.libraries.matrix.api.MatrixClient
@@ -55,6 +55,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
     interface Factory {
         fun create(oneToOne: Boolean): EditDefaultNotificationSettingPresenter
     }
+
     @Composable
     override fun present(): EditDefaultNotificationSettingState {
         var displayMentionsOnlyDisclaimer by remember { mutableStateOf(false) }
@@ -63,7 +64,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
             mutableStateOf(null)
         }

-        val changeNotificationSettingAction: MutableState<Async<Unit>> = remember { mutableStateOf(Async.Uninitialized) }
+        val changeNotificationSettingAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }

         val roomsWithUserDefinedMode: MutableState<List<RoomSummary.Filled>> = remember {
             mutableStateOf(listOf())
@@ -82,7 +83,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
                 is EditDefaultNotificationSettingStateEvents.SetNotificationMode -> {
                     localCoroutineScope.setDefaultNotificationMode(event.mode, changeNotificationSettingAction)
                 }
-                EditDefaultNotificationSettingStateEvents.ClearError -> changeNotificationSettingAction.value = Async.Uninitialized
+                EditDefaultNotificationSettingStateEvents.ClearError -> changeNotificationSettingAction.value = AsyncAction.Uninitialized
             }
         }

@@ -132,17 +133,16 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
                 roomWithUserDefinedRules.contains(it.identifier()) && isOneToOne == room.isOneToOne
             }
             // locale sensitive sorting
-            .sortedWith(compareBy(Collator.getInstance()){ it.details.name })
+            .sortedWith(compareBy(Collator.getInstance()) { it.details.name })

         roomsWithUserDefinedMode.value = sortedSummaries
     }

-    private fun CoroutineScope.setDefaultNotificationMode(mode: RoomNotificationMode,  action: MutableState<Async<Unit>>) = launch {
+    private fun CoroutineScope.setDefaultNotificationMode(mode: RoomNotificationMode, action: MutableState<AsyncAction<Unit>>) = launch {
         suspend {
             // On modern clients, we don't have different settings for encrypted and non-encrypted rooms (Legacy clients did).
             notificationSettingsService.setDefaultRoomNotificationMode(isEncrypted = true, mode = mode, isOneToOne = isOneToOne).getOrThrow()
             notificationSettingsService.setDefaultRoomNotificationMode(isEncrypted = false, mode = mode, isOneToOne = isOneToOne).getOrThrow()
         }.runCatchingUpdatingState(action)
     }
-
 }
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt
index 70868354782..68b29232b0d 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingState.kt
@@ -16,7 +16,7 @@

 package io.element.android.features.preferences.impl.notifications.edit

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.room.RoomNotificationMode
 import io.element.android.libraries.matrix.api.roomlist.RoomSummary
 import kotlinx.collections.immutable.ImmutableList
@@ -25,7 +25,7 @@ data class EditDefaultNotificationSettingState(
     val isOneToOne: Boolean,
     val mode: RoomNotificationMode?,
     val roomsWithUserDefinedMode: ImmutableList<RoomSummary.Filled>,
-    val changeNotificationSettingAction: Async<Unit>,
+    val changeNotificationSettingAction: AsyncAction<Unit>,
     val displayMentionsOnlyDisclaimer: Boolean,
     val eventSink: (EditDefaultNotificationSettingStateEvents) -> Unit,
 )
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt
index dc11b85e6d6..0c4ef95c6cd 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingStateProvider.kt
@@ -17,27 +17,27 @@
 package io.element.android.features.preferences.impl.notifications.edit

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.core.RoomId
 import io.element.android.libraries.matrix.api.room.RoomNotificationMode
 import io.element.android.libraries.matrix.api.roomlist.RoomSummary
 import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails
 import kotlinx.collections.immutable.persistentListOf

-open class EditDefaultNotificationSettingStateProvider: PreviewParameterProvider<EditDefaultNotificationSettingState> {
+open class EditDefaultNotificationSettingStateProvider : PreviewParameterProvider<EditDefaultNotificationSettingState> {
     override val values: Sequence<EditDefaultNotificationSettingState>
         get() = sequenceOf(
             anEditDefaultNotificationSettingsState(),
             anEditDefaultNotificationSettingsState(isOneToOne = true),
-            anEditDefaultNotificationSettingsState(changeNotificationSettingAction = Async.Loading(Unit)),
-            anEditDefaultNotificationSettingsState(changeNotificationSettingAction = Async.Failure(Throwable("error"))),
+            anEditDefaultNotificationSettingsState(changeNotificationSettingAction = AsyncAction.Loading),
+            anEditDefaultNotificationSettingsState(changeNotificationSettingAction = AsyncAction.Failure(Throwable("error"))),
             anEditDefaultNotificationSettingsState(displayMentionsOnlyDisclaimer = true),
         )
 }

 private fun anEditDefaultNotificationSettingsState(
     isOneToOne: Boolean = false,
-    changeNotificationSettingAction: Async<Unit> = Async.Uninitialized,
+    changeNotificationSettingAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
     displayMentionsOnlyDisclaimer: Boolean = false,
 ) = EditDefaultNotificationSettingState(
     isOneToOne = isOneToOne,
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt
index 7b619a73223..d03b8b27540 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/notifications/edit/EditDefaultNotificationSettingView.kt
@@ -23,7 +23,7 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.PreviewParameter
 import io.element.android.features.preferences.impl.R
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.components.avatar.Avatar
 import io.element.android.libraries.designsystem.components.avatar.AvatarData
 import io.element.android.libraries.designsystem.components.avatar.AvatarSize
@@ -117,7 +117,7 @@ fun EditDefaultNotificationSettingView(
                 }
             }
         }
-        AsyncView(
+        AsyncActionView(
             async = state.changeNotificationSettingAction,
             errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) },
             onErrorDismiss = { state.eventSink(EditDefaultNotificationSettingStateEvents.ClearError) },
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt
index db8c5b97b9d..b99c197d69e 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootStateProvider.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.preferences.impl.root

 import io.element.android.features.logout.api.direct.DirectLogoutState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
 import io.element.android.libraries.ui.strings.CommonStrings

@@ -39,7 +39,6 @@ fun aPreferencesRootState() = PreferencesRootState(

 fun aDirectLogoutState() = DirectLogoutState(
     canDoDirectSignOut = true,
-    showConfirmationDialog = false,
-    logoutAction = Async.Uninitialized,
+    logoutAction = AsyncAction.Uninitialized,
     eventSink = {},
 )
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt
index be0a5f4cca6..2a51aad22b9 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt
@@ -31,7 +31,7 @@ import androidx.core.net.toUri
 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.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.architecture.runCatchingUpdatingState
 import io.element.android.libraries.core.mimetype.MimeTypes
@@ -92,7 +92,7 @@ class EditUserProfilePresenter @AssistedInject constructor(
             }
         }

-        val saveAction: MutableState<Async<Unit>> = remember { mutableStateOf(Async.Uninitialized) }
+        val saveAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
         val localCoroutineScope = rememberCoroutineScope()
         fun handleEvents(event: EditUserProfileEvents) {
             when (event) {
@@ -111,7 +111,7 @@ class EditUserProfilePresenter @AssistedInject constructor(
                 }

                 is EditUserProfileEvents.UpdateDisplayName -> userDisplayName = event.name
-                EditUserProfileEvents.CancelSaveChanges -> saveAction.value = Async.Uninitialized
+                EditUserProfileEvents.CancelSaveChanges -> saveAction.value = AsyncAction.Uninitialized
             }
         }

@@ -126,7 +126,7 @@ class EditUserProfilePresenter @AssistedInject constructor(
             displayName = userDisplayName.orEmpty(),
             userAvatarUrl = userAvatarUri,
             avatarActions = avatarActions,
-            saveButtonEnabled = canSave && saveAction.value !is Async.Loading,
+            saveButtonEnabled = canSave && saveAction.value !is AsyncAction.Loading,
             saveAction = saveAction.value,
             cameraPermissionState = cameraPermissionState,
             eventSink = { handleEvents(it) },
@@ -140,7 +140,12 @@ class EditUserProfilePresenter @AssistedInject constructor(
         // Need to call `toUri()?.toString()` to make the test pass (we mockk Uri)
         avatarUri?.toString()?.trim() != currentUser.avatarUrl?.toUri()?.toString()?.trim()

-    private fun CoroutineScope.saveChanges(name: String?, avatarUri: Uri?, currentUser: MatrixUser, action: MutableState<Async<Unit>>) = launch {
+    private fun CoroutineScope.saveChanges(
+        name: String?,
+        avatarUri: Uri?,
+        currentUser: MatrixUser,
+        action: MutableState<AsyncAction<Unit>>,
+    ) = launch {
         val results = mutableListOf<Result<Unit>>()
         suspend {
             if (!name.isNullOrEmpty() && name.trim() != currentUser.displayName.orEmpty().trim()) {
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt
index 9561c8609bc..c37dba8c3ac 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileState.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.preferences.impl.user.editprofile

 import android.net.Uri
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.core.UserId
 import io.element.android.libraries.matrix.ui.media.AvatarAction
 import io.element.android.libraries.permissions.api.PermissionsState
@@ -29,7 +29,7 @@ data class EditUserProfileState(
     val userAvatarUrl: Uri?,
     val avatarActions: ImmutableList<AvatarAction>,
     val saveButtonEnabled: Boolean,
-    val saveAction: Async<Unit>,
+    val saveAction: AsyncAction<Unit>,
     val cameraPermissionState: PermissionsState,
     val eventSink: (EditUserProfileEvents) -> Unit
 )
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt
index c4a8431f4ff..9d0d0274330 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.preferences.impl.user.editprofile

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.core.UserId
 import io.element.android.libraries.permissions.api.aPermissionsState
 import kotlinx.collections.immutable.persistentListOf
@@ -35,7 +35,7 @@ fun aEditUserProfileState() = EditUserProfileState(
     displayName = "John Doe",
     userAvatarUrl = null,
     avatarActions = persistentListOf(),
-    saveAction = Async.Uninitialized,
+    saveAction = AsyncAction.Uninitialized,
     saveButtonEnabled = true,
     cameraPermissionState = aPermissionsState(showDialog = false),
     eventSink = {}
diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt
index 66aaeb6c407..ff587b217d4 100644
--- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt
+++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt
@@ -43,7 +43,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
 import androidx.compose.ui.unit.dp
 import io.element.android.features.preferences.impl.R
 import io.element.android.libraries.designsystem.components.LabelledOutlinedTextField
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.components.avatar.AvatarSize
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.preview.ElementPreview
@@ -57,6 +57,7 @@ import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
 import io.element.android.libraries.matrix.ui.components.EditableAvatarView
 import io.element.android.libraries.permissions.api.PermissionsView
 import io.element.android.compound.theme.ElementTheme
+import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
 import io.element.android.libraries.ui.strings.CommonStrings
 import kotlinx.coroutines.launch

@@ -147,9 +148,13 @@ fun EditUserProfileView(
             onActionSelected = { state.eventSink(EditUserProfileEvents.HandleAvatarAction(it)) }
         )

-        AsyncView(
+        AsyncActionView(
             async = state.saveAction,
-            progressText = stringResource(R.string.screen_edit_profile_updating_details),
+            progressDialog = {
+                AsyncActionViewDefaults.ProgressDialog(
+                    progressText = stringResource(R.string.screen_edit_profile_updating_details),
+                )
+            },
             onSuccess = { onProfileEdited() },
             errorTitle = { stringResource(R.string.screen_edit_profile_error_title) },
             errorMessage = { stringResource(R.string.screen_edit_profile_error) },
diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt
index e90787ab5c4..34506b8e8df 100644
--- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt
+++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt
@@ -30,7 +30,7 @@ import io.element.android.features.rageshake.api.reporter.BugReporter
 import io.element.android.features.rageshake.api.reporter.BugReporterListener
 import io.element.android.features.rageshake.api.screenshot.ScreenshotHolder
 import io.element.android.features.rageshake.impl.logs.VectorFileLogger
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
@@ -45,27 +45,27 @@ class BugReportPresenter @Inject constructor(

     private class BugReporterUploadListener(
         private val sendingProgress: MutableFloatState,
-        private val sendingAction: MutableState<Async<Unit>>
+        private val sendingAction: MutableState<AsyncAction<Unit>>
     ) : BugReporterListener {

         override fun onUploadCancelled() {
             sendingProgress.floatValue = 0f
-            sendingAction.value = Async.Uninitialized
+            sendingAction.value = AsyncAction.Uninitialized
         }

         override fun onUploadFailed(reason: String?) {
             sendingProgress.floatValue = 0f
-            sendingAction.value = Async.Failure(Exception(reason))
+            sendingAction.value = AsyncAction.Failure(Exception(reason))
         }

         override fun onProgress(progress: Int) {
             sendingProgress.floatValue = progress.toFloat() / 100
-            sendingAction.value = Async.Loading()
+            sendingAction.value = AsyncAction.Loading
         }

         override fun onUploadSucceed() {
             sendingProgress.floatValue = 0f
-            sendingAction.value = Async.Success(Unit)
+            sendingAction.value = AsyncAction.Success(Unit)
         }
     }

@@ -83,8 +83,8 @@ class BugReportPresenter @Inject constructor(
         val sendingProgress = remember {
             mutableFloatStateOf(0f)
         }
-        val sendingAction: MutableState<Async<Unit>> = remember {
-            mutableStateOf(Async.Uninitialized)
+        val sendingAction: MutableState<AsyncAction<Unit>> = remember {
+            mutableStateOf(AsyncAction.Uninitialized)
         }
         val formState: MutableState<BugReportFormState> = remember {
             mutableStateOf(BugReportFormState.Default)
@@ -109,7 +109,7 @@ class BugReportPresenter @Inject constructor(
                 }
                 BugReportEvents.ClearError -> {
                     sendingProgress.floatValue = 0f
-                    sendingAction.value = Async.Uninitialized
+                    sendingAction.value = AsyncAction.Uninitialized
                 }
             }
         }
diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt
index b8bbe62dc63..c3bfbec888e 100644
--- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt
+++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.rageshake.impl.bugreport

 import android.os.Parcelable
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import kotlinx.parcelize.Parcelize

 data class BugReportState(
@@ -25,11 +25,11 @@ data class BugReportState(
     val hasCrashLogs: Boolean,
     val screenshotUri: String?,
     val sendingProgress: Float,
-    val sending: Async<Unit>,
+    val sending: AsyncAction<Unit>,
     val eventSink: (BugReportEvents) -> Unit
 ) {
     val submitEnabled =
-        formState.description.length > 10 && sending !is Async.Loading
+        formState.description.length > 10 && sending !is AsyncAction.Loading
 }

 @Parcelize
diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportStateProvider.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportStateProvider.kt
index 3601c2a2590..bb0d273de45 100644
--- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportStateProvider.kt
+++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportStateProvider.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.rageshake.impl.bugreport

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction

 open class BugReportStateProvider : PreviewParameterProvider<BugReportState> {
     override val values: Sequence<BugReportState>
@@ -31,8 +31,8 @@ open class BugReportStateProvider : PreviewParameterProvider<BugReportState> {
                 hasCrashLogs = true,
                 screenshotUri = "aUri"
             ),
-            aBugReportState().copy(sending = Async.Loading()),
-            aBugReportState().copy(sending = Async.Success(Unit)),
+            aBugReportState().copy(sending = AsyncAction.Loading),
+            aBugReportState().copy(sending = AsyncAction.Success(Unit)),
         )
 }

@@ -41,6 +41,6 @@ fun aBugReportState() = BugReportState(
     hasCrashLogs = false,
     screenshotUri = null,
     sendingProgress = 0F,
-    sending = Async.Uninitialized,
+    sending = AsyncAction.Uninitialized,
     eventSink = {}
 )
diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt
index 7833c217641..11843553e86 100644
--- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt
+++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt
@@ -37,8 +37,8 @@ import androidx.compose.ui.unit.dp
 import coil.compose.AsyncImage
 import coil.request.ImageRequest
 import io.element.android.features.rageshake.impl.R
-import io.element.android.libraries.architecture.Async
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.architecture.AsyncAction
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.components.form.textFieldState
 import io.element.android.libraries.designsystem.components.preferences.PreferencePage
 import io.element.android.libraries.designsystem.components.preferences.PreferenceRow
@@ -67,7 +67,7 @@ fun BugReportView(
             title = stringResource(id = CommonStrings.common_report_a_problem),
             onBackPressed = onBackPressed
         ) {
-            val isFormEnabled = state.sending !is Async.Loading
+            val isFormEnabled = state.sending !is AsyncAction.Loading
             var descriptionFieldState by textFieldState(
                 stateValue = state.formState.description
             )
@@ -150,9 +150,9 @@ fun BugReportView(
             }
         }

-        AsyncView(
+        AsyncActionView(
             async = state.sending,
-            showProgressDialog = false,
+            progressDialog = { },
             onSuccess = {
                 eventSink(BugReportEvents.ResetAll)
                 onDone()
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/blockuser/BlockUserSection.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/blockuser/BlockUserSection.kt
index b99319812bb..4ca3c313de5 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/blockuser/BlockUserSection.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/blockuser/BlockUserSection.kt
@@ -26,7 +26,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons
 import io.element.android.features.roomdetails.impl.R
 import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsEvents
 import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.core.bool.orFalse
 import io.element.android.libraries.designsystem.components.dialogs.RetryDialog
 import io.element.android.libraries.designsystem.components.list.ListItemContent
@@ -42,13 +42,13 @@ import io.element.android.libraries.ui.strings.CommonStrings
 internal fun BlockUserSection(state: RoomMemberDetailsState, modifier: Modifier = Modifier) {
     PreferenceCategory(showDivider = false, modifier = modifier) {
         when (state.isBlocked) {
-            is Async.Failure -> PreferenceBlockUser(isBlocked = state.isBlocked.prevData, isLoading = false, eventSink = state.eventSink)
-            is Async.Loading -> PreferenceBlockUser(isBlocked = state.isBlocked.prevData, isLoading = true, eventSink = state.eventSink)
-            is Async.Success -> PreferenceBlockUser(isBlocked = state.isBlocked.data, isLoading = false, eventSink = state.eventSink)
-            Async.Uninitialized -> PreferenceBlockUser(isBlocked = null, isLoading = true, eventSink = state.eventSink)
+            is AsyncData.Failure -> PreferenceBlockUser(isBlocked = state.isBlocked.prevData, isLoading = false, eventSink = state.eventSink)
+            is AsyncData.Loading -> PreferenceBlockUser(isBlocked = state.isBlocked.prevData, isLoading = true, eventSink = state.eventSink)
+            is AsyncData.Success -> PreferenceBlockUser(isBlocked = state.isBlocked.data, isLoading = false, eventSink = state.eventSink)
+            AsyncData.Uninitialized -> PreferenceBlockUser(isBlocked = null, isLoading = true, eventSink = state.eventSink)
         }
     }
-    if (state.isBlocked is Async.Failure) {
+    if (state.isBlocked is AsyncData.Failure) {
         RetryDialog(
             content = stringResource(CommonStrings.error_unknown),
             onDismiss = { state.eventSink(RoomMemberDetailsEvents.ClearBlockUserError) },
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt
index 40df3791d4f..6682db392fd 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditPresenter.kt
@@ -29,7 +29,7 @@ import androidx.compose.runtime.rememberCoroutineScope
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.core.net.toUri
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.architecture.runCatchingUpdatingState
 import io.element.android.libraries.core.mimetype.MimeTypes
@@ -116,7 +116,7 @@ class RoomDetailsEditPresenter @Inject constructor(
             }
         }

-        val saveAction: MutableState<Async<Unit>> = remember { mutableStateOf(Async.Uninitialized) }
+        val saveAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
         val localCoroutineScope = rememberCoroutineScope()
         fun handleEvents(event: RoomDetailsEditEvents) {
             when (event) {
@@ -136,7 +136,7 @@ class RoomDetailsEditPresenter @Inject constructor(

                 is RoomDetailsEditEvents.UpdateRoomName -> roomName = event.name
                 is RoomDetailsEditEvents.UpdateRoomTopic -> roomTopic = event.topic.takeUnless { it.isEmpty() }
-                RoomDetailsEditEvents.CancelSaveChanges -> saveAction.value = Async.Uninitialized
+                RoomDetailsEditEvents.CancelSaveChanges -> saveAction.value = AsyncAction.Uninitialized
             }
         }

@@ -156,7 +156,12 @@ class RoomDetailsEditPresenter @Inject constructor(
         )
     }

-    private fun CoroutineScope.saveChanges(name: String, topic: String?, avatarUri: Uri?, action: MutableState<Async<Unit>>) = launch {
+    private fun CoroutineScope.saveChanges(
+        name: String,
+        topic: String?,
+        avatarUri: Uri?,
+        action: MutableState<AsyncAction<Unit>>,
+    ) = launch {
         val results = mutableListOf<Result<Unit>>()
         suspend {
             if (topic.orEmpty().trim() != room.topic.orEmpty().trim()) {
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt
index 9258d882fc2..d85450b59f6 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditState.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.roomdetails.impl.edit

 import android.net.Uri
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.ui.media.AvatarAction
 import io.element.android.libraries.permissions.api.PermissionsState
 import kotlinx.collections.immutable.ImmutableList
@@ -32,7 +32,7 @@ data class RoomDetailsEditState(
     val canChangeAvatar: Boolean,
     val avatarActions: ImmutableList<AvatarAction>,
     val saveButtonEnabled: Boolean,
-    val saveAction: Async<Unit>,
+    val saveAction: AsyncAction<Unit>,
     val cameraPermissionState: PermissionsState,
     val eventSink: (RoomDetailsEditEvents) -> Unit
 )
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt
index 730acaa1c5d..d70c83b9a06 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditStateProvider.kt
@@ -18,7 +18,7 @@ package io.element.android.features.roomdetails.impl.edit

 import android.net.Uri
 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.permissions.api.aPermissionsState
 import kotlinx.collections.immutable.persistentListOf

@@ -30,8 +30,8 @@ open class RoomDetailsEditStateProvider : PreviewParameterProvider<RoomDetailsEd
             aRoomDetailsEditState().copy(roomAvatarUrl = Uri.parse("example://uri")),
             aRoomDetailsEditState().copy(canChangeName = true, canChangeTopic = false, canChangeAvatar = true, saveButtonEnabled = false),
             aRoomDetailsEditState().copy(canChangeName = false, canChangeTopic = true, canChangeAvatar = false, saveButtonEnabled = false),
-            aRoomDetailsEditState().copy(saveAction = Async.Loading()),
-            aRoomDetailsEditState().copy(saveAction = Async.Failure(Throwable("Whelp")))
+            aRoomDetailsEditState().copy(saveAction = AsyncAction.Loading),
+            aRoomDetailsEditState().copy(saveAction = AsyncAction.Failure(Throwable("Whelp")))
         )
 }

@@ -45,7 +45,7 @@ fun aRoomDetailsEditState() = RoomDetailsEditState(
     canChangeAvatar = true,
     avatarActions = persistentListOf(),
     saveButtonEnabled = true,
-    saveAction = Async.Uninitialized,
+    saveAction = AsyncAction.Uninitialized,
     cameraPermissionState = aPermissionsState(showDialog = false),
     eventSink = {}
 )
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt
index 7fb74f628ba..dca726a77ad 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt
@@ -47,7 +47,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
 import androidx.compose.ui.unit.dp
 import io.element.android.features.roomdetails.impl.R
 import io.element.android.libraries.designsystem.components.LabelledTextField
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.components.avatar.AvatarSize
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.preview.ElementPreview
@@ -61,6 +61,7 @@ import io.element.android.libraries.matrix.ui.components.AvatarActionBottomSheet
 import io.element.android.libraries.matrix.ui.components.EditableAvatarView
 import io.element.android.libraries.permissions.api.PermissionsView
 import io.element.android.compound.theme.ElementTheme
+import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
 import io.element.android.libraries.ui.strings.CommonStrings
 import kotlinx.coroutines.launch

@@ -171,9 +172,13 @@ fun RoomDetailsEditView(
         onActionSelected = { state.eventSink(RoomDetailsEditEvents.HandleAvatarAction(it)) }
     )

-    AsyncView(
+    AsyncActionView(
         async = state.saveAction,
-        progressText = stringResource(R.string.screen_room_details_updating_room),
+        progressDialog = {
+            AsyncActionViewDefaults.ProgressDialog(
+                progressText = stringResource(R.string.screen_room_details_updating_room),
+            )
+        },
         onSuccess = { onRoomEdited() },
         errorMessage = { stringResource(R.string.screen_room_details_edition_error) },
         onErrorDismiss = { state.eventSink(RoomDetailsEditEvents.CancelSaveChanges) }
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt
index cc0886c3af1..d211a5089ab 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/invite/RoomInviteMembersPresenter.kt
@@ -25,7 +25,7 @@ import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import io.element.android.features.roomdetails.impl.members.RoomMemberListDataSource
-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.architecture.runCatchingUpdatingState
 import io.element.android.libraries.core.coroutine.CoroutineDispatchers
@@ -48,7 +48,7 @@ class RoomInviteMembersPresenter @Inject constructor(

     @Composable
     override fun present(): RoomInviteMembersState {
-        val roomMembers = remember { mutableStateOf<Async<ImmutableList<RoomMember>>>(Async.Loading()) }
+        val roomMembers = remember { mutableStateOf<AsyncData<ImmutableList<RoomMember>>>(AsyncData.Loading()) }
         val selectedUsers = remember { mutableStateOf<ImmutableList<MatrixUser>>(persistentListOf()) }
         val searchResults = remember { mutableStateOf<SearchBarResultState<ImmutableList<InvitableUser>>>(SearchBarResultState.NotSearching()) }
         var searchQuery by rememberSaveable { mutableStateOf("") }
@@ -115,7 +115,7 @@ class RoomInviteMembersPresenter @Inject constructor(

     private suspend fun performSearch(
         searchResults: MutableState<SearchBarResultState<ImmutableList<InvitableUser>>>,
-        roomMembers: MutableState<Async<ImmutableList<RoomMember>>>,
+        roomMembers: MutableState<AsyncData<ImmutableList<RoomMember>>>,
         selectedUsers: MutableState<ImmutableList<MatrixUser>>,
         searchQuery: String,
     ) = withContext(coroutineDispatchers.io) {
@@ -142,7 +142,7 @@ class RoomInviteMembersPresenter @Inject constructor(
         }
     }

-    private suspend fun fetchMembers(roomMembers: MutableState<Async<ImmutableList<RoomMember>>>) {
+    private suspend fun fetchMembers(roomMembers: MutableState<AsyncData<ImmutableList<RoomMember>>>) {
         suspend {
             withContext(coroutineDispatchers.io) {
                 roomMemberListDataSource.search("").toImmutableList()
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt
index 49ae479d409..649d2d8482d 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt
@@ -25,7 +25,7 @@ import androidx.compose.runtime.produceState
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
-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.core.coroutine.CoroutineDispatchers
 import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
@@ -44,7 +44,7 @@ class RoomMemberListPresenter @Inject constructor(

     @Composable
     override fun present(): RoomMemberListState {
-        var roomMembers by remember { mutableStateOf<Async<RoomMembers>>(Async.Loading()) }
+        var roomMembers by remember { mutableStateOf<AsyncData<RoomMembers>>(AsyncData.Loading()) }
         var searchQuery by rememberSaveable { mutableStateOf("") }
         var searchResults by remember {
             mutableStateOf<SearchBarResultState<RoomMembers>>(SearchBarResultState.NotSearching())
@@ -59,7 +59,7 @@ class RoomMemberListPresenter @Inject constructor(
         LaunchedEffect(Unit) {
             withContext(coroutineDispatchers.io) {
                 val members = roomMemberListDataSource.search("").groupBy { it.membership }
-                roomMembers = Async.Success(
+                roomMembers = AsyncData.Success(
                     RoomMembers(
                         invited = members.getOrDefault(RoomMembershipState.INVITE, emptyList()).toImmutableList(),
                         joined = members.getOrDefault(RoomMembershipState.JOIN, emptyList()).toImmutableList(),
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt
index f718db703be..aa2d94cc651 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt
@@ -16,13 +16,13 @@

 package io.element.android.features.roomdetails.impl.members

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
 import io.element.android.libraries.matrix.api.room.RoomMember
 import kotlinx.collections.immutable.ImmutableList

 data class RoomMemberListState(
-    val roomMembers: Async<RoomMembers>,
+    val roomMembers: AsyncData<RoomMembers>,
     val searchQuery: String,
     val searchResults: SearchBarResultState<RoomMembers>,
     val isSearchActive: Boolean,
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt
index 4954af8efc1..a9e4037c3ce 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.roomdetails.impl.members

 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.designsystem.theme.components.SearchBarResultState
 import io.element.android.libraries.matrix.api.core.UserId
 import io.element.android.libraries.matrix.api.room.RoomMember
@@ -28,14 +28,14 @@ internal class RoomMemberListStateProvider : PreviewParameterProvider<RoomMember
     override val values: Sequence<RoomMemberListState>
         get() = sequenceOf(
             aRoomMemberListState(
-                roomMembers = Async.Success(
+                roomMembers = AsyncData.Success(
                     RoomMembers(
                         invited = persistentListOf(aVictor(), aWalter()),
                         joined = persistentListOf(anAlice(), aBob()),
                     )
                 )
             ),
-            aRoomMemberListState(roomMembers = Async.Loading()),
+            aRoomMemberListState(roomMembers = AsyncData.Loading()),
             aRoomMemberListState().copy(canInvite = true),
             aRoomMemberListState().copy(isSearchActive = false),
             aRoomMemberListState().copy(isSearchActive = true),
@@ -59,7 +59,7 @@ internal class RoomMemberListStateProvider : PreviewParameterProvider<RoomMember
 }

 internal fun aRoomMemberListState(
-    roomMembers: Async<RoomMembers> = Async.Uninitialized,
+    roomMembers: AsyncData<RoomMembers> = AsyncData.Uninitialized,
     searchResults: SearchBarResultState<RoomMembers> = SearchBarResultState.NotSearching(),
 ) = RoomMemberListState(
     roomMembers = roomMembers,
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt
index 49de90a8548..abd7d4130aa 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt
@@ -39,7 +39,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
 import androidx.compose.ui.unit.dp
 import io.element.android.compound.theme.ElementTheme
 import io.element.android.features.roomdetails.impl.R
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.components.avatar.AvatarSize
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.preview.ElementPreview
@@ -103,7 +103,7 @@ fun RoomMemberListView(
             )

             if (!state.isSearchActive) {
-                if (state.roomMembers is Async.Success) {
+                if (state.roomMembers is AsyncData.Success) {
                     RoomMemberList(
                         roomMembers = state.roomMembers.data,
                         showMembersCount = true,
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsNode.kt
index 3037136f63d..d2de1c1bcfe 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsNode.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsNode.kt
@@ -30,7 +30,7 @@ import im.vector.app.features.analytics.plan.MobileScreen
 import io.element.android.anvilannotations.ContributesNode
 import io.element.android.features.roomdetails.impl.R
 import io.element.android.libraries.androidutils.system.startSharePlainTextIntent
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.architecture.NodeInputs
 import io.element.android.libraries.architecture.inputs
 import io.element.android.libraries.di.RoomScope
@@ -95,7 +95,7 @@ class RoomMemberDetailsNode @AssistedInject constructor(
         val state = presenter.present()

         LaunchedEffect(state.startDmActionState) {
-            if (state.startDmActionState is Async.Success) {
+            if (state.startDmActionState is AsyncAction.Success) {
                 onStartDM(state.startDmActionState.data)
             }
         }
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsPresenter.kt
index e82b5f0cb59..c583980d082 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsPresenter.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsPresenter.kt
@@ -29,7 +29,8 @@ import dagger.assisted.Assisted
 import dagger.assisted.AssistedInject
 import io.element.android.features.createroom.api.StartDMAction
 import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsState.ConfirmationDialog
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.core.bool.orFalse
 import io.element.android.libraries.matrix.api.MatrixClient
@@ -56,14 +57,14 @@ class RoomMemberDetailsPresenter @AssistedInject constructor(
         val coroutineScope = rememberCoroutineScope()
         var confirmationDialog by remember { mutableStateOf<ConfirmationDialog?>(null) }
         val roomMember by room.getRoomMemberAsState(roomMemberId)
-        val startDmActionState: MutableState<Async<RoomId>> = remember { mutableStateOf(Async.Uninitialized) }
+        val startDmActionState: MutableState<AsyncAction<RoomId>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
         // the room member is not really live...
-        val isBlocked: MutableState<Async<Boolean>> = remember(roomMember) {
+        val isBlocked: MutableState<AsyncData<Boolean>> = remember(roomMember) {
             val isIgnored = roomMember?.isIgnored
             if (isIgnored == null) {
-                mutableStateOf(Async.Uninitialized)
+                mutableStateOf(AsyncData.Uninitialized)
             } else {
-                mutableStateOf(Async.Success(isIgnored))
+                mutableStateOf(AsyncData.Success(isIgnored))
             }
         }
         LaunchedEffect(Unit) {
@@ -90,7 +91,7 @@ class RoomMemberDetailsPresenter @AssistedInject constructor(
                 }
                 RoomMemberDetailsEvents.ClearConfirmationDialog -> confirmationDialog = null
                 RoomMemberDetailsEvents.ClearBlockUserError -> {
-                    isBlocked.value = Async.Success(isBlocked.value.dataOrNull().orFalse())
+                    isBlocked.value = AsyncData.Success(isBlocked.value.dataOrNull().orFalse())
                 }
                 RoomMemberDetailsEvents.StartDM -> {
                     coroutineScope.launch {
@@ -98,7 +99,7 @@ class RoomMemberDetailsPresenter @AssistedInject constructor(
                     }
                 }
                 RoomMemberDetailsEvents.ClearStartDMState -> {
-                    startDmActionState.value = Async.Uninitialized
+                    startDmActionState.value = AsyncAction.Uninitialized
                 }
             }
         }
@@ -127,30 +128,30 @@ class RoomMemberDetailsPresenter @AssistedInject constructor(
         )
     }

-    private fun CoroutineScope.blockUser(userId: UserId, isBlockedState: MutableState<Async<Boolean>>) = launch {
-        isBlockedState.value = Async.Loading(false)
+    private fun CoroutineScope.blockUser(userId: UserId, isBlockedState: MutableState<AsyncData<Boolean>>) = launch {
+        isBlockedState.value = AsyncData.Loading(false)
         client.ignoreUser(userId)
             .fold(
                 onSuccess = {
-                    isBlockedState.value = Async.Success(true)
+                    isBlockedState.value = AsyncData.Success(true)
                     room.updateMembers()
                 },
                 onFailure = {
-                    isBlockedState.value = Async.Failure(it, false)
+                    isBlockedState.value = AsyncData.Failure(it, false)
                 }
             )
     }

-    private fun CoroutineScope.unblockUser(userId: UserId, isBlockedState: MutableState<Async<Boolean>>) = launch {
-        isBlockedState.value = Async.Loading(true)
+    private fun CoroutineScope.unblockUser(userId: UserId, isBlockedState: MutableState<AsyncData<Boolean>>) = launch {
+        isBlockedState.value = AsyncData.Loading(true)
         client.unignoreUser(userId)
             .fold(
                 onSuccess = {
-                    isBlockedState.value = Async.Success(false)
+                    isBlockedState.value = AsyncData.Success(false)
                     room.updateMembers()
                 },
                 onFailure = {
-                    isBlockedState.value = Async.Failure(it, true)
+                    isBlockedState.value = AsyncData.Failure(it, true)
                 }
             )
     }
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsState.kt
index ee9cfe388f4..817e5da46be 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsState.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsState.kt
@@ -16,15 +16,16 @@

 package io.element.android.features.roomdetails.impl.members.details

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.core.RoomId

 data class RoomMemberDetailsState(
     val userId: String,
     val userName: String?,
     val avatarUrl: String?,
-    val isBlocked: Async<Boolean>,
-    val startDmActionState: Async<RoomId>,
+    val isBlocked: AsyncData<Boolean>,
+    val startDmActionState: AsyncAction<RoomId>,
     val displayConfirmationDialog: ConfirmationDialog?,
     val isCurrentUser: Boolean,
     val eventSink: (RoomMemberDetailsEvents) -> Unit
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsStateProvider.kt
index c5710986a68..ff4b9ee1b37 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsStateProvider.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsStateProvider.kt
@@ -17,18 +17,19 @@
 package io.element.android.features.roomdetails.impl.members.details

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
+import io.element.android.libraries.architecture.AsyncData

 open class RoomMemberDetailsStateProvider : PreviewParameterProvider<RoomMemberDetailsState> {
     override val values: Sequence<RoomMemberDetailsState>
         get() = sequenceOf(
             aRoomMemberDetailsState(),
             aRoomMemberDetailsState().copy(userName = null),
-            aRoomMemberDetailsState().copy(isBlocked = Async.Success(true)),
+            aRoomMemberDetailsState().copy(isBlocked = AsyncData.Success(true)),
             aRoomMemberDetailsState().copy(displayConfirmationDialog = RoomMemberDetailsState.ConfirmationDialog.Block),
             aRoomMemberDetailsState().copy(displayConfirmationDialog = RoomMemberDetailsState.ConfirmationDialog.Unblock),
-            aRoomMemberDetailsState().copy(isBlocked = Async.Loading(true)),
-            aRoomMemberDetailsState().copy(startDmActionState = Async.Loading()),
+            aRoomMemberDetailsState().copy(isBlocked = AsyncData.Loading(true)),
+            aRoomMemberDetailsState().copy(startDmActionState = AsyncAction.Loading),
             // Add other states here
         )
 }
@@ -37,8 +38,8 @@ fun aRoomMemberDetailsState() = RoomMemberDetailsState(
     userId = "@daniel:domain.com",
     userName = "Daniel",
     avatarUrl = null,
-    isBlocked = Async.Success(false),
-    startDmActionState = Async.Uninitialized,
+    isBlocked = AsyncData.Success(false),
+    startDmActionState = AsyncAction.Uninitialized,
     displayConfirmationDialog = null,
     isCurrentUser = false,
     eventSink = {},
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt
index adf7bc52ed2..8463c98ee06 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/details/RoomMemberDetailsView.kt
@@ -33,7 +33,8 @@ import io.element.android.compound.tokens.generated.CompoundIcons
 import io.element.android.features.roomdetails.impl.R
 import io.element.android.features.roomdetails.impl.blockuser.BlockUserDialogs
 import io.element.android.features.roomdetails.impl.blockuser.BlockUserSection
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
+import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.components.list.ListItemContent
 import io.element.android.libraries.designsystem.preview.ElementPreviewDark
@@ -88,9 +89,13 @@ fun RoomMemberDetailsView(
                 BlockUserSection(state)
                 BlockUserDialogs(state)
             }
-            AsyncView(
+            AsyncActionView(
                 async = state.startDmActionState,
-                progressText = stringResource(CommonStrings.common_starting_chat),
+                progressDialog = {
+                    AsyncActionViewDefaults.ProgressDialog(
+                        progressText = stringResource(CommonStrings.common_starting_chat),
+                    )
+                },
                 onSuccess = onDMStarted,
                 errorMessage = { stringResource(R.string.screen_start_chat_error_starting_chat) },
                 onRetry = { state.eventSink(RoomMemberDetailsEvents.StartDM) },
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsPresenter.kt
index c3994e160c4..06649d25508 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsPresenter.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsPresenter.kt
@@ -28,7 +28,8 @@ 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.AsyncAction
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.architecture.runCatchingUpdatingState
 import io.element.android.libraries.matrix.api.notificationsettings.NotificationSettingsService
@@ -61,11 +62,11 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor(
             mutableStateOf(null)
         }
         val localCoroutineScope = rememberCoroutineScope()
-        val setNotificationSettingAction: MutableState<Async<Unit>> = remember { mutableStateOf(Async.Uninitialized) }
-        val restoreDefaultAction: MutableState<Async<Unit>> = remember { mutableStateOf(Async.Uninitialized) }
+        val setNotificationSettingAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
+        val restoreDefaultAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }

-        val roomNotificationSettings: MutableState<Async<RoomNotificationSettings>> = remember {
-            mutableStateOf(Async.Uninitialized)
+        val roomNotificationSettings: MutableState<AsyncData<RoomNotificationSettings>> = remember {
+            mutableStateOf(AsyncData.Uninitialized)
         }

         // We store state of which mode the user has set via the notification service before the new push settings have been updated.
@@ -103,7 +104,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor(
                         localCoroutineScope.restoreDefaultRoomNotificationMode(restoreDefaultAction, pendingSetDefault)
                     } else {
                         defaultRoomNotificationMode.value?.let {
-                            localCoroutineScope.setRoomNotificationMode(it, pendingRoomNotificationMode, pendingSetDefault,  setNotificationSettingAction)
+                            localCoroutineScope.setRoomNotificationMode(it, pendingRoomNotificationMode, pendingSetDefault, setNotificationSettingAction)
                         }
                     }
                 }
@@ -111,10 +112,10 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor(
                     localCoroutineScope.restoreDefaultRoomNotificationMode(restoreDefaultAction, pendingSetDefault)
                 }
                 RoomNotificationSettingsEvents.ClearSetNotificationError -> {
-                    setNotificationSettingAction.value = Async.Uninitialized
+                    setNotificationSettingAction.value = AsyncAction.Uninitialized
                 }
                 RoomNotificationSettingsEvents.ClearRestoreDefaultError -> {
-                    restoreDefaultAction.value = Async.Uninitialized
+                    restoreDefaultAction.value = AsyncAction.Uninitialized
                 }
             }
         }
@@ -136,7 +137,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor(
     @OptIn(FlowPreview::class)
     private fun CoroutineScope.observeNotificationSettings(
         pendingModeState: MutableState<RoomNotificationMode?>,
-        roomNotificationSettings: MutableState<Async<RoomNotificationSettings>>
+        roomNotificationSettings: MutableState<AsyncData<RoomNotificationSettings>>
     ) {
         notificationSettingsService.notificationSettingsChangeFlow
             .debounce(0.5.seconds)
@@ -148,7 +149,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor(

     private fun CoroutineScope.fetchNotificationSettings(
         pendingModeState: MutableState<RoomNotificationMode?>,
-        roomNotificationSettings: MutableState<Async<RoomNotificationSettings>>
+        roomNotificationSettings: MutableState<AsyncData<RoomNotificationSettings>>
     ) = launch {
         suspend {
             pendingModeState.value = null
@@ -169,7 +170,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor(
         mode: RoomNotificationMode,
         pendingModeState: MutableState<RoomNotificationMode?>,
         pendingDefaultState: MutableState<Boolean?>,
-        action: MutableState<Async<Unit>>
+        action: MutableState<AsyncAction<Unit>>
     ) = launch {
         suspend {
             pendingModeState.value = mode
@@ -184,7 +185,7 @@ class RoomNotificationSettingsPresenter @AssistedInject constructor(
     }

     private fun CoroutineScope.restoreDefaultRoomNotificationMode(
-        action: MutableState<Async<Unit>>,
+        action: MutableState<AsyncAction<Unit>>,
         pendingDefaultState: MutableState<Boolean?>
     ) = launch {
         suspend {
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt
index 4c23c0e2ae3..6f0ec6ea77e 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsState.kt
@@ -16,19 +16,20 @@

 package io.element.android.features.roomdetails.impl.notificationsettings

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.room.RoomNotificationMode
 import io.element.android.libraries.matrix.api.room.RoomNotificationSettings

 data class RoomNotificationSettingsState(
     val showUserDefinedSettingStyle: Boolean,
     val roomName: String,
-    val roomNotificationSettings: Async<RoomNotificationSettings>,
+    val roomNotificationSettings: AsyncData<RoomNotificationSettings>,
     val pendingRoomNotificationMode: RoomNotificationMode?,
     val pendingSetDefault: Boolean?,
     val defaultRoomNotificationMode: RoomNotificationMode?,
-    val setNotificationSettingAction: Async<Unit>,
-    val restoreDefaultAction: Async<Unit>,
+    val setNotificationSettingAction: AsyncAction<Unit>,
+    val restoreDefaultAction: AsyncAction<Unit>,
     val displayMentionsOnlyDisclaimer: Boolean,
     val eventSink: (RoomNotificationSettingsEvents) -> Unit
 )
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt
index aee68383f70..04f0c0859bb 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsStateProvider.kt
@@ -17,7 +17,8 @@
 package io.element.android.features.roomdetails.impl.notificationsettings

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.room.RoomNotificationMode
 import io.element.android.libraries.matrix.api.room.RoomNotificationSettings

@@ -26,23 +27,23 @@ internal class RoomNotificationSettingsStateProvider : PreviewParameterProvider<
         get() = sequenceOf(
             aRoomNotificationSettingsState(),
             aRoomNotificationSettingsState(isDefault = false),
-            aRoomNotificationSettingsState(setNotificationSettingAction = Async.Loading(Unit)),
-            aRoomNotificationSettingsState(setNotificationSettingAction = Async.Failure(Throwable("error"))),
-            aRoomNotificationSettingsState(restoreDefaultAction = Async.Loading(Unit)),
-            aRoomNotificationSettingsState(restoreDefaultAction = Async.Failure(Throwable("error"))),
+            aRoomNotificationSettingsState(setNotificationSettingAction = AsyncAction.Loading),
+            aRoomNotificationSettingsState(setNotificationSettingAction = AsyncAction.Failure(Throwable("error"))),
+            aRoomNotificationSettingsState(restoreDefaultAction = AsyncAction.Loading),
+            aRoomNotificationSettingsState(restoreDefaultAction = AsyncAction.Failure(Throwable("error"))),
             aRoomNotificationSettingsState(displayMentionsOnlyDisclaimer = true)
         )

     private fun aRoomNotificationSettingsState(
         isDefault: Boolean = true,
-        setNotificationSettingAction: Async<Unit> = Async.Uninitialized,
-        restoreDefaultAction: Async<Unit> = Async.Uninitialized,
+        setNotificationSettingAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
+        restoreDefaultAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
         displayMentionsOnlyDisclaimer: Boolean = false,
     ): RoomNotificationSettingsState {
         return RoomNotificationSettingsState(
             showUserDefinedSettingStyle = false,
             roomName = "Room 1",
-            Async.Success(RoomNotificationSettings(
+            AsyncData.Success(RoomNotificationSettings(
                 mode = RoomNotificationMode.MUTE,
                 isDefault = isDefault)),
             pendingRoomNotificationMode = null,
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt
index 6bba2436b31..b70c21798c2 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/RoomNotificationSettingsView.kt
@@ -33,7 +33,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
 import androidx.compose.ui.unit.dp
 import io.element.android.features.roomdetails.impl.R
 import io.element.android.libraries.core.bool.orTrue
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
 import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch
@@ -157,14 +157,14 @@ private fun RoomSpecificNotificationSettingsView(
                 }
             }

-            AsyncView(
+            AsyncActionView(
                 async = state.setNotificationSettingAction,
                 onSuccess = {},
                 errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) },
                 onErrorDismiss = { state.eventSink(RoomNotificationSettingsEvents.ClearSetNotificationError) },
             )

-            AsyncView(
+            AsyncActionView(
                 async = state.restoreDefaultAction,
                 onSuccess = {},
                 errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) },
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsStateProvider.kt
index a3ff7f23d7a..8e0bea68a6f 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsStateProvider.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsStateProvider.kt
@@ -17,7 +17,8 @@
 package io.element.android.features.roomdetails.impl.notificationsettings

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.room.RoomNotificationMode
 import io.element.android.libraries.matrix.api.room.RoomNotificationSettings

@@ -27,7 +28,7 @@ internal class UserDefinedRoomNotificationSettingsStateProvider : PreviewParamet
             RoomNotificationSettingsState(
                 showUserDefinedSettingStyle = false,
                 roomName = "Room 1",
-                Async.Success(
+                AsyncData.Success(
                     RoomNotificationSettings(
                         mode = RoomNotificationMode.MUTE,
                         isDefault = false)
@@ -35,8 +36,8 @@ internal class UserDefinedRoomNotificationSettingsStateProvider : PreviewParamet
                 pendingRoomNotificationMode = null,
                 pendingSetDefault = null,
                 defaultRoomNotificationMode = RoomNotificationMode.ALL_MESSAGES,
-                setNotificationSettingAction = Async.Uninitialized,
-                restoreDefaultAction = Async.Uninitialized,
+                setNotificationSettingAction = AsyncAction.Uninitialized,
+                restoreDefaultAction = AsyncAction.Uninitialized,
                 displayMentionsOnlyDisclaimer = false,
                 eventSink = { },
             ),
diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsView.kt
index 9b982542fdd..df1a41ea878 100644
--- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsView.kt
+++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/notificationsettings/UserDefinedRoomNotificationSettingsView.kt
@@ -29,7 +29,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
 import androidx.compose.ui.unit.dp
 import io.element.android.features.roomdetails.impl.R
 import io.element.android.libraries.core.bool.orTrue
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.components.button.BackButton
 import io.element.android.libraries.designsystem.preview.ElementPreview
 import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@@ -81,14 +81,14 @@ fun UserDefinedRoomNotificationSettingsView(
                 }
             )

-            AsyncView(
+            AsyncActionView(
                 async = state.setNotificationSettingAction,
                 onSuccess = {},
                 errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) },
                 onErrorDismiss = { state.eventSink(RoomNotificationSettingsEvents.ClearSetNotificationError) },
             )

-            AsyncView(
+            AsyncActionView(
                 async = state.restoreDefaultAction,
                 onSuccess = { onBackPressed() },
                 errorMessage = { stringResource(R.string.screen_notification_settings_edit_failed_updating_default_mode) },
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableEvents.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableEvents.kt
index 4cda13f7af5..2406265af6b 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableEvents.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableEvents.kt
@@ -17,6 +17,6 @@
 package io.element.android.features.securebackup.impl.disable

 sealed interface SecureBackupDisableEvents {
-    data class DisableBackup(val force: Boolean) : SecureBackupDisableEvents
+    data object DisableBackup : SecureBackupDisableEvents
     data object DismissDialogs : SecureBackupDisableEvents
 }
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenter.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenter.kt
index 60b46916615..4b98599b93b 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenter.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenter.kt
@@ -23,9 +23,8 @@ import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.runtime.setValue
 import io.element.android.features.securebackup.impl.loggerTagDisable
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.architecture.runCatchingUpdatingState
 import io.element.android.libraries.core.meta.BuildMeta
@@ -44,20 +43,17 @@ class SecureBackupDisablePresenter @Inject constructor(
     override fun present(): SecureBackupDisableState {
         val backupState by encryptionService.backupStateStateFlow.collectAsState()
         Timber.tag(loggerTagDisable.value).d("backupState: $backupState")
-        val disableAction = remember { mutableStateOf<Async<Unit>>(Async.Uninitialized) }
+        val disableAction: MutableState<AsyncAction<Unit>> = remember { mutableStateOf(AsyncAction.Uninitialized) }
         val coroutineScope = rememberCoroutineScope()
-        var showDialog by remember { mutableStateOf(false) }
         fun handleEvents(event: SecureBackupDisableEvents) {
             when (event) {
-                is SecureBackupDisableEvents.DisableBackup -> if (event.force) {
-                    showDialog = false
+                is SecureBackupDisableEvents.DisableBackup -> if (disableAction.value.isConfirming()) {
                     coroutineScope.disableBackup(disableAction)
                 } else {
-                    showDialog = true
+                    disableAction.value = AsyncAction.Confirming
                 }
                 SecureBackupDisableEvents.DismissDialogs -> {
-                    showDialog = false
-                    disableAction.value = Async.Uninitialized
+                    disableAction.value = AsyncAction.Uninitialized
                 }
             }
         }
@@ -65,13 +61,12 @@ class SecureBackupDisablePresenter @Inject constructor(
         return SecureBackupDisableState(
             backupState = backupState,
             disableAction = disableAction.value,
-            showConfirmationDialog = showDialog,
             appName = buildMeta.applicationName,
             eventSink = ::handleEvents
         )
     }

-    private fun CoroutineScope.disableBackup(disableAction: MutableState<Async<Unit>>) = launch {
+    private fun CoroutineScope.disableBackup(disableAction: MutableState<AsyncAction<Unit>>) = launch {
         suspend {
             Timber.tag(loggerTagDisable.value).d("Calling encryptionService.disableRecovery()")
             encryptionService.disableRecovery().getOrThrow()
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableState.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableState.kt
index 41e39c398e6..4875ef8807a 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableState.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableState.kt
@@ -16,13 +16,12 @@

 package io.element.android.features.securebackup.impl.disable

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.encryption.BackupState

 data class SecureBackupDisableState(
     val backupState: BackupState,
-    val disableAction: Async<Unit>,
-    val showConfirmationDialog: Boolean,
+    val disableAction: AsyncAction<Unit>,
     val appName: String,
     val eventSink: (SecureBackupDisableEvents) -> Unit
 )
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableStateProvider.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableStateProvider.kt
index 8c22e369680..036ed12102e 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableStateProvider.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableStateProvider.kt
@@ -17,28 +17,26 @@
 package io.element.android.features.securebackup.impl.disable

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.encryption.BackupState

 open class SecureBackupDisableStateProvider : PreviewParameterProvider<SecureBackupDisableState> {
     override val values: Sequence<SecureBackupDisableState>
         get() = sequenceOf(
             aSecureBackupDisableState(),
-            aSecureBackupDisableState(showConfirmationDialog = true),
-            aSecureBackupDisableState(disableAction = Async.Loading()),
-            aSecureBackupDisableState(disableAction = Async.Failure(Exception("Failed to disable"))),
+            aSecureBackupDisableState(disableAction = AsyncAction.Confirming),
+            aSecureBackupDisableState(disableAction = AsyncAction.Loading),
+            aSecureBackupDisableState(disableAction = AsyncAction.Failure(Exception("Failed to disable"))),
             // Add other states here
         )
 }

 fun aSecureBackupDisableState(
     backupState: BackupState = BackupState.UNKNOWN,
-    disableAction: Async<Unit> = Async.Uninitialized,
-    showConfirmationDialog: Boolean = false,
+    disableAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
 ) = SecureBackupDisableState(
     backupState = backupState,
     disableAction = disableAction,
-    showConfirmationDialog = showConfirmationDialog,
     appName = "Element",
     eventSink = {}
 )
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableView.kt
index 4f515fd841a..21da4557948 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableView.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisableView.kt
@@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.res.stringResource
@@ -34,10 +33,9 @@ import androidx.compose.ui.unit.dp
 import io.element.android.compound.theme.ElementTheme
 import io.element.android.compound.tokens.generated.CompoundIcons
 import io.element.android.features.securebackup.impl.R
-import io.element.android.libraries.architecture.Async
 import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
-import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
 import io.element.android.libraries.designsystem.preview.ElementPreview
 import io.element.android.libraries.designsystem.preview.PreviewsDayNight
 import io.element.android.libraries.designsystem.theme.components.Button
@@ -52,11 +50,6 @@ fun SecureBackupDisableView(
     onBackClicked: () -> Unit,
     modifier: Modifier = Modifier,
 ) {
-    LaunchedEffect(state.disableAction) {
-        if (state.disableAction is Async.Success) {
-            onDone()
-        }
-    }
     FlowStepPage(
         modifier = modifier,
         onBackClicked = onBackClicked,
@@ -67,17 +60,19 @@ fun SecureBackupDisableView(
         buttons = { Buttons(state = state) },
     )

-    if (state.showConfirmationDialog) {
-        SecureBackupDisableConfirmationDialog(
-            onConfirm = { state.eventSink.invoke(SecureBackupDisableEvents.DisableBackup(force = true)) },
-            onDismiss = { state.eventSink.invoke(SecureBackupDisableEvents.DismissDialogs) },
-        )
-    } else if (state.disableAction is Async.Failure) {
-        ErrorDialog(
-            content = state.disableAction.error.let { it.message ?: it.toString() },
-            onDismiss = { state.eventSink.invoke(SecureBackupDisableEvents.DismissDialogs) },
-        )
-    }
+    AsyncActionView(
+        async = state.disableAction,
+        confirmationDialog = {
+            SecureBackupDisableConfirmationDialog(
+                onConfirm = { state.eventSink.invoke(SecureBackupDisableEvents.DisableBackup) },
+                onDismiss = { state.eventSink.invoke(SecureBackupDisableEvents.DismissDialogs) },
+            )
+        },
+        progressDialog = {},
+        errorMessage = { it.message ?: it.toString() },
+        onErrorDismiss = { state.eventSink.invoke(SecureBackupDisableEvents.DismissDialogs) },
+        onSuccess = { onDone() },
+    )
 }

 @Composable
@@ -101,7 +96,7 @@ private fun ColumnScope.Buttons(
         showProgress = state.disableAction.isLoading(),
         destructive = true,
         modifier = Modifier.fillMaxWidth(),
-        onClick = { state.eventSink.invoke(SecureBackupDisableEvents.DisableBackup(force = false)) }
+        onClick = { state.eventSink.invoke(SecureBackupDisableEvents.DisableBackup) }
     )
 }

diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnablePresenter.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnablePresenter.kt
index dfceb16dea7..3ce99ff3539 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnablePresenter.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnablePresenter.kt
@@ -22,7 +22,7 @@ import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
 import io.element.android.features.securebackup.impl.loggerTagDisable
-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.architecture.runCatchingUpdatingState
 import io.element.android.libraries.matrix.api.encryption.EncryptionService
@@ -37,14 +37,14 @@ class SecureBackupEnablePresenter @Inject constructor(

     @Composable
     override fun present(): SecureBackupEnableState {
-        val enableAction = remember { mutableStateOf<Async<Unit>>(Async.Uninitialized) }
+        val enableAction = remember { mutableStateOf<AsyncData<Unit>>(AsyncData.Uninitialized) }
         val coroutineScope = rememberCoroutineScope()
         fun handleEvents(event: SecureBackupEnableEvents) {
             when (event) {
                 is SecureBackupEnableEvents.EnableBackup ->
                     coroutineScope.enableBackup(enableAction)
                 SecureBackupEnableEvents.DismissDialog -> {
-                    enableAction.value = Async.Uninitialized
+                    enableAction.value = AsyncData.Uninitialized
                 }
             }
         }
@@ -55,7 +55,7 @@ class SecureBackupEnablePresenter @Inject constructor(
         )
     }

-    private fun CoroutineScope.enableBackup(action: MutableState<Async<Unit>>) = launch {
+    private fun CoroutineScope.enableBackup(action: MutableState<AsyncData<Unit>>) = launch {
         suspend {
             Timber.tag(loggerTagDisable.value).d("Calling encryptionService.enableBackups()")
             encryptionService.enableBackups().getOrThrow()
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableState.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableState.kt
index 7c3aaf839b9..bd81004f9c4 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableState.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableState.kt
@@ -16,9 +16,9 @@

 package io.element.android.features.securebackup.impl.enable

-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 data class SecureBackupEnableState(
-    val enableAction: Async<Unit>,
+    val enableAction: AsyncData<Unit>,
     val eventSink: (SecureBackupEnableEvents) -> Unit
 )
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableStateProvider.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableStateProvider.kt
index 494c45b5b49..1029278c053 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableStateProvider.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableStateProvider.kt
@@ -17,20 +17,20 @@
 package io.element.android.features.securebackup.impl.enable

 import androidx.compose.ui.tooling.preview.PreviewParameterProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData

 open class SecureBackupEnableStateProvider : PreviewParameterProvider<SecureBackupEnableState> {
     override val values: Sequence<SecureBackupEnableState>
         get() = sequenceOf(
             aSecureBackupEnableState(),
-            aSecureBackupEnableState(enableAction = Async.Loading()),
-            aSecureBackupEnableState(enableAction = Async.Failure(Exception("Failed to enable"))),
+            aSecureBackupEnableState(enableAction = AsyncData.Loading()),
+            aSecureBackupEnableState(enableAction = AsyncData.Failure(Exception("Failed to enable"))),
             // Add other states here
         )
 }

 fun aSecureBackupEnableState(
-    enableAction: Async<Unit> = Async.Uninitialized,
+    enableAction: AsyncData<Unit> = AsyncData.Uninitialized,
 ) = SecureBackupEnableState(
     enableAction = enableAction,
     eventSink = {}
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableView.kt
index d97fc735d88..37a46a14082 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableView.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnableView.kt
@@ -26,7 +26,7 @@ import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.res.vectorResource
 import androidx.compose.ui.tooling.preview.PreviewParameter
 import io.element.android.features.securebackup.impl.R
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage
 import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
 import io.element.android.libraries.designsystem.preview.ElementPreview
@@ -42,7 +42,7 @@ fun SecureBackupEnableView(
     modifier: Modifier = Modifier,
 ) {
     LaunchedEffect(state.enableAction) {
-        if (state.enableAction is Async.Success) {
+        if (state.enableAction is AsyncData.Success) {
             onDone()
         }
     }
@@ -53,7 +53,7 @@ fun SecureBackupEnableView(
         iconVector = ImageVector.vectorResource(CommonDrawables.ic_key),
         buttons = { Buttons(state = state) }
     )
-    if (state.enableAction is Async.Failure) {
+    if (state.enableAction is AsyncData.Failure) {
         ErrorDialog(
             content = state.enableAction.error.let { it.message ?: it.toString() },
             onDismiss = { state.eventSink.invoke(SecureBackupEnableEvents.DismissDialog) },
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenter.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenter.kt
index 9207dbef790..2940ef576e6 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenter.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenter.kt
@@ -27,7 +27,7 @@ import androidx.compose.runtime.setValue
 import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory
 import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
 import io.element.android.features.securebackup.impl.tools.RecoveryKeyTools
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.architecture.Presenter
 import io.element.android.libraries.architecture.runCatchingUpdatingState
 import io.element.android.libraries.matrix.api.encryption.EncryptionService
@@ -46,14 +46,14 @@ class SecureBackupEnterRecoveryKeyPresenter @Inject constructor(
         var recoveryKey by rememberSaveable {
             mutableStateOf("")
         }
-        val submitAction = remember {
-            mutableStateOf<Async<Unit>>(Async.Uninitialized)
+        val submitAction: MutableState<AsyncAction<Unit>> = remember {
+            mutableStateOf(AsyncAction.Uninitialized)
         }

         fun handleEvents(event: SecureBackupEnterRecoveryKeyEvents) {
             when (event) {
                 SecureBackupEnterRecoveryKeyEvents.ClearDialog -> {
-                    submitAction.value = Async.Uninitialized
+                    submitAction.value = AsyncAction.Uninitialized
                 }
                 is SecureBackupEnterRecoveryKeyEvents.OnRecoveryKeyChange -> {
                     val previousRecoveryKey = recoveryKey
@@ -86,7 +86,7 @@ class SecureBackupEnterRecoveryKeyPresenter @Inject constructor(

     private fun CoroutineScope.submitRecoveryKey(
         recoveryKey: String,
-        action: MutableState<Async<Unit>>
+        action: MutableState<AsyncAction<Unit>>
     ) = launch {
         suspend {
             encryptionService.recover(recoveryKey).getOrThrow()
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyState.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyState.kt
index c9a631c11cb..c064a3fc133 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyState.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyState.kt
@@ -17,12 +17,12 @@
 package io.element.android.features.securebackup.impl.enter

 import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction

 // Do not use default value, so no member get forgotten in the presenters.
 data class SecureBackupEnterRecoveryKeyState(
     val recoveryKeyViewState: RecoveryKeyViewState,
     val isSubmitEnabled: Boolean,
-    val submitAction: Async<Unit>,
+    val submitAction: AsyncAction<Unit>,
     val eventSink: (SecureBackupEnterRecoveryKeyEvents) -> Unit
 )
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyStateProvider.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyStateProvider.kt
index 375eafef73f..2869b9a281e 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyStateProvider.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyStateProvider.kt
@@ -20,22 +20,22 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
 import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory
 import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
 import io.element.android.features.securebackup.impl.setup.views.aFormattedRecoveryKey
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction

 open class SecureBackupEnterRecoveryKeyStateProvider : PreviewParameterProvider<SecureBackupEnterRecoveryKeyState> {
     override val values: Sequence<SecureBackupEnterRecoveryKeyState>
         get() = sequenceOf(
             aSecureBackupEnterRecoveryKeyState(recoveryKey = ""),
             aSecureBackupEnterRecoveryKeyState(),
-            aSecureBackupEnterRecoveryKeyState(submitAction = Async.Loading()),
-            aSecureBackupEnterRecoveryKeyState(submitAction = Async.Failure(Exception("A Failure"))),
+            aSecureBackupEnterRecoveryKeyState(submitAction = AsyncAction.Loading),
+            aSecureBackupEnterRecoveryKeyState(submitAction = AsyncAction.Failure(Exception("A Failure"))),
         )
 }

 fun aSecureBackupEnterRecoveryKeyState(
     recoveryKey: String = aFormattedRecoveryKey(),
     isSubmitEnabled: Boolean = recoveryKey.isNotEmpty(),
-    submitAction: Async<Unit> = Async.Uninitialized,
+    submitAction: AsyncAction<Unit> = AsyncAction.Uninitialized,
 ) = SecureBackupEnterRecoveryKeyState(
     recoveryKeyViewState = RecoveryKeyViewState(
         recoveryKeyUserStory = RecoveryKeyUserStory.Enter,
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt
index d5eda2c15a8..b590219a647 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyView.kt
@@ -29,7 +29,7 @@ import androidx.compose.ui.unit.dp
 import io.element.android.features.securebackup.impl.R
 import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyView
 import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage
-import io.element.android.libraries.designsystem.components.async.AsyncView
+import io.element.android.libraries.designsystem.components.async.AsyncActionView
 import io.element.android.libraries.designsystem.preview.ElementPreview
 import io.element.android.libraries.designsystem.preview.PreviewsDayNight
 import io.element.android.libraries.designsystem.theme.components.Button
@@ -43,10 +43,10 @@ fun SecureBackupEnterRecoveryKeyView(
     onBackClicked: () -> Unit,
     modifier: Modifier = Modifier,
 ) {
-    AsyncView(
+    AsyncActionView(
         async = state.submitAction,
         onSuccess = { onDone() },
-        showProgressDialog = false,
+        progressDialog = { },
         errorTitle = { stringResource(id = R.string.screen_recovery_key_confirm_error_title) },
         errorMessage = { stringResource(id = R.string.screen_recovery_key_confirm_error_content) },
         onErrorDismiss = { state.eventSink(SecureBackupEnterRecoveryKeyEvents.ClearDialog) },
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootPresenter.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootPresenter.kt
index 9036200ac95..ca60f7d32fc 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootPresenter.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootPresenter.kt
@@ -25,7 +25,7 @@ import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
 import io.element.android.features.securebackup.impl.loggerTagRoot
-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.architecture.runCatchingUpdatingState
 import io.element.android.libraries.core.meta.BuildMeta
@@ -55,7 +55,7 @@ class SecureBackupRootPresenter @Inject constructor(
         Timber.tag(loggerTagRoot.value).d("backupState: $backupState")
         Timber.tag(loggerTagRoot.value).d("recoveryState: $recoveryState")

-        val doesBackupExistOnServerAction: MutableState<Async<Boolean>> = remember { mutableStateOf(Async.Uninitialized) }
+        val doesBackupExistOnServerAction: MutableState<AsyncData<Boolean>> = remember { mutableStateOf(AsyncData.Uninitialized) }

         LaunchedEffect(backupState) {
             if (backupState == BackupState.UNKNOWN) {
@@ -79,7 +79,7 @@ class SecureBackupRootPresenter @Inject constructor(
         )
     }

-    private fun CoroutineScope.getKeyBackupStatus(action: MutableState<Async<Boolean>>) = launch {
+    private fun CoroutineScope.getKeyBackupStatus(action: MutableState<AsyncData<Boolean>>) = launch {
         suspend {
             encryptionService.doesBackupExistOnServer().getOrThrow()
         }.runCatchingUpdatingState(action)
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootState.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootState.kt
index e2c6c1154c8..0d57ebbf46b 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootState.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootState.kt
@@ -16,14 +16,14 @@

 package io.element.android.features.securebackup.impl.root

-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.encryption.BackupState
 import io.element.android.libraries.matrix.api.encryption.RecoveryState

 data class SecureBackupRootState(
     val backupState: BackupState,
-    val doesBackupExistOnServer: Async<Boolean>,
+    val doesBackupExistOnServer: AsyncData<Boolean>,
     val recoveryState: RecoveryState,
     val appName: String,
     val snackbarMessage: SnackbarMessage?,
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootStateProvider.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootStateProvider.kt
index ae8b2aa63b9..beb54101ff9 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootStateProvider.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootStateProvider.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.securebackup.impl.root

 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.designsystem.utils.snackbar.SnackbarMessage
 import io.element.android.libraries.matrix.api.encryption.BackupState
 import io.element.android.libraries.matrix.api.encryption.RecoveryState
@@ -25,10 +25,10 @@ import io.element.android.libraries.matrix.api.encryption.RecoveryState
 open class SecureBackupRootStateProvider : PreviewParameterProvider<SecureBackupRootState> {
     override val values: Sequence<SecureBackupRootState>
         get() = sequenceOf(
-            aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = Async.Uninitialized),
-            aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = Async.Success(true)),
-            aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = Async.Success(false)),
-            aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = Async.Failure(Exception("An error"))),
+            aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = AsyncData.Uninitialized),
+            aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = AsyncData.Success(true)),
+            aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = AsyncData.Success(false)),
+            aSecureBackupRootState(backupState = BackupState.UNKNOWN, doesBackupExistOnServer = AsyncData.Failure(Exception("An error"))),
             aSecureBackupRootState(backupState = BackupState.ENABLED),
             aSecureBackupRootState(recoveryState = RecoveryState.UNKNOWN),
             aSecureBackupRootState(recoveryState = RecoveryState.ENABLED),
@@ -40,7 +40,7 @@ open class SecureBackupRootStateProvider : PreviewParameterProvider<SecureBackup

 fun aSecureBackupRootState(
     backupState: BackupState = BackupState.UNKNOWN,
-    doesBackupExistOnServer: Async<Boolean> = Async.Uninitialized,
+    doesBackupExistOnServer: AsyncData<Boolean> = AsyncData.Uninitialized,
     recoveryState: RecoveryState = RecoveryState.UNKNOWN,
     snackbarMessage: SnackbarMessage? = null,
 ) = SecureBackupRootState(
diff --git a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootView.kt b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootView.kt
index d4033f1297a..54c37761ed8 100644
--- a/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootView.kt
+++ b/features/securebackup/impl/src/main/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootView.kt
@@ -24,7 +24,7 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.tooling.preview.PreviewParameter
 import io.element.android.features.securebackup.impl.R
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.components.async.AsyncLoading
 import io.element.android.libraries.designsystem.components.list.ListItemContent
 import io.element.android.libraries.designsystem.components.preferences.PreferenceDivider
@@ -82,7 +82,7 @@ fun SecureBackupRootView(
             BackupState.WAITING_FOR_SYNC -> Unit
             BackupState.UNKNOWN -> {
                 when (state.doesBackupExistOnServer) {
-                    is Async.Success -> when (state.doesBackupExistOnServer.data) {
+                    is AsyncData.Success -> when (state.doesBackupExistOnServer.data) {
                         true -> {
                             PreferenceText(
                                 title = stringResource(id = R.string.screen_chat_backup_key_backup_action_disable),
@@ -97,8 +97,8 @@ fun SecureBackupRootView(
                             )
                         }
                     }
-                    is Async.Loading,
-                    Async.Uninitialized -> {
+                    is AsyncData.Loading,
+                    AsyncData.Uninitialized -> {
                         ListItem(headlineContent = {
                             Row(
                                 modifier = Modifier.fillMaxWidth(),
@@ -108,7 +108,7 @@ fun SecureBackupRootView(
                             }
                         })
                     }
-                    is Async.Failure -> {
+                    is AsyncData.Failure -> {
                         ListItem(
                             headlineContent = {
                                 Text(
diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt
index 89751ca6042..0d04ac544d5 100644
--- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt
+++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt
@@ -24,7 +24,7 @@ import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
 import com.freeletics.flowredux.compose.rememberStateAndDispatch
-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.matrix.api.verification.SessionVerificationService
 import io.element.android.libraries.matrix.api.verification.VerificationFlowState
@@ -94,8 +94,8 @@ class VerifySelfSessionPresenter @Inject constructor(

             is StateMachineState.Verifying -> {
                 val async = when (machineState) {
-                    is StateMachineState.Verifying.Replying -> Async.Loading()
-                    else -> Async.Uninitialized
+                    is StateMachineState.Verifying.Replying -> AsyncData.Loading()
+                    else -> AsyncData.Uninitialized
                 }
                 VerifySelfSessionState.VerificationStep.Verifying(machineState.data, async)
             }
diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt
index f3afd3b7b99..3076b1fdc7d 100644
--- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt
+++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt
@@ -18,7 +18,7 @@ package io.element.android.features.verifysession.impl

 import androidx.compose.runtime.Immutable
 import androidx.compose.runtime.Stable
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.verification.SessionVerificationData

 @Immutable
@@ -33,7 +33,7 @@ data class VerifySelfSessionState(
         data object Canceled : VerificationStep
         data object AwaitingOtherDeviceResponse : VerificationStep
         data object Ready : VerificationStep
-        data class Verifying(val data: SessionVerificationData, val state: Async<Unit>) : VerificationStep
+        data class Verifying(val data: SessionVerificationData, val state: AsyncData<Unit>) : VerificationStep
         data object Completed : VerificationStep
     }
 }
diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt
index 9115b8b4444..81f25866bd3 100644
--- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt
+++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt
@@ -17,7 +17,7 @@
 package io.element.android.features.verifysession.impl

 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.matrix.api.verification.SessionVerificationData
 import io.element.android.libraries.matrix.api.verification.VerificationEmoji

@@ -29,10 +29,10 @@ open class VerifySelfSessionStateProvider : PreviewParameterProvider<VerifySelfS
                 verificationFlowStep = VerifySelfSessionState.VerificationStep.AwaitingOtherDeviceResponse
             ),
             aVerifySelfSessionState().copy(
-                verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aEmojisSessionVerificationData(), Async.Uninitialized)
+                verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aEmojisSessionVerificationData(), AsyncData.Uninitialized)
             ),
             aVerifySelfSessionState().copy(
-                verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aEmojisSessionVerificationData(), Async.Loading())
+                verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aEmojisSessionVerificationData(), AsyncData.Loading())
             ),
             aVerifySelfSessionState().copy(
                 verificationFlowStep = VerifySelfSessionState.VerificationStep.Canceled
@@ -41,7 +41,7 @@ open class VerifySelfSessionStateProvider : PreviewParameterProvider<VerifySelfS
                 verificationFlowStep = VerifySelfSessionState.VerificationStep.Ready
             ),
             aVerifySelfSessionState().copy(
-                verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aDecimalsSessionVerificationData(), Async.Uninitialized)
+                verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aDecimalsSessionVerificationData(), AsyncData.Uninitialized)
             ),
             // Add other state here
         )
diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt
index a132431812b..02f5514e9fd 100644
--- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt
+++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt
@@ -43,7 +43,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
 import androidx.compose.ui.unit.dp
 import io.element.android.compound.theme.ElementTheme
 import io.element.android.features.verifysession.impl.emoji.toEmojiResource
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
 import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
 import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
@@ -207,7 +207,7 @@ private fun BottomMenu(screenState: VerifySelfSessionState, goBack: () -> Unit)
     val verificationViewState = screenState.verificationFlowStep
     val eventSink = screenState.eventSink

-    val isVerifying = (verificationViewState as? FlowStep.Verifying)?.state is Async.Loading<Unit>
+    val isVerifying = (verificationViewState as? FlowStep.Verifying)?.state is AsyncData.Loading<Unit>
     val positiveButtonTitle = when (verificationViewState) {
         FlowStep.Initial -> R.string.screen_session_verification_positive_button_initial
         FlowStep.Canceled -> R.string.screen_session_verification_positive_button_canceled
diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncAction.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncAction.kt
new file mode 100644
index 00000000000..ef64c973df2
--- /dev/null
+++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncAction.kt
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2023 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.element.android.libraries.architecture
+
+import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.Stable
+import kotlin.contracts.ExperimentalContracts
+import kotlin.contracts.InvocationKind
+import kotlin.contracts.contract
+
+/**
+ * Sealed type that allows to model an asynchronous operation triggered by the user.
+ */
+@Stable
+sealed interface AsyncAction<out T> {
+
+    /**
+     * Represents an uninitialized operation (i.e. yet to be run by the user).
+     */
+    data object Uninitialized : AsyncAction<Nothing>
+
+    /**
+     * Represents an operation that is currently waiting for user confirmation.
+     */
+    data object Confirming : AsyncAction<Nothing>
+
+    /**
+     * Represents an operation that is currently ongoing.
+     */
+    data object Loading : AsyncAction<Nothing>
+
+    /**
+     * Represents a failed operation.
+     *
+     * @property error the error that caused the operation to fail.
+     */
+    data class Failure(
+        val error: Throwable,
+    ) : AsyncAction<Nothing>
+
+    /**
+     * Represents a successful operation.
+     *
+     * @param T the type of data returned by the operation.
+     * @property data the data returned by the operation.
+     */
+    data class Success<out T>(
+        val data: T,
+    ) : AsyncAction<T>
+
+    /**
+     * Returns the data returned by the operation, or null otherwise.
+     */
+    fun dataOrNull(): T? = when (this) {
+        is Success -> data
+        else -> null
+    }
+
+    /**
+     * Returns the error that caused the operation to fail, or null otherwise.
+     */
+    fun errorOrNull(): Throwable? = when (this) {
+        is Failure -> error
+        else -> null
+    }
+
+    fun isUninitialized(): Boolean = this == Uninitialized
+
+    fun isConfirming(): Boolean = this is Confirming
+
+    fun isLoading(): Boolean = this is Loading
+
+    fun isFailure(): Boolean = this is Failure
+
+    fun isSuccess(): Boolean = this is Success
+}
+
+suspend inline fun <T> MutableState<AsyncAction<T>>.runCatchingUpdatingState(
+    errorTransform: (Throwable) -> Throwable = { it },
+    block: () -> T,
+): Result<T> = runUpdatingState(
+    state = this,
+    errorTransform = errorTransform,
+    resultBlock = {
+        runCatching {
+            block()
+        }
+    },
+)
+
+suspend inline fun <T> (suspend () -> T).runCatchingUpdatingState(
+    state: MutableState<AsyncAction<T>>,
+    errorTransform: (Throwable) -> Throwable = { it },
+): Result<T> = runUpdatingState(
+    state = state,
+    errorTransform = errorTransform,
+    resultBlock = {
+        runCatching {
+            this()
+        }
+    },
+)
+
+suspend inline fun <T> MutableState<AsyncAction<T>>.runUpdatingState(
+    errorTransform: (Throwable) -> Throwable = { it },
+    resultBlock: () -> Result<T>,
+): Result<T> = runUpdatingState(
+    state = this,
+    errorTransform = errorTransform,
+    resultBlock = resultBlock,
+)
+
+/**
+ * Calls the specified [Result]-returning function [resultBlock]
+ * encapsulating its progress and return value into an [AsyncAction] while
+ * posting its updates to the MutableState [state].
+ *
+ * @param T the type of data returned by the operation.
+ * @param state the [MutableState] to post updates to.
+ * @param errorTransform a function to transform the error before posting it.
+ * @param resultBlock a suspending function that returns a [Result].
+ * @return the [Result] returned by [resultBlock].
+ */
+@OptIn(ExperimentalContracts::class)
+@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
+suspend inline fun <T> runUpdatingState(
+    state: MutableState<AsyncAction<T>>,
+    errorTransform: (Throwable) -> Throwable = { it },
+    resultBlock: suspend () -> Result<T>,
+): Result<T> {
+    contract {
+        callsInPlace(resultBlock, InvocationKind.EXACTLY_ONCE)
+    }
+    state.value = AsyncAction.Loading
+    return resultBlock().fold(
+        onSuccess = {
+            state.value = AsyncAction.Success(it)
+            Result.success(it)
+        },
+        onFailure = {
+            val error = errorTransform(it)
+            state.value = AsyncAction.Failure(
+                error = error,
+            )
+            Result.failure(error)
+        }
+    )
+}
diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/Async.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt
similarity index 88%
rename from libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/Async.kt
rename to libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt
index fb7bc2836b9..de547d87e64 100644
--- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/Async.kt
+++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt
@@ -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,
             )
diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncProvider.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncActionProvider.kt
similarity index 65%
rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncProvider.kt
rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncActionProvider.kt
index 028de2d57bf..d74f0de5ca6 100644
--- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncProvider.kt
+++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncActionProvider.kt
@@ -17,14 +17,15 @@
 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.AsyncAction

-open class AsyncProvider : PreviewParameterProvider<Async<Unit>> {
-    override val values: Sequence<Async<Unit>>
+open class AsyncActionProvider : PreviewParameterProvider<AsyncAction<Unit>> {
+    override val values: Sequence<AsyncAction<Unit>>
         get() = sequenceOf(
-            Async.Uninitialized,
-            Async.Loading(),
-            Async.Failure(Exception("An error occurred")),
-            Async.Success(Unit),
+            AsyncAction.Uninitialized,
+            AsyncAction.Confirming,
+            AsyncAction.Loading,
+            AsyncAction.Failure(Exception("An error occurred")),
+            AsyncAction.Success(Unit),
         )
 }
diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncView.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncActionView.kt
similarity index 67%
rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncView.kt
rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncActionView.kt
index d19dc08c6ab..732a3473a3e 100644
--- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncView.kt
+++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/async/AsyncActionView.kt
@@ -19,8 +19,9 @@ 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.AsyncAction
 import io.element.android.libraries.designsystem.components.ProgressDialog
+import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
 import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
 import io.element.android.libraries.designsystem.components.dialogs.ErrorDialogDefaults
 import io.element.android.libraries.designsystem.components.dialogs.RetryDialog
@@ -28,52 +29,28 @@ import io.element.android.libraries.designsystem.preview.ElementPreview
 import io.element.android.libraries.designsystem.preview.PreviewsDayNight

 /**
- * Render an Async object.
+ * Render an AsyncAction object.
  * - If Success, invoke the callback [onSuccess], only once.
  * - If Failure, display a dialog with the error, which can be transformed, using [errorMessage]. When
  * closed, [onErrorDismiss] will be invoked. If [onRetry] is not null, a retry button will be displayed.
- * - When loading, display a loading dialog, if [showProgressDialog] is true, with on optional [progressText].
+ * - When loading, display a loading dialog using [progressDialog]. Pass empty lambda to disable.
  */
 @Composable
-fun <T> AsyncView(
-    async: Async<T>,
+fun <T> AsyncActionView(
+    async: AsyncAction<T>,
     onSuccess: (T) -> Unit,
     onErrorDismiss: () -> Unit,
-    showProgressDialog: Boolean = true,
-    progressText: String? = null,
-    errorTitle: @Composable (Throwable) -> String = { ErrorDialogDefaults.title },
-    errorMessage: @Composable (Throwable) -> String = { it.message ?: it.toString() },
-    onRetry: (() -> Unit)? = null,
-) {
-    AsyncView(
-        async = async,
-        onSuccess = onSuccess,
-        onErrorDismiss = onErrorDismiss,
-        progressDialog = {
-            if (showProgressDialog) {
-                AsyncViewDefaults.ProgressDialog(progressText)
-            }
-        },
-        errorTitle = errorTitle,
-        errorMessage = errorMessage,
-        onRetry = onRetry,
-    )
-}
-
-@Composable
-fun <T> AsyncView(
-    async: Async<T>,
-    onSuccess: (T) -> Unit,
-    onErrorDismiss: () -> Unit,
-    progressDialog: @Composable () -> Unit = { AsyncViewDefaults.ProgressDialog() },
+    confirmationDialog: @Composable () -> Unit = { },
+    progressDialog: @Composable () -> Unit = { AsyncActionViewDefaults.ProgressDialog() },
     errorTitle: @Composable (Throwable) -> String = { ErrorDialogDefaults.title },
     errorMessage: @Composable (Throwable) -> String = { it.message ?: it.toString() },
     onRetry: (() -> Unit)? = null,
 ) {
     when (async) {
-        Async.Uninitialized -> Unit
-        is Async.Loading -> progressDialog()
-        is Async.Failure -> {
+        AsyncAction.Uninitialized -> Unit
+        AsyncAction.Confirming -> confirmationDialog()
+        is AsyncAction.Loading -> progressDialog()
+        is AsyncAction.Failure -> {
             if (onRetry == null) {
                 ErrorDialog(
                     title = errorTitle(async.error),
@@ -89,7 +66,7 @@ fun <T> AsyncView(
                 )
             }
         }
-        is Async.Success -> {
+        is AsyncAction.Success -> {
             LaunchedEffect(async) {
                 onSuccess(async.data)
             }
@@ -97,7 +74,7 @@ fun <T> AsyncView(
     }
 }

-object AsyncViewDefaults {
+object AsyncActionViewDefaults {
     @Composable
     fun ProgressDialog(progressText: String? = null) {
         ProgressDialog(
@@ -108,12 +85,20 @@ object AsyncViewDefaults {

 @PreviewsDayNight
 @Composable
-internal fun AsyncViewPreview(
-    @PreviewParameter(AsyncProvider::class) async: Async<Unit>,
+internal fun AsyncActionViewPreview(
+    @PreviewParameter(AsyncActionProvider::class) async: AsyncAction<Unit>,
 ) = ElementPreview {
-    AsyncView(
+    AsyncActionView(
         async = async,
         onSuccess = {},
         onErrorDismiss = {},
+        confirmationDialog = {
+            ConfirmationDialog(
+                title = "Confirmation",
+                content = "Are you sure?",
+                onSubmitClicked = {},
+                onDismiss = {},
+            )
+        },
     )
 }
diff --git a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerPresenter.kt b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerPresenter.kt
index 90d81a4d0c6..574c6344f12 100644
--- a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerPresenter.kt
+++ b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerPresenter.kt
@@ -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))
diff --git a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerState.kt b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerState.kt
index 4b68f4afcc6..6d88cc7c060 100644
--- a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerState.kt
+++ b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerState.kt
@@ -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,
diff --git a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerStateProvider.kt b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerStateProvider.kt
index 14f792c2c62..a9d6e4fc98c 100644
--- a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerStateProvider.kt
+++ b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerStateProvider.kt
@@ -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,
diff --git a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerView.kt b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerView.kt
index d7f743f7ad9..1fb557c1268 100644
--- a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerView.kt
+++ b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/viewer/MediaViewerView.kt
@@ -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)
     }

diff --git a/features/call/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt b/features/call/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt
index 77f83de2098..2b5365118e6 100644
--- a/features/call/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt
+++ b/features/call/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt
@@ -23,7 +23,7 @@ import com.google.common.truth.Truth.assertThat
 import io.element.android.features.call.CallType
 import io.element.android.features.call.utils.FakeCallWidgetProvider
 import io.element.android.features.call.utils.FakeWidgetMessageInterceptor
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.core.coroutine.CoroutineDispatchers
 import io.element.android.libraries.matrix.api.sync.SyncState
 import io.element.android.libraries.matrix.test.A_ROOM_ID
@@ -62,7 +62,7 @@ class CallScreenPresenterTest {
             skipItems(1)

             val initialState = awaitItem()
-            assertThat(initialState.urlState).isEqualTo(Async.Success("https://call.element.io"))
+            assertThat(initialState.urlState).isEqualTo(AsyncData.Success("https://call.element.io"))
             assertThat(initialState.isInWidgetMode).isFalse()
         }
     }
@@ -83,7 +83,7 @@ class CallScreenPresenterTest {
             skipItems(1)

             val initialState = awaitItem()
-            assertThat(initialState.urlState).isInstanceOf(Async.Success::class.java)
+            assertThat(initialState.urlState).isInstanceOf(AsyncData.Success::class.java)
             assertThat(initialState.isInWidgetMode).isTrue()
             assertThat(widgetProvider.getWidgetCalled).isTrue()
             assertThat(widgetDriver.runCalledCount).isEqualTo(1)
diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultStartDMActionTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultStartDMActionTests.kt
index f2ed30c58dd..e325b026de8 100644
--- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultStartDMActionTests.kt
+++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/DefaultStartDMActionTests.kt
@@ -19,7 +19,7 @@ package io.element.android.features.createroom.impl
 import androidx.compose.runtime.mutableStateOf
 import com.google.common.truth.Truth.assertThat
 import im.vector.app.features.analytics.plan.CreatedRoom
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.MatrixClient
 import io.element.android.libraries.matrix.api.core.RoomId
 import io.element.android.libraries.matrix.test.A_ROOM_ID
@@ -39,9 +39,9 @@ class DefaultStartDMActionTests {
             givenFindDmResult(A_ROOM_ID)
         }
         val action = createStartDMAction(matrixClient)
-        val state = mutableStateOf<Async<RoomId>>(Async.Uninitialized)
+        val state = mutableStateOf<AsyncAction<RoomId>>(AsyncAction.Uninitialized)
         action.execute(A_USER_ID, state)
-        assertThat(state.value).isEqualTo(Async.Success(A_ROOM_ID))
+        assertThat(state.value).isEqualTo(AsyncAction.Success(A_ROOM_ID))
     }

     @Test
@@ -52,9 +52,9 @@ class DefaultStartDMActionTests {
         }
         val analyticsService = FakeAnalyticsService()
         val action = createStartDMAction(matrixClient, analyticsService)
-        val state = mutableStateOf<Async<RoomId>>(Async.Uninitialized)
+        val state = mutableStateOf<AsyncAction<RoomId>>(AsyncAction.Uninitialized)
         action.execute(A_USER_ID, state)
-        assertThat(state.value).isEqualTo(Async.Success(A_ROOM_ID))
+        assertThat(state.value).isEqualTo(AsyncAction.Success(A_ROOM_ID))
         assertThat(analyticsService.capturedEvents).containsExactly(CreatedRoom(isDM = true))
     }

@@ -65,9 +65,9 @@ class DefaultStartDMActionTests {
             givenCreateDmResult(Result.failure(A_THROWABLE))
         }
         val action = createStartDMAction(matrixClient)
-        val state = mutableStateOf<Async<RoomId>>(Async.Uninitialized)
+        val state = mutableStateOf<AsyncAction<RoomId>>(AsyncAction.Uninitialized)
         action.execute(A_USER_ID, state)
-        assertThat(state.value).isEqualTo(Async.Failure<RoomId>(A_THROWABLE))
+        assertThat(state.value).isEqualTo(AsyncAction.Failure(A_THROWABLE))
     }

     private fun createStartDMAction(
diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt
index 96935ed5986..1834c0aee7c 100644
--- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt
+++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenterTests.kt
@@ -25,7 +25,7 @@ import im.vector.app.features.analytics.plan.CreatedRoom
 import io.element.android.features.createroom.impl.CreateRoomConfig
 import io.element.android.features.createroom.impl.CreateRoomDataStore
 import io.element.android.features.createroom.impl.userlist.UserListDataStore
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.core.RoomId
 import io.element.android.libraries.matrix.test.AN_AVATAR_URL
 import io.element.android.libraries.matrix.test.A_MESSAGE
@@ -234,9 +234,9 @@ class ConfigureRoomPresenterTests {
             fakeMatrixClient.givenCreateRoomResult(createRoomResult)

             initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
-            assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
             val stateAfterCreateRoom = awaitItem()
-            assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(Async.Success::class.java)
+            assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Success::class.java)
             assertThat(stateAfterCreateRoom.createRoomAction.dataOrNull()).isEqualTo(createRoomResult.getOrNull())
         }
     }
@@ -272,16 +272,16 @@ class ConfigureRoomPresenterTests {

             val initialState = awaitItem()
             initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
-            assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
             val stateAfterCreateRoom = awaitItem()
-            assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(Async.Failure::class.java)
+            assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
             assertThat(fakeAnalyticsService.capturedEvents.filterIsInstance<CreatedRoom>()).isEmpty()

             fakeMatrixClient.givenUploadMediaResult(Result.success(AN_AVATAR_URL))
             stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
-            assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Uninitialized::class.java)
-            assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Loading::class.java)
-            assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Success::class.java)
+            assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
+            assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
+            assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Success::class.java)
         }
     }

@@ -297,22 +297,22 @@ class ConfigureRoomPresenterTests {

             // Create
             initialState.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
-            assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
             val stateAfterCreateRoom = awaitItem()
-            assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(Async.Failure::class.java)
-            assertThat((stateAfterCreateRoom.createRoomAction as? Async.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull())
+            assertThat(stateAfterCreateRoom.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
+            assertThat((stateAfterCreateRoom.createRoomAction as? AsyncAction.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull())

             // Retry
             stateAfterCreateRoom.eventSink(ConfigureRoomEvents.CreateRoom(initialState.config))
-            assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Uninitialized::class.java)
-            assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
+            assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Loading::class.java)
             val stateAfterRetry = awaitItem()
-            assertThat(stateAfterRetry.createRoomAction).isInstanceOf(Async.Failure::class.java)
-            assertThat((stateAfterRetry.createRoomAction as? Async.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull())
+            assertThat(stateAfterRetry.createRoomAction).isInstanceOf(AsyncAction.Failure::class.java)
+            assertThat((stateAfterRetry.createRoomAction as? AsyncAction.Failure)?.error).isEqualTo(createRoomResult.exceptionOrNull())

             // Cancel
             stateAfterRetry.eventSink(ConfigureRoomEvents.CancelCreateRoom)
-            assertThat(awaitItem().createRoomAction).isInstanceOf(Async.Uninitialized::class.java)
+            assertThat(awaitItem().createRoomAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
         }
     }
 }
diff --git a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt
index a0fb71dd313..63241a3a50b 100644
--- a/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt
+++ b/features/createroom/impl/src/test/kotlin/io/element/android/features/createroom/impl/root/CreateRoomRootPresenterTests.kt
@@ -25,8 +25,7 @@ import io.element.android.features.createroom.impl.userlist.FakeUserListPresente
 import io.element.android.features.createroom.impl.userlist.FakeUserListPresenterFactory
 import io.element.android.features.createroom.impl.userlist.UserListDataStore
 import io.element.android.features.createroom.test.FakeStartDMAction
-import io.element.android.libraries.architecture.Async
-import io.element.android.libraries.matrix.api.core.RoomId
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.core.UserId
 import io.element.android.libraries.matrix.api.user.MatrixUser
 import io.element.android.libraries.matrix.test.A_ROOM_ID
@@ -52,20 +51,20 @@ class CreateRoomRootPresenterTests {
         }.test {
             val initialState = awaitItem()

-            assertThat(initialState.startDmAction).isInstanceOf(Async.Uninitialized::class.java)
+            assertThat(initialState.startDmAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
             assertThat(initialState.applicationName).isEqualTo(aBuildMeta().applicationName)
             assertThat(initialState.userListState.selectedUsers).isEmpty()
             assertThat(initialState.userListState.isSearchActive).isFalse()
             assertThat(initialState.userListState.isMultiSelectionEnabled).isFalse()

             val matrixUser = MatrixUser(UserId("@name:domain"))
-            val startDMSuccessResult = Async.Success(A_ROOM_ID)
-            val startDMFailureResult = Async.Failure<RoomId>(A_THROWABLE)
+            val startDMSuccessResult = AsyncAction.Success(A_ROOM_ID)
+            val startDMFailureResult = AsyncAction.Failure(A_THROWABLE)

             // Failure
             startDMAction.givenExecuteResult(startDMFailureResult)
             initialState.eventSink(CreateRoomRootEvents.StartDM(matrixUser))
-            assertThat(awaitItem().startDmAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(awaitItem().startDmAction).isInstanceOf(AsyncAction.Loading::class.java)
             awaitItem().also { state ->
                 assertThat(state.startDmAction).isEqualTo(startDMFailureResult)
                 state.eventSink(CreateRoomRootEvents.CancelStartDM)
@@ -74,10 +73,10 @@ class CreateRoomRootPresenterTests {
             // Success
             startDMAction.givenExecuteResult(startDMSuccessResult)
             awaitItem().also { state ->
-                assertThat(state.startDmAction).isEqualTo(Async.Uninitialized)
+                assertThat(state.startDmAction).isEqualTo(AsyncAction.Uninitialized)
                 state.eventSink(CreateRoomRootEvents.StartDM(matrixUser))
             }
-            assertThat(awaitItem().startDmAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(awaitItem().startDmAction).isInstanceOf(AsyncAction.Loading::class.java)
             awaitItem().also { state ->
                 assertThat(state.startDmAction).isEqualTo(startDMSuccessResult)
             }
diff --git a/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/test/FakeStartDMAction.kt b/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/test/FakeStartDMAction.kt
index c1888dc53ff..9e96f68fc32 100644
--- a/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/test/FakeStartDMAction.kt
+++ b/features/createroom/test/src/main/kotlin/io/element/android/features/createroom/test/FakeStartDMAction.kt
@@ -18,7 +18,7 @@ package io.element.android.features.createroom.test

 import androidx.compose.runtime.MutableState
 import io.element.android.features.createroom.api.StartDMAction
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.core.RoomId
 import io.element.android.libraries.matrix.api.core.UserId
 import io.element.android.libraries.matrix.test.A_ROOM_ID
@@ -26,14 +26,14 @@ import kotlinx.coroutines.delay

 class FakeStartDMAction : StartDMAction {

-    private var executeResult: Async<RoomId> = Async.Success(A_ROOM_ID)
+    private var executeResult: AsyncAction<RoomId> = AsyncAction.Success(A_ROOM_ID)

-    fun givenExecuteResult(result: Async<RoomId>) {
+    fun givenExecuteResult(result: AsyncAction<RoomId>) {
         executeResult = result
     }

-    override suspend fun execute(userId: UserId, actionState: MutableState<Async<RoomId>>) {
-        actionState.value = Async.Loading()
+    override suspend fun execute(userId: UserId, actionState: MutableState<AsyncAction<RoomId>>) {
+        actionState.value = AsyncAction.Loading
         delay(1)
         actionState.value = executeResult
     }
diff --git a/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt b/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt
index 70908941a6a..a3bafdb0345 100644
--- a/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt
+++ b/features/invitelist/impl/src/test/kotlin/io/element/android/features/invitelist/impl/InviteListPresenterTests.kt
@@ -22,7 +22,7 @@ import app.cash.turbine.test
 import com.google.common.truth.Truth.assertThat
 import io.element.android.features.invitelist.api.SeenInvitesStore
 import io.element.android.features.invitelist.test.FakeSeenInvitesStore
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.designsystem.components.avatar.AvatarData
 import io.element.android.libraries.designsystem.components.avatar.AvatarSize
 import io.element.android.libraries.matrix.api.MatrixClient
@@ -245,7 +245,7 @@ class InviteListPresenterTests {

             val newState = awaitItem()

-            assertThat(newState.declinedAction).isEqualTo(Async.Failure<Unit>(ex))
+            assertThat(newState.declinedAction).isEqualTo(AsyncData.Failure<Unit>(ex))
         }
     }

@@ -277,7 +277,7 @@ class InviteListPresenterTests {

             val newState = awaitItem()

-            assertThat(newState.declinedAction).isEqualTo(Async.Uninitialized)
+            assertThat(newState.declinedAction).isEqualTo(AsyncData.Uninitialized)
         }
     }

@@ -300,7 +300,7 @@ class InviteListPresenterTests {

             val newState = awaitItem()

-            assertThat(newState.acceptedAction).isEqualTo(Async.Success(A_ROOM_ID))
+            assertThat(newState.acceptedAction).isEqualTo(AsyncData.Success(A_ROOM_ID))
             assertThat(fakeNotificationDrawerManager.getClearMembershipNotificationForRoomCount(client.sessionId, A_ROOM_ID)).isEqualTo(1)
         }
     }
@@ -323,7 +323,7 @@ class InviteListPresenterTests {
             val originalState = awaitItem()
             originalState.eventSink(InviteListEvents.AcceptInvite(originalState.inviteList[0]))

-            assertThat(awaitItem().acceptedAction).isEqualTo(Async.Failure<RoomId>(ex))
+            assertThat(awaitItem().acceptedAction).isEqualTo(AsyncData.Failure<RoomId>(ex))
         }
     }

@@ -350,7 +350,7 @@ class InviteListPresenterTests {
             originalState.eventSink(InviteListEvents.DismissAcceptError)

             val newState = awaitItem()
-            assertThat(newState.acceptedAction).isEqualTo(Async.Uninitialized)
+            assertThat(newState.acceptedAction).isEqualTo(AsyncData.Uninitialized)
         }
     }

diff --git a/features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockPresenterTest.kt b/features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockPresenterTest.kt
index 87d673066d0..1c1451f9bf6 100644
--- a/features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockPresenterTest.kt
+++ b/features/lockscreen/impl/src/test/kotlin/io/element/android/features/lockscreen/impl/unlock/PinUnlockPresenterTest.kt
@@ -28,7 +28,7 @@ import io.element.android.features.lockscreen.impl.pin.PinCodeManager
 import io.element.android.features.lockscreen.impl.pin.model.PinEntry
 import io.element.android.features.lockscreen.impl.pin.model.assertText
 import io.element.android.features.lockscreen.impl.unlock.keypad.PinKeypadModel
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.test.FakeMatrixClient
 import io.element.android.tests.testutils.awaitLastSequentialItem
 import io.element.android.tests.testutils.consumeItemsUntilPredicate
@@ -48,15 +48,15 @@ class PinUnlockPresenterTest {
             presenter.present()
         }.test {
             awaitItem().also { state ->
-                assertThat(state.pinEntry).isInstanceOf(Async.Uninitialized::class.java)
+                assertThat(state.pinEntry).isInstanceOf(AsyncData.Uninitialized::class.java)
                 assertThat(state.showWrongPinTitle).isFalse()
                 assertThat(state.showSignOutPrompt).isFalse()
                 assertThat(state.isUnlocked).isFalse()
-                assertThat(state.signOutAction).isInstanceOf(Async.Uninitialized::class.java)
-                assertThat(state.remainingAttempts).isInstanceOf(Async.Uninitialized::class.java)
+                assertThat(state.signOutAction).isInstanceOf(AsyncData.Uninitialized::class.java)
+                assertThat(state.remainingAttempts).isInstanceOf(AsyncData.Uninitialized::class.java)
             }
             consumeItemsUntilPredicate {
-                it.pinEntry is Async.Success && it.remainingAttempts is Async.Success
+                it.pinEntry is AsyncData.Success && it.remainingAttempts is AsyncData.Success
             }.last().also { state ->
                 state.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('1')))
                 state.eventSink(PinUnlockEvents.OnPinKeypadPressed(PinKeypadModel.Number('2')))
@@ -83,7 +83,7 @@ class PinUnlockPresenterTest {
             presenter.present()
         }.test {
             val initialState = consumeItemsUntilPredicate {
-                it.pinEntry is Async.Success && it.remainingAttempts is Async.Success
+                it.pinEntry is AsyncData.Success && it.remainingAttempts is AsyncData.Success
             }.last()
             val numberOfAttempts = initialState.remainingAttempts.dataOrNull() ?: 0
             repeat(numberOfAttempts) {
@@ -107,7 +107,7 @@ class PinUnlockPresenterTest {
             presenter.present()
         }.test {
             consumeItemsUntilPredicate {
-                it.pinEntry is Async.Success && it.remainingAttempts is Async.Success
+                it.pinEntry is AsyncData.Success && it.remainingAttempts is AsyncData.Success
             }.last().also { state ->
                 state.eventSink(PinUnlockEvents.OnForgetPin)
             }
@@ -125,12 +125,12 @@ class PinUnlockPresenterTest {
                 state.eventSink(PinUnlockEvents.SignOut)
             }
             consumeItemsUntilPredicate { state ->
-                state.signOutAction is Async.Success
+                state.signOutAction is AsyncData.Success
             }
         }
     }

-    private fun Async<PinEntry>.assertText(text: String) {
+    private fun AsyncData<PinEntry>.assertText(text: String) {
         dataOrNull()?.assertText(text)
     }

diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt
index 44c36128e2b..0615b94ce62 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/changeserver/ChangeServerPresenterTest.kt
@@ -22,7 +22,7 @@ import app.cash.turbine.test
 import com.google.common.truth.Truth.assertThat
 import io.element.android.features.login.impl.accountprovider.AccountProvider
 import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.test.A_HOMESERVER
 import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
 import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService
@@ -46,7 +46,7 @@ class ChangeServerPresenterTest {
             presenter.present()
         }.test {
             val initialState = awaitItem()
-            assertThat(initialState.changeServerAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
         }
     }

@@ -61,13 +61,13 @@ class ChangeServerPresenterTest {
             presenter.present()
         }.test {
             val initialState = awaitItem()
-            assertThat(initialState.changeServerAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
             authenticationService.givenHomeserver(A_HOMESERVER)
             initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
             val loadingState = awaitItem()
-            assertThat(loadingState.changeServerAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.changeServerAction).isInstanceOf(AsyncData.Loading::class.java)
             val successState = awaitItem()
-            assertThat(successState.changeServerAction).isEqualTo(Async.Success(Unit))
+            assertThat(successState.changeServerAction).isEqualTo(AsyncData.Success(Unit))
         }
     }

@@ -82,16 +82,16 @@ class ChangeServerPresenterTest {
             presenter.present()
         }.test {
             val initialState = awaitItem()
-            assertThat(initialState.changeServerAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
             initialState.eventSink.invoke(ChangeServerEvents.ChangeServer(AccountProvider(url = A_HOMESERVER_URL)))
             val loadingState = awaitItem()
-            assertThat(loadingState.changeServerAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.changeServerAction).isInstanceOf(AsyncData.Loading::class.java)
             val failureState = awaitItem()
-            assertThat(failureState.changeServerAction).isInstanceOf(Async.Failure::class.java)
+            assertThat(failureState.changeServerAction).isInstanceOf(AsyncData.Failure::class.java)
             // Clear error
             failureState.eventSink.invoke(ChangeServerEvents.ClearError)
             val finalState = awaitItem()
-            assertThat(finalState.changeServerAction).isEqualTo(Async.Uninitialized)
+            assertThat(finalState.changeServerAction).isEqualTo(AsyncData.Uninitialized)
         }
     }
 }
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt
index 70d6da7783e..3920ceb5977 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/oidc/webview/OidcPresenterTest.kt
@@ -23,7 +23,7 @@ import app.cash.molecule.moleculeFlow
 import app.cash.turbine.test
 import com.google.common.truth.Truth.assertThat
 import io.element.android.features.login.api.oidc.OidcAction
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.test.A_THROWABLE
 import io.element.android.libraries.matrix.test.auth.A_OIDC_DATA
 import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService
@@ -49,7 +49,7 @@ class OidcPresenterTest {
         }.test {
             val initialState = awaitItem()
             assertThat(initialState.oidcDetails).isEqualTo(A_OIDC_DATA)
-            assertThat(initialState.requestState).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.requestState).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -65,9 +65,9 @@ class OidcPresenterTest {
             val initialState = awaitItem()
             initialState.eventSink.invoke(OidcEvents.Cancel)
             val loadingState = awaitItem()
-            assertThat(loadingState.requestState).isEqualTo(Async.Loading<Unit>())
+            assertThat(loadingState.requestState).isEqualTo(AsyncAction.Loading)
             val finalState = awaitItem()
-            assertThat(finalState.requestState).isEqualTo(Async.Success(Unit))
+            assertThat(finalState.requestState).isEqualTo(AsyncAction.Success(Unit))
         }
     }

@@ -85,9 +85,9 @@ class OidcPresenterTest {
             val initialState = awaitItem()
             initialState.eventSink.invoke(OidcEvents.Cancel)
             val loadingState = awaitItem()
-            assertThat(loadingState.requestState).isEqualTo(Async.Loading<Unit>())
+            assertThat(loadingState.requestState).isEqualTo(AsyncAction.Loading)
             val finalState = awaitItem()
-            assertThat(finalState.requestState).isEqualTo(Async.Failure<Unit>(A_THROWABLE))
+            assertThat(finalState.requestState).isEqualTo(AsyncAction.Failure(A_THROWABLE))
             // Note: in real life I do not think this can happen, and the app should not block the user.
         }
     }
@@ -104,9 +104,9 @@ class OidcPresenterTest {
             val initialState = awaitItem()
             initialState.eventSink.invoke(OidcEvents.OidcActionEvent(OidcAction.GoBack))
             val loadingState = awaitItem()
-            assertThat(loadingState.requestState).isEqualTo(Async.Loading<Unit>())
+            assertThat(loadingState.requestState).isEqualTo(AsyncAction.Loading)
             val finalState = awaitItem()
-            assertThat(finalState.requestState).isEqualTo(Async.Success(Unit))
+            assertThat(finalState.requestState).isEqualTo(AsyncAction.Success(Unit))
         }
     }

@@ -122,7 +122,7 @@ class OidcPresenterTest {
             val initialState = awaitItem()
             initialState.eventSink.invoke(OidcEvents.OidcActionEvent(OidcAction.Success("A_URL")))
             val loadingState = awaitItem()
-            assertThat(loadingState.requestState).isEqualTo(Async.Loading<Unit>())
+            assertThat(loadingState.requestState).isEqualTo(AsyncAction.Loading)
             // In this case, no success, the session is created and the node get destroyed.
         }
     }
@@ -141,12 +141,12 @@ class OidcPresenterTest {
             val initialState = awaitItem()
             initialState.eventSink.invoke(OidcEvents.OidcActionEvent(OidcAction.Success("A_URL")))
             val loadingState = awaitItem()
-            assertThat(loadingState.requestState).isEqualTo(Async.Loading<Unit>())
+            assertThat(loadingState.requestState).isEqualTo(AsyncAction.Loading)
             val errorState = awaitItem()
-            assertThat(errorState.requestState).isEqualTo(Async.Failure<Unit>(A_THROWABLE))
+            assertThat(errorState.requestState).isEqualTo(AsyncAction.Failure(A_THROWABLE))
             errorState.eventSink.invoke(OidcEvents.ClearError)
             val finalState = awaitItem()
-            assertThat(finalState.requestState).isEqualTo(Async.Uninitialized)
+            assertThat(finalState.requestState).isEqualTo(AsyncAction.Uninitialized)
         }
     }
 }
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt
index f348839c972..ad78f7b3289 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/confirmaccountprovider/ConfirmAccountProviderPresenterTest.kt
@@ -25,7 +25,7 @@ import io.element.android.features.login.impl.DefaultLoginUserStory
 import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
 import io.element.android.features.login.impl.oidc.customtab.DefaultOidcActionFlow
 import io.element.android.features.login.impl.util.defaultAccountProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
 import io.element.android.libraries.matrix.test.A_HOMESERVER
 import io.element.android.libraries.matrix.test.A_HOMESERVER_OIDC
@@ -52,7 +52,7 @@ class ConfirmAccountProviderPresenterTest {
             assertThat(initialState.isAccountCreation).isFalse()
             assertThat(initialState.submitEnabled).isTrue()
             assertThat(initialState.accountProvider).isEqualTo(defaultAccountProvider)
-            assertThat(initialState.loginFlow).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.loginFlow).isEqualTo(AsyncData.Uninitialized)
         }
     }

@@ -70,10 +70,10 @@ class ConfirmAccountProviderPresenterTest {
             initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
             val loadingState = awaitItem()
             assertThat(loadingState.submitEnabled).isTrue()
-            assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
             val successState = awaitItem()
             assertThat(successState.submitEnabled).isFalse()
-            assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
+            assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
             assertThat(successState.loginFlow.dataOrNull()).isEqualTo(LoginFlow.PasswordLogin)
         }
     }
@@ -92,10 +92,10 @@ class ConfirmAccountProviderPresenterTest {
             initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
             val loadingState = awaitItem()
             assertThat(loadingState.submitEnabled).isTrue()
-            assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
             val successState = awaitItem()
             assertThat(successState.submitEnabled).isFalse()
-            assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
+            assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
             assertThat(successState.loginFlow.dataOrNull()).isInstanceOf(LoginFlow.OidcFlow::class.java)
         }
     }
@@ -116,15 +116,15 @@ class ConfirmAccountProviderPresenterTest {
             initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
             val loadingState = awaitItem()
             assertThat(loadingState.submitEnabled).isTrue()
-            assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
             val successState = awaitItem()
             assertThat(successState.submitEnabled).isFalse()
-            assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
+            assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
             assertThat(successState.loginFlow.dataOrNull()).isInstanceOf(LoginFlow.OidcFlow::class.java)
             authenticationService.givenOidcCancelError(A_THROWABLE)
             defaultOidcActionFlow.post(OidcAction.GoBack)
             val cancelFailureState = awaitItem()
-            assertThat(cancelFailureState.loginFlow).isInstanceOf(Async.Failure::class.java)
+            assertThat(cancelFailureState.loginFlow).isInstanceOf(AsyncData.Failure::class.java)
         }
     }

@@ -144,14 +144,14 @@ class ConfirmAccountProviderPresenterTest {
             initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
             val loadingState = awaitItem()
             assertThat(loadingState.submitEnabled).isTrue()
-            assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
             val successState = awaitItem()
             assertThat(successState.submitEnabled).isFalse()
-            assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
+            assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
             assertThat(successState.loginFlow.dataOrNull()).isInstanceOf(LoginFlow.OidcFlow::class.java)
             defaultOidcActionFlow.post(OidcAction.GoBack)
             val cancelFinalState = awaitItem()
-            assertThat(cancelFinalState.loginFlow).isInstanceOf(Async.Uninitialized::class.java)
+            assertThat(cancelFinalState.loginFlow).isInstanceOf(AsyncData.Uninitialized::class.java)
         }
     }

@@ -171,17 +171,17 @@ class ConfirmAccountProviderPresenterTest {
             initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
             val loadingState = awaitItem()
             assertThat(loadingState.submitEnabled).isTrue()
-            assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
             val successState = awaitItem()
             assertThat(successState.submitEnabled).isFalse()
-            assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
+            assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
             assertThat(successState.loginFlow.dataOrNull()).isInstanceOf(LoginFlow.OidcFlow::class.java)
             authenticationService.givenLoginError(A_THROWABLE)
             defaultOidcActionFlow.post(OidcAction.Success("aUrl"))
             val cancelLoadingState = awaitItem()
-            assertThat(cancelLoadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
+            assertThat(cancelLoadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
             val cancelFailureState = awaitItem()
-            assertThat(cancelFailureState.loginFlow).isInstanceOf(Async.Failure::class.java)
+            assertThat(cancelFailureState.loginFlow).isInstanceOf(AsyncData.Failure::class.java)
         }
     }

@@ -205,15 +205,15 @@ class ConfirmAccountProviderPresenterTest {
             initialState.eventSink.invoke(ConfirmAccountProviderEvents.Continue)
             val loadingState = awaitItem()
             assertThat(loadingState.submitEnabled).isTrue()
-            assertThat(loadingState.loginFlow).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
             val successState = awaitItem()
             assertThat(successState.submitEnabled).isFalse()
-            assertThat(successState.loginFlow).isInstanceOf(Async.Success::class.java)
+            assertThat(successState.loginFlow).isInstanceOf(AsyncData.Success::class.java)
             assertThat(successState.loginFlow.dataOrNull()).isInstanceOf(LoginFlow.OidcFlow::class.java)
             assertThat(defaultLoginUserStory.loginFlowIsDone.value).isFalse()
             defaultOidcActionFlow.post(OidcAction.Success("aUrl"))
             val successSuccessState = awaitItem()
-            assertThat(successSuccessState.loginFlow).isInstanceOf(Async.Loading::class.java)
+            assertThat(successSuccessState.loginFlow).isInstanceOf(AsyncData.Loading::class.java)
             waitForPredicate { defaultLoginUserStory.loginFlowIsDone.value }
         }
     }
@@ -233,7 +233,7 @@ class ConfirmAccountProviderPresenterTest {
             skipItems(1) // Loading
             val failureState = awaitItem()
             assertThat(failureState.submitEnabled).isFalse()
-            assertThat(failureState.loginFlow).isInstanceOf(Async.Failure::class.java)
+            assertThat(failureState.loginFlow).isInstanceOf(AsyncData.Failure::class.java)
         }
     }

@@ -256,12 +256,12 @@ class ConfirmAccountProviderPresenterTest {

             // Check an error was returned
             val submittedState = awaitItem()
-            assertThat(submittedState.loginFlow).isInstanceOf(Async.Failure::class.java)
+            assertThat(submittedState.loginFlow).isInstanceOf(AsyncData.Failure::class.java)

             // Assert the error is then cleared
             submittedState.eventSink(ConfirmAccountProviderEvents.ClearError)
             val clearedState = awaitItem()
-            assertThat(clearedState.loginFlow).isEqualTo(Async.Uninitialized)
+            assertThat(clearedState.loginFlow).isEqualTo(AsyncData.Uninitialized)
         }
     }

diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt
index a2b0fae4494..23672974eed 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/loginpassword/LoginPasswordPresenterTest.kt
@@ -23,7 +23,7 @@ import com.google.common.truth.Truth.assertThat
 import io.element.android.features.login.impl.DefaultLoginUserStory
 import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource
 import io.element.android.features.login.impl.util.defaultAccountProvider
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.core.SessionId
 import io.element.android.libraries.matrix.test.A_HOMESERVER
 import io.element.android.libraries.matrix.test.A_PASSWORD
@@ -57,7 +57,7 @@ class LoginPasswordPresenterTest {
             val initialState = awaitItem()
             assertThat(initialState.accountProvider).isEqualTo(defaultAccountProvider)
             assertThat(initialState.formState).isEqualTo(LoginFormState.Default)
-            assertThat(initialState.loginAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.loginAction).isEqualTo(AsyncData.Uninitialized)
             assertThat(initialState.submitEnabled).isFalse()
         }
     }
@@ -110,9 +110,9 @@ class LoginPasswordPresenterTest {
             val loginAndPasswordState = awaitItem()
             loginAndPasswordState.eventSink.invoke(LoginPasswordEvents.Submit)
             val submitState = awaitItem()
-            assertThat(submitState.loginAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
             val loggedInState = awaitItem()
-            assertThat(loggedInState.loginAction).isEqualTo(Async.Success(A_SESSION_ID))
+            assertThat(loggedInState.loginAction).isEqualTo(AsyncData.Success(A_SESSION_ID))
             assertThat(loginUserStory.loginFlowIsDone.value).isTrue()
         }
     }
@@ -139,9 +139,9 @@ class LoginPasswordPresenterTest {
             authenticationService.givenLoginError(A_THROWABLE)
             loginAndPasswordState.eventSink.invoke(LoginPasswordEvents.Submit)
             val submitState = awaitItem()
-            assertThat(submitState.loginAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
             val loggedInState = awaitItem()
-            assertThat(loggedInState.loginAction).isEqualTo(Async.Failure<SessionId>(A_THROWABLE))
+            assertThat(loggedInState.loginAction).isEqualTo(AsyncData.Failure<SessionId>(A_THROWABLE))
         }
     }

@@ -167,14 +167,14 @@ class LoginPasswordPresenterTest {
             authenticationService.givenLoginError(A_THROWABLE)
             loginAndPasswordState.eventSink.invoke(LoginPasswordEvents.Submit)
             val submitState = awaitItem()
-            assertThat(submitState.loginAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
             val loggedInState = awaitItem()
             // Check an error was returned
-            assertThat(loggedInState.loginAction).isEqualTo(Async.Failure<SessionId>(A_THROWABLE))
+            assertThat(loggedInState.loginAction).isEqualTo(AsyncData.Failure<SessionId>(A_THROWABLE))
             // Assert the error is then cleared
             loggedInState.eventSink(LoginPasswordEvents.ClearError)
             val clearedState = awaitItem()
-            assertThat(clearedState.loginAction).isEqualTo(Async.Uninitialized)
+            assertThat(clearedState.loginAction).isEqualTo(AsyncData.Uninitialized)
         }
     }
 }
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenterTest.kt
index 84bd6925db6..d951902490c 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/searchaccountprovider/SearchAccountProviderPresenterTest.kt
@@ -27,7 +27,7 @@ import io.element.android.features.login.impl.resolver.network.FakeWellknownRequ
 import io.element.android.features.login.impl.resolver.network.WellKnown
 import io.element.android.features.login.impl.resolver.network.WellKnownBaseConfig
 import io.element.android.features.login.impl.resolver.network.WellKnownSlidingSyncConfig
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
 import io.element.android.libraries.matrix.test.auth.FakeAuthenticationService
 import io.element.android.tests.testutils.WarmUpRule
@@ -57,7 +57,7 @@ class SearchAccountProviderPresenterTest {
         }.test {
             val initialState = awaitItem()
             assertThat(initialState.userInput).isEmpty()
-            assertThat(initialState.userInputResult).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
         }
     }

@@ -79,9 +79,9 @@ class SearchAccountProviderPresenterTest {
             initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("test"))
             val withInputState = awaitItem()
             assertThat(withInputState.userInput).isEqualTo("test")
-            assertThat(initialState.userInputResult).isEqualTo(Async.Uninitialized)
-            assertThat(awaitItem().userInputResult).isInstanceOf(Async.Loading::class.java)
-            assertThat(awaitItem().userInputResult).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
+            assertThat(awaitItem().userInputResult).isInstanceOf(AsyncData.Loading::class.java)
+            assertThat(awaitItem().userInputResult).isEqualTo(AsyncData.Uninitialized)
         }
     }

@@ -103,10 +103,10 @@ class SearchAccountProviderPresenterTest {
             initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("https://test.org"))
             val withInputState = awaitItem()
             assertThat(withInputState.userInput).isEqualTo("https://test.org")
-            assertThat(initialState.userInputResult).isEqualTo(Async.Uninitialized)
-            assertThat(awaitItem().userInputResult).isInstanceOf(Async.Loading::class.java)
+            assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
+            assertThat(awaitItem().userInputResult).isInstanceOf(AsyncData.Loading::class.java)
             assertThat(awaitItem().userInputResult).isEqualTo(
-                Async.Success(
+                AsyncData.Success(
                     listOf(
                         aHomeserverData(homeserverUrl = "https://test.org", isWellknownValid = false, supportSlidingSync = false)
                     )
@@ -138,10 +138,10 @@ class SearchAccountProviderPresenterTest {
             initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("test"))
             val withInputState = awaitItem()
             assertThat(withInputState.userInput).isEqualTo("test")
-            assertThat(initialState.userInputResult).isEqualTo(Async.Uninitialized)
-            assertThat(awaitItem().userInputResult).isInstanceOf(Async.Loading::class.java)
+            assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
+            assertThat(awaitItem().userInputResult).isInstanceOf(AsyncData.Loading::class.java)
             assertThat(awaitItem().userInputResult).isEqualTo(
-                Async.Success(
+                AsyncData.Success(
                     listOf(
                         aHomeserverData(homeserverUrl = "https://test.org", isWellknownValid = true, supportSlidingSync = false)
                     )
@@ -173,10 +173,10 @@ class SearchAccountProviderPresenterTest {
             initialState.eventSink.invoke(SearchAccountProviderEvents.UserInput("test"))
             val withInputState = awaitItem()
             assertThat(withInputState.userInput).isEqualTo("test")
-            assertThat(initialState.userInputResult).isEqualTo(Async.Uninitialized)
-            assertThat(awaitItem().userInputResult).isInstanceOf(Async.Loading::class.java)
+            assertThat(initialState.userInputResult).isEqualTo(AsyncData.Uninitialized)
+            assertThat(awaitItem().userInputResult).isInstanceOf(AsyncData.Loading::class.java)
             assertThat(awaitItem().userInputResult).isEqualTo(
-                Async.Success(
+                AsyncData.Success(
                     listOf(
                         aHomeserverData(homeserverUrl = "https://test.io")
                     )
diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenterTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenterTest.kt
index 590fa8efc01..9cdac92dbb5 100644
--- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenterTest.kt
+++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/waitlistscreen/WaitListPresenterTest.kt
@@ -22,7 +22,7 @@ import app.cash.turbine.test
 import com.google.common.truth.Truth.assertThat
 import io.element.android.features.login.impl.DefaultLoginUserStory
 import io.element.android.features.login.impl.screens.loginpassword.LoginFormState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.core.SessionId
 import io.element.android.libraries.matrix.test.A_HOMESERVER
 import io.element.android.libraries.matrix.test.A_HOMESERVER_URL
@@ -58,7 +58,7 @@ class WaitListPresenterTest {
             val initialState = awaitItem()
             assertThat(initialState.appName).isEqualTo("Application Name")
             assertThat(initialState.serverName).isEqualTo(A_HOMESERVER_URL)
-            assertThat(initialState.loginAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.loginAction).isEqualTo(AsyncData.Uninitialized)
         }
     }

@@ -83,13 +83,13 @@ class WaitListPresenterTest {
             expectNoEvents()
             initialState.eventSink.invoke(WaitListEvents.AttemptLogin)
             val submitState = awaitItem()
-            assertThat(submitState.loginAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
             val errorState = awaitItem()
-            assertThat(errorState.loginAction).isEqualTo(Async.Failure<SessionId>(A_THROWABLE))
+            assertThat(errorState.loginAction).isEqualTo(AsyncData.Failure<SessionId>(A_THROWABLE))
             // Assert the error can be cleared
             errorState.eventSink(WaitListEvents.ClearError)
             val clearedState = awaitItem()
-            assertThat(clearedState.loginAction).isEqualTo(Async.Uninitialized)
+            assertThat(clearedState.loginAction).isEqualTo(AsyncData.Uninitialized)
         }
     }

@@ -113,9 +113,9 @@ class WaitListPresenterTest {
             expectNoEvents()
             initialState.eventSink.invoke(WaitListEvents.AttemptLogin)
             val submitState = awaitItem()
-            assertThat(submitState.loginAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(submitState.loginAction).isInstanceOf(AsyncData.Loading::class.java)
             val successState = awaitItem()
-            assertThat(successState.loginAction).isEqualTo(Async.Success(A_USER_ID))
+            assertThat(successState.loginAction).isEqualTo(AsyncData.Success(A_USER_ID))
             assertThat(loginUserStory.loginFlowIsDone.value).isFalse()
             successState.eventSink.invoke(WaitListEvents.Continue)
             assertThat(loginUserStory.loginFlowIsDone.value).isTrue()
diff --git a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPresenterTest.kt b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPresenterTest.kt
index c486e763126..6bcdce418e9 100644
--- a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPresenterTest.kt
+++ b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/LogoutPresenterTest.kt
@@ -18,9 +18,10 @@ package io.element.android.features.logout.impl

 import app.cash.molecule.RecompositionMode
 import app.cash.molecule.moleculeFlow
+import app.cash.turbine.ReceiveTurbine
 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.AsyncAction
 import io.element.android.libraries.featureflag.api.FeatureFlags
 import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
 import io.element.android.libraries.matrix.api.MatrixClient
@@ -32,7 +33,6 @@ import io.element.android.libraries.matrix.test.A_THROWABLE
 import io.element.android.libraries.matrix.test.FakeMatrixClient
 import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
 import io.element.android.tests.testutils.WarmUpRule
-import io.element.android.tests.testutils.awaitLastSequentialItem
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.test.runTest
@@ -50,14 +50,13 @@ class LogoutPresenterTest {
         moleculeFlow(RecompositionMode.Immediate) {
             presenter.present()
         }.test {
-            val initialState = awaitLastSequentialItem()
+            val initialState = awaitFirstItem()
             assertThat(initialState.isLastSession).isFalse()
             assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN)
             assertThat(initialState.doesBackupExistOnServer).isTrue()
             assertThat(initialState.recoveryState).isEqualTo(RecoveryState.UNKNOWN)
             assertThat(initialState.backupUploadState).isEqualTo(BackupUploadState.Unknown)
-            assertThat(initialState.showConfirmationDialog).isFalse()
-            assertThat(initialState.logoutAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -75,8 +74,7 @@ class LogoutPresenterTest {
             val initialState = awaitItem()
             assertThat(initialState.isLastSession).isTrue()
             assertThat(initialState.backupUploadState).isEqualTo(BackupUploadState.Unknown)
-            assertThat(initialState.showConfirmationDialog).isFalse()
-            assertThat(initialState.logoutAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -101,8 +99,7 @@ class LogoutPresenterTest {
             val initialState = awaitItem()
             assertThat(initialState.isLastSession).isFalse()
             assertThat(initialState.backupUploadState).isEqualTo(BackupUploadState.Unknown)
-            assertThat(initialState.showConfirmationDialog).isFalse()
-            assertThat(initialState.logoutAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
             skipItems(1)
             val waitingState = awaitItem()
             assertThat(waitingState.backupUploadState).isEqualTo(BackupUploadState.Waiting)
@@ -120,13 +117,13 @@ class LogoutPresenterTest {
         moleculeFlow(RecompositionMode.Immediate) {
             presenter.present()
         }.test {
-            val initialState = awaitLastSequentialItem()
+            val initialState = awaitFirstItem()
             initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
             val confirmationState = awaitItem()
-            assertThat(confirmationState.showConfirmationDialog).isTrue()
+            assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
             initialState.eventSink.invoke(LogoutEvents.CloseDialogs)
             val finalState = awaitItem()
-            assertThat(finalState.showConfirmationDialog).isFalse()
+            assertThat(finalState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -136,17 +133,15 @@ class LogoutPresenterTest {
         moleculeFlow(RecompositionMode.Immediate) {
             presenter.present()
         }.test {
-            val initialState = awaitLastSequentialItem()
+            val initialState = awaitFirstItem()
             initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
             val confirmationState = awaitItem()
-            assertThat(confirmationState.showConfirmationDialog).isTrue()
+            assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
             confirmationState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
-            skipItems(1)
             val loadingState = awaitItem()
-            assertThat(loadingState.showConfirmationDialog).isFalse()
-            assertThat(loadingState.logoutAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
             val successState = awaitItem()
-            assertThat(successState.logoutAction).isInstanceOf(Async.Success::class.java)
+            assertThat(successState.logoutAction).isInstanceOf(AsyncAction.Success::class.java)
         }
     }

@@ -161,22 +156,18 @@ class LogoutPresenterTest {
         moleculeFlow(RecompositionMode.Immediate) {
             presenter.present()
         }.test {
-            skipItems(1)
-            val initialState = awaitItem()
+            val initialState = awaitFirstItem()
             initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
             val confirmationState = awaitItem()
-            assertThat(confirmationState.showConfirmationDialog).isTrue()
+            assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
             confirmationState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
-            skipItems(1)
             val loadingState = awaitItem()
-            assertThat(loadingState.showConfirmationDialog).isFalse()
-            assertThat(loadingState.logoutAction).isInstanceOf(Async.Loading::class.java)
-            skipItems(1)
+            assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
             val errorState = awaitItem()
-            assertThat(errorState.logoutAction).isEqualTo(Async.Failure<LogoutState>(A_THROWABLE))
+            assertThat(errorState.logoutAction).isEqualTo(AsyncAction.Failure(A_THROWABLE))
             errorState.eventSink.invoke(LogoutEvents.CloseDialogs)
             val finalState = awaitItem()
-            assertThat(finalState.logoutAction).isEqualTo(Async.Uninitialized)
+            assertThat(finalState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -191,28 +182,28 @@ class LogoutPresenterTest {
         moleculeFlow(RecompositionMode.Immediate) {
             presenter.present()
         }.test {
-            skipItems(1)
-            val initialState = awaitItem()
+            val initialState = awaitFirstItem()
             initialState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
             val confirmationState = awaitItem()
-            assertThat(confirmationState.showConfirmationDialog).isTrue()
+            assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
             confirmationState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = false))
-            skipItems(1)
             val loadingState = awaitItem()
-            assertThat(loadingState.showConfirmationDialog).isFalse()
-            assertThat(loadingState.logoutAction).isInstanceOf(Async.Loading::class.java)
-            skipItems(1)
+            assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
             val errorState = awaitItem()
-            assertThat(errorState.logoutAction).isEqualTo(Async.Failure<LogoutState>(A_THROWABLE))
+            assertThat(errorState.logoutAction).isEqualTo(AsyncAction.Failure(A_THROWABLE))
             errorState.eventSink.invoke(LogoutEvents.Logout(ignoreSdkError = true))
             val loadingState2 = awaitItem()
-            assertThat(loadingState2.showConfirmationDialog).isFalse()
-            assertThat(loadingState2.logoutAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState2.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
             val successState = awaitItem()
-            assertThat(successState.logoutAction).isInstanceOf(Async.Success::class.java)
+            assertThat(successState.logoutAction).isInstanceOf(AsyncAction.Success::class.java)
         }
     }

+    private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
+        skipItems(2)
+        return awaitItem()
+    }
+
     private fun createLogoutPresenter(
         matrixClient: MatrixClient = FakeMatrixClient(),
         encryptionService: EncryptionService = FakeEncryptionService(),
diff --git a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutPresenterTest.kt b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutPresenterTest.kt
index 5341a8c19ed..6686e02efa9 100644
--- a/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutPresenterTest.kt
+++ b/features/logout/impl/src/test/kotlin/io/element/android/features/logout/impl/direct/DefaultDirectLogoutPresenterTest.kt
@@ -18,11 +18,11 @@ package io.element.android.features.logout.impl.direct

 import app.cash.molecule.RecompositionMode
 import app.cash.molecule.moleculeFlow
+import app.cash.turbine.ReceiveTurbine
 import app.cash.turbine.test
 import com.google.common.truth.Truth.assertThat
 import io.element.android.features.logout.api.direct.DirectLogoutEvents
-import io.element.android.features.logout.api.direct.DirectLogoutState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.featureflag.api.FeatureFlags
 import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
 import io.element.android.libraries.matrix.api.MatrixClient
@@ -32,7 +32,6 @@ import io.element.android.libraries.matrix.test.A_THROWABLE
 import io.element.android.libraries.matrix.test.FakeMatrixClient
 import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
 import io.element.android.tests.testutils.WarmUpRule
-import io.element.android.tests.testutils.awaitLastSequentialItem
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.test.runTest
 import org.junit.Rule
@@ -49,10 +48,9 @@ class DefaultDirectLogoutPresenterTest {
         moleculeFlow(RecompositionMode.Immediate) {
             presenter.present()
         }.test {
-            val initialState = awaitLastSequentialItem()
+            val initialState = awaitFirstItem()
             assertThat(initialState.canDoDirectSignOut).isTrue()
-            assertThat(initialState.showConfirmationDialog).isFalse()
-            assertThat(initialState.logoutAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -69,8 +67,7 @@ class DefaultDirectLogoutPresenterTest {
             skipItems(2)
             val initialState = awaitItem()
             assertThat(initialState.canDoDirectSignOut).isFalse()
-            assertThat(initialState.showConfirmationDialog).isFalse()
-            assertThat(initialState.logoutAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -91,8 +88,7 @@ class DefaultDirectLogoutPresenterTest {
             skipItems(2)
             val initialState = awaitItem()
             assertThat(initialState.canDoDirectSignOut).isFalse()
-            assertThat(initialState.showConfirmationDialog).isFalse()
-            assertThat(initialState.logoutAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -102,13 +98,13 @@ class DefaultDirectLogoutPresenterTest {
         moleculeFlow(RecompositionMode.Immediate) {
             presenter.present()
         }.test {
-            val initialState = awaitLastSequentialItem()
+            val initialState = awaitFirstItem()
             initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
             val confirmationState = awaitItem()
-            assertThat(confirmationState.showConfirmationDialog).isTrue()
+            assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
             initialState.eventSink.invoke(DirectLogoutEvents.CloseDialogs)
             val finalState = awaitItem()
-            assertThat(finalState.showConfirmationDialog).isFalse()
+            assertThat(finalState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -118,17 +114,15 @@ class DefaultDirectLogoutPresenterTest {
         moleculeFlow(RecompositionMode.Immediate) {
             presenter.present()
         }.test {
-            val initialState = awaitLastSequentialItem()
+            val initialState = awaitFirstItem()
             initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
             val confirmationState = awaitItem()
-            assertThat(confirmationState.showConfirmationDialog).isTrue()
+            assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
             confirmationState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
-            skipItems(1)
             val loadingState = awaitItem()
-            assertThat(loadingState.showConfirmationDialog).isFalse()
-            assertThat(loadingState.logoutAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
             val successState = awaitItem()
-            assertThat(successState.logoutAction).isInstanceOf(Async.Success::class.java)
+            assertThat(successState.logoutAction).isInstanceOf(AsyncAction.Success::class.java)
         }
     }

@@ -143,21 +137,18 @@ class DefaultDirectLogoutPresenterTest {
         moleculeFlow(RecompositionMode.Immediate) {
             presenter.present()
         }.test {
-            skipItems(1)
-            val initialState = awaitItem()
+            val initialState = awaitFirstItem()
             initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
             val confirmationState = awaitItem()
-            assertThat(confirmationState.showConfirmationDialog).isTrue()
+            assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
             confirmationState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
-            skipItems(1)
             val loadingState = awaitItem()
-            assertThat(loadingState.showConfirmationDialog).isFalse()
-            assertThat(loadingState.logoutAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
             val errorState = awaitItem()
-            assertThat(errorState.logoutAction).isEqualTo(Async.Failure<DirectLogoutState>(A_THROWABLE))
+            assertThat(errorState.logoutAction).isEqualTo(AsyncAction.Failure(A_THROWABLE))
             errorState.eventSink.invoke(DirectLogoutEvents.CloseDialogs)
             val finalState = awaitItem()
-            assertThat(finalState.logoutAction).isEqualTo(Async.Uninitialized)
+            assertThat(finalState.logoutAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -172,27 +163,28 @@ class DefaultDirectLogoutPresenterTest {
         moleculeFlow(RecompositionMode.Immediate) {
             presenter.present()
         }.test {
-            skipItems(1)
-            val initialState = awaitItem()
+            val initialState = awaitFirstItem()
             initialState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
             val confirmationState = awaitItem()
-            assertThat(confirmationState.showConfirmationDialog).isTrue()
+            assertThat(confirmationState.logoutAction).isEqualTo(AsyncAction.Confirming)
             confirmationState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = false))
-            skipItems(1)
             val loadingState = awaitItem()
-            assertThat(loadingState.showConfirmationDialog).isFalse()
-            assertThat(loadingState.logoutAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
             val errorState = awaitItem()
-            assertThat(errorState.logoutAction).isEqualTo(Async.Failure<DirectLogoutState>(A_THROWABLE))
+            assertThat(errorState.logoutAction).isEqualTo(AsyncAction.Failure(A_THROWABLE))
             errorState.eventSink.invoke(DirectLogoutEvents.Logout(ignoreSdkError = true))
             val loadingState2 = awaitItem()
-            assertThat(loadingState2.showConfirmationDialog).isFalse()
-            assertThat(loadingState2.logoutAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState2.logoutAction).isInstanceOf(AsyncAction.Loading::class.java)
             val successState = awaitItem()
-            assertThat(successState.logoutAction).isInstanceOf(Async.Success::class.java)
+            assertThat(successState.logoutAction).isInstanceOf(AsyncAction.Success::class.java)
         }
     }

+    private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
+        skipItems(1)
+        return awaitItem()
+    }
+
     private fun createDefaultDirectLogoutPresenter(
         matrixClient: MatrixClient = FakeMatrixClient(),
         encryptionService: EncryptionService = FakeEncryptionService(),
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt
index 876884b6cf8..e173279ce95 100644
--- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt
@@ -51,7 +51,7 @@ import io.element.android.features.networkmonitor.test.FakeNetworkMonitor
 import io.element.android.features.poll.test.actions.FakeEndPollAction
 import io.element.android.features.poll.test.actions.FakeSendPollResponseAction
 import io.element.android.libraries.androidutils.clipboard.FakeClipboardHelper
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.core.coroutine.CoroutineDispatchers
 import io.element.android.libraries.core.mimetype.MimeTypes
 import io.element.android.libraries.designsystem.components.avatar.AvatarData
@@ -117,14 +117,14 @@ class MessagesPresenterTest {
         }.test {
             val initialState = consumeItemsUntilTimeout().last()
             assertThat(initialState.roomId).isEqualTo(A_ROOM_ID)
-            assertThat(initialState.roomName).isEqualTo(Async.Success(""))
+            assertThat(initialState.roomName).isEqualTo(AsyncData.Success(""))
             assertThat(initialState.roomAvatar)
-                .isEqualTo(Async.Success(AvatarData(id = A_ROOM_ID.value, name = "", url = AN_AVATAR_URL, size = AvatarSize.TimelineRoom)))
+                .isEqualTo(AsyncData.Success(AvatarData(id = A_ROOM_ID.value, name = "", url = AN_AVATAR_URL, size = AvatarSize.TimelineRoom)))
             assertThat(initialState.userHasPermissionToSendMessage).isTrue()
             assertThat(initialState.userHasPermissionToRedact).isFalse()
             assertThat(initialState.hasNetworkConnection).isTrue()
             assertThat(initialState.snackbarMessage).isNull()
-            assertThat(initialState.inviteProgress).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.inviteProgress).isEqualTo(AsyncData.Uninitialized)
             assertThat(initialState.showReinvitePrompt).isFalse()
         }
     }
diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTests.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTests.kt
index d09feaf49f2..3e6b6c9a677 100644
--- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTests.kt
+++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/report/ReportMessagePresenterTests.kt
@@ -20,7 +20,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.AsyncAction
 import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
 import io.element.android.libraries.matrix.api.room.MatrixRoom
 import io.element.android.libraries.matrix.test.AN_EVENT_ID
@@ -45,7 +45,7 @@ class ReportMessagePresenterTests {
             val initialState = awaitItem()
             assertThat(initialState.reason).isEmpty()
             assertThat(initialState.blockUser).isFalse()
-            assertThat(initialState.result).isInstanceOf(Async.Uninitialized::class.java)
+            assertThat(initialState.result).isInstanceOf(AsyncAction.Uninitialized::class.java)
         }
     }

@@ -91,8 +91,8 @@ class ReportMessagePresenterTests {
             initialState.eventSink(ReportMessageEvents.ToggleBlockUser)
             skipItems(1)
             initialState.eventSink(ReportMessageEvents.Report)
-            assertThat(awaitItem().result).isInstanceOf(Async.Loading::class.java)
-            assertThat(awaitItem().result).isInstanceOf(Async.Success::class.java)
+            assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)
+            assertThat(awaitItem().result).isInstanceOf(AsyncAction.Success::class.java)
             assertThat(room.reportedContentCount).isEqualTo(1)
         }
     }
@@ -106,8 +106,8 @@ class ReportMessagePresenterTests {
         }.test {
             val initialState = awaitItem()
             initialState.eventSink(ReportMessageEvents.Report)
-            assertThat(awaitItem().result).isInstanceOf(Async.Loading::class.java)
-            assertThat(awaitItem().result).isInstanceOf(Async.Success::class.java)
+            assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)
+            assertThat(awaitItem().result).isInstanceOf(AsyncAction.Success::class.java)
             assertThat(room.reportedContentCount).isEqualTo(1)
         }
     }
@@ -123,13 +123,13 @@ class ReportMessagePresenterTests {
         }.test {
             val initialState = awaitItem()
             initialState.eventSink(ReportMessageEvents.Report)
-            assertThat(awaitItem().result).isInstanceOf(Async.Loading::class.java)
+            assertThat(awaitItem().result).isInstanceOf(AsyncAction.Loading::class.java)
             val resultState = awaitItem()
-            assertThat(resultState.result).isInstanceOf(Async.Failure::class.java)
+            assertThat(resultState.result).isInstanceOf(AsyncAction.Failure::class.java)
             assertThat(room.reportedContentCount).isEqualTo(1)

             resultState.eventSink(ReportMessageEvents.ClearError)
-            assertThat(awaitItem().result).isInstanceOf(Async.Uninitialized::class.java)
+            assertThat(awaitItem().result).isInstanceOf(AsyncAction.Uninitialized::class.java)
         }
     }

diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt
index 07705446d94..9872ed0804a 100644
--- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt
+++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsPresenterTest.kt
@@ -26,7 +26,7 @@ import io.element.android.features.preferences.impl.tasks.FakeComputeCacheSizeUs
 import io.element.android.features.rageshake.impl.preferences.DefaultRageshakePreferencesPresenter
 import io.element.android.features.rageshake.test.rageshake.FakeRageShake
 import io.element.android.features.rageshake.test.rageshake.FakeRageshakeDataStore
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.featureflag.api.FeatureFlags
 import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
 import io.element.android.libraries.featureflag.test.InMemoryPreferencesStore
@@ -49,8 +49,8 @@ class DeveloperSettingsPresenterTest {
         }.test {
             val initialState = awaitItem()
             assertThat(initialState.features).isEmpty()
-            assertThat(initialState.clearCacheAction).isEqualTo(Async.Uninitialized)
-            assertThat(initialState.cacheSize).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.clearCacheAction).isEqualTo(AsyncData.Uninitialized)
+            assertThat(initialState.cacheSize).isEqualTo(AsyncData.Uninitialized)
             assertThat(initialState.customElementCallBaseUrlState).isNotNull()
             assertThat(initialState.customElementCallBaseUrlState.baseUrl).isNull()
             val loadedState = awaitItem()
@@ -105,9 +105,9 @@ class DeveloperSettingsPresenterTest {
             assertThat(clearCacheUseCase.executeHasBeenCalled).isFalse()
             initialState.eventSink(DeveloperSettingsEvents.ClearCache)
             val stateAfterEvent = awaitItem()
-            assertThat(stateAfterEvent.clearCacheAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(stateAfterEvent.clearCacheAction).isInstanceOf(AsyncData.Loading::class.java)
             skipItems(1)
-            assertThat(awaitItem().clearCacheAction).isInstanceOf(Async.Success::class.java)
+            assertThat(awaitItem().clearCacheAction).isInstanceOf(AsyncData.Success::class.java)
             assertThat(clearCacheUseCase.executeHasBeenCalled).isTrue()
             cancelAndIgnoreRemainingEvents()
         }
diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt
index fc657bfbd75..0a2dd8efe35 100644
--- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt
+++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenterTest.kt
@@ -23,7 +23,7 @@ import app.cash.turbine.test
 import com.google.common.truth.Truth.assertThat
 import io.element.android.features.logout.api.direct.DirectLogoutPresenter
 import io.element.android.features.logout.api.direct.DirectLogoutState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.core.meta.BuildType
 import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
 import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
@@ -47,8 +47,7 @@ class PreferencesRootPresenterTest {

     private val aDirectLogoutState = DirectLogoutState(
         canDoDirectSignOut = true,
-        showConfirmationDialog = false,
-        logoutAction = Async.Uninitialized,
+        logoutAction = AsyncAction.Uninitialized,
         eventSink = {},
     )

diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt
index 3e32ed675f8..8b3bb0c2f8f 100644
--- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt
+++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt
@@ -21,7 +21,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.AsyncAction
 import io.element.android.libraries.matrix.api.MatrixClient
 import io.element.android.libraries.matrix.api.user.MatrixUser
 import io.element.android.libraries.matrix.test.AN_AVATAR_URL
@@ -110,7 +110,7 @@ class EditUserProfilePresenterTest {
                 AvatarAction.Remove
             )
             assertThat(initialState.saveButtonEnabled).isFalse()
-            assertThat(initialState.saveAction).isInstanceOf(Async.Uninitialized::class.java)
+            assertThat(initialState.saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
         }
     }

@@ -359,7 +359,7 @@ class EditUserProfilePresenterTest {
             initialState.eventSink(EditUserProfileEvents.Save)
             skipItems(2)
             assertThat(matrixClient.uploadAvatarCalled).isFalse()
-            assertThat(awaitItem().saveAction).isInstanceOf(Async.Failure::class.java)
+            assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
         }
     }

@@ -406,9 +406,9 @@ class EditUserProfilePresenterTest {
             initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("foo"))
             initialState.eventSink(EditUserProfileEvents.Save)
             skipItems(2)
-            assertThat(awaitItem().saveAction).isInstanceOf(Async.Failure::class.java)
+            assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
             initialState.eventSink(EditUserProfileEvents.CancelSaveChanges)
-            assertThat(awaitItem().saveAction).isInstanceOf(Async.Uninitialized::class.java)
+            assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
         }
     }

@@ -421,8 +421,8 @@ class EditUserProfilePresenterTest {
             initialState.eventSink(event)
             initialState.eventSink(EditUserProfileEvents.Save)
             skipItems(1)
-            assertThat(awaitItem().saveAction).isInstanceOf(Async.Loading::class.java)
-            assertThat(awaitItem().saveAction).isInstanceOf(Async.Failure::class.java)
+            assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Loading::class.java)
+            assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
         }
     }

diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt
index 3360ce3dd32..9161862256c 100644
--- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt
+++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt
@@ -24,7 +24,7 @@ import io.element.android.features.rageshake.test.crash.A_CRASH_DATA
 import io.element.android.features.rageshake.test.crash.FakeCrashDataStore
 import io.element.android.features.rageshake.test.screenshot.A_SCREENSHOT_URI
 import io.element.android.features.rageshake.test.screenshot.FakeScreenshotHolder
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.test.A_FAILURE_REASON
 import io.element.android.tests.testutils.WarmUpRule
 import kotlinx.coroutines.test.runTest
@@ -53,7 +53,7 @@ class BugReportPresenterTest {
             val initialState = awaitItem()
             assertThat(initialState.hasCrashLogs).isFalse()
             assertThat(initialState.formState).isEqualTo(BugReportFormState.Default)
-            assertThat(initialState.sending).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.sending).isEqualTo(AsyncAction.Uninitialized)
             assertThat(initialState.screenshotUri).isNull()
             assertThat(initialState.sendingProgress).isEqualTo(0f)
             assertThat(initialState.submitEnabled).isFalse()
@@ -174,13 +174,13 @@ class BugReportPresenterTest {
             initialState.eventSink.invoke(BugReportEvents.SendBugReport)
             skipItems(1)
             val progressState = awaitItem()
-            assertThat(progressState.sending).isEqualTo(Async.Loading(null))
+            assertThat(progressState.sending).isEqualTo(AsyncAction.Loading)
             assertThat(progressState.sendingProgress).isEqualTo(0f)
             assertThat(progressState.submitEnabled).isFalse()
             assertThat(awaitItem().sendingProgress).isEqualTo(0.5f)
             assertThat(awaitItem().sendingProgress).isEqualTo(1f)
             skipItems(1)
-            assertThat(awaitItem().sending).isEqualTo(Async.Success(Unit))
+            assertThat(awaitItem().sending).isEqualTo(AsyncAction.Success(Unit))
         }
     }

@@ -199,17 +199,17 @@ class BugReportPresenterTest {
             initialState.eventSink.invoke(BugReportEvents.SendBugReport)
             skipItems(1)
             val progressState = awaitItem()
-            assertThat(progressState.sending).isEqualTo(Async.Loading(null))
+            assertThat(progressState.sending).isEqualTo(AsyncAction.Loading)
             assertThat(progressState.sendingProgress).isEqualTo(0f)
             assertThat(awaitItem().sendingProgress).isEqualTo(0.5f)
             // Failure
             assertThat(awaitItem().sendingProgress).isEqualTo(0f)
-            assertThat((awaitItem().sending as Async.Failure).error.message).isEqualTo(A_FAILURE_REASON)
+            assertThat((awaitItem().sending as AsyncAction.Failure).error.message).isEqualTo(A_FAILURE_REASON)
             // Reset failure
             initialState.eventSink.invoke(BugReportEvents.ClearError)
             val lastItem = awaitItem()
             assertThat(lastItem.sendingProgress).isEqualTo(0f)
-            assertThat(lastItem.sending).isInstanceOf(Async.Uninitialized::class.java)
+            assertThat(lastItem.sending).isInstanceOf(AsyncAction.Uninitialized::class.java)
         }
     }

@@ -228,12 +228,12 @@ class BugReportPresenterTest {
             initialState.eventSink.invoke(BugReportEvents.SendBugReport)
             skipItems(1)
             val progressState = awaitItem()
-            assertThat(progressState.sending).isEqualTo(Async.Loading(null))
+            assertThat(progressState.sending).isEqualTo(AsyncAction.Loading)
             assertThat(progressState.sendingProgress).isEqualTo(0f)
             assertThat(awaitItem().sendingProgress).isEqualTo(0.5f)
             // Cancelled
             assertThat(awaitItem().sendingProgress).isEqualTo(0f)
-            assertThat(awaitItem().sending).isEqualTo(Async.Uninitialized)
+            assertThat(awaitItem().sending).isEqualTo(AsyncAction.Uninitialized)
         }
     }
 }
diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt
index 2c1b399da8f..a9a2d81b202 100644
--- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt
+++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/edit/RoomDetailsEditPresenterTest.kt
@@ -24,7 +24,7 @@ import com.google.common.truth.Truth.assertThat
 import io.element.android.features.roomdetails.aMatrixRoom
 import io.element.android.features.roomdetails.impl.edit.RoomDetailsEditEvents
 import io.element.android.features.roomdetails.impl.edit.RoomDetailsEditPresenter
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.room.MatrixRoom
 import io.element.android.libraries.matrix.api.room.StateEventType
 import io.element.android.libraries.matrix.test.AN_AVATAR_URL
@@ -108,7 +108,7 @@ class RoomDetailsEditPresenterTest {
                 AvatarAction.Remove
             )
             assertThat(initialState.saveButtonEnabled).isFalse()
-            assertThat(initialState.saveAction).isInstanceOf(Async.Uninitialized::class.java)
+            assertThat(initialState.saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
         }
     }

@@ -533,7 +533,7 @@ class RoomDetailsEditPresenterTest {
             assertThat(room.newAvatarData).isNull()
             assertThat(room.removedAvatar).isFalse()

-            assertThat(awaitItem().saveAction).isInstanceOf(Async.Failure::class.java)
+            assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
         }
     }

@@ -594,10 +594,10 @@ class RoomDetailsEditPresenterTest {
             initialState.eventSink(RoomDetailsEditEvents.Save)
             skipItems(2)

-            assertThat(awaitItem().saveAction).isInstanceOf(Async.Failure::class.java)
+            assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)

             initialState.eventSink(RoomDetailsEditEvents.CancelSaveChanges)
-            assertThat(awaitItem().saveAction).isInstanceOf(Async.Uninitialized::class.java)
+            assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java)
         }
     }

@@ -613,8 +613,8 @@ class RoomDetailsEditPresenterTest {
             initialState.eventSink(RoomDetailsEditEvents.Save)
             skipItems(1)

-            assertThat(awaitItem().saveAction).isInstanceOf(Async.Loading::class.java)
-            assertThat(awaitItem().saveAction).isInstanceOf(Async.Failure::class.java)
+            assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Loading::class.java)
+            assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java)
         }
     }

diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt
index 097919a5e1c..1b5ae747654 100644
--- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt
+++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/RoomMemberListPresenterTests.kt
@@ -26,7 +26,7 @@ import io.element.android.features.roomdetails.impl.members.RoomMemberListPresen
 import io.element.android.features.roomdetails.impl.members.aRoomMemberList
 import io.element.android.features.roomdetails.impl.members.aVictor
 import io.element.android.features.roomdetails.impl.members.aWalter
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.core.coroutine.CoroutineDispatchers
 import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
 import io.element.android.libraries.matrix.api.room.MatrixRoom
@@ -53,14 +53,14 @@ class RoomMemberListPresenterTests {
             presenter.present()
         }.test {
             val initialState = awaitItem()
-            assertThat(initialState.roomMembers).isInstanceOf(Async.Loading::class.java)
+            assertThat(initialState.roomMembers).isInstanceOf(AsyncData.Loading::class.java)
             assertThat(initialState.searchQuery).isEmpty()
             assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.NotSearching::class.java)
             assertThat(initialState.isSearchActive).isFalse()
             val loadedState = awaitItem()
-            assertThat(loadedState.roomMembers).isInstanceOf(Async.Success::class.java)
-            assertThat((loadedState.roomMembers as Async.Success).data.invited).isEqualTo(listOf(aVictor(), aWalter()))
-            assertThat((loadedState.roomMembers as Async.Success).data.joined).isNotEmpty()
+            assertThat(loadedState.roomMembers).isInstanceOf(AsyncData.Success::class.java)
+            assertThat((loadedState.roomMembers as AsyncData.Success).data.invited).isEqualTo(listOf(aVictor(), aWalter()))
+            assertThat((loadedState.roomMembers as AsyncData.Success).data.joined).isNotEmpty()
         }
     }

diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt
index ac429e262d7..f1553f8d06c 100644
--- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt
+++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/details/RoomMemberDetailsPresenterTests.kt
@@ -27,9 +27,9 @@ import io.element.android.features.roomdetails.impl.members.aRoomMember
 import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsEvents
 import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter
 import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsState
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.MatrixClient
-import io.element.android.libraries.matrix.api.core.RoomId
 import io.element.android.libraries.matrix.api.room.MatrixRoom
 import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
 import io.element.android.libraries.matrix.api.room.RoomMember
@@ -68,7 +68,7 @@ class RoomMemberDetailsPresenterTests {
             assertThat(initialState.userId).isEqualTo(roomMember.userId.value)
             assertThat(initialState.userName).isEqualTo(roomMember.displayName)
             assertThat(initialState.avatarUrl).isEqualTo(roomMember.avatarUrl)
-            assertThat(initialState.isBlocked).isEqualTo(Async.Success(roomMember.isIgnored))
+            assertThat(initialState.isBlocked).isEqualTo(AsyncData.Success(roomMember.isIgnored))
             skipItems(1)
             val loadedState = awaitItem()
             assertThat(loadedState.userName).isEqualTo("A custom name")
@@ -173,7 +173,7 @@ class RoomMemberDetailsPresenterTests {
             assertThat(errorState.isBlocked.errorOrNull()).isEqualTo(A_THROWABLE)
             // Clear error
             initialState.eventSink(RoomMemberDetailsEvents.ClearBlockUserError)
-            assertThat(awaitItem().isBlocked).isEqualTo(Async.Success(false))
+            assertThat(awaitItem().isBlocked).isEqualTo(AsyncData.Success(false))
         }
     }

@@ -204,14 +204,14 @@ class RoomMemberDetailsPresenterTests {
             presenter.present()
         }.test {
             val initialState = awaitItem()
-            assertThat(initialState.startDmActionState).isInstanceOf(Async.Uninitialized::class.java)
-            val startDMSuccessResult = Async.Success(A_ROOM_ID)
-            val startDMFailureResult = Async.Failure<RoomId>(A_THROWABLE)
+            assertThat(initialState.startDmActionState).isInstanceOf(AsyncAction.Uninitialized::class.java)
+            val startDMSuccessResult = AsyncAction.Success(A_ROOM_ID)
+            val startDMFailureResult = AsyncAction.Failure(A_THROWABLE)

             // Failure
             startDMAction.givenExecuteResult(startDMFailureResult)
             initialState.eventSink(RoomMemberDetailsEvents.StartDM)
-            assertThat(awaitItem().startDmActionState).isInstanceOf(Async.Loading::class.java)
+            assertThat(awaitItem().startDmActionState).isInstanceOf(AsyncAction.Loading::class.java)
             awaitItem().also { state ->
                 assertThat(state.startDmActionState).isEqualTo(startDMFailureResult)
                 state.eventSink(RoomMemberDetailsEvents.ClearStartDMState)
@@ -220,10 +220,10 @@ class RoomMemberDetailsPresenterTests {
             // Success
             startDMAction.givenExecuteResult(startDMSuccessResult)
             awaitItem().also { state ->
-                assertThat(state.startDmActionState).isEqualTo(Async.Uninitialized)
+                assertThat(state.startDmActionState).isEqualTo(AsyncAction.Uninitialized)
                 state.eventSink(RoomMemberDetailsEvents.StartDM)
             }
-            assertThat(awaitItem().startDmActionState).isInstanceOf(Async.Loading::class.java)
+            assertThat(awaitItem().startDmActionState).isInstanceOf(AsyncAction.Loading::class.java)
             awaitItem().also { state ->
                 assertThat(state.startDmActionState).isEqualTo(startDMSuccessResult)
             }
diff --git a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenterTest.kt b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenterTest.kt
index 8e42ee7efe9..18fd9b800a5 100644
--- a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenterTest.kt
+++ b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/disable/SecureBackupDisablePresenterTest.kt
@@ -20,7 +20,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.AsyncAction
 import io.element.android.libraries.matrix.api.encryption.BackupState
 import io.element.android.libraries.matrix.api.encryption.EncryptionService
 import io.element.android.libraries.matrix.test.core.aBuildMeta
@@ -42,8 +42,7 @@ class SecureBackupDisablePresenterTest {
         }.test {
             val initialState = awaitItem()
             assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN)
-            assertThat(initialState.disableAction).isEqualTo(Async.Uninitialized)
-            assertThat(initialState.showConfirmationDialog).isFalse()
+            assertThat(initialState.disableAction).isEqualTo(AsyncAction.Uninitialized)
             assertThat(initialState.appName).isEqualTo("Element")
         }
     }
@@ -55,13 +54,12 @@ class SecureBackupDisablePresenterTest {
             presenter.present()
         }.test {
             val initialState = awaitItem()
-            assertThat(initialState.showConfirmationDialog).isFalse()
-            initialState.eventSink(SecureBackupDisableEvents.DisableBackup(force = false))
+            initialState.eventSink(SecureBackupDisableEvents.DisableBackup)
             val state = awaitItem()
-            assertThat(state.showConfirmationDialog).isTrue()
+            assertThat(state.disableAction).isEqualTo(AsyncAction.Confirming)
             initialState.eventSink(SecureBackupDisableEvents.DismissDialogs)
             val finalState = awaitItem()
-            assertThat(finalState.showConfirmationDialog).isFalse()
+            assertThat(finalState.disableAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

@@ -72,17 +70,15 @@ class SecureBackupDisablePresenterTest {
             presenter.present()
         }.test {
             val initialState = awaitItem()
-            assertThat(initialState.showConfirmationDialog).isFalse()
-            initialState.eventSink(SecureBackupDisableEvents.DisableBackup(force = false))
+            assertThat(initialState.disableAction).isEqualTo(AsyncAction.Uninitialized)
+            initialState.eventSink(SecureBackupDisableEvents.DisableBackup)
             val state = awaitItem()
-            assertThat(state.showConfirmationDialog).isTrue()
-            initialState.eventSink(SecureBackupDisableEvents.DisableBackup(force = true))
-            skipItems(1)
+            assertThat(state.disableAction).isEqualTo(AsyncAction.Confirming)
+            initialState.eventSink(SecureBackupDisableEvents.DisableBackup)
             val loadingState = awaitItem()
-            assertThat(loadingState.showConfirmationDialog).isFalse()
-            assertThat(loadingState.disableAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.disableAction).isInstanceOf(AsyncAction.Loading::class.java)
             val finalState = awaitItem()
-            assertThat(finalState.disableAction).isEqualTo(Async.Success(Unit))
+            assertThat(finalState.disableAction).isEqualTo(AsyncAction.Success(Unit))
         }
     }

@@ -98,20 +94,18 @@ class SecureBackupDisablePresenterTest {
             presenter.present()
         }.test {
             val initialState = awaitItem()
-            assertThat(initialState.showConfirmationDialog).isFalse()
-            initialState.eventSink(SecureBackupDisableEvents.DisableBackup(force = false))
+            assertThat(initialState.disableAction).isEqualTo(AsyncAction.Uninitialized)
+            initialState.eventSink(SecureBackupDisableEvents.DisableBackup)
             val state = awaitItem()
-            assertThat(state.showConfirmationDialog).isTrue()
-            initialState.eventSink(SecureBackupDisableEvents.DisableBackup(force = true))
-            skipItems(1)
+            assertThat(state.disableAction).isEqualTo(AsyncAction.Confirming)
+            initialState.eventSink(SecureBackupDisableEvents.DisableBackup)
             val loadingState = awaitItem()
-            assertThat(loadingState.showConfirmationDialog).isFalse()
-            assertThat(loadingState.disableAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.disableAction).isInstanceOf(AsyncAction.Loading::class.java)
             val errorState = awaitItem()
-            assertThat(errorState.disableAction).isInstanceOf(Async.Failure::class.java)
+            assertThat(errorState.disableAction).isInstanceOf(AsyncAction.Failure::class.java)
             errorState.eventSink(SecureBackupDisableEvents.DismissDialogs)
             val finalState = awaitItem()
-            assertThat(finalState.disableAction).isEqualTo(Async.Uninitialized)
+            assertThat(finalState.disableAction).isEqualTo(AsyncAction.Uninitialized)
         }
     }

diff --git a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnablePresenterTest.kt b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnablePresenterTest.kt
index 7bc051662b2..39d8ebf81f8 100644
--- a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnablePresenterTest.kt
+++ b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enable/SecureBackupEnablePresenterTest.kt
@@ -20,7 +20,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.matrix.api.encryption.EncryptionService
 import io.element.android.libraries.matrix.test.AN_EXCEPTION
 import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
@@ -40,7 +40,7 @@ class SecureBackupEnablePresenterTest {
             presenter.present()
         }.test {
             val initialState = awaitItem()
-            assertThat(initialState.enableAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.enableAction).isEqualTo(AsyncData.Uninitialized)
         }
     }

@@ -53,9 +53,9 @@ class SecureBackupEnablePresenterTest {
             val initialState = awaitItem()
             initialState.eventSink(SecureBackupEnableEvents.EnableBackup)
             val loadingState = awaitItem()
-            assertThat(loadingState.enableAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.enableAction).isInstanceOf(AsyncData.Loading::class.java)
             val finalState = awaitItem()
-            assertThat(finalState.enableAction).isEqualTo(Async.Success(Unit))
+            assertThat(finalState.enableAction).isEqualTo(AsyncData.Success(Unit))
         }
     }

@@ -70,12 +70,12 @@ class SecureBackupEnablePresenterTest {
             val initialState = awaitItem()
             initialState.eventSink(SecureBackupEnableEvents.EnableBackup)
             val loadingState = awaitItem()
-            assertThat(loadingState.enableAction).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState.enableAction).isInstanceOf(AsyncData.Loading::class.java)
             val errorState = awaitItem()
-            assertThat(errorState.enableAction).isEqualTo(Async.Failure<Unit>(AN_EXCEPTION))
+            assertThat(errorState.enableAction).isEqualTo(AsyncData.Failure<Unit>(AN_EXCEPTION))
             errorState.eventSink(SecureBackupEnableEvents.DismissDialog)
             val finalState = awaitItem()
-            assertThat(finalState.enableAction).isEqualTo(Async.Uninitialized)
+            assertThat(finalState.enableAction).isEqualTo(AsyncData.Uninitialized)
         }
     }

diff --git a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenterTest.kt b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenterTest.kt
index 862cbbde722..3991fe306c2 100644
--- a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenterTest.kt
+++ b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/enter/SecureBackupEnterRecoveryKeyPresenterTest.kt
@@ -23,7 +23,7 @@ import com.google.common.truth.Truth.assertThat
 import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyUserStory
 import io.element.android.features.securebackup.impl.setup.views.RecoveryKeyViewState
 import io.element.android.features.securebackup.impl.tools.RecoveryKeyTools
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncAction
 import io.element.android.libraries.matrix.api.encryption.EncryptionService
 import io.element.android.libraries.matrix.test.AN_EXCEPTION
 import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
@@ -44,7 +44,7 @@ class SecureBackupEnterRecoveryKeyPresenterTest {
         }.test {
             val initialState = awaitItem()
             assertThat(initialState.isSubmitEnabled).isFalse()
-            assertThat(initialState.submitAction).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.submitAction).isEqualTo(AsyncAction.Uninitialized)
             assertThat(initialState.recoveryKeyViewState).isEqualTo(
                 RecoveryKeyViewState(
                     recoveryKeyUserStory = RecoveryKeyUserStory.Enter,
@@ -76,22 +76,22 @@ class SecureBackupEnterRecoveryKeyPresenterTest {
             encryptionService.givenRecoverFailure(AN_EXCEPTION)
             withRecoveryKeyState.eventSink(SecureBackupEnterRecoveryKeyEvents.Submit)
             val loadingState = awaitItem()
-            assertThat(loadingState.submitAction).isEqualTo(Async.Loading<Unit>())
+            assertThat(loadingState.submitAction).isEqualTo(AsyncAction.Loading)
             assertThat(loadingState.isSubmitEnabled).isFalse()
             val errorState = awaitItem()
-            assertThat(errorState.submitAction).isEqualTo(Async.Failure<Unit>(AN_EXCEPTION))
+            assertThat(errorState.submitAction).isEqualTo(AsyncAction.Failure(AN_EXCEPTION))
             assertThat(errorState.isSubmitEnabled).isFalse()
             errorState.eventSink(SecureBackupEnterRecoveryKeyEvents.ClearDialog)
             val clearedState = awaitItem()
-            assertThat(clearedState.submitAction).isEqualTo(Async.Uninitialized)
+            assertThat(clearedState.submitAction).isEqualTo(AsyncAction.Uninitialized)
             assertThat(clearedState.isSubmitEnabled).isTrue()
             encryptionService.givenRecoverFailure(null)
             clearedState.eventSink(SecureBackupEnterRecoveryKeyEvents.Submit)
             val loadingState2 = awaitItem()
-            assertThat(loadingState2.submitAction).isEqualTo(Async.Loading<Unit>())
+            assertThat(loadingState2.submitAction).isEqualTo(AsyncAction.Loading)
             assertThat(loadingState2.isSubmitEnabled).isFalse()
             val finalState = awaitItem()
-            assertThat(finalState.submitAction).isEqualTo(Async.Success(Unit))
+            assertThat(finalState.submitAction).isEqualTo(AsyncAction.Success(Unit))
             assertThat(finalState.isSubmitEnabled).isFalse()
         }
     }
diff --git a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootPresenterTest.kt b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootPresenterTest.kt
index 6b88e207484..3baecd4381a 100644
--- a/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootPresenterTest.kt
+++ b/features/securebackup/impl/src/test/kotlin/io/element/android/features/securebackup/impl/root/SecureBackupRootPresenterTest.kt
@@ -20,7 +20,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.api.encryption.BackupState
 import io.element.android.libraries.matrix.api.encryption.EncryptionService
@@ -65,15 +65,15 @@ class SecureBackupRootPresenterTest {
             val initialState = awaitItem()
             encryptionService.givenDoesBackupExistOnServerResult(Result.failure(AN_EXCEPTION))
             assertThat(initialState.backupState).isEqualTo(BackupState.UNKNOWN)
-            assertThat(initialState.doesBackupExistOnServer).isEqualTo(Async.Uninitialized)
+            assertThat(initialState.doesBackupExistOnServer).isEqualTo(AsyncData.Uninitialized)
             val loadingState1 = awaitItem()
-            assertThat(loadingState1.doesBackupExistOnServer).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState1.doesBackupExistOnServer).isInstanceOf(AsyncData.Loading::class.java)
             val errorState = awaitItem()
-            assertThat(errorState.doesBackupExistOnServer).isEqualTo(Async.Failure<Boolean>(AN_EXCEPTION))
+            assertThat(errorState.doesBackupExistOnServer).isEqualTo(AsyncData.Failure<Boolean>(AN_EXCEPTION))
             encryptionService.givenDoesBackupExistOnServerResult(Result.success(false))
             errorState.eventSink.invoke(SecureBackupRootEvents.RetryKeyBackupState)
             val loadingState2 = awaitItem()
-            assertThat(loadingState2.doesBackupExistOnServer).isInstanceOf(Async.Loading::class.java)
+            assertThat(loadingState2.doesBackupExistOnServer).isInstanceOf(AsyncData.Loading::class.java)
             val finalState = awaitItem()
             assertThat(finalState.doesBackupExistOnServer.dataOrNull()).isFalse()
         }
diff --git a/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt b/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt
index c96866cb5ab..2943b0aa0f7 100644
--- a/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt
+++ b/features/verifysession/impl/src/test/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenterTests.kt
@@ -22,7 +22,7 @@ import app.cash.turbine.ReceiveTurbine
 import app.cash.turbine.test
 import com.google.common.truth.Truth.assertThat
 import io.element.android.features.verifysession.impl.VerifySelfSessionState.VerificationStep
-import io.element.android.libraries.architecture.Async
+import io.element.android.libraries.architecture.AsyncData
 import io.element.android.libraries.matrix.api.verification.SessionVerificationData
 import io.element.android.libraries.matrix.api.verification.VerificationEmoji
 import io.element.android.libraries.matrix.api.verification.VerificationFlowState
@@ -173,7 +173,7 @@ class VerifySelfSessionPresenterTests {
             assertThat(awaitItem().verificationFlowStep).isEqualTo(
                 VerificationStep.Verifying(
                     SessionVerificationData.Emojis(emojis),
-                    Async.Loading(),
+                    AsyncData.Loading(),
                 )
             )
             assertThat(awaitItem().verificationFlowStep).isEqualTo(VerificationStep.Completed)
@@ -192,7 +192,7 @@ class VerifySelfSessionPresenterTests {
             assertThat(awaitItem().verificationFlowStep).isEqualTo(
                 VerificationStep.Verifying(
                     SessionVerificationData.Emojis(emptyList()),
-                    Async.Loading(),
+                    AsyncData.Loading(),
                 )
             )
             assertThat(awaitItem().verificationFlowStep).isEqualTo(VerificationStep.Canceled)
diff --git a/libraries/architecture/src/test/kotlin/io/element/android/libraries/architecture/AsyncKtTest.kt b/libraries/architecture/src/test/kotlin/io/element/android/libraries/architecture/AsyncDataKtTest.kt
similarity index 74%
rename from libraries/architecture/src/test/kotlin/io/element/android/libraries/architecture/AsyncKtTest.kt
rename to libraries/architecture/src/test/kotlin/io/element/android/libraries/architecture/AsyncDataKtTest.kt
index 4b6c75a1086..5069950b7a2 100644
--- a/libraries/architecture/src/test/kotlin/io/element/android/libraries/architecture/AsyncKtTest.kt
+++ b/libraries/architecture/src/test/kotlin/io/element/android/libraries/architecture/AsyncDataKtTest.kt
@@ -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()
     }
 }
diff --git a/libraries/mediaviewer/api/src/test/kotlin/io/element/android/libraries/mediaviewer/MediaViewerPresenterTest.kt b/libraries/mediaviewer/api/src/test/kotlin/io/element/android/libraries/mediaviewer/MediaViewerPresenterTest.kt
index ce2b4651a5f..c8589e2adbd 100644
--- a/libraries/mediaviewer/api/src/test/kotlin/io/element/android/libraries/mediaviewer/MediaViewerPresenterTest.kt
+++ b/libraries/mediaviewer/api/src/test/kotlin/io/element/android/libraries/mediaviewer/MediaViewerPresenterTest.kt
@@ -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()
         }
     }
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_0,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_0,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_0,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_1,NEXUS_5,1.0,en].png
new file mode 100644
index 00000000000..b5e040deaec
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_1,NEXUS_5,1.0,en].png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:babf7dba9e6ae0344bd1817db450195630dc63fb8c84fec1c2c747444184ee45
+size 17475
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_2,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_1,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_2,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_3,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_2,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_3,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_4,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Day_0_null_3,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Day_0_null_4,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_0,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_0,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_0,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_1,NEXUS_5,1.0,en].png
new file mode 100644
index 00000000000..c963ae3a8c2
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_1,NEXUS_5,1.0,en].png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:628a1c2531719e617cf10f44c4f61d898429067bc72dd8e4aa4d211bd4968feb
+size 14263
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_2,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_1,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_2,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_3,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_2,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_3,NEXUS_5,1.0,en].png
diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_4,NEXUS_5,1.0,en].png
similarity index 100%
rename from tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncView_null_AsyncView-Night_1_null_3,NEXUS_5,1.0,en].png
rename to tests/uitests/src/test/snapshots/images/ui_S_t[l.designsystem.components.async_AsyncActionView_null_AsyncActionView-Night_1_null_4,NEXUS_5,1.0,en].png