diff --git a/android/Omnivore/app/build.gradle b/android/Omnivore/app/build.gradle index e63b5e4f5..a8e4021ae 100644 --- a/android/Omnivore/app/build.gradle +++ b/android/Omnivore/app/build.gradle @@ -71,6 +71,7 @@ dependencies { implementation("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version") // LiveData implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version") + implementation("androidx.compose.runtime:runtime-livedata:1.2.1") // Saved state module for ViewModel implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version") diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/DatastoreRepository.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/DatastoreRepository.kt index 77fa5ec96..9ed4c5221 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/DatastoreRepository.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/DatastoreRepository.kt @@ -2,12 +2,15 @@ package app.omnivore.omnivore 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.intPreferencesKey -import androidx.datastore.preferences.core.stringPreferencesKey +import androidx.datastore.dataStore +import androidx.datastore.preferences.core.* import androidx.datastore.preferences.preferencesDataStore +import androidx.lifecycle.asLiveData +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map +import java.io.IOException import javax.inject.Inject private val Context.dataStore: DataStore by preferencesDataStore( @@ -15,6 +18,7 @@ private val Context.dataStore: DataStore by preferencesDataStore( ) interface DatastoreRepository { + val hasAuthTokenFlow: Flow suspend fun putString(key: String, value: String) suspend fun putInt(key: String, value: Int) suspend fun getString(key: String): String? @@ -49,4 +53,11 @@ class OmnivoreDatastore @Inject constructor( val preferences = context.dataStore.data.first() return preferences[preferencesKey] } + + override val hasAuthTokenFlow: Flow = context + .dataStore.data.map { preferences -> + val key = stringPreferencesKey(DatastoreKeys.omnivoreAuthToken) + val token = preferences[key] + token != null + } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/LoginViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/LoginViewModel.kt index be10d9920..e11d89e0d 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/LoginViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/LoginViewModel.kt @@ -2,9 +2,12 @@ package app.omnivore.omnivore import android.content.ContentValues import android.util.Log -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.lifecycle.* import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.launch import javax.inject.Inject @@ -12,6 +15,11 @@ import javax.inject.Inject class LoginViewModel @Inject constructor( private val datastoreRepo: DatastoreRepository ): ViewModel() { + val hasAuthTokenLiveData: LiveData = datastoreRepo + .hasAuthTokenFlow + .distinctUntilChanged() + .asLiveData() + fun login(email: String, password: String) { val emailLogin = RetrofitHelper.getInstance().create(EmailLoginSubmit::class.java) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt index 1502200ff..db3278273 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.unit.dp import app.omnivore.omnivore.ui.theme.OmnivoreTheme import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.setValue import dagger.hilt.android.AndroidEntryPoint @@ -36,13 +37,37 @@ class MainActivity : ComponentActivity() { OmnivoreTheme { // A surface container using the 'background' color from the theme Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) { - LoginView(viewModel) + rootView(viewModel) } } } } } +@Composable +fun rootView(viewModel: LoginViewModel) { + val hasAuthToken: Boolean by viewModel.hasAuthTokenLiveData.observeAsState(false) + + if (hasAuthToken) { + loggedInView() + } else { + LoginView(viewModel) + } +} + +@Composable +fun loggedInView() { + Column( + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .background(MaterialTheme.colors.background) + .fillMaxSize() + ) { + Text("You have a valid auth token. Nice. Go save something in Chrome!") + } +} + @Composable fun LoginView(viewModel: LoginViewModel) { var email by rememberSaveable { mutableStateOf("") }