Fix bunch of issues around login/logout and introduces messages feature
This commit is contained in:
parent
b5e4ef9637
commit
d04d847521
19 changed files with 314 additions and 89 deletions
|
|
@ -4,15 +4,20 @@ import android.content.Context
|
|||
import io.element.android.x.core.data.CoroutineDispatchers
|
||||
import io.element.android.x.matrix.session.SessionStore
|
||||
import io.element.android.x.matrix.util.logError
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.rustcomponents.sdk.AuthenticationService
|
||||
import org.matrix.rustcomponents.sdk.Client
|
||||
import org.matrix.rustcomponents.sdk.ClientBuilder
|
||||
import java.io.File
|
||||
import java.util.Optional
|
||||
|
||||
class Matrix(
|
||||
coroutineScope: CoroutineScope,
|
||||
context: Context,
|
||||
) {
|
||||
|
||||
private val coroutineDispatchers = CoroutineDispatchers(
|
||||
io = Dispatchers.IO,
|
||||
computation = Dispatchers.Default,
|
||||
|
|
@ -20,9 +25,31 @@ class Matrix(
|
|||
)
|
||||
private val baseFolder = File(context.filesDir, "matrix")
|
||||
private val sessionStore = SessionStore(context)
|
||||
private val matrixClient = MutableStateFlow<Optional<MatrixClient>>(Optional.empty())
|
||||
private val isLoggedIn = MutableStateFlow(false)
|
||||
|
||||
suspend fun restoreSession(): MatrixClient? {
|
||||
return sessionStore.getStoredData()
|
||||
init {
|
||||
sessionStore.isLoggedIn()
|
||||
.distinctUntilChanged()
|
||||
.onEach { isLoggedIn ->
|
||||
this.isLoggedIn.value = isLoggedIn
|
||||
if (!isLoggedIn) {
|
||||
matrixClient.value = Optional.empty()
|
||||
}
|
||||
}
|
||||
.launchIn(coroutineScope)
|
||||
}
|
||||
|
||||
fun isLoggedIn(): Flow<Boolean> {
|
||||
return isLoggedIn
|
||||
}
|
||||
|
||||
fun matrixClient(): Flow<Optional<MatrixClient>> {
|
||||
return matrixClient
|
||||
}
|
||||
|
||||
suspend fun restoreSession() = withContext(coroutineDispatchers.io) {
|
||||
sessionStore.getStoredData()
|
||||
?.let { sessionData ->
|
||||
try {
|
||||
ClientBuilder()
|
||||
|
|
@ -36,15 +63,26 @@ class Matrix(
|
|||
null
|
||||
}
|
||||
}?.let {
|
||||
MatrixClient(it, sessionStore, coroutineDispatchers)
|
||||
createMatrixClient(it)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun login(homeserver: String, username: String, password: String): MatrixClient {
|
||||
val authService = AuthenticationService(baseFolder.absolutePath)
|
||||
authService.configureHomeserver(homeserver)
|
||||
val client = authService.login(username, password, "MatrixRustSDKSample", null)
|
||||
sessionStore.storeData(SessionStore.SessionData(client.userId(), client.restoreToken()))
|
||||
return MatrixClient(client, sessionStore, coroutineDispatchers)
|
||||
suspend fun login(homeserver: String, username: String, password: String): MatrixClient =
|
||||
withContext(coroutineDispatchers.io) {
|
||||
val authService = AuthenticationService(baseFolder.absolutePath)
|
||||
authService.configureHomeserver(homeserver)
|
||||
val client = authService.login(username, password, "MatrixRustSDKSample", null)
|
||||
sessionStore.storeData(SessionStore.SessionData(client.userId(), client.restoreToken()))
|
||||
createMatrixClient(client)
|
||||
}
|
||||
|
||||
private fun createMatrixClient(client: Client): MatrixClient {
|
||||
return MatrixClient(
|
||||
client = client,
|
||||
sessionStore = sessionStore,
|
||||
dispatchers = coroutineDispatchers
|
||||
).also {
|
||||
matrixClient.value = Optional.of(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -61,7 +61,6 @@ class MatrixClient internal constructor(
|
|||
init {
|
||||
client.setDelegate(clientDelegate)
|
||||
}
|
||||
|
||||
fun startSync() {
|
||||
slidingSync.setObserver(slidingSyncObserver)
|
||||
slidingSyncObserverToken = slidingSync.sync()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package io.element.android.x.matrix
|
|||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
|
||||
|
||||
object MatrixInstance {
|
||||
|
|
@ -9,7 +10,7 @@ object MatrixInstance {
|
|||
private lateinit var instance: Matrix
|
||||
|
||||
fun init(context: Context) {
|
||||
instance = Matrix(context)
|
||||
instance = Matrix(GlobalScope, context)
|
||||
}
|
||||
|
||||
fun getInstance(): Matrix {
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@ import androidx.datastore.preferences.core.Preferences
|
|||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "elementx_sessions")
|
||||
private val userIdPreference = stringPreferencesKey("userId")
|
||||
|
||||
// TODO It contains the access token, so it has to be stored in a more secured storage.
|
||||
// I would expect the Rust SDK to provide a more obscure token.
|
||||
private val restoreTokenPreference = stringPreferencesKey("restoreToken")
|
||||
|
|
@ -25,6 +28,11 @@ internal class SessionStore(
|
|||
|
||||
private val store = context.dataStore
|
||||
|
||||
fun isLoggedIn(): Flow<Boolean> {
|
||||
return store.data.map { prefs ->
|
||||
prefs[userIdPreference] != null && prefs[restoreTokenPreference] != null
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun storeData(sessionData: SessionData) {
|
||||
store.edit { prefs ->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue