Browse Source

Login: change server screen WIP

feature/bma/flipper
Benoit Marty 2 years ago
parent
commit
0840602069
  1. 21
      app/src/main/java/io/element/android/x/Navigation.kt
  2. 8
      features/login/src/main/java/io/element/android/x/features/login/LoginActions.kt
  3. 136
      features/login/src/main/java/io/element/android/x/features/login/LoginScreen.kt
  4. 39
      features/login/src/main/java/io/element/android/x/features/login/LoginViewModel.kt
  5. 7
      features/login/src/main/java/io/element/android/x/features/login/LoginViewState.kt
  6. 149
      features/login/src/main/java/io/element/android/x/features/login/changeserver/ChangeServerScreen.kt
  7. 32
      features/login/src/main/java/io/element/android/x/features/login/changeserver/ChangeServerViewModel.kt
  8. 13
      features/login/src/main/java/io/element/android/x/features/login/changeserver/ChangeServerViewState.kt
  9. 5
      features/onboarding/src/main/java/io/element/android/x/features/onboarding/OnBoardingActions.kt
  10. 1
      libraries/core/build.gradle
  11. 26
      libraries/core/src/main/java/io/element/android/x/core/compose/Keyboard.kt
  12. 10
      libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt

21
app/src/main/java/io/element/android/x/Navigation.kt

