Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persist username in Vault Screen & added animation in SearchBar #165

Merged
merged 2 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")
}
}
Loading