diff options
| author | Alberto Duarte (PWC) <alberto.duarte.delgado@pwc.com> | 2023-07-21 12:03:55 +0100 |
|---|---|---|
| committer | Alberto Duarte (PWC) <alberto.duarte.delgado@pwc.com> | 2023-07-21 12:03:55 +0100 |
| commit | bc2fd808fdf8691580901327ffce1f26f6d0334f (patch) | |
| tree | 16743025deaaf97994f9a474a6ed3b0af65a5a4c | |
| parent | 7dd32dceac9e87bc204fe1997a5ff3a1a24b3aed (diff) | |
asdfasdf
25 files changed, 496 insertions, 98 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index aff3be9..04feae1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,7 +18,6 @@ android:theme="@style/Theme.ProyectoAndroid"> <intent-filter> <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/dao/ScoreDAO.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/dao/ScoreDAO.kt index d9f678d..4640e5f 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/dao/ScoreDAO.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/dao/ScoreDAO.kt @@ -23,6 +23,6 @@ interface ScoreDao { @Query("DELETE FROM score") fun wipe() - @Query("DELETE FROM score WHERE category != 'total'") + @Query("DELETE FROM score") fun wipeScores() } diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/dao/UserDAO.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/dao/UserDAO.kt index bfa7d99..6f04ec9 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/dao/UserDAO.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/dao/UserDAO.kt @@ -1,15 +1,13 @@ package com.frannazario.proyectoandroid.data.dao import androidx.room.Dao -import androidx.room.Delete -import androidx.room.Insert import androidx.room.Query -import com.frannazario.proyectoandroid.data.models.User +import com.frannazario.proyectoandroid.data.models.UserLocal @Dao interface UserDao { @Query("SELECT * FROM user") - fun getAll(): List<User> + fun getAll(): List<UserLocal> // @Query("SELECT * FROM user WHERE category LIKE :id") // fun getByCategory(id: Int): List<User> diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/TotalScoreRemoteDataSource.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/TotalScoreRemoteDataSource.kt new file mode 100644 index 0000000..e82daed --- /dev/null +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/TotalScoreRemoteDataSource.kt @@ -0,0 +1,37 @@ +package com.frannazario.proyectoandroid.data.datasources + +import com.google.firebase.firestore.ktx.firestore +import com.google.firebase.ktx.Firebase + +class TotalScoreRemoteDataSource { +// +// private val db = Firebase.firestore +// +// suspend fun getTotalScores(): UserLocal { +// try { +// val response = db.collection("Usuarios") +// .document(uid) +// .get() +// .await() +// +// if (response.exists()) { +// // User found, return the user object +// return response.toObject<UserLocal>() ?: UserLocal(username = "gato") +// } else { +// // User not found, create a new user +// val newUser = UserLocal(username = email) +// db.collection("Usuarios") +// .document(uid) +// .set(newUser) +// .await() +// return newUser +// } +// } catch (e: Exception) { +// e.printStackTrace() +// Log.e("pruebax", e.toString()) +// } +// +// // Return a default user if there was an error +// return UserLocal(username = "perro", userimage = "https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png") +// } +}
\ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/UsersRemoteDataSource.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/UsersRemoteDataSource.kt index 3068d2b..5f92d4b 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/UsersRemoteDataSource.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/UsersRemoteDataSource.kt @@ -1,41 +1,112 @@ package com.frannazario.proyectoandroid.data.datasources import android.util.Log -import com.frannazario.proyectoandroid.data.models.User +import com.frannazario.proyectoandroid.data.models.UserRemote import com.google.firebase.firestore.ktx.firestore import com.google.firebase.firestore.ktx.toObject import com.google.firebase.ktx.Firebase import kotlinx.coroutines.tasks.await class UsersRemoteDataSource { + private val db = Firebase.firestore -suspend fun getUser(uid: String, email: String): User { - try { - val response = db.collection("Usuarios") - .document(uid) - .get() - .await() - - if (response.exists()) { - // User found, return the user object - return response.toObject<User>() ?: User(username = "gato") - } else { - // User not found, create a new user - val newUser = User(username = email) - db.collection("Usuarios") + suspend fun getUser(uid: String, email: String): UserRemote { + try { + val response = db.collection("Usuarios") .document(uid) - .set(newUser) + .get() .await() - return newUser + return if (response.exists()) { + // User found, return the user object + response.toObject<UserRemote>() ?: UserRemote() + } else { + // User not found, create a new user + val newUser = UserRemote(username = email) + db.collection("Usuarios") + .document(uid) + .set(newUser) + .await() + newUser + } + } catch (e: Exception) { + e.printStackTrace() + Log.e("pruebax", e.toString()) } - } catch (e: Exception) { - e.printStackTrace() - Log.e("pruebax", e.toString()) + + // Return a default user if there was an error + return UserRemote(username = "perro", userimage = "https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png") } - // Return a default user if there was an error - return User(username = "perro", userimage = "https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png") -} +// suspend fun updateUser(uid: String, user: UserRemote, ): UserRemote { +// try { +// val userRef = db.collection("Usuarios").document(uid) +// +//// First, fetch the existing user data using get() method +// val response = userRef.get().await() +// +// if (response.exists()) { +// // User exists in Firestore +// // Get the current user data as a map +// val existingUserData = response.data +// +// // Modify the existing user data as needed +// existingUserData?.set(user) +// +// // Update the user data in Firestore using the update() method +// if (existingUserData != null) { +// userRef.update(user) +// .addOnSuccessListener { +// } +// .addOnFailureListener { e -> +// } +// } +// } else { +// // User does not exist in Firestore +// // Handle the case where the user doesn't exist +// } +// } catch (e: Exception) { +// e.printStackTrace() +// Log.e("pruebay", e.toString()) +// } +// } + + suspend fun updateUser(uid: String, user: UserRemote): UserRemote { + try { + val userRef = db.collection("Usuarios").document(uid) + + // First, fetch the existing user data using get() method + val response = userRef.get().await() + + if (response.exists()) { + // User exists in Firestore + // Get the current user data as a map + val existingUserData = response.data + + // Create a map of the fields you want to update + val updatedData = mapOf( + "username" to user.username, + "userimage" to user.userimage, + "scores" to user.scores + // Add other fields you want to update here + ) + + // Update the user data in Firestore using the update() method + try { + userRef.update(updatedData) + return user + }catch (e: Exception){ + + } + } else { + // User does not exist in Firestore + // Handle the case where the user doesn't exist + } + } catch (e: Exception) { + e.printStackTrace() + Log.e("pruebay", e.toString()) + } + return UserRemote(username = "algo fallo") // Return the user object after the update (optional) + } }
\ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/models/TotalScoreDTO.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/models/TotalScoreDTO.kt new file mode 100644 index 0000000..0108c30 --- /dev/null +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/models/TotalScoreDTO.kt @@ -0,0 +1,6 @@ +package com.frannazario.proyectoandroid.data.models + +data class TotalScore( + val score: String = "", + val date: String = "" // O cualquier tipo de dato que uses para la fecha en Firestore (String, Timestamp, etc.) +)
\ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserDTO.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserLocal.kt index 77f1818..7903652 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserDTO.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserLocal.kt @@ -5,8 +5,8 @@ import androidx.room.Entity import androidx.room.PrimaryKey @Entity -data class User( +data class UserLocal( @PrimaryKey (autoGenerate = true) var id: Int = 0, - @ColumnInfo var username: String = "", - @ColumnInfo var userimage: String = "", -) + @ColumnInfo override var username: String = "", + @ColumnInfo override var userimage: String = "", +) : UserModel diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserModel.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserModel.kt new file mode 100644 index 0000000..28d761a --- /dev/null +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserModel.kt @@ -0,0 +1,6 @@ +package com.frannazario.proyectoandroid.data.models + +interface UserModel { + val username: String + val userimage: String +}
\ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserRemote.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserRemote.kt new file mode 100644 index 0000000..cc20978 --- /dev/null +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserRemote.kt @@ -0,0 +1,7 @@ +package com.frannazario.proyectoandroid.data.models + +data class UserRemote ( + override var username: String = "error", + override var userimage: String = "", + var scores: List<TotalScore> = emptyList() +) : UserModel
\ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SignoutRepository.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SignoutRepository.kt new file mode 100644 index 0000000..0c0484a --- /dev/null +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SignoutRepository.kt @@ -0,0 +1,28 @@ +package com.frannazario.proyectoandroid.data.repositories + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.frannazario.proyectoandroid.data.responses.SignoutResponse +import com.google.firebase.auth.FirebaseAuth +import kotlinx.coroutines.flow.flow + +class SignoutRepository { + + private val auth: FirebaseAuth = FirebaseAuth.getInstance() + + fun signout() = flow { + try { + auth.signOut() + val user = auth.currentUser + if (auth.currentUser == null) { + emit(SignoutResponse.Success("Sucess")) + } else { + throw Exception() + } + } catch (e: Exception) { + + emit(SignoutResponse.Error(e.message ?: "Error generico")) + } + } + +}
\ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/TotalScoreRepository.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/TotalScoreRepository.kt new file mode 100644 index 0000000..6827085 --- /dev/null +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/TotalScoreRepository.kt @@ -0,0 +1,4 @@ +package com.frannazario.proyectoandroid.data.repositories + +class TotalScoreRepository { +}
\ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/UserRepository.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/UserRepository.kt index eea7e56..fbccfc1 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/UserRepository.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/UserRepository.kt @@ -1,8 +1,8 @@ package com.frannazario.proyectoandroid.data.repositories -import android.content.Context import android.util.Log import com.frannazario.proyectoandroid.data.datasources.UsersRemoteDataSource +import com.frannazario.proyectoandroid.data.models.UserRemote import com.frannazario.proyectoandroid.data.responses.UsersResponse import kotlinx.coroutines.flow.flow @@ -14,8 +14,19 @@ class UserRepository { val user = remoteDataSource.getUser(uid, email) emit(UsersResponse.Success(user = user)) } catch (e: Exception) { - emit(UsersResponse.Error(e.message ?: "Error genérico")) - Log.e("", e.message ?: "Error generico") + emit(UsersResponse.Error(e.message ?: "Error genérico")) + Log.e("", e.message ?: "Error generico") } } + + fun updateUser(uid: String, user: UserRemote) = flow { + try { + val updatedUser = remoteDataSource.updateUser(uid, user) + emit(UsersResponse.Success(user = updatedUser)) + } catch (e: Exception) { + emit(UsersResponse.Error(e.message ?: "Error genérico")) + Log.e("", e.message ?: "Error generico") + } + } + } diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SignoutResponse.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SignoutResponse.kt new file mode 100644 index 0000000..090c235 --- /dev/null +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SignoutResponse.kt @@ -0,0 +1,6 @@ +package com.frannazario.proyectoandroid.data.responses + +sealed class SignoutResponse { + data class Success(val string: String?): SignoutResponse() + data class Error(val error: String): SignoutResponse() +}
\ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/UsersResponse.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/UsersResponse.kt index 2319640..d02d7a3 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/UsersResponse.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/UsersResponse.kt @@ -1,8 +1,9 @@ package com.frannazario.proyectoandroid.data.responses -import com.frannazario.proyectoandroid.data.models.User +import com.frannazario.proyectoandroid.data.models.UserLocal +import com.frannazario.proyectoandroid.data.models.UserRemote sealed class UsersResponse { - data class Success(val user: User): UsersResponse() + data class Success(val user: UserRemote): UsersResponse() data class Error(val error: String): UsersResponse() } diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/PlayViewModel.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/PlayViewModel.kt index a027328..31d83ab 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/PlayViewModel.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/PlayViewModel.kt @@ -6,6 +6,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.frannazario.proyectoandroid.data.models.Question import com.frannazario.proyectoandroid.data.models.Score +import com.frannazario.proyectoandroid.data.models.TotalScore import com.frannazario.proyectoandroid.data.repositories.QuestionsRepository import com.frannazario.proyectoandroid.data.repositories.ScoreRepository import com.frannazario.proyectoandroid.data.responses.QuestionsResponse @@ -17,9 +18,15 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update +import java.util.Date -class PlayViewModel(private val context: Context, private val repositoryScores: ScoreRepository = ScoreRepository(), private val repositoryQuestions: QuestionsRepository = QuestionsRepository()): ViewModel() { - +class PlayViewModel( + private val context: Context, + private val repositoryScores: ScoreRepository = ScoreRepository(), + private val repositoryQuestions: QuestionsRepository = QuestionsRepository(), + userViewModel: UserViewModel +): ViewModel() { + val userVM = userViewModel private val mutableStateQuestions = MutableStateFlow(QuestionsViewState()) val questionsViewState: StateFlow<QuestionsViewState> = mutableStateQuestions private val mutableStateScores = MutableStateFlow(ScoreViewState()) @@ -79,7 +86,7 @@ class PlayViewModel(private val context: Context, private val repositoryScores: scoresViewState.value.scores?.forEach { score -> totalScore += score.score.toInt() } - saveScore(Score(score = totalScore.toString(), category = "total")) + userVM.updateUserScores(TotalScore(totalScore.toString(), Date().time.toString())) val response = repositoryScores.wipeScores(context = context) response.onEach { scoresResponse -> when (scoresResponse) { diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/UserViewModel.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/UserViewModel.kt index 00cf311..b5f325b 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/UserViewModel.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/UserViewModel.kt @@ -1,11 +1,19 @@ package com.frannazario.proyectoandroid.data.viewmodels -import android.content.Context +import android.content.Intent +import android.util.Log +import androidx.core.content.ContextCompat.startActivity +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.frannazario.proyectoandroid.data.models.User +import com.frannazario.proyectoandroid.data.models.TotalScore +import com.frannazario.proyectoandroid.data.models.UserRemote +import com.frannazario.proyectoandroid.data.repositories.SignoutRepository import com.frannazario.proyectoandroid.data.repositories.UserRepository +import com.frannazario.proyectoandroid.data.responses.SignoutResponse import com.frannazario.proyectoandroid.data.responses.UsersResponse +import com.frannazario.proyectoandroid.presentation.activities.AuthActivity +import com.frannazario.proyectoandroid.presentation.activities.MainActivity import com.google.firebase.auth.FirebaseAuth import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -15,27 +23,75 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.update -class UserViewModel(private val userRepository: UserRepository = UserRepository()): ViewModel() { +class UserViewModel(private val userRepository: UserRepository = UserRepository(), private val signoutRepository: SignoutRepository = SignoutRepository()): ViewModel() { private val auth: FirebaseAuth = FirebaseAuth.getInstance() - private val mutableStateQuestions = MutableStateFlow(UserViewState()) - val userViewState: StateFlow<UserViewState> = mutableStateQuestions + private val mutableStateUser = MutableStateFlow(UserViewState()) + val userViewState: StateFlow<UserViewState> = mutableStateUser + + fun signout() { + val response = signoutRepository.signout() + response.onEach { signoutResponse -> + when(signoutResponse){ + is SignoutResponse.Success -> { + mutableStateUser.update { it.copy(user = UserRemote()) } + } + is SignoutResponse.Error-> { + } + } + }.flowOn(Dispatchers.IO).launchIn(viewModelScope) + } + fun getUser() { val response = userRepository.getUser(uid = auth.uid ?: "", email = auth.currentUser?.email ?: "No Account") response.onEach { userResponse -> when (userResponse) { is UsersResponse.Success -> { - mutableStateQuestions.update { it.copy(user = userResponse.user) } + mutableStateUser.update { it.copy(user = userResponse.user) } + } + is UsersResponse.Error -> { + mutableStateUser.update { it.copy(error = userResponse.error) } + } + } + }.flowOn(Dispatchers.IO).launchIn(viewModelScope) + } + + fun updateUserimage(userimage: String) { + val user: UserRemote = mutableStateUser.value.user + user.userimage = userimage + updateUser(user) + } + + fun updateUserScores(totalScore: TotalScore) { + val user: UserRemote = mutableStateUser.value.user + user.scores = user.scores.plus(totalScore) + updateUser(user) + } + + fun updateUsername(username: String) { + val user: UserRemote = mutableStateUser.value.user + user.username = username + updateUser(user) + } + + private fun updateUser(user: UserRemote) { + val response = userRepository.updateUser(uid = auth.uid ?: "", user) + response.onEach { userResponse -> + when (userResponse) { + is UsersResponse.Success -> { + mutableStateUser.update { it.copy(user = userResponse.user) } } is UsersResponse.Error -> { - mutableStateQuestions.update { it.copy(error = userResponse.error) } + mutableStateUser.update { it.copy(error = userResponse.error) } } } + }.flowOn(Dispatchers.IO).launchIn(viewModelScope) + Log.e("prueba", mutableStateUser.value.user.toString()) } } data class UserViewState( - val user: User = User(), + val user: UserRemote = UserRemote(), val error: String? = null, )
\ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/activities/MainActivity.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/activities/MainActivity.kt index 07b481e..40ad63c 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/activities/MainActivity.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/activities/MainActivity.kt @@ -1,5 +1,6 @@ package com.frannazario.proyectoandroid.presentation.activities +import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -37,4 +38,9 @@ class MainActivity: ComponentActivity() { } } + fun navigateToAuth() { + val intent = Intent(this, AuthActivity:: class.java) + startActivity(intent) + } + } diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/navigation/AppNavigation.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/navigation/AppNavigation.kt index fc2b6ae..85a9a1c 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/navigation/AppNavigation.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/navigation/AppNavigation.kt @@ -1,23 +1,26 @@ package com.frannazario.proyectoandroid.presentation.navigation import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument +import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel import com.frannazario.proyectoandroid.presentation.screens.BaseBottomNavScreen import com.frannazario.proyectoandroid.presentation.screens.CategoryDetailScreen @Composable fun AppNavigation() { val mainNavController = rememberNavController() + val userViewModel = remember { UserViewModel() } // Create the instance here NavHost(navController = mainNavController, startDestination = AppScreens.BaseBottomNav.route) { composable(route = AppScreens.BaseBottomNav.route) { - BaseBottomNavScreen(mainNavController) + BaseBottomNavScreen(mainNavController, userViewModel) } composable( diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/BaseBottomNavScreen.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/BaseBottomNavScreen.kt index ebb2894..b1594a3 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/BaseBottomNavScreen.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/BaseBottomNavScreen.kt @@ -1,5 +1,6 @@ package com.frannazario.proyectoandroid.presentation.screens +import android.annotation.SuppressLint import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api @@ -26,15 +27,17 @@ import com.frannazario.proyectoandroid.presentation.ui.widgets.BottomNav import com.frannazario.proyectoandroid.presentation.navigation.AppScreens import com.frannazario.proyectoandroid.presentation.ui.widgets.TopBar +@SuppressLint("StateFlowValueCalledInComposition") @OptIn(ExperimentalMaterial3Api::class) @Composable -fun BaseBottomNavScreen(mainNavController: NavController) { +fun BaseBottomNavScreen(mainNavController: NavController, + userViewModel: UserViewModel, // Pass the instance of UserViewModel here +) { val context = LocalContext.current val bottomNavController = rememberNavController() - val viewModel by remember {mutableStateOf(PlayViewModel(context))} - val scoreViewState = viewModel.scoresViewState.collectAsState() - val userViewModel by remember {mutableStateOf(UserViewModel())} val userViewState = userViewModel.userViewState.collectAsState() + val viewModel by remember {mutableStateOf(PlayViewModel(context, userViewModel = userViewModel))} + val scoreViewState = viewModel.scoresViewState.collectAsState() LaunchedEffect(Unit) { viewModel.getScoreList() @@ -43,10 +46,10 @@ fun BaseBottomNavScreen(mainNavController: NavController) { Scaffold( bottomBar = { - BottomNav(bottomNavController) + BottomNav(bottomNavController) }, topBar = { - TopBar(user = userViewState.value.user) + TopBar(userViewState) } ) { Surface( @@ -66,13 +69,13 @@ fun BaseBottomNavScreen(mainNavController: NavController) { ScoreScreen(mainNavController, viewModel) } composable(AppScreens.TotalScoreScreen.route) { - TotalScoreScreen(mainNavController, viewModel) + TotalScoreScreen(mainNavController, userViewModel) } composable(AppScreens.PlayListScreen.route) { PlayListScreen(bottomNavController, viewModel) } composable(AppScreens.SettingsScreen.route) { - SettingsScreen(mainNavController, viewModel) + SettingsScreen(mainNavController, userViewModel) } composable( route = "${AppScreens.PlayScreen.route}/{id}", diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/PlayListScreen.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/PlayListScreen.kt index de8c898..013f3f2 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/PlayListScreen.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/PlayListScreen.kt @@ -2,7 +2,6 @@ package com.frannazario.proyectoandroid.presentation.screens import android.widget.Toast import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.material3.ExperimentalMaterial3Api @@ -19,12 +18,16 @@ import androidx.navigation.NavHostController import com.frannazario.proyectoandroid.R import com.frannazario.proyectoandroid.data.viewmodels.CategoriesViewModel import com.frannazario.proyectoandroid.data.viewmodels.PlayViewModel +import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel import com.frannazario.proyectoandroid.presentation.navigation.AppScreens import com.frannazario.proyectoandroid.presentation.ui.widgets.CategorySmallCard @OptIn(ExperimentalMaterial3Api::class) @Composable -fun PlayListScreen(NavController: NavHostController, viewModelx: PlayViewModel){ +fun PlayListScreen( + NavController: NavHostController, + viewModelx: PlayViewModel, +){ val context = LocalContext.current val viewModel by remember { mutableStateOf(CategoriesViewModel()) } val categoriesViewState by viewModel.categoriesViewState.collectAsState() diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/PlayScreen.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/PlayScreen.kt index f312486..7694395 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/PlayScreen.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/PlayScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState +import androidx.compose.runtime.State import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -23,13 +24,18 @@ import com.frannazario.proyectoandroid.data.models.Question import com.frannazario.proyectoandroid.data.models.Score import com.frannazario.proyectoandroid.data.viewmodels.PlayViewModel import com.frannazario.proyectoandroid.data.viewmodels.ScoreViewState +import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel +import com.frannazario.proyectoandroid.data.viewmodels.UserViewState import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch @Composable -fun PlayScreen(id: Int, viewModel: PlayViewModel){ +fun PlayScreen( + id: Int, + viewModel: PlayViewModel, +){ val context = LocalContext.current val randomQuestion = remember { mutableStateOf<Question?>(null) } val shuffledResponses = remember {mutableStateOf<List<String>?>(null)} diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/ScoreScreen.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/ScoreScreen.kt index 086a132..6e420b4 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/ScoreScreen.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/ScoreScreen.kt @@ -13,18 +13,15 @@ import com.frannazario.proyectoandroid.data.viewmodels.PlayViewModel fun ScoreScreen(navController: NavController, viewModel: PlayViewModel){ val scoreViewState = viewModel.scoresViewState.collectAsState() -Column() { - scoreViewState.value.scores?.forEach { score -> - if(score.category != "total"){ + Column() { + scoreViewState.value.scores?.forEach { score -> Row() { Text(text = score.category) Text(text = " ") Text(text = score.score) } - } } -} } diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/SettingsScreen.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/SettingsScreen.kt index 8c27e67..f26d0c0 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/SettingsScreen.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/SettingsScreen.kt @@ -1,23 +1,126 @@ package com.frannazario.proyectoandroid.presentation.screens -import androidx.compose.foundation.layout.Box +import android.content.Intent +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text +import androidx.compose.material3.TextFieldDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.frannazario.proyectoandroid.data.viewmodels.PlayViewModel +import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel +import com.frannazario.proyectoandroid.presentation.activities.AuthActivity +@OptIn(ExperimentalMaterial3Api::class) @Composable -fun SettingsScreen(navController: NavController, viewModel: PlayViewModel){ - Box( - modifier = Modifier - .fillMaxSize(), - contentAlignment = Alignment.Center +fun SettingsScreen(navController: NavController, viewModel: UserViewModel){ + + val userViewState = viewModel.userViewState.collectAsState() + val username = remember { mutableStateOf(userViewState.value.user.username) } + val userimage = remember { mutableStateOf(userViewState.value.user.userimage) } + val context = LocalContext.current + + LaunchedEffect(userViewState.value.user) { + if (userViewState.value.user.username == "error"){ + val intent = Intent(context, AuthActivity:: class.java) + context.startActivity(intent) + } + } + + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally ) { - Text ( - text = "Settings" + + OutlinedTextField( + value = username.value, + onValueChange = { username.value = it }, // Update the username in the ViewModel + label = { "Username" }, + colors = TextFieldDefaults.outlinedTextFieldColors( + textColor = Color.Black, + cursorColor = Color.Black, + focusedBorderColor = Color.Black, + unfocusedBorderColor = Color.Black, + focusedLabelColor = Color(0xFF008477) + ), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp) ) + Button( + onClick = { + viewModel.updateUsername(username.value) + }, + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF008477)) + ) { + Text( + text = "Change Username", + color = Color.Black + ) + } + + OutlinedTextField( + value = userimage.value, + onValueChange = { userimage.value = it }, // Update the user image in the ViewModel + label = { "User Image URL"}, + colors = TextFieldDefaults.outlinedTextFieldColors( + textColor = Color.Black, + cursorColor = Color.Black, + focusedBorderColor = Color.Black, + unfocusedBorderColor = Color.Black, + focusedLabelColor = Color(0xFF008477) + ), + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp) + ) + + Button( + onClick = { + viewModel.updateUserimage(userimage.value) + }, + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF008477)) + ) { + Text( + text = "Change Userimage", + color = Color.Black + ) + } + Button( + onClick = { + viewModel.signout() + }, + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF008477)) + ) { + Text( + text = "Signout", + color = Color.Black + ) + } } + + +// Box( +// modifier = Modifier +// .fillMaxSize(), +// contentAlignment = Alignment.Center +// ) { +// Text ( +// text = "Settings" +// ) +// } } diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/TotalScoreScreen.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/TotalScoreScreen.kt index bb6d1c8..ce3bc2b 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/TotalScoreScreen.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/TotalScoreScreen.kt @@ -1,24 +1,27 @@ package com.frannazario.proyectoandroid.presentation.screens import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue import androidx.navigation.NavController -import com.frannazario.proyectoandroid.data.viewmodels.PlayViewModel +import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale @Composable -fun TotalScoreScreen(navController: NavController, viewModel: PlayViewModel){ - val scoreViewState = viewModel.scoresViewState.collectAsState() +fun TotalScoreScreen(navController: NavController, viewModel: UserViewModel){ + + val userViewState = viewModel.userViewState.collectAsState() Column() { - scoreViewState.value.scores?.forEach { score -> - if (score.category == "total"){ - Text(text = "Total Score: ") - Text(text = score.score) - } + userViewState.value.user.scores?.forEach { score -> + val dateInMillis = score.date.toLong() + val dateFormat = SimpleDateFormat("dd MMM yyyy", Locale.getDefault()) + val formattedDate = dateFormat.format(Date(dateInMillis)) + Text(text = formattedDate) + Text(text = score.score) } } diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/TopBar.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/TopBar.kt index 1e57934..84dd02f 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/TopBar.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/TopBar.kt @@ -1,5 +1,7 @@ package com.frannazario.proyectoandroid.presentation.ui.widgets +import android.util.Log +import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.size @@ -7,35 +9,70 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Text import androidx.compose.material.TopAppBar import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.State +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import coil.compose.AsyncImage -import com.frannazario.proyectoandroid.data.models.User +import coil.compose.AsyncImagePainter +import com.frannazario.proyectoandroid.R +import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel +import com.frannazario.proyectoandroid.data.viewmodels.UserViewState @Composable -fun TopBar(user: User) { +fun TopBar(userViewState: State<UserViewState>) { + + val imageLoaded = remember { mutableStateOf(true) } + + LaunchedEffect(userViewState) { + Log.e("topbar", userViewState.value.user.username) + Log.e("topbar", userViewState.value.user.userimage) + } + Row( horizontalArrangement = Arrangement.SpaceAround, verticalAlignment = Alignment.CenterVertically ) { TopAppBar( - title = { Text(text = user.username)}, + title = { Text(text = userViewState.value.user.username)}, navigationIcon = { - AsyncImage( - model = user.userimage, - contentDescription = null, - contentScale = ContentScale.Crop, - modifier = Modifier - .size(40.dp) - .clip( - RoundedCornerShape(40.dp) - ), - ) + if( imageLoaded.value && userViewState.value.user.userimage != ""){ + AsyncImage( + model = userViewState.value.user.userimage, + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier + .size(40.dp) + .clip( + RoundedCornerShape(40.dp) + ), + onState = {state -> + if(state is AsyncImagePainter.State.Error){ + imageLoaded.value = false + } + } + ) + } else { + Image(painter = painterResource(id = R.drawable.ic_sports), + contentDescription = null, + modifier = Modifier + .size(40.dp) + .clip( + RoundedCornerShape(40.dp) + ) + ) + } }, ) } + }
\ No newline at end of file |