@ -5,11 +5,9 @@ import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootNavGraph import com.ramcosta.composedestinations.annotation.RootNavGraph
import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import com.ramcosta.composedestinations.navigation.popUpTo import com.ramcosta.composedestinations.navigation.popUpTo
import io.element.android.x.destinations.LoginScreenNavigationDestination import io.element.android.x.destinations.*
import io.element.android.x.destinations.MessagesScreenNavigationDestination
import io.element.android.x.destinations.RoomListScreenNavigationDestination
import io.element.android.x.destinations.OnBoardingScreenNavigationDestination
import io.element.android.x.features.login.LoginScreen import io.element.android.x.features.login.LoginScreen
import io.element.android.x.features.login.changeserver.ChangeServerScreen
import io.element.android.x.features.messages.MessagesScreen import io.element.android.x.features.messages.MessagesScreen
import io.element.android.x.features.onboarding.OnBoardingScreen import io.element.android.x.features.onboarding.OnBoardingScreen
import io.element.android.x.features.roomlist.RoomListScreen import io.element.android.x.features.roomlist.RoomListScreen
@ -32,6 +30,10 @@ fun OnBoardingScreenNavigation(navigator: DestinationsNavigator) {
@Composable @Composable
fun LoginScreenNavigation(navigator: DestinationsNavigator) { fun LoginScreenNavigation(navigator: DestinationsNavigator) {
LoginScreen( LoginScreen(
homeserver = "matrix.org",
onChangeServer = {
navigator.navigate(ChangeServerScreenNavigationDestination)
},
onLoginWithSuccess = { onLoginWithSuccess = {
navigator.navigate(RoomListScreenNavigationDestination) { navigator.navigate(RoomListScreenNavigationDestination) {
popUpTo(OnBoardingScreenNavigationDestination) { popUpTo(OnBoardingScreenNavigationDestination) {
@ -42,6 +44,17 @@ fun LoginScreenNavigation(navigator: DestinationsNavigator) {
) )
} }
// TODO Create a subgraph in Login module
@Destination
@Composable
fun ChangeServerScreenNavigation(navigator: DestinationsNavigator) {
ChangeServerScreen(
onChangeServerSuccess = {
navigator.popBackStack()
}
)
}
@RootNavGraph(start = true) @RootNavGraph(start = true)
@Destination @Destination
@Composable @Composable

8
features/login/src/main/java/io/element/android/x/features/login/LoginActions.kt

@ -1,8 +0,0 @@
package io.element.android.x.features.login
sealed interface LoginActions {
data class SetHomeserver(val homeserver: String) : LoginActions
data class SetLogin(val login: String) : LoginActions
data class SetPassword(val password: String) : LoginActions
object Submit : LoginActions
}

136
features/login/src/main/java/io/element/android/x/features/login/LoginScreen.kt

@ -2,86 +2,126 @@
package io.element.android.x.features.login package io.element.android.x.features.login
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success import com.airbnb.mvrx.Success
import com.airbnb.mvrx.compose.collectAsState import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel import com.airbnb.mvrx.compose.mavericksViewModel
import io.element.android.x.designsystem.components.VectorButton import io.element.android.x.designsystem.ElementXTheme
@Composable @Composable
fun LoginScreen( fun LoginScreen(
viewModel: LoginViewModel = mavericksViewModel(), viewModel: LoginViewModel = mavericksViewModel(),
onLoginWithSuccess: () -> Unit = { } homeserver: String,
onChangeServer: () -> Unit = { },
onLoginWithSuccess: () -> Unit = { },
) { ) {
val state: LoginViewState by viewModel.collectAsState() val state: LoginViewState by viewModel.collectAsState()
LaunchedEffect(key1 = Unit) {
viewModel.homeserver = homeserver
}
LoginContent( LoginContent(
state = state, state = state,
onHomeserverChanged = { viewModel.handle(LoginActions.SetHomeserver(it)) }, homeserver = homeserver,
onLoginChanged = { viewModel.handle(LoginActions.SetLogin(it)) }, onChangeServer = onChangeServer,
onPasswordChanged = { viewModel.handle(LoginActions.SetPassword(it)) }, onLoginChanged = viewModel::onSetName,
onSubmitClicked = { viewModel.handle(LoginActions.Submit) }, onPasswordChanged = viewModel::onSetPassword,
onSubmitClicked = viewModel::onSubmit,
onLoginWithSuccess = onLoginWithSuccess onLoginWithSuccess = onLoginWithSuccess
) )
} }
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun LoginContent( fun LoginContent(
state: LoginViewState, state: LoginViewState,
onHomeserverChanged: (String) -> Unit, homeserver: String = "",
onLoginChanged: (String) -> Unit, onChangeServer: () -> Unit = {},
onPasswordChanged: (String) -> Unit, onLoginChanged: (String) -> Unit = {},
onSubmitClicked: () -> Unit, onPasswordChanged: (String) -> Unit = {},
onLoginWithSuccess: () -> Unit onSubmitClicked: () -> Unit = {},
onLoginWithSuccess: () -> Unit = {},
) { ) {
Surface(color = MaterialTheme.colorScheme.background) { Surface(color = MaterialTheme.colorScheme.background) {
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(16.dp)
) { ) {
val scrollState = rememberScrollState()
Column( Column(
modifier = Modifier.fillMaxSize(), modifier = Modifier
.verticalScroll(
state = scrollState,
)
.padding(horizontal = 16.dp),
) { ) {
val isError = state.isLoggedIn is Fail val isError = state.isLoggedIn is Fail
Image( // Title
painterResource(id = R.drawable.element_logo_green), Text(
contentDescription = null, text = "Welcome back",
modifier = Modifier modifier = Modifier
.align(Alignment.CenterHorizontally) .fillMaxWidth()
.padding(40.dp) .padding(horizontal = 16.dp, vertical = 48.dp),
textAlign = TextAlign.Center,
fontWeight = FontWeight.Bold,
fontSize = 24.sp,
) )
// Form
Column(
//modifier = Modifier.weight(1f),
) {
Box(
modifier = Modifier.fillMaxWidth()
) {
OutlinedTextField( OutlinedTextField(
value = state.homeserver, value = homeserver,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
onValueChange = { onValueChange = { /* no op */ },
onHomeserverChanged(it) enabled = false,
label = {
Text(text = "Server")
}, },
keyboardOptions = KeyboardOptions( keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Uri, keyboardType = KeyboardType.Uri,
), ),
) )
Button(
onClick = onChangeServer,
modifier = Modifier
.align(Alignment.CenterEnd)
.padding(top = 8.dp, end = 8.dp),
content = {
Text(text = "Change")
}
)
}
OutlinedTextField( OutlinedTextField(
value = state.login, value = state.login,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 8.dp), .padding(top = 60.dp),
onValueChange = { label = {
onLoginChanged(it) Text(text = "Email or username")
}, },
onValueChange = onLoginChanged,
keyboardOptions = KeyboardOptions( keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text, keyboardType = KeyboardType.Text,
), ),
@ -90,9 +130,10 @@ fun LoginContent(
value = state.password, value = state.password,
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(top = 8.dp), .padding(top = 24.dp),
onValueChange = { onValueChange = onPasswordChanged,
onPasswordChanged(it) label = {
Text(text = "Password")
}, },
isError = isError, isError = isError,
keyboardOptions = KeyboardOptions( keyboardOptions = KeyboardOptions(
@ -108,26 +149,37 @@ fun LoginContent(
modifier = Modifier.padding(start = 16.dp) modifier = Modifier.padding(start = 16.dp)
) )
} }
VectorButton( }
text = "Submit", // Submit
onClick = { Button(
onSubmitClicked() onClick = onSubmitClicked,
},
enabled = state.submitEnabled, enabled = state.submitEnabled,
modifier = Modifier modifier = Modifier
.align(Alignment.End) .fillMaxWidth()
.padding(top = 16.dp) .padding(vertical = 32.dp)
) ) {
if (state.isLoggedIn is Loading) { Text(text = "Continue")
// FIXME This does not work, we never enter this if block
CircularProgressIndicator(
modifier = Modifier.align(Alignment.CenterHorizontally)
)
} }
if (state.isLoggedIn is Success) { if (state.isLoggedIn is Success) {
onLoginWithSuccess() onLoginWithSuccess()
} }
} }
if (state.isLoggedIn is Loading) {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.Center)
)
} }
} }
}
}
@Composable
@Preview
private fun LoginContentPreview() {
ElementXTheme(darkTheme = false) {
LoginContent(
state = LoginViewState(),
homeserver = "matrix.org",
)
}
} }

39
features/login/src/main/java/io/element/android/x/features/login/LoginViewModel.kt

@ -1,27 +1,28 @@
package io.element.android.x.features.login package io.element.android.x.features.login
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksViewModel import com.airbnb.mvrx.MavericksViewModel
import com.airbnb.mvrx.Uninitialized
import io.element.android.x.matrix.MatrixInstance import io.element.android.x.matrix.MatrixInstance
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
class LoginViewModel(initialState: LoginViewState) : class LoginViewModel(initialState: LoginViewState) :
MavericksViewModel<LoginViewState>(initialState) { MavericksViewModel<LoginViewState>(initialState) {
lateinit var homeserver: String
private val matrix = MatrixInstance.getInstance() private val matrix = MatrixInstance.getInstance()
fun handle(action: LoginActions) { fun onSubmit() = withState { state ->
when (action) { setState {
is LoginActions.SetHomeserver -> handleSetHomeserver(action) copy(isLoggedIn = Loading())
is LoginActions.SetLogin -> handleSetName(action)
is LoginActions.SetPassword -> handleSetPassword(action)
LoginActions.Submit -> handleSubmit()
}
} }
private fun handleSubmit() = withState { state ->
viewModelScope.launch { viewModelScope.launch {
suspend { suspend {
matrix.login(state.homeserver, state.login, state.password) // Ensure the server is passed to the Rust SDK
matrix.setHomeserver(homeserver)
matrix.login(state.login, state.password)
matrix.activeClient().startSync() matrix.activeClient().startSync()
}.execute { }.execute {
copy(isLoggedIn = it) copy(isLoggedIn = it)
@ -29,15 +30,21 @@ class LoginViewModel(initialState: LoginViewState) :
} }
} }
private fun handleSetHomeserver(action: LoginActions.SetHomeserver) { fun onSetPassword(password: String) {
setState { copy(homeserver = action.homeserver) } setState {
copy(
password = password,
isLoggedIn = Uninitialized,
)
} }
private fun handleSetPassword(action: LoginActions.SetPassword) {
setState { copy(password = action.password) }
} }
private fun handleSetName(action: LoginActions.SetLogin) { fun onSetName(name: String) {
setState { copy(login = action.login) } setState {
copy(
login = name,
isLoggedIn = Uninitialized,
)
}
} }
} }

7
features/login/src/main/java/io/element/android/x/features/login/LoginViewState.kt

@ -1,17 +1,14 @@
package io.element.android.x.features.login package io.element.android.x.features.login
import com.airbnb.mvrx.Async import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.Uninitialized import com.airbnb.mvrx.Uninitialized
data class LoginViewState( data class LoginViewState(
val homeserver: String = "matrix.org",
val login: String = "", val login: String = "",
val password: String = "", val password: String = "",
val isLoggedIn: Async<Unit> = Uninitialized, val isLoggedIn: Async<Unit> = Uninitialized,
) : MavericksState { ) : MavericksState {
val submitEnabled = login.isNotEmpty() && password.isNotEmpty() && isLoggedIn !is Loading
val submitEnabled = homeserver.isNotEmpty() && login.isNotEmpty() && password.isNotEmpty()
} }

149
features/login/src/main/java/io/element/android/x/features/login/changeserver/ChangeServerScreen.kt

@ -0,0 +1,149 @@
@file:OptIn(ExperimentalMaterial3Api::class)
package io.element.android.x.features.login.changeserver
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.airbnb.mvrx.Fail
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel
@Composable
fun ChangeServerScreen(
viewModel: ChangeServerViewModel = mavericksViewModel(),
onChangeServerSuccess: () -> Unit = { }
) {
val state: ChangeServerViewState by viewModel.collectAsState()
ChangeServerContent(
state = state,
onChangeServer = viewModel::setServer,
onChangeServerSubmit = viewModel::setServerSubmit,
onChangeServerSuccess = onChangeServerSuccess
)
}
@Composable
fun ChangeServerContent(
state: ChangeServerViewState,
onChangeServer: (String) -> Unit = {},
onChangeServerSubmit: () -> Unit = {},
onChangeServerSuccess: () -> Unit = {},
) {
Surface(color = MaterialTheme.colorScheme.background) {
Box(modifier = Modifier.fillMaxSize()) {
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.verticalScroll(
state = scrollState,
)
.padding(horizontal = 16.dp),
)
{
val isError = state.changeServerAction is Fail
Text(
modifier = Modifier
.padding(top = 99.dp)
.size(width = 81.dp, height = 73.dp)
.align(Alignment.CenterHorizontally)
.background(
color = MaterialTheme.colorScheme.surfaceVariant,
shape = RoundedCornerShape(32.dp)
),
text = "\uDBC2\uDEAC",
fontSize = 34.sp,
textAlign = TextAlign.Center,
)
Text(
text = "Your server",
modifier = Modifier
.fillMaxWidth()
.defaultMinSize(minHeight = 56.dp)
.align(Alignment.CenterHorizontally)
.padding(top = 38.dp),
textAlign = TextAlign.Center,
fontWeight = FontWeight.Bold,
fontSize = 24.sp,
)
Text(
text = "A server is a home for all your data.\n" +
"You choose your server and it’s easy to make one.", // TODO "Learn more.",
modifier = Modifier
.fillMaxWidth()
.align(Alignment.CenterHorizontally)
.padding(top = 16.dp),
textAlign = TextAlign.Center,
fontSize = 16.sp,
color = MaterialTheme.colorScheme.secondary
)
OutlinedTextField(
value = state.homeserver,
modifier = Modifier
.fillMaxWidth()
.padding(top = 200.dp),
onValueChange = onChangeServer,
label = {
Text(text = "Server")
},
isError = isError,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Send,
),
)
if (isError) {
Text(
text = (state.changeServerAction as? Fail)?.toString().orEmpty(),
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(start = 16.dp)
)
}
Button(
onClick = onChangeServerSubmit,
enabled = state.submitEnabled,
modifier = Modifier
.fillMaxWidth()
.padding(top = 44.dp)
) {
Text(text = "Continue")
}
if (state.changeServerAction is Success) {
onChangeServerSuccess()
}
}
if (state.changeServerAction is Loading) {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.Center)
)
}
}
}
}
@Composable
@Preview
private fun ChangeServerContentPreview() {
ChangeServerContent(
state = ChangeServerViewState(homeserver = "matrix.org"),
)
}

32
features/login/src/main/java/io/element/android/x/features/login/changeserver/ChangeServerViewModel.kt

@ -0,0 +1,32 @@
package io.element.android.x.features.login.changeserver
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksViewModel
import io.element.android.x.matrix.MatrixInstance
import kotlinx.coroutines.launch
class ChangeServerViewModel(initialState: ChangeServerViewState) :
MavericksViewModel<ChangeServerViewState>(initialState) {
private val matrix = MatrixInstance.getInstance()
fun setServer(server: String) {
setState {
copy(homeserver = server)
}
}
fun setServerSubmit() = withState { state ->
setState {
copy(changeServerAction = Loading())
}
viewModelScope.launch {
suspend {
matrix.setHomeserver(state.homeserver)
}.execute { it ->
copy(changeServerAction = it)
}
}
}
}

13
features/login/src/main/java/io/element/android/x/features/login/changeserver/ChangeServerViewState.kt

@ -0,0 +1,13 @@
package io.element.android.x.features.login.changeserver
import com.airbnb.mvrx.Async
import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.MavericksState
import com.airbnb.mvrx.Uninitialized
data class ChangeServerViewState(
val homeserver: String = "matrix.org",
val changeServerAction: Async<Unit> = Uninitialized,
) : MavericksState {
val submitEnabled = homeserver.isNotEmpty() && changeServerAction !is Loading
}

5
features/onboarding/src/main/java/io/element/android/x/features/onboarding/OnBoardingActions.kt

@ -1,5 +0,0 @@
package io.element.android.x.features.onboarding
sealed interface OnBoardingActions {
data class GoToPage(val page: Int) : OnBoardingActions
}

1
libraries/core/build.gradle

@ -48,4 +48,5 @@ dependencies {
implementation 'androidx.fragment:fragment-ktx:1.5.3' implementation 'androidx.fragment:fragment-ktx:1.5.3'
implementation 'com.airbnb.android:mavericks-compose:3.0.1' implementation 'com.airbnb.android:mavericks-compose:3.0.1'
implementation 'androidx.compose.foundation:foundation-layout:1.3.1'
} }

