Benoit Marty
2 years ago
14 changed files with 131 additions and 34 deletions
@ -0,0 +1,12 @@ |
|||||||
|
package io.element.android.x |
||||||
|
|
||||||
|
import android.app.Application |
||||||
|
import io.element.android.x.sdk.matrix.MatrixInstance |
||||||
|
|
||||||
|
class ElementXApplication : Application() { |
||||||
|
|
||||||
|
override fun onCreate() { |
||||||
|
super.onCreate() |
||||||
|
MatrixInstance.init(this) |
||||||
|
} |
||||||
|
} |
@ -1,2 +1,6 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?> |
<?xml version="1.0" encoding="utf-8"?> |
||||||
<manifest /> |
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" /> |
||||||
|
|
||||||
|
</manifest> |
||||||
|
@ -0,0 +1,3 @@ |
|||||||
|
package io.element.android.x.sdk.matrix |
||||||
|
|
||||||
|
internal const val LOG_TAG = "Matrix" |
@ -1,40 +1,18 @@ |
|||||||
package io.element.android.x.sdk.matrix |
package io.element.android.x.sdk.matrix |
||||||
|
|
||||||
import android.content.Context |
import android.content.Context |
||||||
import android.util.Log |
import uniffi.matrix_sdk_ffi.AuthenticationService |
||||||
import java.io.File |
import java.io.File |
||||||
|
|
||||||
private const val LOG_TAG = "Matrix" |
|
||||||
|
|
||||||
class Matrix( |
class Matrix( |
||||||
private val context: Context, |
context: Context, |
||||||
) { |
) { |
||||||
fun login(username: String, password: String) { |
private val authFolder = File(context.filesDir, "auth") |
||||||
val authFolder = File(context.filesDir, "auth") |
|
||||||
|
fun login(homeserver: String, username: String, password: String): MatrixClient { |
||||||
val authService = AuthenticationService(authFolder.absolutePath) |
val authService = AuthenticationService(authFolder.absolutePath) |
||||||
authService.configureHomeserver("matrix.org") |
authService.configureHomeserver(homeserver) |
||||||
val client = authService.login(username, password, "MatrixRustSDKSample", null) |
val client = authService.login(username, password, "MatrixRustSDKSample", null) |
||||||
val clientDelegate = object : ClientDelegate { |
return MatrixClient(client) |
||||||
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() |
|
||||||
} |
} |
||||||
} |
} |
@ -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() |
||||||
|
} |
||||||
|
} |
@ -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 |
||||||
|
} |
||||||
|
} |
@ -1,37 +1,72 @@ |
|||||||
package io.element.android.x.ui.screen.login |
package io.element.android.x.ui.screen.login |
||||||
|
|
||||||
|
import android.util.Log |
||||||
import androidx.lifecycle.ViewModel |
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.MutableStateFlow |
||||||
import kotlinx.coroutines.flow.asStateFlow |
import kotlinx.coroutines.flow.asStateFlow |
||||||
|
import kotlinx.coroutines.launch |
||||||
|
|
||||||
class LoginViewModel : ViewModel() { |
class LoginViewModel : ViewModel() { |
||||||
|
|
||||||
|
private val matrix = MatrixInstance.getInstance() |
||||||
|
|
||||||
private val _state = MutableStateFlow(LoginViewState()) |
private val _state = MutableStateFlow(LoginViewState()) |
||||||
val state = _state.asStateFlow() |
val state = _state.asStateFlow() |
||||||
|
|
||||||
|
init { |
||||||
|
observeState() |
||||||
|
} |
||||||
|
|
||||||
|
private fun observeState() { |
||||||
|
// TODO Update submitEnabled when other state members are updated. |
||||||
|
} |
||||||
|
|
||||||
fun handle(action: LoginActions) { |
fun handle(action: LoginActions) { |
||||||
when (action) { |
when (action) { |
||||||
|
is LoginActions.SetHomeserver -> handleSetHomeserver(action) |
||||||
is LoginActions.SetLogin -> handleSetName(action) |
is LoginActions.SetLogin -> handleSetName(action) |
||||||
is LoginActions.SetPassword -> handleSetPassword(action) |
is LoginActions.SetPassword -> handleSetPassword(action) |
||||||
LoginActions.Submit -> handleSubmit() |
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() { |
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) { |
private fun handleSetPassword(action: LoginActions.SetPassword) { |
||||||
_state.value = _state.value.copy( |
_state.value = _state.value.copy( |
||||||
password = action.password, |
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) { |
private fun handleSetName(action: LoginActions.SetLogin) { |
||||||
_state.value = _state.value.copy( |
_state.value = _state.value.copy( |
||||||
login = action.login, |
login = action.login, |
||||||
submitEnabled = action.login.isNotEmpty() && _state.value.password.isNotEmpty() |
submitEnabled = action.login.isNotEmpty() && |
||||||
|
_state.value.homeserver.isNotEmpty() && |
||||||
|
_state.value.password.isNotEmpty() |
||||||
) |
) |
||||||
} |
} |
||||||
} |
} |
Loading…
Reference in new issue