Login: try to fix some stuff around login/logout..

This commit is contained in:
ganfra
2022-11-22 12:04:01 +01:00
parent 8f03957c23
commit 0cbf4bf328
5 changed files with 66 additions and 23 deletions

View File

@@ -4,17 +4,18 @@ package io.element.android.x.features.login
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.*
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.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -24,6 +25,7 @@ import com.airbnb.mvrx.Loading
import com.airbnb.mvrx.Success
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel
import io.element.android.x.core.compose.textFieldState
import io.element.android.x.designsystem.ElementXTheme
import timber.log.Timber
@@ -59,6 +61,8 @@ fun LoginContent(
onSubmitClicked: () -> Unit = {},
onLoginWithSuccess: () -> Unit = {},
) {
var login by textFieldState(state.login)
var password by textFieldState(state.password)
Surface(color = MaterialTheme.colorScheme.background) {
Box(
modifier = Modifier
@@ -113,31 +117,42 @@ fun LoginContent(
)
}
OutlinedTextField(
value = state.login,
value = login,
modifier = Modifier
.fillMaxWidth()
.padding(top = 60.dp),
label = {
Text(text = "Email or username")
},
onValueChange = onLoginChanged,
onValueChange = {
login = it
onLoginChanged(it)
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Next
),
)
OutlinedTextField(
value = state.password,
value = password,
modifier = Modifier
.fillMaxWidth()
.padding(top = 24.dp),
onValueChange = onPasswordChanged,
onValueChange = {
password = it
onPasswordChanged(it)
},
label = {
Text(text = "Password")
},
isError = isError,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Send,
imeAction = ImeAction.Done,
),
visualTransformation = PasswordVisualTransformation(),
keyboardActions = KeyboardActions(
onDone = { onSubmitClicked() }
),
)
if (isError) {

View File

@@ -1,6 +1,7 @@
package io.element.android.x.features.login
import com.airbnb.mvrx.Loading
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import com.airbnb.mvrx.MavericksViewModel
import com.airbnb.mvrx.Uninitialized
import io.element.android.x.matrix.MatrixInstance
@@ -20,18 +21,15 @@ class LoginViewModel(initialState: LoginViewState) :
}
}
fun onSubmit() = withState { state ->
setState {
copy(isLoggedIn = Loading())
}
fun onSubmit() {
viewModelScope.launch {
suspend {
val state = awaitState()
// Ensure the server is provided to the Rust SDK
if (matrix.getHomeserver() == null) {
matrix.setHomeserver(state.homeserver)
}
matrix.login(state.login, state.password)
matrix.login(state.login.trim(), state.password.trim())
matrix.activeClient().startSync()
}.execute {
copy(isLoggedIn = it)

View File

@@ -0,0 +1,11 @@
package io.element.android.x.core.compose
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@Composable
public fun textFieldState(stateValue: String): MutableState<String> =
remember(stateValue) { mutableStateOf(stateValue) }

View File

@@ -12,6 +12,7 @@ import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.AuthenticationService
import org.matrix.rustcomponents.sdk.Client
import org.matrix.rustcomponents.sdk.ClientBuilder
import timber.log.Timber
import java.io.File
import java.util.*
import java.util.concurrent.Executors
@@ -26,10 +27,10 @@ class Matrix(
main = Dispatchers.Main,
diffUpdateDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()
)
private val baseFolder = File(context.filesDir, "matrix")
private val baseDirectory = File(context.filesDir, "sessions")
private val sessionStore = SessionStore(context)
private val matrixClient = MutableStateFlow<Optional<MatrixClient>>(Optional.empty())
private val authService = AuthenticationService(baseFolder.absolutePath)
private val authService = AuthenticationService(baseDirectory.absolutePath)
init {
sessionStore.isLoggedIn()
@@ -59,7 +60,7 @@ class Matrix(
?.let { session ->
try {
ClientBuilder()
.basePath(baseFolder.absolutePath)
.basePath(baseDirectory.absolutePath)
.username(session.userId)
.build().apply {
restoreSession(session)
@@ -85,7 +86,12 @@ class Matrix(
suspend fun login(username: String, password: String): MatrixClient =
withContext(coroutineDispatchers.io) {
val client = authService.login(username, password, "MatrixRustSDKSample", null)
val client = try {
authService.login(username, password, "ElementX", null)
}catch (failure:Throwable){
Timber.e(failure,"Fail login")
throw failure
}
sessionStore.storeData(client.session())
createMatrixClient(client)
}
@@ -95,7 +101,8 @@ class Matrix(
client = client,
sessionStore = sessionStore,
coroutineScope = coroutineScope,
dispatchers = coroutineDispatchers
dispatchers = coroutineDispatchers,
baseDirectory = baseDirectory,
).also {
matrixClient.value = Optional.of(it)
}

View File

@@ -14,6 +14,7 @@ import kotlinx.coroutines.withContext
import org.matrix.rustcomponents.sdk.*
import timber.log.Timber
import java.io.Closeable
import java.io.File
import java.util.concurrent.atomic.AtomicBoolean
class MatrixClient internal constructor(
@@ -21,6 +22,7 @@ class MatrixClient internal constructor(
private val sessionStore: SessionStore,
private val coroutineScope: CoroutineScope,
private val dispatchers: CoroutineDispatchers,
private val baseDirectory: File,
) : Closeable {
private val clientDelegate = object : ClientDelegate {
@@ -114,7 +116,12 @@ class MatrixClient internal constructor(
suspend fun logout() = withContext(dispatchers.io) {
close()
client.logout()
try {
client.logout()
} catch (failure: Throwable) {
Timber.e(failure, "Fail to call logout on HS. Still delete local files.")
}
baseDirectory.deleteSessionDirectory(userID = client.userId())
sessionStore.reset()
}
@@ -150,5 +157,10 @@ class MatrixClient internal constructor(
}
}
private fun File.deleteSessionDirectory(userID: String): Boolean {
// Rust sanitises the user ID replacing invalid characters with an _
val sanitisedUserID = userID.replace(":", "_")
val sessionDirectory = File(this, sanitisedUserID)
return sessionDirectory.deleteRecursively()
}
}