26
libraries/core/src/main/java/io/element/android/x/core/compose/Keyboard.kt

@ -0,0 +1,26 @@
package io.element.android.x.core.compose
import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.isImeVisible
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
/**
* Inspired from https://stackoverflow.com/questions/68847559/how-can-i-detect-keyboard-opening-and-closing-in-jetpack-compose
*/
enum class Keyboard {
Opened, Closed
}
// Note: it does not work as expected...
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun keyboardAsState(): State<Keyboard> {
val lifecycle = LocalLifecycleOwner.current.lifecycle
val isResumed = lifecycle.currentState == Lifecycle.State.RESUMED
return rememberUpdatedState(if (WindowInsets.isImeVisible && isResumed) Keyboard.Opened else Keyboard.Closed)
}

10
libraries/matrix/src/main/java/io/element/android/x/matrix/Matrix.kt

@ -7,7 +7,6 @@ import io.element.android.x.matrix.util.logError
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.AuthenticationService import org.matrix.rustcomponents.sdk.AuthenticationService
import org.matrix.rustcomponents.sdk.Client import org.matrix.rustcomponents.sdk.Client
@ -27,6 +26,7 @@ class Matrix(
private val baseFolder = File(context.filesDir, "matrix") private val baseFolder = File(context.filesDir, "matrix")
private val sessionStore = SessionStore(context) private val sessionStore = SessionStore(context)
private val matrixClient = MutableStateFlow<Optional<MatrixClient>>(Optional.empty()) private val matrixClient = MutableStateFlow<Optional<MatrixClient>>(Optional.empty())
private val authService = AuthenticationService(baseFolder.absolutePath)
init { init {
sessionStore.isLoggedIn() sessionStore.isLoggedIn()
@ -70,10 +70,14 @@ class Matrix(
} }
} }
suspend fun login(homeserver: String, username: String, password: String): MatrixClient = suspend fun setHomeserver(homeserver: String) {
withContext(coroutineDispatchers.io) { withContext(coroutineDispatchers.io) {
val authService = AuthenticationService(baseFolder.absolutePath)
authService.configureHomeserver(homeserver) authService.configureHomeserver(homeserver)
}
}
suspend fun login(username: String, password: String): MatrixClient =
withContext(coroutineDispatchers.io) {
val client = authService.login(username, password, "MatrixRustSDKSample", null) val client = authService.login(username, password, "MatrixRustSDKSample", null)
sessionStore.storeData(client.session()) sessionStore.storeData(client.session())
createMatrixClient(client) createMatrixClient(client)

Loading…
Cancel
Save