diff --git a/app/src/main/java/io/element/android/x/MainActivity.kt b/app/src/main/java/io/element/android/x/MainActivity.kt index d9097dca77..0ad2576d26 100644 --- a/app/src/main/java/io/element/android/x/MainActivity.kt +++ b/app/src/main/java/io/element/android/x/MainActivity.kt @@ -4,8 +4,11 @@ import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.result.contract.ActivityResultContracts +import androidx.activity.viewModels +import androidx.lifecycle.lifecycleScope import io.element.android.x.ui.screen.login.LoginActivity import io.element.android.x.ui.screen.login.RoomListActivity +import kotlinx.coroutines.launch class MainActivity : ComponentActivity() { private val launcher = @@ -18,11 +21,17 @@ class MainActivity : ComponentActivity() { } } + private val viewModel: MainViewModel by viewModels() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - // Just start the LoginActivity for now. - // TODO if a session exist, start the room list - launcher.launch(Intent(this, LoginActivity::class.java)) + lifecycleScope.launch { + if (viewModel.hasSession()) { + startRoomActivityAndFinish() + } else { + launcher.launch(Intent(this@MainActivity, LoginActivity::class.java)) + } + } } private fun startRoomActivityAndFinish() { diff --git a/app/src/main/java/io/element/android/x/MainViewModel.kt b/app/src/main/java/io/element/android/x/MainViewModel.kt new file mode 100644 index 0000000000..7474901daa --- /dev/null +++ b/app/src/main/java/io/element/android/x/MainViewModel.kt @@ -0,0 +1,12 @@ +package io.element.android.x + +import androidx.lifecycle.ViewModel +import io.element.android.x.sdk.matrix.MatrixInstance + +class MainViewModel : ViewModel() { + private val matrix = MatrixInstance.getInstance() + + suspend fun hasSession(): Boolean { + return matrix.restoreSession() != null + } +} \ No newline at end of file diff --git a/libraries/sdk/matrix/build.gradle b/libraries/sdk/matrix/build.gradle index 1744df8994..0e463642ac 100644 --- a/libraries/sdk/matrix/build.gradle +++ b/libraries/sdk/matrix/build.gradle @@ -30,4 +30,6 @@ android { dependencies { implementation(name: 'matrix-rust-sdk', ext: 'aar') implementation "net.java.dev.jna:jna:5.10.0@aar" + implementation 'androidx.datastore:datastore-core:1.0.0' + implementation 'androidx.datastore:datastore-preferences:1.0.0' } \ No newline at end of file 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 3dde7675bb..606f51049a 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,18 +1,35 @@ package io.element.android.x.sdk.matrix import android.content.Context +import io.element.android.x.sdk.matrix.store.SessionStore import org.matrix.rustcomponents.sdk.AuthenticationService +import org.matrix.rustcomponents.sdk.ClientBuilder import java.io.File class Matrix( context: Context, ) { private val authFolder = File(context.filesDir, "auth") + private val sessionStore = SessionStore(context) - fun login(homeserver: String, username: String, password: String): MatrixClient { + suspend fun restoreSession(): MatrixClient? { + return sessionStore.getStoredData() + ?.let { sessionData -> + val client = ClientBuilder() + .username(sessionData.userId) + .build() + client.restoreLogin(sessionData.restoreToken) + client + }?.let { + MatrixClient(it) + } + } + + suspend fun login(homeserver: String, username: String, password: String): MatrixClient { val authService = AuthenticationService(authFolder.absolutePath) authService.configureHomeserver(homeserver) val client = authService.login(username, password, "MatrixRustSDKSample", null) + sessionStore.storeData(SessionStore.SessionData(username, client.restoreToken())) return MatrixClient(client) } } \ No newline at end of file diff --git a/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/store/SessionStore.kt b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/store/SessionStore.kt new file mode 100644 index 0000000000..414e8e94ca --- /dev/null +++ b/libraries/sdk/matrix/src/main/java/io/element/android/x/sdk/matrix/store/SessionStore.kt @@ -0,0 +1,48 @@ +package io.element.android.x.sdk.matrix.store + +import android.content.Context +import androidx.datastore.core.DataStore +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.firstOrNull + + +private val Context.dataStore: DataStore by preferencesDataStore(name = "elementx_sessions") + +internal class SessionStore( + context: Context +) { + data class SessionData( + val userId: String, + val restoreToken: String, + ) + + private val store = context.dataStore + + private val userIdPreference = stringPreferencesKey("userId") + private val restoreTokenPreference = stringPreferencesKey("restoreToken") + + suspend fun storeData(sessionData: SessionData) { + store.edit { prefs -> + prefs[userIdPreference] = sessionData.userId + prefs[restoreTokenPreference] = sessionData.restoreToken + } + } + + suspend fun getStoredData(): SessionData? { + return store.data.firstOrNull()?.let { prefs -> + val userId = prefs[userIdPreference] ?: return@let null + val restoreToken = prefs[restoreTokenPreference] ?: return@let null + SessionData( + userId = userId, + restoreToken = restoreToken, + ) + } + } + + suspend fun reset() { + store.edit { it.clear() } + } +} \ No newline at end of file