diff --git a/app/build.gradle b/app/build.gradle index b50f3eb714..d4d4b98158 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -57,6 +57,7 @@ android { dependencies { implementation project(":libraries:ui:theme") implementation project(":libraries:ui:screens:login") + implementation project(":libraries:sdk:matrix") implementation 'androidx.core:core-ktx:1.9.0' implementation "androidx.compose.ui:ui:$compose_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b9e4d22fdd..f36a886878 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools"> - + + + + + diff --git a/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/LogTag.kt b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/LogTag.kt new file mode 100644 index 0000000000..29092e5fa5 --- /dev/null +++ b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/LogTag.kt @@ -0,0 +1,3 @@ +package io.element.android.x.sdk.matrix + +internal const val LOG_TAG = "Matrix" diff --git a/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/Matrix.kt b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/Matrix.kt index 76c488f714..426de60819 100644 --- a/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/Matrix.kt +++ b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/Matrix.kt @@ -1,40 +1,18 @@ package io.element.android.x.sdk.matrix import android.content.Context -import android.util.Log +import uniffi.matrix_sdk_ffi.AuthenticationService import java.io.File -private const val LOG_TAG = "Matrix" - class Matrix( - private val context: Context, + context: Context, ) { - fun login(username: String, password: String) { - val authFolder = File(context.filesDir, "auth") + private val authFolder = File(context.filesDir, "auth") + + fun login(homeserver: String, username: String, password: String): MatrixClient { val authService = AuthenticationService(authFolder.absolutePath) - authService.configureHomeserver("matrix.org") + authService.configureHomeserver(homeserver) val client = authService.login(username, password, "MatrixRustSDKSample", null) - val clientDelegate = object : ClientDelegate { - override fun didReceiveAuthError(isSoftLogout: Boolean) { - Log.v(LOG_TAG, "didReceiveAuthError()") - } - - override fun didReceiveSyncUpdate() { - Log.v(LOG_TAG, "didReceiveSyncUpdate()") - } - - override fun didUpdateRestoreToken() { - Log.v(LOG_TAG, "didUpdateRestoreToken()") - } - } - - client.setDelegate(clientDelegate) - Log.v(LOG_TAG, "DisplayName = ${client.displayName()}") - try { - client.fullSlidingSync() - } catch (failure: Throwable) { - Log.e(LOG_TAG, "fullSlidingSync() fail", failure) - } - client.logout() + return MatrixClient(client) } } \ No newline at end of file diff --git a/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixClient.kt b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixClient.kt new file mode 100644 index 0000000000..0590af7bc1 --- /dev/null +++ b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixClient.kt @@ -0,0 +1,37 @@ +package io.element.android.x.sdk.matrix + +import android.util.Log +import uniffi.matrix_sdk_ffi.Client +import uniffi.matrix_sdk_ffi.ClientDelegate + +class MatrixClient internal constructor( + private val client: Client +) { + fun startSync() { + val clientDelegate = object : ClientDelegate { + override fun didReceiveAuthError(isSoftLogout: Boolean) { + Log.v(LOG_TAG, "didReceiveAuthError()") + } + + override fun didReceiveSyncUpdate() { + Log.v(LOG_TAG, "didReceiveSyncUpdate()") + } + + override fun didUpdateRestoreToken() { + Log.v(LOG_TAG, "didUpdateRestoreToken()") + } + } + + client.setDelegate(clientDelegate) + Log.v(LOG_TAG, "DisplayName = ${client.displayName()}") + try { + client.fullSlidingSync() + } catch (failure: Throwable) { + Log.e(LOG_TAG, "fullSlidingSync() fail", failure) + } + } + + fun logout() { + client.logout() + } +} diff --git a/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixInstance.kt b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixInstance.kt new file mode 100644 index 0000000000..231ae54eb6 --- /dev/null +++ b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/MatrixInstance.kt @@ -0,0 +1,18 @@ +package io.element.android.x.sdk.matrix + +import android.annotation.SuppressLint +import android.content.Context + + +object MatrixInstance { + @SuppressLint("StaticFieldLeak") + private lateinit var instance: Matrix + + fun init(context: Context) { + instance = Matrix(context) + } + + fun getInstance(): Matrix { + return instance + } +} \ No newline at end of file diff --git a/libraries/ui/screens/login/build.gradle b/libraries/ui/screens/login/build.gradle index 3bf2b03084..012c0f8161 100644 --- a/libraries/ui/screens/login/build.gradle +++ b/libraries/ui/screens/login/build.gradle @@ -37,6 +37,7 @@ android { dependencies { implementation project(":libraries:ui:theme") + implementation project(":libraries:sdk:matrix") implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.appcompat:appcompat:1.5.1' diff --git a/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActions.kt b/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActions.kt index 2cd1b76adb..b52e5fde8a 100644 --- a/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActions.kt +++ b/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActions.kt @@ -1,6 +1,7 @@ package io.element.android.x.ui.screen.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 diff --git a/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActivity.kt b/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActivity.kt index 799a1c025c..95c1b84a83 100644 --- a/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActivity.kt +++ b/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginActivity.kt @@ -36,6 +36,11 @@ class LoginActivity : ComponentActivity() { modifier = Modifier.fillMaxSize() ) { val state = viewModel.state.collectAsState().value + VectorTextField( + value = state.homeserver, + onValueChange = { + viewModel.handle(LoginActions.SetHomeserver(it)) + }) VectorTextField( value = state.login, onValueChange = { diff --git a/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginViewModel.kt b/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginViewModel.kt index 565d7d8a38..2a8812e53a 100644 --- a/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginViewModel.kt +++ b/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginViewModel.kt @@ -1,37 +1,72 @@ package io.element.android.x.ui.screen.login +import android.util.Log import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import io.element.android.x.sdk.matrix.MatrixInstance import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch class LoginViewModel : ViewModel() { + private val matrix = MatrixInstance.getInstance() + private val _state = MutableStateFlow(LoginViewState()) val state = _state.asStateFlow() + init { + observeState() + } + + private fun observeState() { + // TODO Update submitEnabled when other state members are updated. + } + fun handle(action: LoginActions) { when (action) { + is LoginActions.SetHomeserver -> handleSetHomeserver(action) is LoginActions.SetLogin -> handleSetName(action) is LoginActions.SetPassword -> handleSetPassword(action) LoginActions.Submit -> handleSubmit() } } + private fun handleSetHomeserver(action: LoginActions.SetHomeserver) { + _state.value = _state.value.copy( + homeserver = action.homeserver, + submitEnabled = _state.value.login.isNotEmpty() && + _state.value.password.isNotEmpty() && + action.homeserver.isNotEmpty() + ) + } + private fun handleSubmit() { - // TODO + viewModelScope.launch { + val currentState = state.value + try { + matrix.login(currentState.homeserver, currentState.login, currentState.password) + } catch (throwable: Throwable) { + Log.e("Error", "Cannot login", throwable) + } + } } private fun handleSetPassword(action: LoginActions.SetPassword) { _state.value = _state.value.copy( password = action.password, - submitEnabled = _state.value.login.isNotEmpty() && action.password.isNotEmpty() + submitEnabled = _state.value.login.isNotEmpty() && + _state.value.homeserver.isNotEmpty() && + action.password.isNotEmpty() ) } private fun handleSetName(action: LoginActions.SetLogin) { _state.value = _state.value.copy( login = action.login, - submitEnabled = action.login.isNotEmpty() && _state.value.password.isNotEmpty() + submitEnabled = action.login.isNotEmpty() && + _state.value.homeserver.isNotEmpty() && + _state.value.password.isNotEmpty() ) } } \ No newline at end of file diff --git a/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginViewState.kt b/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginViewState.kt index c0ccc5f86c..406fc55751 100644 --- a/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginViewState.kt +++ b/libraries/ui/screens/login/src/main/java/io/element/android/x/ui/screen/login/LoginViewState.kt @@ -1,6 +1,7 @@ package io.element.android.x.ui.screen.login data class LoginViewState( + val homeserver: String = "matrix.org", val login: String = "", val password: String = "", val submitEnabled: Boolean = false, diff --git a/settings.gradle b/settings.gradle index 89568ceeb8..55bf47e307 100644 --- a/settings.gradle +++ b/settings.gradle @@ -11,7 +11,7 @@ dependencyResolutionManagement { google() mavenCentral() flatDir { - dirs 'libs' + dirs 'libraries/sdk/matrix/libs' } } }