Skip to content

Commit

Permalink
Merge pull request #165 from uncrack-vault/persist_data
Browse files Browse the repository at this point in the history
Persist username in Vault Screen & added animation in SearchBar
  • Loading branch information
aritra-tech authored Nov 8, 2024
2 parents 7824d72 + d086fce commit 4c214fa
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.aritradas.uncrack.components

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import com.aritradas.uncrack.ui.theme.OnSurfaceVariantLight
import com.aritradas.uncrack.ui.theme.normal16
import kotlinx.coroutines.delay
import kotlin.streams.toList

@Composable
fun TypewriterText(
texts: List<String>,
modifier: Modifier = Modifier,
) {
var textIndex by remember {
mutableIntStateOf(0)
}
var textToDisplay by remember {
mutableStateOf("")
}
val textCharsList: List<List<String>> = remember {
texts.map {
it.splitToCodePoints()
}
}

LaunchedEffect(key1 = texts) {
while (textIndex < textCharsList.size) {
textCharsList[textIndex].forEachIndexed { charIndex, _ ->
textToDisplay = textCharsList[textIndex]
.take(
n = charIndex + 1
).joinToString(
separator = ""
)
delay(160)
}
textIndex = (textIndex + 1) % texts.size
delay(1000)
}
}

Text(
modifier = modifier,
text = textToDisplay,
style = normal16.copy(OnSurfaceVariantLight),
)
}

fun String.splitToCodePoints(): List<String> {
return codePoints()
.toList()
.map {
String(Character.toChars(it))
}
}
12 changes: 12 additions & 0 deletions app/src/main/java/com/aritradas/uncrack/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package com.aritradas.uncrack.di

import android.app.Application
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStoreFile
import androidx.room.Room
import com.aritradas.uncrack.data.datastore.DataStoreUtil
import com.aritradas.uncrack.data.db.AccountDatabase
Expand Down Expand Up @@ -76,4 +80,12 @@ object AppModule {
@Provides
@Singleton
fun provideFirebaseFirestore(): FirebaseFirestore = FirebaseFirestore.getInstance()

@Provides
@Singleton
fun provideDataStore(@ApplicationContext appContext: Context): DataStore<Preferences> {
return PreferenceDataStoreFactory.create(
produceFile = { appContext.preferencesDataStoreFile("user_preferences") }
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.aritradas.uncrack.presentation.vault
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
Expand Down Expand Up @@ -34,6 +35,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.aritradas.uncrack.R
import com.aritradas.uncrack.components.EmptyState
import com.aritradas.uncrack.components.TypewriterText
import com.aritradas.uncrack.components.VaultCard
import com.aritradas.uncrack.sharedViewModel.UserViewModel
import com.aritradas.uncrack.presentation.vault.viewmodel.VaultViewModel
Expand All @@ -58,6 +60,7 @@ fun VaultScreen(

LaunchedEffect(Unit) {
vaultViewModel.getAccounts()
userViewModel.getCurrentUser()
}

Scaffold(
Expand Down Expand Up @@ -96,10 +99,19 @@ fun VaultScreen(
active = false,
onActiveChange = {},
placeholder = {
Text(
text = "Search here",
style = normal16.copy(OnSurfaceVariantLight),
)
Row {
Text(
text = "Search here ",
style = normal16.copy(OnSurfaceVariantLight),
)
TypewriterText(texts = listOf(
"Instagram",
"Snapchat",
"Reddit",
"Linkedin"
))
}

},
colors = SearchBarDefaults.colors(
containerColor = PrimaryContainerLight
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.aritradas.uncrack.sharedViewModel

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.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.aritradas.uncrack.domain.model.User
Expand All @@ -10,6 +14,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import timber.log.Timber
Expand All @@ -18,22 +23,37 @@ import javax.inject.Inject
@HiltViewModel
class UserViewModel @Inject constructor(
private val auth: FirebaseAuth,
private val firestore: FirebaseFirestore
private val firestore: FirebaseFirestore,
private val dataStore: DataStore<Preferences>
) : ViewModel() {

private val _state = MutableStateFlow(User())
val state: StateFlow<User> = _state

init {
loadUserFromDataStore()
getCurrentUser()
}

private fun getCurrentUser() = viewModelScope.launch(Dispatchers.IO) {
private fun loadUserFromDataStore() {
viewModelScope.launch(Dispatchers.IO) {
try {
val userNamePreference = dataStore.data.first()
val userName = userNamePreference[USER_NAME_KEY] ?: ""
_state.value = _state.value.copy(name = userName)
} catch (e: Exception) {
Timber.e("Error loading user name from DataStore: $e")
}
}
}

fun getCurrentUser() = viewModelScope.launch(Dispatchers.IO) {
try {
val currentUser = auth.currentUser
if (currentUser != null) {
val user = fetchUserFromFirestore(currentUser.uid)
_state.value = user
saveUserNameToDataStore(user.name)
} else {
Timber.e("No user is currently logged in")
}
Expand All @@ -57,4 +77,18 @@ class UserViewModel @Inject constructor(
User()
}
}

private suspend fun saveUserNameToDataStore(userName: String) {
try {
dataStore.edit { preferences ->
preferences[USER_NAME_KEY] = userName
}
} catch (e: Exception) {
Timber.e("Error saving user name to DataStore: $e")
}
}

companion object {
private val USER_NAME_KEY = stringPreferencesKey("user_name")
}
}

0 comments on commit 4c214fa

Please sign in to comment.