Introduce SessionComponent
This commit is contained in:
parent
eba807e37a
commit
0a06ca0539
18 changed files with 176 additions and 104 deletions
|
|
@ -30,13 +30,14 @@ import com.airbnb.mvrx.compose.collectAsState
|
|||
import com.airbnb.mvrx.compose.mavericksViewModel
|
||||
import io.element.android.x.designsystem.ElementXTheme
|
||||
import io.element.android.x.features.login.error.loginError
|
||||
import io.element.android.x.matrix.MatrixClient
|
||||
import timber.log.Timber
|
||||
|
||||
@Composable
|
||||
fun LoginScreen(
|
||||
viewModel: LoginViewModel = mavericksViewModel(),
|
||||
onChangeServer: () -> Unit = { },
|
||||
onLoginWithSuccess: () -> Unit = { },
|
||||
onLoginWithSuccess: (MatrixClient) -> Unit = { },
|
||||
) {
|
||||
val state: LoginViewState by viewModel.collectAsState()
|
||||
val formState: LoginFormState by viewModel.formState
|
||||
|
|
@ -65,7 +66,7 @@ fun LoginContent(
|
|||
onLoginChanged: (String) -> Unit = {},
|
||||
onPasswordChanged: (String) -> Unit = {},
|
||||
onSubmitClicked: () -> Unit = {},
|
||||
onLoginWithSuccess: () -> Unit = {},
|
||||
onLoginWithSuccess: (MatrixClient) -> Unit = {},
|
||||
) {
|
||||
Surface(color = MaterialTheme.colorScheme.background) {
|
||||
Box(
|
||||
|
|
@ -82,7 +83,7 @@ fun LoginContent(
|
|||
)
|
||||
.padding(horizontal = 16.dp),
|
||||
) {
|
||||
val isError = state.isLoggedIn is Fail
|
||||
val isError = state.loggedInClient is Fail
|
||||
// Title
|
||||
Text(
|
||||
text = "Welcome back",
|
||||
|
|
@ -137,7 +138,7 @@ fun LoginContent(
|
|||
),
|
||||
)
|
||||
var passwordVisible by remember { mutableStateOf(false) }
|
||||
if (state.isLoggedIn is Loading) {
|
||||
if (state.loggedInClient is Loading) {
|
||||
// Ensure password is hidden when user submits the form
|
||||
passwordVisible = false
|
||||
}
|
||||
|
|
@ -170,9 +171,9 @@ fun LoginContent(
|
|||
onDone = { onSubmitClicked() }
|
||||
),
|
||||
)
|
||||
if (state.isLoggedIn is Fail) {
|
||||
if (state.loggedInClient is Fail) {
|
||||
Text(
|
||||
text = loginError(state.formState, state.isLoggedIn.error),
|
||||
text = loginError(state.formState, state.loggedInClient.error),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
modifier = Modifier.padding(start = 16.dp)
|
||||
|
|
@ -189,11 +190,12 @@ fun LoginContent(
|
|||
) {
|
||||
Text(text = "Continue")
|
||||
}
|
||||
if (state.isLoggedIn is Success) {
|
||||
onLoginWithSuccess()
|
||||
when (val loggedInClient = state.loggedInClient) {
|
||||
is Success -> onLoginWithSuccess(loggedInClient())
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
if (state.isLoggedIn is Loading) {
|
||||
if (state.loggedInClient is Loading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.align(Alignment.Center)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import io.element.android.x.anvilannotations.ContributesViewModel
|
|||
import io.element.android.x.core.di.daggerMavericksViewModelFactory
|
||||
import io.element.android.x.di.AppScope
|
||||
import io.element.android.x.matrix.Matrix
|
||||
import io.element.android.x.matrix.MatrixInstance
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -49,21 +48,22 @@ class LoginViewModel @AssistedInject constructor(
|
|||
val state = awaitState()
|
||||
// Ensure the server is provided to the Rust SDK
|
||||
matrix.setHomeserver(state.homeserver)
|
||||
matrix.login(state.formState.login.trim(), state.formState.password.trim())
|
||||
matrix.activeClient().startSync()
|
||||
matrix.login(state.formState.login.trim(), state.formState.password.trim()).also {
|
||||
it.startSync()
|
||||
}
|
||||
}.execute {
|
||||
copy(isLoggedIn = it)
|
||||
copy(loggedInClient = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onSetPassword(password: String) {
|
||||
formState.value = formState.value.copy(password = password)
|
||||
setState { copy(isLoggedIn = Uninitialized) }
|
||||
setState { copy(loggedInClient = Uninitialized) }
|
||||
}
|
||||
|
||||
fun onSetName(name: String) {
|
||||
formState.value = formState.value.copy(login = name)
|
||||
setState { copy(isLoggedIn = Uninitialized) }
|
||||
setState { copy(loggedInClient = Uninitialized) }
|
||||
}
|
||||
}
|
||||
|
|
@ -4,14 +4,15 @@ import com.airbnb.mvrx.Async
|
|||
import com.airbnb.mvrx.Loading
|
||||
import com.airbnb.mvrx.MavericksState
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import io.element.android.x.matrix.MatrixClient
|
||||
|
||||
data class LoginViewState(
|
||||
val homeserver: String = "",
|
||||
val isLoggedIn: Async<Unit> = Uninitialized,
|
||||
val loggedInClient: Async<MatrixClient> = Uninitialized,
|
||||
val formState: LoginFormState = LoginFormState.Default,
|
||||
) : MavericksState {
|
||||
val submitEnabled =
|
||||
formState.login.isNotEmpty() && formState.password.isNotEmpty() && isLoggedIn !is Loading
|
||||
formState.login.isNotEmpty() && formState.password.isNotEmpty() && loggedInClient !is Loading
|
||||
}
|
||||
|
||||
data class LoginFormState(
|
||||
|
|
|
|||
|
|
@ -1,14 +1,25 @@
|
|||
package io.element.android.x.features.login.changeserver
|
||||
|
||||
import com.airbnb.mvrx.MavericksViewModel
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import io.element.android.x.matrix.MatrixInstance
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import io.element.android.x.anvilannotations.ContributesViewModel
|
||||
import io.element.android.x.core.di.daggerMavericksViewModelFactory
|
||||
import io.element.android.x.di.AppScope
|
||||
import io.element.android.x.matrix.Matrix
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ChangeServerViewModel(initialState: ChangeServerViewState) :
|
||||
@ContributesViewModel(AppScope::class)
|
||||
class ChangeServerViewModel @AssistedInject constructor(
|
||||
private val matrix: Matrix,
|
||||
@Assisted initialState: ChangeServerViewState
|
||||
) :
|
||||
MavericksViewModel<ChangeServerViewState>(initialState) {
|
||||
|
||||
private val matrix = MatrixInstance.getInstance()
|
||||
companion object :
|
||||
MavericksViewModelFactory<ChangeServerViewModel, ChangeServerViewState> by daggerMavericksViewModelFactory()
|
||||
|
||||
init {
|
||||
setState {
|
||||
|
|
@ -32,7 +43,7 @@ class ChangeServerViewModel(initialState: ChangeServerViewState) :
|
|||
suspend {
|
||||
val state = awaitState()
|
||||
matrix.setHomeserver(state.homeserver)
|
||||
}.execute { it ->
|
||||
}.execute {
|
||||
copy(changeServerAction = it)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import io.element.android.x.core.di.daggerMavericksViewModelFactory
|
|||
import io.element.android.x.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.x.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.x.di.AppScope
|
||||
import io.element.android.x.di.SessionScope
|
||||
import io.element.android.x.features.messages.model.MessagesItemAction
|
||||
import io.element.android.x.features.messages.model.MessagesItemActionsSheetState
|
||||
import io.element.android.x.features.messages.model.MessagesTimelineItemState
|
||||
|
|
@ -17,6 +18,7 @@ import io.element.android.x.features.messages.model.MessagesViewState
|
|||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemRedactedContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemTextBasedContent
|
||||
import io.element.android.x.matrix.Matrix
|
||||
import io.element.android.x.matrix.MatrixClient
|
||||
import io.element.android.x.matrix.media.MediaResolver
|
||||
import io.element.android.x.matrix.timeline.MatrixTimeline
|
||||
import io.element.android.x.matrix.timeline.MatrixTimelineItem
|
||||
|
|
@ -28,16 +30,15 @@ import kotlinx.coroutines.launch
|
|||
|
||||
private const val PAGINATION_COUNT = 50
|
||||
|
||||
@ContributesViewModel(AppScope::class)
|
||||
@ContributesViewModel(SessionScope::class)
|
||||
class MessagesViewModel @AssistedInject constructor(
|
||||
matrix: Matrix,
|
||||
private val client: MatrixClient,
|
||||
@Assisted private val initialState: MessagesViewState
|
||||
) :
|
||||
MavericksViewModel<MessagesViewState>(initialState) {
|
||||
|
||||
companion object : MavericksViewModelFactory<MessagesViewModel, MessagesViewState> by daggerMavericksViewModelFactory()
|
||||
|
||||
private val client = matrix.activeClient()
|
||||
private val room = client.getRoom(initialState.roomId)!!
|
||||
private val messageTimelineItemStateFactory =
|
||||
MessageTimelineItemStateFactory(client, room, Dispatchers.Default)
|
||||
|
|
|
|||
|
|
@ -7,20 +7,18 @@ import dagger.assisted.AssistedInject
|
|||
import io.element.android.x.anvilannotations.ContributesViewModel
|
||||
import io.element.android.x.core.data.StableCharSequence
|
||||
import io.element.android.x.core.di.daggerMavericksViewModelFactory
|
||||
import io.element.android.x.di.AppScope
|
||||
import io.element.android.x.matrix.Matrix
|
||||
import io.element.android.x.di.SessionScope
|
||||
import io.element.android.x.matrix.MatrixClient
|
||||
|
||||
@ContributesViewModel(AppScope::class)
|
||||
@ContributesViewModel(SessionScope::class)
|
||||
class MessageComposerViewModel @AssistedInject constructor(
|
||||
private val matrix: Matrix,
|
||||
private val client: MatrixClient,
|
||||
@Assisted private val initialState: MessageComposerViewState
|
||||
) : MavericksViewModel<MessageComposerViewState>(initialState) {
|
||||
|
||||
companion object :
|
||||
MavericksViewModelFactory<MessageComposerViewModel, MessageComposerViewState> by daggerMavericksViewModelFactory()
|
||||
|
||||
private val client = matrix.activeClient()
|
||||
|
||||
fun onComposerFullScreenChange() {
|
||||
setState {
|
||||
copy(
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ import io.element.android.x.core.di.daggerMavericksViewModelFactory
|
|||
import io.element.android.x.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.x.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.x.di.AppScope
|
||||
import io.element.android.x.di.SessionScope
|
||||
import io.element.android.x.features.roomlist.model.MatrixUser
|
||||
import io.element.android.x.features.roomlist.model.RoomListRoomSummary
|
||||
import io.element.android.x.features.roomlist.model.RoomListRoomSummaryPlaceholders
|
||||
import io.element.android.x.features.roomlist.model.RoomListViewState
|
||||
import io.element.android.x.matrix.Matrix
|
||||
import io.element.android.x.matrix.MatrixClient
|
||||
import io.element.android.x.matrix.MatrixInstance
|
||||
import io.element.android.x.matrix.media.MediaResolver
|
||||
import io.element.android.x.matrix.room.RoomSummary
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -28,9 +28,9 @@ import kotlinx.coroutines.launch
|
|||
|
||||
private const val extendedRangeSize = 40
|
||||
|
||||
@ContributesViewModel(AppScope::class)
|
||||
@ContributesViewModel(SessionScope::class)
|
||||
class RoomListViewModel @AssistedInject constructor(
|
||||
matrix: Matrix,
|
||||
private val client: MatrixClient,
|
||||
@Assisted initialState: RoomListViewState
|
||||
) :
|
||||
MavericksViewModel<RoomListViewState>(initialState) {
|
||||
|
|
@ -38,7 +38,6 @@ class RoomListViewModel @AssistedInject constructor(
|
|||
companion object : MavericksViewModelFactory<RoomListViewModel, RoomListViewState> by daggerMavericksViewModelFactory()
|
||||
|
||||
private val lastMessageFormatter = LastMessageFormatter()
|
||||
private val client = matrix.activeClient()
|
||||
|
||||
init {
|
||||
handleInit()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue