From 1dd6d976f1e78cde69ac9e0f89b1b80b1e89cba3 Mon Sep 17 00:00:00 2001 From: "Alberto Duarte (PWC)" Date: Mon, 9 Oct 2023 17:35:35 +0100 Subject: Not sure --- .gitignore | 66 +-- app/build.gradle | 176 +++---- app/mio_google-services.json | 39 ++ app/proguard-rules.pro | 40 +- .../proyectoandroid/ExampleInstrumentedTest.kt | 46 +- app/src/main/AndroidManifest.xml | 60 +-- .../com/frannazario/proyectoandroid/data/DB.kt | 28 +- .../proyectoandroid/data/dao/QuestionDAO.kt | 42 +- .../proyectoandroid/data/dao/ScoreDAO.kt | 56 +-- .../data/datasources/PasswordRecoveryDataSource.kt | 14 +- .../data/datasources/QuestionsDataSource.kt | 16 +- .../data/datasources/QuestionsLocalDataSource.kt | 50 +- .../data/datasources/QuestionsRemoteDataSource.kt | 68 +-- .../data/datasources/ScoreLocalDataSource.kt | 68 +-- .../data/datasources/SigninDataSource.kt | 14 +- .../data/datasources/SignupDataSource.kt | 14 +- .../data/datasources/UsersRemoteDataSource.kt | 156 +++--- .../proyectoandroid/data/models/Question.kt | 32 +- .../proyectoandroid/data/models/Score.kt | 26 +- .../proyectoandroid/data/models/TotalScore.kt | 14 +- .../proyectoandroid/data/models/UserModel.kt | 14 +- .../proyectoandroid/data/models/UserRemote.kt | 16 +- .../data/repositories/CategoriesRepository.kt | 32 +- .../repositories/PasswordRecoveryRepository.kt | 54 +-- .../data/repositories/QuestionsRepository.kt | 66 +-- .../data/repositories/ScoreRepository.kt | 72 +-- .../data/repositories/SigninRepository.kt | 54 +-- .../data/repositories/SignoutRepository.kt | 48 +- .../data/repositories/SignupRepository.kt | 52 +- .../data/repositories/UserRepository.kt | 64 +-- .../data/responses/CategoriesResponse.kt | 14 +- .../data/responses/PasswordRecoveryResponse.kt | 16 +- .../data/responses/QuestionsResponse.kt | 14 +- .../data/responses/ScoresResponse.kt | 16 +- .../data/responses/SigninResponse.kt | 18 +- .../data/responses/SignoutResponse.kt | 10 +- .../data/responses/SignupResponse.kt | 16 +- .../data/responses/UsersResponse.kt | 16 +- .../proyectoandroid/data/utils/CategoryEnum.kt | 44 +- .../proyectoandroid/data/utils/StringUtils.kt | 96 ++-- .../data/viewmodels/CategoriesViewModel.kt | 66 +-- .../data/viewmodels/PasswordRecoveryViewModel.kt | 78 +-- .../data/viewmodels/PlayViewModel.kt | 256 +++++----- .../data/viewmodels/SigninViewModel.kt | 86 ++-- .../data/viewmodels/SignupViewModel.kt | 92 ++-- .../data/viewmodels/UserViewModel.kt | 181 ++++--- .../presentation/activities/AuthActivity.kt | 59 +-- .../presentation/activities/MainActivity.kt | 58 +-- .../presentation/fragments/LoginFragment.kt | 138 +++--- .../fragments/PasswordRecoveryFragment.kt | 126 ++--- .../presentation/fragments/SigninFragment.kt | 124 ++--- .../presentation/navigation/AppNavigation.kt | 78 +-- .../presentation/navigation/AppScreens.kt | 26 +- .../presentation/screens/BaseBottomNavScreen.kt | 186 +++---- .../presentation/screens/CategoryDetailScreen.kt | 46 +- .../presentation/screens/CategoryListScreen.kt | 110 ++--- .../presentation/screens/PlayListScreen.kt | 124 ++--- .../presentation/screens/PlayScreen.kt | 537 ++++++++++++--------- .../presentation/screens/ScoreScreen.kt | 52 +- .../presentation/screens/SettingsScreen.kt | 364 +++++++++----- .../presentation/screens/TotalScoreScreen.kt | 58 +-- .../proyectoandroid/presentation/ui/theme/Color.kt | 20 +- .../proyectoandroid/presentation/ui/theme/Theme.kt | 138 +++--- .../proyectoandroid/presentation/ui/theme/Type.kt | 66 +-- .../presentation/ui/widgets/BottomNav.kt | 71 ++- .../presentation/ui/widgets/CategoryCard.kt | 180 +++---- .../presentation/ui/widgets/CategorySmallCard.kt | 180 +++---- .../presentation/ui/widgets/SettingsButton.kt | 46 ++ .../presentation/ui/widgets/TopBar.kt | 158 +++--- .../res/drawable-v24/ic_launcher_foreground.xml | 58 +-- app/src/main/res/drawable/baseline_edit_24.xml | 5 + app/src/main/res/drawable/baseline_edit_off_24.xml | 5 + app/src/main/res/drawable/baseline_settings_24.xml | 5 + app/src/main/res/drawable/button_background.xml | 8 +- app/src/main/res/drawable/button_clicked.xml | 18 +- app/src/main/res/drawable/button_stand.xml | 10 +- .../main/res/drawable/ic_launcher_background.xml | 340 ++++++------- app/src/main/res/drawable/input_background.xml | 6 +- app/src/main/res/layout/activity_auth.xml | 30 +- app/src/main/res/layout/fragment_login.xml | 246 +++++----- .../main/res/layout/fragment_password_recovery.xml | 188 ++++---- app/src/main/res/layout/fragment_signin.xml | 224 ++++----- app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml | 10 +- .../res/mipmap-anydpi-v26/ic_launcher_round.xml | 10 +- app/src/main/res/navigation/nav_graph.xml | 94 ++-- app/src/main/res/values-es/strings.xml | 32 +- app/src/main/res/values/colors.xml | 18 +- app/src/main/res/values/strings.xml | 36 +- app/src/main/res/values/themes.xml | 8 +- app/src/main/res/xml/backup_rules.xml | 24 +- app/src/main/res/xml/data_extraction_rules.xml | 36 +- .../frannazario/proyectoandroid/ExampleUnitTest.kt | 32 +- build.gradle | 18 +- gradle.properties | 44 +- gradle/wrapper/gradle-wrapper.properties | 12 +- gradlew | 370 +++++++------- gradlew.bat | 178 +++---- settings.gradle | 32 +- 98 files changed, 3938 insertions(+), 3620 deletions(-) create mode 100644 app/mio_google-services.json create mode 100644 app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/SettingsButton.kt create mode 100644 app/src/main/res/drawable/baseline_edit_24.xml create mode 100644 app/src/main/res/drawable/baseline_edit_off_24.xml create mode 100644 app/src/main/res/drawable/baseline_settings_24.xml diff --git a/.gitignore b/.gitignore index 347e252..0c1aed6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,33 +1,33 @@ -# Gradle files -.gradle/ -build/ - -# Local configuration file (sdk path, etc) -local.properties - -# Log/OS Files -*.log - -# Android Studio generated files and folders -captures/ -.externalNativeBuild/ -.cxx/ -*.apk -output.json - -# IntelliJ -*.iml -.idea/ -misc.xml -deploymentTargetDropDown.xml -render.experimental.xml - -# Keystore files -*.jks -*.keystore - -# Google Services (e.g. APIs or Firebase) -google-services.json - -# Android Profiling -*.hprof +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Log/OS Files +*.log + +# Android Studio generated files and folders +captures/ +.externalNativeBuild/ +.cxx/ +*.apk +output.json + +# IntelliJ +*.iml +.idea/ +misc.xml +deploymentTargetDropDown.xml +render.experimental.xml + +# Keystore files +*.jks +*.keystore + +# Google Services (e.g. APIs or Firebase) +google-services.json + +# Android Profiling +*.hprof diff --git a/app/build.gradle b/app/build.gradle index 2efcdc8..ac3e57a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,89 +1,89 @@ -plugins { - id 'com.android.application' - id 'org.jetbrains.kotlin.android' - id 'com.google.gms.google-services' - id 'kotlin-kapt' -} - -android { - namespace 'com.frannazario.proyectoandroid' - compileSdk 33 - - defaultConfig { - applicationId "com.frannazario.proyectoandroid" - minSdk 24 - targetSdk 33 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables { - useSupportLibrary true - } - viewBinding { - enabled = true - } - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - kotlinOptions { - jvmTarget = '1.8' - } - buildFeatures { - compose true - } - composeOptions { - kotlinCompilerExtensionVersion '1.3.2' - } - packagingOptions { - resources { - excludes += '/META-INF/{AL2.0,LGPL2.1}' - } - } -} - -dependencies { - - implementation 'androidx.core:core-ktx:1.10.1' - implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0') - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' - implementation 'androidx.activity:activity-compose:1.7.2' - implementation platform('androidx.compose:compose-bom:2022.10.00') - implementation 'androidx.compose.ui:ui' - implementation 'androidx.compose.ui:ui-graphics' - implementation 'androidx.compose.ui:ui-tooling-preview' - implementation 'androidx.compose.material3:material3' - implementation 'androidx.compose.material:material:1.4.3' - implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3' - implementation "androidx.fragment:fragment-ktx:1.5.7" - implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'com.google.android.material:material:1.9.0' - implementation 'com.google.firebase:firebase-auth-ktx:22.0.0' - implementation 'com.google.firebase:firebase-firestore-ktx' - implementation platform('com.google.firebase:firebase-bom:32.1.1') - implementation 'com.google.firebase:firebase-analytics-ktx' - implementation 'androidx.navigation:navigation-compose:2.5.3' - implementation ("io.coil-kt:coil-compose:2.4.0") - - implementation("androidx.room:room-runtime:2.5.0") - annotationProcessor("androidx.room:room-compiler:2.5.0") - kapt("androidx.room:room-compiler:2.5.0") - - - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00') - androidTestImplementation 'androidx.compose.ui:ui-test-junit4' - debugImplementation 'androidx.compose.ui:ui-tooling' - debugImplementation 'androidx.compose.ui:ui-test-manifest' +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' + id 'com.google.gms.google-services' + id 'kotlin-kapt' +} + +android { + namespace 'com.frannazario.proyectoandroid' + compileSdk 33 + + defaultConfig { + applicationId "com.frannazario.proyectoandroid" + minSdk 24 + targetSdk 33 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary true + } + viewBinding { + enabled = true + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } + buildFeatures { + compose true + } + composeOptions { + kotlinCompilerExtensionVersion '1.3.2' + } + packagingOptions { + resources { + excludes += '/META-INF/{AL2.0,LGPL2.1}' + } + } +} + +dependencies { + + implementation 'androidx.core:core-ktx:1.10.1' + implementation platform('org.jetbrains.kotlin:kotlin-bom:1.8.0') + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' + implementation 'androidx.activity:activity-compose:1.7.2' + implementation platform('androidx.compose:compose-bom:2022.10.00') + implementation 'androidx.compose.ui:ui' + implementation 'androidx.compose.ui:ui-graphics' + implementation 'androidx.compose.ui:ui-tooling-preview' + implementation 'androidx.compose.material3:material3' + implementation 'androidx.compose.material:material:1.4.3' + implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3' + implementation "androidx.fragment:fragment-ktx:1.5.7" + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + implementation 'com.google.android.material:material:1.9.0' + implementation 'com.google.firebase:firebase-auth-ktx:22.0.0' + implementation 'com.google.firebase:firebase-firestore-ktx' + implementation platform('com.google.firebase:firebase-bom:32.1.1') + implementation 'com.google.firebase:firebase-analytics-ktx' + implementation 'androidx.navigation:navigation-compose:2.5.3' + implementation ("io.coil-kt:coil-compose:2.4.0") + + implementation("androidx.room:room-runtime:2.5.0") + annotationProcessor("androidx.room:room-compiler:2.5.0") + kapt("androidx.room:room-compiler:2.5.0") + + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00') + androidTestImplementation 'androidx.compose.ui:ui-test-junit4' + debugImplementation 'androidx.compose.ui:ui-tooling' + debugImplementation 'androidx.compose.ui:ui-test-manifest' } \ No newline at end of file diff --git a/app/mio_google-services.json b/app/mio_google-services.json new file mode 100644 index 0000000..2660a9f --- /dev/null +++ b/app/mio_google-services.json @@ -0,0 +1,39 @@ +{ + "project_info": { + "project_number": "840275502507", + "project_id": "formacion-android-badc5", + "storage_bucket": "formacion-android-badc5.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:840275502507:android:6786b588061c5e8fe15eee", + "android_client_info": { + "package_name": "com.frannazario.proyectoandroid" + } + }, + "oauth_client": [ + { + "client_id": "840275502507-1iclha7eiloposqaqbsej6unsoipmolk.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyAeGeLnE6YYdoSPVaCcBOudpZ-KQ3DtUaU" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "840275502507-1iclha7eiloposqaqbsej6unsoipmolk.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 481bb43..64b4a05 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,21 +1,21 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. #-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/frannazario/proyectoandroid/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/frannazario/proyectoandroid/ExampleInstrumentedTest.kt index 6c3e781..32443a9 100644 --- a/app/src/androidTest/java/com/frannazario/proyectoandroid/ExampleInstrumentedTest.kt +++ b/app/src/androidTest/java/com/frannazario/proyectoandroid/ExampleInstrumentedTest.kt @@ -1,24 +1,24 @@ -package com.frannazario.proyectoandroid - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.frannazario.proyectoandroid", appContext.packageName) - } +package com.frannazario.proyectoandroid + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.frannazario.proyectoandroid", appContext.packageName) + } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 04feae1..7d7ce2b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,31 +1,31 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/DB.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/DB.kt index a8209bb..147c83a 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/DB.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/DB.kt @@ -1,14 +1,14 @@ -package com.frannazario.proyectoandroid.data - -import androidx.room.Database -import androidx.room.RoomDatabase -import com.frannazario.proyectoandroid.data.dao.QuestionDao -import com.frannazario.proyectoandroid.data.dao.ScoreDao -import com.frannazario.proyectoandroid.data.models.Question -import com.frannazario.proyectoandroid.data.models.Score - -@Database(entities = [Question::class, Score::class], version = 1) -abstract class AppDatabase : RoomDatabase() { - abstract fun questionDao(): QuestionDao - abstract fun scoreDao(): ScoreDao -} +package com.frannazario.proyectoandroid.data + +import androidx.room.Database +import androidx.room.RoomDatabase +import com.frannazario.proyectoandroid.data.dao.QuestionDao +import com.frannazario.proyectoandroid.data.dao.ScoreDao +import com.frannazario.proyectoandroid.data.models.Question +import com.frannazario.proyectoandroid.data.models.Score + +@Database(entities = [Question::class, Score::class], version = 1) +abstract class AppDatabase : RoomDatabase() { + abstract fun questionDao(): QuestionDao + abstract fun scoreDao(): ScoreDao +} diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/dao/QuestionDAO.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/dao/QuestionDAO.kt index cfc2c5f..3f3e300 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/dao/QuestionDAO.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/dao/QuestionDAO.kt @@ -1,22 +1,22 @@ -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.Question - -@Dao -interface QuestionDao { - @Query("SELECT * FROM question") - fun getAll(): List - - @Query("SELECT * FROM question WHERE category LIKE :id") - fun getByCategory(id: Int): List - - @Insert - fun insertAll(vararg questions: Question) - - @Delete - fun delete(question: Question) +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.Question + +@Dao +interface QuestionDao { + @Query("SELECT * FROM question") + fun getAll(): List + + @Query("SELECT * FROM question WHERE category LIKE :id") + fun getByCategory(id: Int): List + + @Insert + fun insertAll(vararg questions: Question) + + @Delete + fun delete(question: Question) } \ No newline at end of file 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 4640e5f..8e7743b 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 @@ -1,28 +1,28 @@ -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.Score - -@Dao -interface ScoreDao { - @Query("SELECT * FROM score") - fun getAll(): List - - @Query("SELECT * FROM score WHERE category LIKE :id") - fun getByCategory(id: Int): Score - - @Insert - fun insert(score: Score) - - @Delete - fun delete(score: Score) - - @Query("DELETE FROM score") - fun wipe() - - @Query("DELETE FROM score") - fun wipeScores() -} +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.Score + +@Dao +interface ScoreDao { + @Query("SELECT * FROM score") + fun getAll(): List + + @Query("SELECT * FROM score WHERE category LIKE :id") + fun getByCategory(id: Int): Score + + @Insert + fun insert(score: Score) + + @Delete + fun delete(score: Score) + + @Query("DELETE FROM score") + fun wipe() + + @Query("DELETE FROM score") + fun wipeScores() +} diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/PasswordRecoveryDataSource.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/PasswordRecoveryDataSource.kt index 5ef08f4..7ebbe5c 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/PasswordRecoveryDataSource.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/PasswordRecoveryDataSource.kt @@ -1,8 +1,8 @@ -package com.frannazario.proyectoandroid.data.datasources - -import androidx.lifecycle.LiveData -import com.frannazario.proyectoandroid.data.responses.PasswordRecoveryResponse - -interface PasswordRecoveryDataSource { - fun recover (email: String): LiveData +package com.frannazario.proyectoandroid.data.datasources + +import androidx.lifecycle.LiveData +import com.frannazario.proyectoandroid.data.responses.PasswordRecoveryResponse + +interface PasswordRecoveryDataSource { + fun recover (email: String): LiveData } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsDataSource.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsDataSource.kt index 285a52e..8dce6c6 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsDataSource.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsDataSource.kt @@ -1,9 +1,9 @@ -package com.frannazario.proyectoandroid.data.datasources - -import android.content.Context -import com.frannazario.proyectoandroid.data.models.Question - -interface QuestionsDataSource { - suspend fun getQuestions(context: Context, id: Int): List - fun saveQuestions(context: Context, questions: List) +package com.frannazario.proyectoandroid.data.datasources + +import android.content.Context +import com.frannazario.proyectoandroid.data.models.Question + +interface QuestionsDataSource { + suspend fun getQuestions(context: Context, id: Int): List + fun saveQuestions(context: Context, questions: List) } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsLocalDataSource.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsLocalDataSource.kt index 62d23e6..3e1dd3e 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsLocalDataSource.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsLocalDataSource.kt @@ -1,25 +1,25 @@ -package com.frannazario.proyectoandroid.data.datasources - -import android.content.Context -import androidx.room.Room -import com.frannazario.proyectoandroid.data.AppDatabase -import com.frannazario.proyectoandroid.data.models.Question - -class QuestionsLocalDataSource: QuestionsDataSource { - - override suspend fun getQuestions(context: Context, id: Int): List { - val dbLocal = Room.databaseBuilder( - context.applicationContext, - AppDatabase::class.java, "database-name" - ).build() - return dbLocal.questionDao().getByCategory(id) - } - - override fun saveQuestions(context: Context, questions: List) { - val dbLocal = Room.databaseBuilder( - context.applicationContext, - AppDatabase::class.java, "database-name" - ).build() - return dbLocal.questionDao().insertAll() - } -} +package com.frannazario.proyectoandroid.data.datasources + +import android.content.Context +import androidx.room.Room +import com.frannazario.proyectoandroid.data.AppDatabase +import com.frannazario.proyectoandroid.data.models.Question + +class QuestionsLocalDataSource: QuestionsDataSource { + + override suspend fun getQuestions(context: Context, id: Int): List { + val dbLocal = Room.databaseBuilder( + context.applicationContext, + AppDatabase::class.java, "database-name" + ).build() + return dbLocal.questionDao().getByCategory(id) + } + + override fun saveQuestions(context: Context, questions: List) { + val dbLocal = Room.databaseBuilder( + context.applicationContext, + AppDatabase::class.java, "database-name" + ).build() + return dbLocal.questionDao().insertAll() + } +} diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsRemoteDataSource.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsRemoteDataSource.kt index b26d62c..f43e5a3 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsRemoteDataSource.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/QuestionsRemoteDataSource.kt @@ -1,35 +1,35 @@ -package com.frannazario.proyectoandroid.data.datasources - -import android.content.Context -import com.frannazario.proyectoandroid.data.models.Question -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 QuestionsRemoteDataSource: QuestionsDataSource { - private val db = Firebase.firestore - private val questionList = mutableListOf() - override suspend fun getQuestions(context: Context, id: Int): List { - val response = - db.collection("Preguntas") - .get() - .await() - for (document in response) { - try { - val pregunta = document.toObject() - if (pregunta.category == id){ - questionList.add(pregunta) - } - } catch (e: Exception){ - e.printStackTrace() - } - } - return questionList - } - - //Never implemented just for local repo - override fun saveQuestions(context: Context, questions: List) { - TODO("Not yet implemented") - } +package com.frannazario.proyectoandroid.data.datasources + +import android.content.Context +import com.frannazario.proyectoandroid.data.models.Question +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 QuestionsRemoteDataSource: QuestionsDataSource { + private val db = Firebase.firestore + private val questionList = mutableListOf() + override suspend fun getQuestions(context: Context, id: Int): List { + val response = + db.collection("Preguntas") + .get() + .await() + for (document in response) { + try { + val pregunta = document.toObject() + if (pregunta.category == id){ + questionList.add(pregunta) + } + } catch (e: Exception){ + e.printStackTrace() + } + } + return questionList + } + + //Never implemented just for local repo + override fun saveQuestions(context: Context, questions: List) { + TODO("Not yet implemented") + } } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/ScoreLocalDataSource.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/ScoreLocalDataSource.kt index 5e8492e..c4bb71b 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/ScoreLocalDataSource.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/ScoreLocalDataSource.kt @@ -1,35 +1,35 @@ -package com.frannazario.proyectoandroid.data.datasources - -import android.content.Context -import androidx.room.Room -import com.frannazario.proyectoandroid.data.AppDatabase -import com.frannazario.proyectoandroid.data.models.Score - -class ScoreLocalDataSource { - - fun getScores(context: Context): List { - val dbLocal = Room.databaseBuilder( - context.applicationContext, - AppDatabase::class.java, "database-name" - ).build() - return dbLocal.scoreDao().getAll() - } - - fun saveScore(context: Context, score: Score): List { - val dbLocal = Room.databaseBuilder( - context.applicationContext, - AppDatabase::class.java, "database-name" - ).build() - dbLocal.scoreDao().insert(score) - return dbLocal.scoreDao().getAll() - } - - fun wipeScores(context: Context): List { - val dbLocal = Room.databaseBuilder( - context.applicationContext, - AppDatabase::class.java, "database-name" - ).build() - dbLocal.scoreDao().wipeScores() - return dbLocal.scoreDao().getAll() - } +package com.frannazario.proyectoandroid.data.datasources + +import android.content.Context +import androidx.room.Room +import com.frannazario.proyectoandroid.data.AppDatabase +import com.frannazario.proyectoandroid.data.models.Score + +class ScoreLocalDataSource { + + fun getScores(context: Context): List { + val dbLocal = Room.databaseBuilder( + context.applicationContext, + AppDatabase::class.java, "database-name" + ).build() + return dbLocal.scoreDao().getAll() + } + + fun saveScore(context: Context, score: Score): List { + val dbLocal = Room.databaseBuilder( + context.applicationContext, + AppDatabase::class.java, "database-name" + ).build() + dbLocal.scoreDao().insert(score) + return dbLocal.scoreDao().getAll() + } + + fun wipeScores(context: Context): List { + val dbLocal = Room.databaseBuilder( + context.applicationContext, + AppDatabase::class.java, "database-name" + ).build() + dbLocal.scoreDao().wipeScores() + return dbLocal.scoreDao().getAll() + } } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/SigninDataSource.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/SigninDataSource.kt index 9b11980..b8f3234 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/SigninDataSource.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/SigninDataSource.kt @@ -1,8 +1,8 @@ -package com.frannazario.proyectoandroid.data.datasources - -import androidx.lifecycle.LiveData -import com.frannazario.proyectoandroid.data.responses.SigninResponse - -interface SigninDataSource { - fun login (email: String, password: String): LiveData +package com.frannazario.proyectoandroid.data.datasources + +import androidx.lifecycle.LiveData +import com.frannazario.proyectoandroid.data.responses.SigninResponse + +interface SigninDataSource { + fun login (email: String, password: String): LiveData } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/SignupDataSource.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/SignupDataSource.kt index 9591c76..4d4326b 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/SignupDataSource.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/datasources/SignupDataSource.kt @@ -1,8 +1,8 @@ -package com.frannazario.proyectoandroid.data.datasources - -import androidx.lifecycle.LiveData -import com.frannazario.proyectoandroid.data.responses.SignupResponse - -interface SignupDataSource { - fun register(email: String, password: String): LiveData +package com.frannazario.proyectoandroid.data.datasources + +import androidx.lifecycle.LiveData +import com.frannazario.proyectoandroid.data.responses.SignupResponse + +interface SignupDataSource { + fun register(email: String, password: String): LiveData } \ 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 2c8124d..abd7ea3 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,79 +1,79 @@ -package com.frannazario.proyectoandroid.data.datasources - -import android.util.Log -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): UserRemote { - try { - val response = db.collection("Usuarios") - .document(uid) - .get() - .await() - return if (response.exists()) { - // User found, return the user object - response.toObject() ?: 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()) - } - - // 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") - } - - 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) - } - +package com.frannazario.proyectoandroid.data.datasources + +import android.util.Log +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): UserRemote { + try { + val response = db.collection("Usuarios") + .document(uid) + .get() + .await() + return if (response.exists()) { + // User found, return the user object + response.toObject() ?: 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()) + } + + // 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") + } + + 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/Question.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/models/Question.kt index 4e62bf0..d95d1a8 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/models/Question.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/models/Question.kt @@ -1,16 +1,16 @@ -package com.frannazario.proyectoandroid.data.models - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey - -//DTO -@Entity - data class Question( -// @PrimaryKey (autoGenerate = true) var id: Int = 0, - @PrimaryKey var question: String = "", - @ColumnInfo var response1: String = "", - @ColumnInfo var response2: String = "", - @ColumnInfo var response3: String = "", - @ColumnInfo var category: Int = -1 -) +package com.frannazario.proyectoandroid.data.models + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +//DTO +@Entity + data class Question( +// @PrimaryKey (autoGenerate = true) var id: Int = 0, + @PrimaryKey var question: String = "", + @ColumnInfo var response1: String = "", + @ColumnInfo var response2: String = "", + @ColumnInfo var response3: String = "", + @ColumnInfo var category: Int = -1 +) diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/models/Score.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/models/Score.kt index 4311a11..e981519 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/models/Score.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/models/Score.kt @@ -1,13 +1,13 @@ -package com.frannazario.proyectoandroid.data.models - -import androidx.room.ColumnInfo -import androidx.room.Entity -import androidx.room.PrimaryKey - -//DTO -@Entity -data class Score( - @PrimaryKey(autoGenerate = true) var id: Int = 0, - @ColumnInfo var score: String = "", - @ColumnInfo var category: String = "", -) +package com.frannazario.proyectoandroid.data.models + +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.PrimaryKey + +//DTO +@Entity +data class Score( + @PrimaryKey(autoGenerate = true) var id: Int = 0, + @ColumnInfo var score: String = "", + @ColumnInfo var category: String = "", +) diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/models/TotalScore.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/models/TotalScore.kt index 7acd152..cd769da 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/models/TotalScore.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/models/TotalScore.kt @@ -1,8 +1,8 @@ -package com.frannazario.proyectoandroid.data.models - - -//DTO -data class TotalScore( - val score: String = "", - val date: String = "" // O cualquier tipo de dato que uses para la fecha en Firestore (String, Timestamp, etc.) +package com.frannazario.proyectoandroid.data.models + + +//DTO +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/UserModel.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserModel.kt index 8d92589..7905cc2 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserModel.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserModel.kt @@ -1,8 +1,8 @@ -package com.frannazario.proyectoandroid.data.models - - -//DTO this interface is crreated in case you want to create a userLocal too, to play offline -interface UserModel { - val username: String - val userimage: String +package com.frannazario.proyectoandroid.data.models + + +//DTO this interface is crreated in case you want to create a userLocal too, to play offline +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 index 383a589..9e52406 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserRemote.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/models/UserRemote.kt @@ -1,9 +1,9 @@ -package com.frannazario.proyectoandroid.data.models - - -//DTO -data class UserRemote ( - override var username: String = "error", - override var userimage: String = "", - var scores: List = emptyList() +package com.frannazario.proyectoandroid.data.models + + +//DTO +data class UserRemote ( + override var username: String = "error", + override var userimage: String = "", + var scores: List = emptyList() ) : UserModel \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/CategoriesRepository.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/CategoriesRepository.kt index 9400bc7..459bd12 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/CategoriesRepository.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/CategoriesRepository.kt @@ -1,17 +1,17 @@ -package com.frannazario.proyectoandroid.data.repositories - -import com.frannazario.proyectoandroid.data.responses.CategoriesResponse -import com.frannazario.proyectoandroid.presentation.utils.CategoryEnum -import kotlinx.coroutines.flow.flow -import java.lang.Exception - -class CategoriesRepository { - - fun getCategories() = flow { - try { - emit(CategoriesResponse.Success(CategoryEnum.values().toList())) - } catch (e: Exception) { - emit(CategoriesResponse.Error(e.message ?: "Error genérico")) - } - } +package com.frannazario.proyectoandroid.data.repositories + +import com.frannazario.proyectoandroid.data.responses.CategoriesResponse +import com.frannazario.proyectoandroid.presentation.utils.CategoryEnum +import kotlinx.coroutines.flow.flow +import java.lang.Exception + +class CategoriesRepository { + + fun getCategories() = flow { + try { + emit(CategoriesResponse.Success(CategoryEnum.values().toList())) + } catch (e: Exception) { + emit(CategoriesResponse.Error(e.message ?: "Error genérico")) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/PasswordRecoveryRepository.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/PasswordRecoveryRepository.kt index aa0170e..97a62ab 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/PasswordRecoveryRepository.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/PasswordRecoveryRepository.kt @@ -1,28 +1,28 @@ -package com.frannazario.proyectoandroid.data.repositories - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import com.frannazario.proyectoandroid.data.responses.PasswordRecoveryResponse -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.google.firebase.auth.FirebaseAuth - -class PasswordRecoveryRepository { - private val auth: FirebaseAuth = FirebaseAuth.getInstance() - - fun recover (email: String): LiveData { - val resultLiveData = MutableLiveData() - - auth.sendPasswordResetEmail(email) - .addOnCompleteListener { task -> - if (task.isSuccessful) { - val user = auth.currentUser - resultLiveData.value = PasswordRecoveryResponse.Success(user) - } else { - val error = task.exception?.message ?: "Error desconocido" - val field = FieldEnum.EMAIL_FIELD // Replace with the appropriate field - resultLiveData.value = PasswordRecoveryResponse.Error(error, field) - } - } - return resultLiveData - } +package com.frannazario.proyectoandroid.data.repositories + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.frannazario.proyectoandroid.data.responses.PasswordRecoveryResponse +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.google.firebase.auth.FirebaseAuth + +class PasswordRecoveryRepository { + private val auth: FirebaseAuth = FirebaseAuth.getInstance() + + fun recover (email: String): LiveData { + val resultLiveData = MutableLiveData() + + auth.sendPasswordResetEmail(email) + .addOnCompleteListener { task -> + if (task.isSuccessful) { + val user = auth.currentUser + resultLiveData.value = PasswordRecoveryResponse.Success(user) + } else { + val error = task.exception?.message ?: "Error desconocido" + val field = FieldEnum.EMAIL_FIELD // Replace with the appropriate field + resultLiveData.value = PasswordRecoveryResponse.Error(error, field) + } + } + return resultLiveData + } } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/QuestionsRepository.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/QuestionsRepository.kt index 2d20347..de697ec 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/QuestionsRepository.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/QuestionsRepository.kt @@ -1,34 +1,34 @@ -package com.frannazario.proyectoandroid.data.repositories - -import android.content.ContentValues.TAG -import android.content.Context -import android.util.Log -import com.frannazario.proyectoandroid.data.datasources.QuestionsLocalDataSource -import com.frannazario.proyectoandroid.data.datasources.QuestionsRemoteDataSource -import com.frannazario.proyectoandroid.data.responses.QuestionsResponse -import kotlinx.coroutines.flow.flow - -class QuestionsRepository { - private val remoteDataSource = QuestionsRemoteDataSource() - private val localDataSource = QuestionsLocalDataSource() - - fun getQuestions(context: Context, id: Int) = flow { - try { - val questions = remoteDataSource.getQuestions(context = context, id) - if (questions.isEmpty()){ - throw Exception() - } - localDataSource.saveQuestions(context = context, questions = questions) - emit(QuestionsResponse.Success(questions = questions)) - } catch (e: Exception) { - try { - val questions = localDataSource.getQuestions(context = context, id = id) - emit(QuestionsResponse.Success(questions = questions)) - }catch (e: Exception){ - emit(QuestionsResponse.Error(e.message ?: "Error genérico")) - Log.e(TAG, e.message ?: "Error generico") - } - } - } - +package com.frannazario.proyectoandroid.data.repositories + +import android.content.ContentValues.TAG +import android.content.Context +import android.util.Log +import com.frannazario.proyectoandroid.data.datasources.QuestionsLocalDataSource +import com.frannazario.proyectoandroid.data.datasources.QuestionsRemoteDataSource +import com.frannazario.proyectoandroid.data.responses.QuestionsResponse +import kotlinx.coroutines.flow.flow + +class QuestionsRepository { + private val remoteDataSource = QuestionsRemoteDataSource() + private val localDataSource = QuestionsLocalDataSource() + + fun getQuestions(context: Context, id: Int) = flow { + try { + val questions = remoteDataSource.getQuestions(context = context, id) + if (questions.isEmpty()){ + throw Exception() + } + localDataSource.saveQuestions(context = context, questions = questions) + emit(QuestionsResponse.Success(questions = questions)) + } catch (e: Exception) { + try { + val questions = localDataSource.getQuestions(context = context, id = id) + emit(QuestionsResponse.Success(questions = questions)) + }catch (e: Exception){ + emit(QuestionsResponse.Error(e.message ?: "Error genérico")) + Log.e(TAG, e.message ?: "Error generico") + } + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/ScoreRepository.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/ScoreRepository.kt index 62c56b7..bf8953e 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/ScoreRepository.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/ScoreRepository.kt @@ -1,37 +1,37 @@ -package com.frannazario.proyectoandroid.data.repositories - -import android.content.Context -import com.frannazario.proyectoandroid.data.datasources.ScoreLocalDataSource -import com.frannazario.proyectoandroid.data.models.Score -import com.frannazario.proyectoandroid.data.responses.ScoresResponse -import kotlinx.coroutines.flow.flow - -class ScoreRepository { - private val localDataSource = ScoreLocalDataSource() - - fun getScores(context: Context) = flow { - try { - val scores = localDataSource.getScores(context = context) - emit(ScoresResponse.Success(scores = scores)) - }catch (e: Exception){ - emit(ScoresResponse.Error(e.message ?: "Error genérico")) - } - } - fun saveScore(context: Context, score: Score) = flow { - try { - val scores = localDataSource.saveScore(context = context, score) - emit(ScoresResponse.Success(scores = scores)) - }catch (e: Exception){ - emit(ScoresResponse.Error(e.message ?: "Error genérico")) - } - } - fun wipeScores(context: Context) = flow { - try { - val scores = localDataSource.wipeScores(context = context) - emit(ScoresResponse.Success(scores = scores)) - }catch (e: Exception){ - emit(ScoresResponse.Error(e.message ?: "Error genérico")) - } - } - +package com.frannazario.proyectoandroid.data.repositories + +import android.content.Context +import com.frannazario.proyectoandroid.data.datasources.ScoreLocalDataSource +import com.frannazario.proyectoandroid.data.models.Score +import com.frannazario.proyectoandroid.data.responses.ScoresResponse +import kotlinx.coroutines.flow.flow + +class ScoreRepository { + private val localDataSource = ScoreLocalDataSource() + + fun getScores(context: Context) = flow { + try { + val scores = localDataSource.getScores(context = context) + emit(ScoresResponse.Success(scores = scores)) + }catch (e: Exception){ + emit(ScoresResponse.Error(e.message ?: "Error genérico")) + } + } + fun saveScore(context: Context, score: Score) = flow { + try { + val scores = localDataSource.saveScore(context = context, score) + emit(ScoresResponse.Success(scores = scores)) + }catch (e: Exception){ + emit(ScoresResponse.Error(e.message ?: "Error genérico")) + } + } + fun wipeScores(context: Context) = flow { + try { + val scores = localDataSource.wipeScores(context = context) + emit(ScoresResponse.Success(scores = scores)) + }catch (e: Exception){ + emit(ScoresResponse.Error(e.message ?: "Error genérico")) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SigninRepository.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SigninRepository.kt index 272b7fa..94d7139 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SigninRepository.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SigninRepository.kt @@ -1,28 +1,28 @@ -package com.frannazario.proyectoandroid.data.repositories - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import com.frannazario.proyectoandroid.data.responses.SigninResponse -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.google.firebase.auth.FirebaseAuth - -class SigninRepository{ - private val auth: FirebaseAuth = FirebaseAuth.getInstance() - - fun login(email: String, password: String): LiveData { - val resultLiveData = MutableLiveData() - - auth.signInWithEmailAndPassword(email, password) - .addOnCompleteListener { task -> - if (task.isSuccessful) { - val user = auth.currentUser - resultLiveData.value = SigninResponse.Success(user) - } else { - val error = task.exception?.message ?: "Error desconocido" - val field = FieldEnum.EMAIL_FIELD // Replace with the appropriate field - resultLiveData.value = SigninResponse.Error(error, field) - } - } - return resultLiveData - } +package com.frannazario.proyectoandroid.data.repositories + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.frannazario.proyectoandroid.data.responses.SigninResponse +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.google.firebase.auth.FirebaseAuth + +class SigninRepository{ + private val auth: FirebaseAuth = FirebaseAuth.getInstance() + + fun login(email: String, password: String): LiveData { + val resultLiveData = MutableLiveData() + + auth.signInWithEmailAndPassword(email, password) + .addOnCompleteListener { task -> + if (task.isSuccessful) { + val user = auth.currentUser + resultLiveData.value = SigninResponse.Success(user) + } else { + val error = task.exception?.message ?: "Error desconocido" + val field = FieldEnum.EMAIL_FIELD // Replace with the appropriate field + resultLiveData.value = SigninResponse.Error(error, field) + } + } + return resultLiveData + } } \ 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 index e943830..cd2e017 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SignoutRepository.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SignoutRepository.kt @@ -1,25 +1,25 @@ -package com.frannazario.proyectoandroid.data.repositories - -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() - if (auth.currentUser == null) { - emit(SignoutResponse.Success("Sucess")) - } else { - throw Exception() - } - } catch (e: Exception) { - - emit(SignoutResponse.Error(e.message ?: "Error generico")) - } - } - +package com.frannazario.proyectoandroid.data.repositories + +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() + 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/SignupRepository.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SignupRepository.kt index 500e553..58d7be0 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SignupRepository.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/repositories/SignupRepository.kt @@ -1,27 +1,27 @@ -package com.frannazario.proyectoandroid.data.repositories - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import com.frannazario.proyectoandroid.data.responses.SignupResponse -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.google.firebase.auth.FirebaseAuth - -class SignupRepository { - private val auth = FirebaseAuth.getInstance() - - fun register(email: String, password: String): LiveData { - val resultLiveData = MutableLiveData() - - auth.createUserWithEmailAndPassword(email, password) - .addOnCompleteListener { task -> - if (task.isSuccessful) { - val user = auth.currentUser - resultLiveData.value = SignupResponse.Success(user) - } else { - val error = task.exception?.message ?: "Error desconocido" - resultLiveData.value = SignupResponse.Error(error, FieldEnum.EMAIL_FIELD) - } - } - return resultLiveData - } +package com.frannazario.proyectoandroid.data.repositories + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import com.frannazario.proyectoandroid.data.responses.SignupResponse +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.google.firebase.auth.FirebaseAuth + +class SignupRepository { + private val auth = FirebaseAuth.getInstance() + + fun register(email: String, password: String): LiveData { + val resultLiveData = MutableLiveData() + + auth.createUserWithEmailAndPassword(email, password) + .addOnCompleteListener { task -> + if (task.isSuccessful) { + val user = auth.currentUser + resultLiveData.value = SignupResponse.Success(user) + } else { + val error = task.exception?.message ?: "Error desconocido" + resultLiveData.value = SignupResponse.Error(error, FieldEnum.EMAIL_FIELD) + } + } + return resultLiveData + } } \ 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 fbccfc1..1f15ed9 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,32 +1,32 @@ -package com.frannazario.proyectoandroid.data.repositories - -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 - -class UserRepository { - private val remoteDataSource = UsersRemoteDataSource() - - fun getUser(uid: String, email: String) = flow { - try { - 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") - } - } - - 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") - } - } - -} +package com.frannazario.proyectoandroid.data.repositories + +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 + +class UserRepository { + private val remoteDataSource = UsersRemoteDataSource() + + fun getUser(uid: String, email: String) = flow { + try { + 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") + } + } + + 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/CategoriesResponse.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/CategoriesResponse.kt index 8dde7b9..494d007 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/CategoriesResponse.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/CategoriesResponse.kt @@ -1,8 +1,8 @@ -package com.frannazario.proyectoandroid.data.responses - -import com.frannazario.proyectoandroid.presentation.utils.CategoryEnum - -sealed class CategoriesResponse { - data class Success(val categories: List) : CategoriesResponse() - data class Error(val error: String): CategoriesResponse() +package com.frannazario.proyectoandroid.data.responses + +import com.frannazario.proyectoandroid.presentation.utils.CategoryEnum + +sealed class CategoriesResponse { + data class Success(val categories: List) : CategoriesResponse() + data class Error(val error: String): CategoriesResponse() } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/PasswordRecoveryResponse.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/PasswordRecoveryResponse.kt index 56314f2..edd7399 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/PasswordRecoveryResponse.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/PasswordRecoveryResponse.kt @@ -1,9 +1,9 @@ -package com.frannazario.proyectoandroid.data.responses - -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.google.firebase.auth.FirebaseUser - -sealed class PasswordRecoveryResponse { - data class Success(val user: FirebaseUser?): PasswordRecoveryResponse() - data class Error(val error: String, val field: FieldEnum): PasswordRecoveryResponse() +package com.frannazario.proyectoandroid.data.responses + +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.google.firebase.auth.FirebaseUser + +sealed class PasswordRecoveryResponse { + data class Success(val user: FirebaseUser?): PasswordRecoveryResponse() + data class Error(val error: String, val field: FieldEnum): PasswordRecoveryResponse() } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/QuestionsResponse.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/QuestionsResponse.kt index 93c7f9b..852cd0e 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/QuestionsResponse.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/QuestionsResponse.kt @@ -1,8 +1,8 @@ -package com.frannazario.proyectoandroid.data.responses - -import com.frannazario.proyectoandroid.data.models.Question - -sealed class QuestionsResponse { - data class Success(val questions: List) : QuestionsResponse() - data class Error(val error: String): QuestionsResponse() +package com.frannazario.proyectoandroid.data.responses + +import com.frannazario.proyectoandroid.data.models.Question + +sealed class QuestionsResponse { + data class Success(val questions: List) : QuestionsResponse() + data class Error(val error: String): QuestionsResponse() } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/ScoresResponse.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/ScoresResponse.kt index 0fc4ecd..da49338 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/ScoresResponse.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/ScoresResponse.kt @@ -1,8 +1,8 @@ -package com.frannazario.proyectoandroid.data.responses - -import com.frannazario.proyectoandroid.data.models.Score - -sealed class ScoresResponse { - data class Success(val scores: List) : ScoresResponse() - data class Error(val error: String): ScoresResponse() -} +package com.frannazario.proyectoandroid.data.responses + +import com.frannazario.proyectoandroid.data.models.Score + +sealed class ScoresResponse { + data class Success(val scores: List) : ScoresResponse() + data class Error(val error: String): ScoresResponse() +} diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SigninResponse.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SigninResponse.kt index 9f481c7..3b332a5 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SigninResponse.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SigninResponse.kt @@ -1,10 +1,10 @@ -package com.frannazario.proyectoandroid.data.responses - -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.google.firebase.auth.FirebaseUser - -sealed class SigninResponse { - - data class Success(val user: FirebaseUser?): SigninResponse() - data class Error(val error: String, val field: FieldEnum): SigninResponse() +package com.frannazario.proyectoandroid.data.responses + +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.google.firebase.auth.FirebaseUser + +sealed class SigninResponse { + + data class Success(val user: FirebaseUser?): SigninResponse() + data class Error(val error: String, val field: FieldEnum): SigninResponse() } \ No newline at end of file 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 index 090c235..21f7e5f 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SignoutResponse.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SignoutResponse.kt @@ -1,6 +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() +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/SignupResponse.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SignupResponse.kt index f7170f9..55eabbe 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SignupResponse.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/responses/SignupResponse.kt @@ -1,9 +1,9 @@ -package com.frannazario.proyectoandroid.data.responses - -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.google.firebase.auth.FirebaseUser - -sealed class SignupResponse { - data class Success(val user: FirebaseUser?): SignupResponse() - data class Error(val error: String, val field: FieldEnum): SignupResponse() +package com.frannazario.proyectoandroid.data.responses + +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.google.firebase.auth.FirebaseUser + +sealed class SignupResponse { + data class Success(val user: FirebaseUser?): SignupResponse() + data class Error(val error: String, val field: FieldEnum): SignupResponse() } \ 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 cf5f9cb..59a8dcd 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,8 @@ -package com.frannazario.proyectoandroid.data.responses - -import com.frannazario.proyectoandroid.data.models.UserRemote - -sealed class UsersResponse { - data class Success(val user: UserRemote): UsersResponse() - data class Error(val error: String): UsersResponse() -} +package com.frannazario.proyectoandroid.data.responses + +import com.frannazario.proyectoandroid.data.models.UserRemote + +sealed class 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/utils/CategoryEnum.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/utils/CategoryEnum.kt index 5eefe1b..6ea55f7 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/utils/CategoryEnum.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/utils/CategoryEnum.kt @@ -1,23 +1,23 @@ -package com.frannazario.proyectoandroid.presentation.utils - -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import com.frannazario.proyectoandroid.R - -enum class CategoryEnum( - val id: Int, - @StringRes val title: Int, - @DrawableRes val icon: Int, - val url: String -) { - SCIENCE(1, R.string.category_science, R.drawable.ic_science, "https://es.wikipedia.org/wiki/Ciencia"), - ART(2, R.string.category_art, R.drawable.ic_art, "https://es.wikipedia.org/wiki/Arte"), - ENTERTAINMENT(3, R.string.category_entertainment, R.drawable.ic_entertainment, ""), - GEOGRAPHY(4, R.string.category_geography, R.drawable.ic_geography, ""), - HISTORY(5, R.string.category_history, R.drawable.ic_history, ""), - POP(6, R.string.category_pop, R.drawable.ic_pop, ""), - SPORTS(7, R.string.category_sports, R.drawable.ic_sports, ""), - GENERAL(8, R.string.category_general, R.drawable.ic_general, "") -} - +package com.frannazario.proyectoandroid.presentation.utils + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import com.frannazario.proyectoandroid.R + +enum class CategoryEnum( + val id: Int, + @StringRes val title: Int, + @DrawableRes val icon: Int, + val url: String +) { + SCIENCE(1, R.string.category_science, R.drawable.ic_science, "https://es.wikipedia.org/wiki/Ciencia"), + ART(2, R.string.category_art, R.drawable.ic_art, "https://es.wikipedia.org/wiki/Arte"), + ENTERTAINMENT(3, R.string.category_entertainment, R.drawable.ic_entertainment, ""), + GEOGRAPHY(4, R.string.category_geography, R.drawable.ic_geography, ""), + HISTORY(5, R.string.category_history, R.drawable.ic_history, ""), + POP(6, R.string.category_pop, R.drawable.ic_pop, ""), + SPORTS(7, R.string.category_sports, R.drawable.ic_sports, ""), + GENERAL(8, R.string.category_general, R.drawable.ic_general, "") +} + //fun getCategoryById(id: Int) = CategoryEnum.values().firstOrNull { it.id == id } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/utils/StringUtils.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/utils/StringUtils.kt index 1dc4daf..aab0ec2 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/utils/StringUtils.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/utils/StringUtils.kt @@ -1,49 +1,49 @@ -package com.frannazario.proyectoandroid.data.utils - -fun String?.isEmail(): Boolean { - val emailRegex = "[a-zA-Z0-9+._%\\-]{1,256}" + - "@" + - "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" + - "(" + - "\\." + - "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" + - ")+" - return this?.matches(emailRegex.toRegex()) ?: false -} - -fun String?.isValidPassword(): Boolean { - val passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*?[#?!@\$%^&*-])[a-zA-Z\\w\\W]{8,}\$" - return this?.matches(passwordRegex.toRegex()) ?: false -} - -fun checkEmail(email: String?): ErrorTypes? { - return if (email.isNullOrBlank()) { - ErrorTypes.EMAIL_EMPTY - } else if (email.isEmail()) { - null - } else { - ErrorTypes.EMAIL_WRONG_FORMAT - } -} - -fun checkPassword(password: String?): ErrorTypes? { - return if (password.isNullOrBlank()) { - ErrorTypes.PASSWORD_TOO_SHORT - } else if (password.isValidPassword()) { - null - } else { - ErrorTypes.PASSWORD_WRONG_FORMAT - } -} - -enum class ErrorTypes(val error: String) { - EMAIL_EMPTY("Email vacio"), - EMAIL_WRONG_FORMAT("El formato del email es incorrecto"), - PASSWORD_TOO_SHORT("Contraseña demasiado corta"), - PASSWORD_WRONG_FORMAT("La password debe contener una minuscula, una mayuscula, un número y un simbolo") -} - -enum class FieldEnum { - PASSWORD_FIELD, - EMAIL_FIELD +package com.frannazario.proyectoandroid.data.utils + +fun String?.isEmail(): Boolean { + val emailRegex = "[a-zA-Z0-9+._%\\-]{1,256}" + + "@" + + "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" + + "(" + + "\\." + + "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" + + ")+" + return this?.matches(emailRegex.toRegex()) ?: false +} + +fun String?.isValidPassword(): Boolean { + val passwordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*?[#?!@\$%^&*-])[a-zA-Z\\w\\W]{8,}\$" + return this?.matches(passwordRegex.toRegex()) ?: false +} + +fun checkEmail(email: String?): ErrorTypes? { + return if (email.isNullOrBlank()) { + ErrorTypes.EMAIL_EMPTY + } else if (email.isEmail()) { + null + } else { + ErrorTypes.EMAIL_WRONG_FORMAT + } +} + +fun checkPassword(password: String?): ErrorTypes? { + return if (password.isNullOrBlank()) { + ErrorTypes.PASSWORD_TOO_SHORT + } else if (password.isValidPassword()) { + null + } else { + ErrorTypes.PASSWORD_WRONG_FORMAT + } +} + +enum class ErrorTypes(val error: String) { + EMAIL_EMPTY("Email vacio"), + EMAIL_WRONG_FORMAT("El formato del email es incorrecto"), + PASSWORD_TOO_SHORT("Contraseña demasiado corta"), + PASSWORD_WRONG_FORMAT("La password debe contener una minuscula, una mayuscula, un número y un simbolo") +} + +enum class FieldEnum { + PASSWORD_FIELD, + EMAIL_FIELD } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/CategoriesViewModel.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/CategoriesViewModel.kt index f3e2797..ec16762 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/CategoriesViewModel.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/CategoriesViewModel.kt @@ -1,34 +1,34 @@ -package com.frannazario.proyectoandroid.data.viewmodels - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.frannazario.proyectoandroid.data.repositories.CategoriesRepository -import com.frannazario.proyectoandroid.data.responses.CategoriesResponse -import com.frannazario.proyectoandroid.presentation.utils.CategoryEnum -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.update - -class CategoriesViewModel(private val repository: CategoriesRepository = CategoriesRepository()): ViewModel() { - private val mutableState = MutableStateFlow(CategoriesViewState()) - val categoriesViewState: StateFlow = mutableState - - fun getCategories() { - mutableState.update { CategoriesViewState(isLoading = true) } - repository.getCategories().onEach { response -> - when (response) { - is CategoriesResponse.Success -> mutableState.update { CategoriesViewState(data = response.categories) } - is CategoriesResponse.Error -> mutableState.update { CategoriesViewState(error = response.error) } - } - }.launchIn(viewModelScope) - } - -} - -data class CategoriesViewState( - val data: List? = null, - val error: String? = null, - val isLoading: Boolean = false +package com.frannazario.proyectoandroid.data.viewmodels + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.frannazario.proyectoandroid.data.repositories.CategoriesRepository +import com.frannazario.proyectoandroid.data.responses.CategoriesResponse +import com.frannazario.proyectoandroid.presentation.utils.CategoryEnum +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.update + +class CategoriesViewModel(private val repository: CategoriesRepository = CategoriesRepository()): ViewModel() { + private val mutableState = MutableStateFlow(CategoriesViewState()) + val categoriesViewState: StateFlow = mutableState + + fun getCategories() { + mutableState.update { CategoriesViewState(isLoading = true) } + repository.getCategories().onEach { response -> + when (response) { + is CategoriesResponse.Success -> mutableState.update { CategoriesViewState(data = response.categories) } + is CategoriesResponse.Error -> mutableState.update { CategoriesViewState(error = response.error) } + } + }.launchIn(viewModelScope) + } + +} + +data class CategoriesViewState( + val data: List? = null, + val error: String? = null, + val isLoading: Boolean = false ) \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/PasswordRecoveryViewModel.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/PasswordRecoveryViewModel.kt index b884704..a41a152 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/PasswordRecoveryViewModel.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/PasswordRecoveryViewModel.kt @@ -1,39 +1,39 @@ -package com.frannazario.proyectoandroid.data.viewmodels - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import com.frannazario.proyectoandroid.data.repositories.PasswordRecoveryRepository -import com.frannazario.proyectoandroid.data.responses.PasswordRecoveryResponse -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.frannazario.proyectoandroid.data.utils.checkEmail - -class PasswordRecoveryViewModel(private val repository: PasswordRecoveryRepository = PasswordRecoveryRepository()): ViewModel() { - private val passwordRecoveryResponseLiveData = MutableLiveData() - - fun getPasswordRecoveryResultLiveData(): LiveData { - return passwordRecoveryResponseLiveData - } - - fun recover (email: String) { - val emailState = checkEmail(email) - - if(emailState == null) { - val response = repository.recover( - email - ) - response.observeForever { passwordRecoveryResponse -> - passwordRecoveryResponseLiveData.postValue(passwordRecoveryResponse) - } - } else { - passwordRecoveryResponseLiveData.postValue( - PasswordRecoveryResponse.Error( - emailState.error, - FieldEnum.EMAIL_FIELD - ) - ) - } - val response = repository.recover(email) - passwordRecoveryResponseLiveData.postValue(response.value) - } -} +package com.frannazario.proyectoandroid.data.viewmodels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.frannazario.proyectoandroid.data.repositories.PasswordRecoveryRepository +import com.frannazario.proyectoandroid.data.responses.PasswordRecoveryResponse +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.frannazario.proyectoandroid.data.utils.checkEmail + +class PasswordRecoveryViewModel(private val repository: PasswordRecoveryRepository = PasswordRecoveryRepository()): ViewModel() { + private val passwordRecoveryResponseLiveData = MutableLiveData() + + fun getPasswordRecoveryResultLiveData(): LiveData { + return passwordRecoveryResponseLiveData + } + + fun recover (email: String) { + val emailState = checkEmail(email) + + if(emailState == null) { + val response = repository.recover( + email + ) + response.observeForever { passwordRecoveryResponse -> + passwordRecoveryResponseLiveData.postValue(passwordRecoveryResponse) + } + } else { + passwordRecoveryResponseLiveData.postValue( + PasswordRecoveryResponse.Error( + emailState.error, + FieldEnum.EMAIL_FIELD + ) + ) + } + val response = repository.recover(email) + passwordRecoveryResponseLiveData.postValue(response.value) + } +} 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 3c95ccb..4fee043 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 @@ -1,128 +1,128 @@ -package com.frannazario.proyectoandroid.data.viewmodels - -import android.content.Context -import androidx.compose.runtime.MutableState -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 -import com.frannazario.proyectoandroid.data.responses.ScoresResponse -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -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(), - userViewModel: UserViewModel -): ViewModel() { - private val userVM = userViewModel - private val mutableStateQuestions = MutableStateFlow(QuestionsViewState()) - val questionsViewState: StateFlow = mutableStateQuestions - private val mutableStateScores = MutableStateFlow(ScoreViewState()) - val scoresViewState: StateFlow = mutableStateScores - - fun getQuestionList(id: Int) { - mutableStateQuestions.update { it.copy(isLoading = true) } - val response = repositoryQuestions.getQuestions(context = context , id) - response.onEach { questionsResponse -> - when (questionsResponse) { - is QuestionsResponse.Success -> { - mutableStateQuestions.update { it.copy(questions = questionsResponse.questions, isLoading = false) } - } - is QuestionsResponse.Error -> { - mutableStateQuestions.update { it.copy(error = questionsResponse.error, isLoading = false) } - } - } - }.flowOn(Dispatchers.IO).launchIn(viewModelScope) - } - - fun getScoreList() { - val response = repositoryScores.getScores(context = context) - response.onEach { scoresResponse -> - when (scoresResponse) { - is ScoresResponse.Success -> { - mutableStateScores.update { it.copy(scores = scoresResponse.scores) } - } - is ScoresResponse.Error -> { - mutableStateScores.update { it.copy(error = scoresResponse.error) } - } - } - }.flowOn(Dispatchers.IO).launchIn(viewModelScope) - } - - fun saveScore(score: Score) { - val response = repositoryScores.saveScore(context = context, score) - response.onEach { scoresResponse -> - when (scoresResponse) { - is ScoresResponse.Success -> { - mutableStateScores.update { it.copy(scores = scoresResponse.scores) - } - if(score.category != "total"){ - mutableStateScores.update { currentState -> - currentState.copy(scoresDone = currentState.scoresDone + 1) - } - } - } - is ScoresResponse.Error -> { - mutableStateScores.update { it.copy(error = scoresResponse.error) } - } - } - }.flowOn(Dispatchers.IO).launchIn(viewModelScope) - } - - fun saveTotalScore() { - var totalScore = 0 - scoresViewState.value.scores?.forEach { score -> - totalScore += score.score.toInt() - } - userVM.updateUserScores(TotalScore(totalScore.toString(), Date().time.toString())) - val response = repositoryScores.wipeScores(context = context) - response.onEach { scoresResponse -> - when (scoresResponse) { - is ScoresResponse.Success -> { - mutableStateScores.update { it.copy(scores = scoresResponse.scores, scoresDone = 0) - } - } - is ScoresResponse.Error -> { - mutableStateScores.update { it.copy(error = scoresResponse.error) } - } - } - }.flowOn(Dispatchers.IO).launchIn(viewModelScope) - } - - fun compareAnswer(s: String, response: String?): Boolean { - return s === response - } - - fun getQuestion(questionList: List): Question { - return questionList.randomOrNull() ?: Question() - } - - fun shuffle(randomQuestion: MutableState): List = listOf( - randomQuestion.value?.response1 ?: "1", - randomQuestion.value?.response2 ?: "2", - randomQuestion.value?.response3 ?: "3" - ).shuffled() -} - -data class QuestionsViewState( - val questions: List? = null, - val error: String? = null, - val isLoading: Boolean = false -) -data class ScoreViewState( - val scores: List? = null, - var scoresDone: Int = 0, - val error: String? = null, -) +package com.frannazario.proyectoandroid.data.viewmodels + +import android.content.Context +import androidx.compose.runtime.MutableState +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 +import com.frannazario.proyectoandroid.data.responses.ScoresResponse +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +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(), + userViewModel: UserViewModel +): ViewModel() { + private val userVM = userViewModel + private val mutableStateQuestions = MutableStateFlow(QuestionsViewState()) + val questionsViewState: StateFlow = mutableStateQuestions + private val mutableStateScores = MutableStateFlow(ScoreViewState()) + val scoresViewState: StateFlow = mutableStateScores + + fun getQuestionList(id: Int) { + mutableStateQuestions.update { it.copy(isLoading = true) } + val response = repositoryQuestions.getQuestions(context = context , id) + response.onEach { questionsResponse -> + when (questionsResponse) { + is QuestionsResponse.Success -> { + mutableStateQuestions.update { it.copy(questions = questionsResponse.questions, isLoading = false) } + } + is QuestionsResponse.Error -> { + mutableStateQuestions.update { it.copy(error = questionsResponse.error, isLoading = false) } + } + } + }.flowOn(Dispatchers.IO).launchIn(viewModelScope) + } + + fun getScoreList() { + val response = repositoryScores.getScores(context = context) + response.onEach { scoresResponse -> + when (scoresResponse) { + is ScoresResponse.Success -> { + mutableStateScores.update { it.copy(scores = scoresResponse.scores) } + } + is ScoresResponse.Error -> { + mutableStateScores.update { it.copy(error = scoresResponse.error) } + } + } + }.flowOn(Dispatchers.IO).launchIn(viewModelScope) + } + + fun saveScore(score: Score) { + val response = repositoryScores.saveScore(context = context, score) + response.onEach { scoresResponse -> + when (scoresResponse) { + is ScoresResponse.Success -> { + mutableStateScores.update { it.copy(scores = scoresResponse.scores) + } + if(score.category != "total"){ + mutableStateScores.update { currentState -> + currentState.copy(scoresDone = currentState.scoresDone + 1) + } + } + } + is ScoresResponse.Error -> { + mutableStateScores.update { it.copy(error = scoresResponse.error) } + } + } + }.flowOn(Dispatchers.IO).launchIn(viewModelScope) + } + + fun saveTotalScore() { + var totalScore = 0 + scoresViewState.value.scores?.forEach { score -> + totalScore += score.score.toInt() + } + userVM.updateUserScores(TotalScore(totalScore.toString(), Date().time.toString())) + val response = repositoryScores.wipeScores(context = context) + response.onEach { scoresResponse -> + when (scoresResponse) { + is ScoresResponse.Success -> { + mutableStateScores.update { it.copy(scores = scoresResponse.scores, scoresDone = 0) + } + } + is ScoresResponse.Error -> { + mutableStateScores.update { it.copy(error = scoresResponse.error) } + } + } + }.flowOn(Dispatchers.IO).launchIn(viewModelScope) + } + + fun compareAnswer(s: String, response: String?): Boolean { + return s === response + } + + fun getQuestion(questionList: List): Question { + return questionList.randomOrNull() ?: Question() + } + + fun shuffle(randomQuestion: MutableState): List = listOf( + randomQuestion.value?.response1 ?: "1", + randomQuestion.value?.response2 ?: "2", + randomQuestion.value?.response3 ?: "3" + ).shuffled() +} + +data class QuestionsViewState( + val questions: List? = null, + val error: String? = null, + val isLoading: Boolean = false +) +data class ScoreViewState( + val scores: List? = null, + var scoresDone: Int = 0, + val error: String? = null, +) diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/SigninViewModel.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/SigninViewModel.kt index 11eb00b..02189bf 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/SigninViewModel.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/SigninViewModel.kt @@ -1,43 +1,43 @@ -package com.frannazario.proyectoandroid.data.viewmodels - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import com.frannazario.proyectoandroid.data.repositories.SigninRepository -import com.frannazario.proyectoandroid.data.responses.SigninResponse -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.frannazario.proyectoandroid.data.utils.checkEmail -import com.frannazario.proyectoandroid.data.utils.checkPassword - -class SigninViewModel(private val repository: SigninRepository= SigninRepository()): ViewModel() { - private val siginResponseLiveData = MutableLiveData() - fun getSigninResultLiveData(): LiveData { - return siginResponseLiveData - } - fun signin(email: String?, password: String?) { - val emailState = checkEmail(email) - val passState = checkPassword(password) - - if(emailState == null && passState == null) { - val response = repository.login( - email ?: "", - password ?: "") - response.observeForever { loginResponse -> - siginResponseLiveData.postValue(loginResponse) - } - } else if (emailState != null) { - siginResponseLiveData.postValue( - SigninResponse.Error( - emailState.error, - FieldEnum.EMAIL_FIELD - ) - ) - } else if (passState != null) { - siginResponseLiveData.postValue( - SigninResponse.Error(passState.error, FieldEnum.PASSWORD_FIELD) - ) - } - } -} - - +package com.frannazario.proyectoandroid.data.viewmodels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.frannazario.proyectoandroid.data.repositories.SigninRepository +import com.frannazario.proyectoandroid.data.responses.SigninResponse +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.frannazario.proyectoandroid.data.utils.checkEmail +import com.frannazario.proyectoandroid.data.utils.checkPassword + +class SigninViewModel(private val repository: SigninRepository= SigninRepository()): ViewModel() { + private val siginResponseLiveData = MutableLiveData() + fun getSigninResultLiveData(): LiveData { + return siginResponseLiveData + } + fun signin(email: String?, password: String?) { + val emailState = checkEmail(email) + val passState = checkPassword(password) + + if(emailState == null && passState == null) { + val response = repository.login( + email ?: "", + password ?: "") + response.observeForever { loginResponse -> + siginResponseLiveData.postValue(loginResponse) + } + } else if (emailState != null) { + siginResponseLiveData.postValue( + SigninResponse.Error( + emailState.error, + FieldEnum.EMAIL_FIELD + ) + ) + } else if (passState != null) { + siginResponseLiveData.postValue( + SigninResponse.Error(passState.error, FieldEnum.PASSWORD_FIELD) + ) + } + } +} + + diff --git a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/SignupViewModel.kt b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/SignupViewModel.kt index 218b876..fc5f449 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/SignupViewModel.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/data/viewmodels/SignupViewModel.kt @@ -1,47 +1,47 @@ -package com.frannazario.proyectoandroid.data.viewmodels - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import com.frannazario.proyectoandroid.data.repositories.SignupRepository -import com.frannazario.proyectoandroid.data.responses.SignupResponse -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.frannazario.proyectoandroid.data.utils.checkEmail -import com.frannazario.proyectoandroid.data.utils.checkPassword - -class SignupViewModel(private val repository: SignupRepository = SignupRepository()): ViewModel() { - - private val signinResponseLiveData = MutableLiveData() - - fun getSignupResultLiveData(): LiveData { - return signinResponseLiveData - } - - fun register(email: String?, password: String?) { - val emailState = checkEmail(email) - val passState = checkPassword(password) - - if(emailState == null && passState == null) { - val response = repository.register( - email ?: "", - password ?: "") - response.observeForever { signinResponse -> - signinResponseLiveData.postValue(signinResponse) - } - } else if (emailState != null) { - signinResponseLiveData.postValue( - SignupResponse.Error( - emailState.error, - FieldEnum.EMAIL_FIELD - ) - ) - } else if (passState != null) { - signinResponseLiveData.postValue( - SignupResponse.Error( - passState.error, - FieldEnum.PASSWORD_FIELD - ) - ) - } - } +package com.frannazario.proyectoandroid.data.viewmodels + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.frannazario.proyectoandroid.data.repositories.SignupRepository +import com.frannazario.proyectoandroid.data.responses.SignupResponse +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.frannazario.proyectoandroid.data.utils.checkEmail +import com.frannazario.proyectoandroid.data.utils.checkPassword + +class SignupViewModel(private val repository: SignupRepository = SignupRepository()): ViewModel() { + + private val signinResponseLiveData = MutableLiveData() + + fun getSignupResultLiveData(): LiveData { + return signinResponseLiveData + } + + fun register(email: String?, password: String?) { + val emailState = checkEmail(email) + val passState = checkPassword(password) + + if(emailState == null && passState == null) { + val response = repository.register( + email ?: "", + password ?: "") + response.observeForever { signinResponse -> + signinResponseLiveData.postValue(signinResponse) + } + } else if (emailState != null) { + signinResponseLiveData.postValue( + SignupResponse.Error( + emailState.error, + FieldEnum.EMAIL_FIELD + ) + ) + } else if (passState != null) { + signinResponseLiveData.postValue( + SignupResponse.Error( + passState.error, + FieldEnum.PASSWORD_FIELD + ) + ) + } + } } \ No newline at end of file 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 263c75d..ae3432d 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,93 +1,90 @@ -package com.frannazario.proyectoandroid.data.viewmodels - -import android.util.Log -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -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.google.firebase.auth.FirebaseAuth -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.flowOn -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.update - -class UserViewModel(private val userRepository: UserRepository = UserRepository(), private val signoutRepository: SignoutRepository = SignoutRepository()): ViewModel() { - - private val auth: FirebaseAuth = FirebaseAuth.getInstance() - private val mutableStateUser = MutableStateFlow(UserViewState()) - val userViewState: StateFlow = 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 -> { - 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) } - Log.e("prueba", mutableStateUser.value.user.toString()) - } - is UsersResponse.Error -> { - mutableStateUser.update { it.copy(error = userResponse.error) } - } - } - - }.flowOn(Dispatchers.IO).launchIn(viewModelScope) - Log.e("prueba2", mutableStateUser.value.user.toString()) - } -} -data class UserViewState( - val user: UserRemote = UserRemote(), - val error: String? = null, +package com.frannazario.proyectoandroid.data.viewmodels + +import android.util.Log +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +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.google.firebase.auth.FirebaseAuth +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.update + +class UserViewModel(private val userRepository: UserRepository = UserRepository(), private val signoutRepository: SignoutRepository = SignoutRepository()): ViewModel() { + + private val auth: FirebaseAuth = FirebaseAuth.getInstance() + private val mutableStateUser = MutableStateFlow(UserViewState()) + val userViewState: StateFlow = 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 -> { + 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.copy( userimage = userimage) + updateUser(user) + } + + fun updateUserScores(totalScore: TotalScore) { + val user: UserRemote = mutableStateUser.value.user.copy( scores = mutableStateUser.value.user.scores.plus(totalScore)) + updateUser(user) + } + + fun updateUsername(username: String) { + val user: UserRemote = mutableStateUser.value.user.copy( 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) } + Log.e("prueba", mutableStateUser.value.user.toString()) + } + is UsersResponse.Error -> { + mutableStateUser.update { it.copy(error = userResponse.error) } + } + } + + }.flowOn(Dispatchers.IO).launchIn(viewModelScope) + Log.e("prueba2", mutableStateUser.value.user.toString()) + } +} +data class UserViewState( + 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/AuthActivity.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/activities/AuthActivity.kt index 1784a11..bb98739 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/activities/AuthActivity.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/activities/AuthActivity.kt @@ -1,30 +1,31 @@ -package com.frannazario.proyectoandroid.presentation.activities - -import android.content.Intent -import android.os.Bundle -import androidx.fragment.app.FragmentActivity -import com.frannazario.proyectoandroid.databinding.ActivityAuthBinding -import com.google.firebase.auth.FirebaseAuth - -class AuthActivity : FragmentActivity() { - private lateinit var binding: ActivityAuthBinding - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - checkIfLogged() - binding = ActivityAuthBinding.inflate(layoutInflater) - setContentView(binding.root) - } - - private fun checkIfLogged(){ - val auth = FirebaseAuth.getInstance() - auth.currentUser?.let { - navigateToMain() - } - } - - private fun navigateToMain() { - val intent = Intent(this, MainActivity:: class.java) - startActivity(intent) - } +package com.frannazario.proyectoandroid.presentation.activities + +import android.content.Intent +import android.os.Bundle +import androidx.fragment.app.FragmentActivity +import com.frannazario.proyectoandroid.databinding.ActivityAuthBinding +import com.frannazario.proyectoandroid.databinding.FragmentLoginBinding +import com.google.firebase.auth.FirebaseAuth + +class AuthActivity : FragmentActivity() { + private lateinit var binding: ActivityAuthBinding + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + checkIfLogged() + binding = ActivityAuthBinding.inflate(layoutInflater) + setContentView(binding.root) + } + + private fun checkIfLogged(){ + val auth = FirebaseAuth.getInstance() + auth.currentUser?.let { + navigateToMain() + } + } + + private fun navigateToMain() { + val intent = Intent(this, MainActivity:: class.java) + startActivity(intent) + } } \ 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 83f0f1d..999bfe9 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,29 +1,29 @@ -package com.frannazario.proyectoandroid.presentation.activities - -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.ui.Modifier -import com.frannazario.proyectoandroid.presentation.navigation.AppNavigation -import com.frannazario.proyectoandroid.presentation.ui.theme.ProyectoAndroidTheme - -class MainActivity: ComponentActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - ProyectoAndroidTheme { - Surface( - modifier = Modifier - .fillMaxSize(), - color = MaterialTheme.colorScheme.background - ) { - AppNavigation() - } - } - } - } -} +package com.frannazario.proyectoandroid.presentation.activities + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.ui.Modifier +import com.frannazario.proyectoandroid.presentation.navigation.AppNavigation +import com.frannazario.proyectoandroid.presentation.ui.theme.ProyectoAndroidTheme + +class MainActivity: ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + ProyectoAndroidTheme { + Surface( + modifier = Modifier + .fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + AppNavigation() + } + } + } + } +} diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/LoginFragment.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/LoginFragment.kt index e5a5c98..0396a4b 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/LoginFragment.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/LoginFragment.kt @@ -1,70 +1,70 @@ -package com.frannazario.proyectoandroid.presentation.fragments - -import android.content.Intent -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.findNavController -import com.frannazario.proyectoandroid.R -import com.frannazario.proyectoandroid.data.responses.SigninResponse -import com.frannazario.proyectoandroid.data.viewmodels.SigninViewModel -import com.frannazario.proyectoandroid.databinding.FragmentLoginBinding -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.frannazario.proyectoandroid.presentation.activities.MainActivity - - -class LoginFragment: Fragment() { - private lateinit var binding: FragmentLoginBinding - private lateinit var viewModel: SigninViewModel - - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - viewModel = SigninViewModel() - } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentLoginBinding.inflate(inflater, container, false) - binding.signinBtn.setOnClickListener { - findNavController().navigate(R.id.navigate_from_loginfragment_to_signinfragment) - } - binding.forgetPasswordBtn.setOnClickListener { - findNavController().navigate(R.id.navigate_from_loginfragment_to_passwordrecoveryfragment) - } - return binding.root - } - - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - viewModel.getSigninResultLiveData().observe(viewLifecycleOwner) { response -> - response?.apply { - when (response) { - is SigninResponse.Success -> { - val intent = Intent(requireContext(), MainActivity::class.java) - startActivity(intent) - } - - is SigninResponse.Error -> { - if (response.field == FieldEnum.EMAIL_FIELD) { - binding.emailIet.error = response.error - } else if (response.field == FieldEnum.PASSWORD_FIELD) { - binding.passwordIet.error = response.error - } - } - } - } - } - binding.loginBtn.setOnClickListener { - viewModel.signin( - email = binding.emailIet.text?.toString(), - password = binding.passwordIet.text?.toString() - ) - } - } +package com.frannazario.proyectoandroid.presentation.fragments + +import android.content.Intent +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.navigation.fragment.findNavController +import com.frannazario.proyectoandroid.R +import com.frannazario.proyectoandroid.data.responses.SigninResponse +import com.frannazario.proyectoandroid.data.viewmodels.SigninViewModel +import com.frannazario.proyectoandroid.databinding.FragmentLoginBinding +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.frannazario.proyectoandroid.presentation.activities.MainActivity + + +class LoginFragment: Fragment() { + private lateinit var binding: FragmentLoginBinding + private lateinit var viewModel: SigninViewModel + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + viewModel = SigninViewModel() + } + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentLoginBinding.inflate(inflater, container, false) + binding.signinBtn.setOnClickListener { + findNavController().navigate(R.id.navigate_from_loginfragment_to_signinfragment) + } + binding.forgetPasswordBtn.setOnClickListener { + findNavController().navigate(R.id.navigate_from_loginfragment_to_passwordrecoveryfragment) + } + return binding.root + } + + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewModel.getSigninResultLiveData().observe(viewLifecycleOwner) { response -> + response?.apply { + when (response) { + is SigninResponse.Success -> { + val intent = Intent(requireContext(), MainActivity::class.java) + startActivity(intent) + } + + is SigninResponse.Error -> { + if (response.field == FieldEnum.EMAIL_FIELD) { + binding.emailIet.error = response.error + } else if (response.field == FieldEnum.PASSWORD_FIELD) { + binding.passwordIet.error = response.error + } + } + } + } + } + binding.loginBtn.setOnClickListener { + viewModel.signin( + email = binding.emailIet.text?.toString(), + password = binding.passwordIet.text?.toString() + ) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/PasswordRecoveryFragment.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/PasswordRecoveryFragment.kt index e788626..ee7b6df 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/PasswordRecoveryFragment.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/PasswordRecoveryFragment.kt @@ -1,64 +1,64 @@ -package com.frannazario.proyectoandroid.presentation.fragments - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Toast -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.findNavController -import com.frannazario.proyectoandroid.R -import com.frannazario.proyectoandroid.data.responses.PasswordRecoveryResponse -import com.frannazario.proyectoandroid.data.viewmodels.PasswordRecoveryViewModel -import com.frannazario.proyectoandroid.databinding.FragmentPasswordRecoveryBinding -import com.frannazario.proyectoandroid.data.utils.FieldEnum - -class PasswordRecoveryFragment: Fragment() { - private lateinit var binding: FragmentPasswordRecoveryBinding - private lateinit var viewModel: PasswordRecoveryViewModel - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - viewModel = PasswordRecoveryViewModel() - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentPasswordRecoveryBinding.inflate(inflater, container, false) - binding.loginBtn.setOnClickListener { - findNavController().navigate(R.id.navigate_from_passwordrecoveryfragment_to_loginfragment) - } - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - viewModel.getPasswordRecoveryResultLiveData().observe(viewLifecycleOwner) { response -> - response?.apply { - when (response) { - is PasswordRecoveryResponse.Success -> { - Toast.makeText(requireContext(), "Funciona perfect", Toast.LENGTH_LONG) - .show() - } - - is PasswordRecoveryResponse.Error -> { - if (response.field == FieldEnum.EMAIL_FIELD) { - binding.emailIet.error = response.error - } - } - - } - } - } - binding.sendEmailBtn.setOnClickListener { - binding.emailIet.text?.toString()?.let { it1 -> - viewModel.recover( - email = it1, - ) - } - } - } +package com.frannazario.proyectoandroid.presentation.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.navigation.fragment.findNavController +import com.frannazario.proyectoandroid.R +import com.frannazario.proyectoandroid.data.responses.PasswordRecoveryResponse +import com.frannazario.proyectoandroid.data.viewmodels.PasswordRecoveryViewModel +import com.frannazario.proyectoandroid.databinding.FragmentPasswordRecoveryBinding +import com.frannazario.proyectoandroid.data.utils.FieldEnum + +class PasswordRecoveryFragment: Fragment() { + private lateinit var binding: FragmentPasswordRecoveryBinding + private lateinit var viewModel: PasswordRecoveryViewModel + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + viewModel = PasswordRecoveryViewModel() + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentPasswordRecoveryBinding.inflate(inflater, container, false) + binding.loginBtn.setOnClickListener { + findNavController().navigate(R.id.navigate_from_passwordrecoveryfragment_to_loginfragment) + } + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewModel.getPasswordRecoveryResultLiveData().observe(viewLifecycleOwner) { response -> + response?.apply { + when (response) { + is PasswordRecoveryResponse.Success -> { + Toast.makeText(requireContext(), "Funciona perfect", Toast.LENGTH_LONG) + .show() + } + + is PasswordRecoveryResponse.Error -> { + if (response.field == FieldEnum.EMAIL_FIELD) { + binding.emailIet.error = response.error + } + } + + } + } + } + binding.sendEmailBtn.setOnClickListener { + binding.emailIet.text?.toString()?.let { it1 -> + viewModel.recover( + email = it1, + ) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/SigninFragment.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/SigninFragment.kt index ee41f74..ffd5768 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/SigninFragment.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/fragments/SigninFragment.kt @@ -1,63 +1,63 @@ -package com.frannazario.proyectoandroid.presentation.fragments - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Toast -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.findNavController -import com.frannazario.proyectoandroid.R -import com.frannazario.proyectoandroid.data.responses.SignupResponse -import com.frannazario.proyectoandroid.data.utils.FieldEnum -import com.frannazario.proyectoandroid.data.viewmodels.SignupViewModel -import com.frannazario.proyectoandroid.databinding.FragmentSigninBinding - -class SigninFragment: Fragment() { - private lateinit var binding: FragmentSigninBinding - private lateinit var viewModel: SignupViewModel - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - viewModel = SignupViewModel() - } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentSigninBinding.inflate(inflater, container, false) - binding.loginBtn.setOnClickListener { - findNavController().navigate(R.id.navigate_from_signinfragment_to_loginfragment) - } - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - viewModel.getSignupResultLiveData().observe(viewLifecycleOwner) { response -> - response?.apply { - when (response) { - is SignupResponse.Success -> { - Toast.makeText(requireContext(), "Funciona perfect", Toast.LENGTH_LONG) - .show() - } - - is SignupResponse.Error -> { - if (response.field == FieldEnum.EMAIL_FIELD) { - binding.emailIet.error = response.error - } else if (response.field == FieldEnum.PASSWORD_FIELD) { - binding.passwordIet.error = response.error - } - } - } - } - } - binding.signinBtn.setOnClickListener { - viewModel.register( - email = binding.emailIet.text?.toString(), - password = binding.passwordIet.text?.toString() - ) - } - } +package com.frannazario.proyectoandroid.presentation.fragments + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.navigation.fragment.findNavController +import com.frannazario.proyectoandroid.R +import com.frannazario.proyectoandroid.data.responses.SignupResponse +import com.frannazario.proyectoandroid.data.utils.FieldEnum +import com.frannazario.proyectoandroid.data.viewmodels.SignupViewModel +import com.frannazario.proyectoandroid.databinding.FragmentSigninBinding + +class SigninFragment: Fragment() { + private lateinit var binding: FragmentSigninBinding + private lateinit var viewModel: SignupViewModel + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + viewModel = SignupViewModel() + } + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentSigninBinding.inflate(inflater, container, false) + binding.loginBtn.setOnClickListener { + findNavController().navigate(R.id.navigate_from_signinfragment_to_loginfragment) + } + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewModel.getSignupResultLiveData().observe(viewLifecycleOwner) { response -> + response?.apply { + when (response) { + is SignupResponse.Success -> { + Toast.makeText(requireContext(), "Funciona perfect", Toast.LENGTH_LONG) + .show() + } + + is SignupResponse.Error -> { + if (response.field == FieldEnum.EMAIL_FIELD) { + binding.emailIet.error = response.error + } else if (response.field == FieldEnum.PASSWORD_FIELD) { + binding.passwordIet.error = response.error + } + } + } + } + } + binding.signinBtn.setOnClickListener { + viewModel.register( + email = binding.emailIet.text?.toString(), + password = binding.passwordIet.text?.toString() + ) + } + } } \ No newline at end of file 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 85a9a1c..bcdcf48 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,39 +1,39 @@ -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, userViewModel) - } - - composable( - route = "${AppScreens.CategoryDetailScreen.route}/{id}", - arguments = listOf(navArgument("id") { type = NavType.IntType }) - ) { backStackEntry -> - backStackEntry.arguments?.getInt("id")?.let { id -> - CategoryDetailScreen( - navController = mainNavController, - id = id - ) - } - } - - } -} +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, userViewModel) + } + + composable( + route = "${AppScreens.CategoryDetailScreen.route}/{id}", + arguments = listOf(navArgument("id") { type = NavType.IntType }) + ) { backStackEntry -> + backStackEntry.arguments?.getInt("id")?.let { id -> + CategoryDetailScreen( + navController = mainNavController, + id = id + ) + } + } + + } +} diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/navigation/AppScreens.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/navigation/AppScreens.kt index b91dbbd..f622984 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/navigation/AppScreens.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/navigation/AppScreens.kt @@ -1,13 +1,13 @@ -package com.frannazario.proyectoandroid.presentation.navigation - -sealed class AppScreens(val route: String) { - object CategoryListScreen: AppScreens("category_list_screen") - object CategoryDetailScreen: AppScreens("category_detail_screen") - object PlayListScreen: AppScreens("play_list_screen") - object PlayScreen: AppScreens("play_screen") - object ScoreScreen: AppScreens("score_screen") - object SettingsScreen: AppScreens("settings_screen") - object BaseBottomNav: AppScreens("BottomNavScreen") - - object TotalScoreScreen: AppScreens("total_score_screen") -} +package com.frannazario.proyectoandroid.presentation.navigation + +sealed class AppScreens(val route: String) { + object CategoryListScreen: AppScreens("category_list_screen") + object CategoryDetailScreen: AppScreens("category_detail_screen") + object PlayListScreen: AppScreens("play_list_screen") + object PlayScreen: AppScreens("play_screen") + object ScoreScreen: AppScreens("score_screen") + object SettingsScreen: AppScreens("settings_screen") + object BaseBottomNav: AppScreens("BottomNavScreen") + + object TotalScoreScreen: AppScreens("total_score_screen") +} 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 d7f296e..fb64723 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,94 +1,94 @@ -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 -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.navigation.NavController -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.PlayViewModel -import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel -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, - userViewModel: UserViewModel, // Pass the instance of UserViewModel here -) { - val context = LocalContext.current - val bottomNavController = rememberNavController() -// val userViewState = userViewModel.userViewState.collectAsState() - val viewModel by remember {mutableStateOf(PlayViewModel(context, userViewModel = userViewModel))} - val scoreViewState = viewModel.scoresViewState.collectAsState() - - LaunchedEffect(Unit) { - viewModel.getScoreList() - userViewModel.getUser() - } - - Scaffold( - bottomBar = { - BottomNav(bottomNavController) - }, - topBar = { - TopBar(userViewModel) - } - ) { - Surface( - modifier = Modifier - .fillMaxSize() - .padding(bottom = it.calculateBottomPadding(), top = it.calculateTopPadding()), - color = MaterialTheme.colorScheme.background - ) { - NavHost( - navController = bottomNavController, - startDestination = AppScreens.CategoryListScreen.route - ) { - composable(AppScreens.CategoryListScreen.route) { - CategoryListScreen(mainNavController, viewModel) - } - composable(AppScreens.ScoreScreen.route) { - ScoreScreen(mainNavController, viewModel) - } - composable(AppScreens.TotalScoreScreen.route) { - TotalScoreScreen(mainNavController, userViewModel) - } - composable(AppScreens.PlayListScreen.route) { - PlayListScreen(bottomNavController, viewModel) - } - composable(AppScreens.SettingsScreen.route) { - SettingsScreen(mainNavController, userViewModel) - } - composable( - route = "${AppScreens.PlayScreen.route}/{id}", - arguments = listOf(navArgument("id") { type = NavType.IntType }) - ) { backStackEntry -> - backStackEntry.arguments?.getInt("id")?.let { id -> - PlayScreen( - id = id, - viewModel = viewModel - ) - } - } - } - } - } +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 +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.navigation.NavController +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.PlayViewModel +import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel +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, + userViewModel: UserViewModel, // Pass the instance of UserViewModel here +) { + val context = LocalContext.current + val bottomNavController = rememberNavController() +// val userViewState = userViewModel.userViewState.collectAsState() + val viewModel by remember {mutableStateOf(PlayViewModel(context, userViewModel = userViewModel))} + val scoreViewState = viewModel.scoresViewState.collectAsState() + + LaunchedEffect(Unit) { + viewModel.getScoreList() + userViewModel.getUser() + } + + Scaffold( + bottomBar = { + BottomNav(bottomNavController) + }, + topBar = { + TopBar(userViewModel, bottomNavController) + } + ) { + Surface( + modifier = Modifier + .fillMaxSize() + .padding(bottom = it.calculateBottomPadding(), top = it.calculateTopPadding()), + color = MaterialTheme.colorScheme.background + ) { + NavHost( + navController = bottomNavController, + startDestination = AppScreens.CategoryListScreen.route + ) { + composable(AppScreens.CategoryListScreen.route) { + CategoryListScreen(mainNavController, viewModel) + } + composable(AppScreens.ScoreScreen.route) { + ScoreScreen(mainNavController, viewModel) + } + composable(AppScreens.TotalScoreScreen.route) { + TotalScoreScreen(mainNavController, userViewModel) + } + composable(AppScreens.PlayListScreen.route) { + PlayListScreen(bottomNavController, viewModel) + } + composable(AppScreens.SettingsScreen.route) { + SettingsScreen(mainNavController, userViewModel) + } + composable( + route = "${AppScreens.PlayScreen.route}/{id}", + arguments = listOf(navArgument("id") { type = NavType.IntType }) + ) { backStackEntry -> + backStackEntry.arguments?.getInt("id")?.let { id -> + PlayScreen( + id = id, + viewModel = viewModel + ) + } + } + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/CategoryDetailScreen.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/CategoryDetailScreen.kt index 676175b..5ff1077 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/CategoryDetailScreen.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/CategoryDetailScreen.kt @@ -1,23 +1,23 @@ -package com.frannazario.proyectoandroid.presentation.screens - -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.navigation.NavController - -@Composable -fun CategoryDetailScreen(navController: NavController, id: Int){ - Box( - modifier = Modifier - .fillMaxSize(), - contentAlignment = Alignment.Center - ) { - Text ( - text = id.toString() - ) - } -} - +package com.frannazario.proyectoandroid.presentation.screens + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.navigation.NavController + +@Composable +fun CategoryDetailScreen(navController: NavController, id: Int){ + Box( + modifier = Modifier + .fillMaxSize(), + contentAlignment = Alignment.Center + ) { + Text ( + text = id.toString() + ) + } +} + diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/CategoryListScreen.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/CategoryListScreen.kt index 23029f0..e0504de 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/CategoryListScreen.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/screens/CategoryListScreen.kt @@ -1,56 +1,56 @@ -package com.frannazario.proyectoandroid.presentation.screens - -import android.widget.Toast -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import androidx.navigation.NavController -import com.frannazario.proyectoandroid.data.viewmodels.CategoriesViewModel -import com.frannazario.proyectoandroid.data.viewmodels.PlayViewModel -import com.frannazario.proyectoandroid.presentation.navigation.AppScreens -import com.frannazario.proyectoandroid.presentation.ui.widgets.CategoryCard - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun CategoryListScreen(mainNavController: NavController, viewModel: PlayViewModel){ - val context = LocalContext.current - val viewModel by remember { mutableStateOf(CategoriesViewModel()) } - val categoriesViewState by viewModel.categoriesViewState.collectAsState() - - LaunchedEffect(Unit) { - viewModel.getCategories() - } - - LaunchedEffect(categoriesViewState.error) { - categoriesViewState.error?.let { - Toast.makeText(context, it, Toast.LENGTH_LONG).show() - } - } - - LazyColumn( - modifier = Modifier - .fillMaxSize(), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - categoriesViewState.data?.forEach() { category -> - item { - CategoryCard(category = category, modifier = Modifier.fillMaxWidth()) {navigateCategoryDetailScreen(mainNavController, category.id)} - } - } - } -} - -fun navigateCategoryDetailScreen (mainNavController: NavController, id: Int){ - mainNavController.navigate("${AppScreens.CategoryDetailScreen.route}/${id}") +package com.frannazario.proyectoandroid.presentation.screens + +import android.widget.Toast +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import com.frannazario.proyectoandroid.data.viewmodels.CategoriesViewModel +import com.frannazario.proyectoandroid.data.viewmodels.PlayViewModel +import com.frannazario.proyectoandroid.presentation.navigation.AppScreens +import com.frannazario.proyectoandroid.presentation.ui.widgets.CategoryCard + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun CategoryListScreen(mainNavController: NavController, viewModel: PlayViewModel){ + val context = LocalContext.current + val viewModel by remember { mutableStateOf(CategoriesViewModel()) } + val categoriesViewState by viewModel.categoriesViewState.collectAsState() + + LaunchedEffect(Unit) { + viewModel.getCategories() + } + + LaunchedEffect(categoriesViewState.error) { + categoriesViewState.error?.let { + Toast.makeText(context, it, Toast.LENGTH_LONG).show() + } + } + + LazyColumn( + modifier = Modifier + .fillMaxSize(), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + categoriesViewState.data?.forEach() { category -> + item { + CategoryCard(category = category, modifier = Modifier.fillMaxWidth()) {navigateCategoryDetailScreen(mainNavController, category.id)} + } + } + } +} + +fun navigateCategoryDetailScreen (mainNavController: NavController, id: Int){ + mainNavController.navigate("${AppScreens.CategoryDetailScreen.route}/${id}") } \ No newline at end of file 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 013f3f2..ce893de 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 @@ -1,63 +1,63 @@ -package com.frannazario.proyectoandroid.presentation.screens - -import android.widget.Toast -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -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, -){ - val context = LocalContext.current - val viewModel by remember { mutableStateOf(CategoriesViewModel()) } - val categoriesViewState by viewModel.categoriesViewState.collectAsState() - val scoreViewState = viewModelx.scoresViewState.collectAsState() - - LaunchedEffect(Unit) { - viewModel.getCategories() - } - - LaunchedEffect(categoriesViewState.error) { - categoriesViewState.error?.let { - Toast.makeText(context, it, Toast.LENGTH_LONG).show() - } - } - - Column() { - LazyVerticalGrid(columns = GridCells.Adaptive(200.dp)){ - categoriesViewState.data?.forEach() { category -> - val containsScore = scoreViewState.value.scores?.any { score -> - score.category.toIntOrNull() == category.id - } ?: false - item { - if(containsScore){ - CategorySmallCard(category = category, modifier = Modifier.weight(1f), image = R.drawable.baseline_check_24, enabled = !containsScore) {NavController.navigate("${AppScreens.PlayScreen.route}/${category.id}")} - }else { - CategorySmallCard(category = category, modifier = Modifier.weight(1f), image = R.drawable.baseline_close_24, enabled = !containsScore) {NavController.navigate("${AppScreens.PlayScreen.route}/${category.id}")} - } - } - } - - } - } +package com.frannazario.proyectoandroid.presentation.screens + +import android.widget.Toast +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +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, +){ + val context = LocalContext.current + val viewModel by remember { mutableStateOf(CategoriesViewModel()) } + val categoriesViewState by viewModel.categoriesViewState.collectAsState() + val scoreViewState = viewModelx.scoresViewState.collectAsState() + + LaunchedEffect(Unit) { + viewModel.getCategories() + } + + LaunchedEffect(categoriesViewState.error) { + categoriesViewState.error?.let { + Toast.makeText(context, it, Toast.LENGTH_LONG).show() + } + } + + Column() { + LazyVerticalGrid(columns = GridCells.Adaptive(200.dp)){ + categoriesViewState.data?.forEach() { category -> + val containsScore = scoreViewState.value.scores?.any { score -> + score.category.toIntOrNull() == category.id + } ?: false + item { + if(containsScore){ + CategorySmallCard(category = category, modifier = Modifier.weight(1f), image = R.drawable.baseline_check_24, enabled = !containsScore) {NavController.navigate("${AppScreens.PlayScreen.route}/${category.id}")} + }else { + CategorySmallCard(category = category, modifier = Modifier.weight(1f), image = R.drawable.baseline_close_24, enabled = !containsScore) {NavController.navigate("${AppScreens.PlayScreen.route}/${category.id}")} + } + } + } + + } + } } \ No newline at end of file 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 6253600..7b2c09c 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 @@ -1,216 +1,321 @@ -package com.frannazario.proyectoandroid.presentation.screens - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.Button -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 -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -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, -){ - val context = LocalContext.current - val randomQuestion = remember { mutableStateOf(null) } - val shuffledResponses = remember {mutableStateOf?>(null)} - val questionsViewState by viewModel.questionsViewState.collectAsState() - val scoreViewState by viewModel.scoresViewState.collectAsState() - var questionList = remember { mutableStateOf(listOf()) } - var isLoading by remember {mutableStateOf(true)} // Initial loading state is true - val buttonEnabled = remember {mutableStateOf(true)} // Initial loading state is true - val colorOfBackground = remember {mutableStateOf(Color.White)} - val score = remember {mutableStateOf(0)} - val counter = remember {mutableStateOf(-1)} - val counterCoroutine = rememberCoroutineScope() - val delayCoroutine = rememberCoroutineScope() - - LaunchedEffect(Unit) { - viewModel.getQuestionList(id) - } - - LaunchedEffect(questionsViewState.questions) { - questionsViewState.questions?.let { - questionList.value = it - changeQuestion(questionList.value, randomQuestion, shuffledResponses, colorOfBackground, buttonEnabled, viewModel) - isLoading = false - startCounter(counter, score, counterCoroutine, viewModel, id, scoreViewState) - } - } - - if (score.value > 4) { - Text(text = "felicidades tu puntuacion es de: ${counter.value}") - }else { - if (isLoading) { - // Show loader - Text( text = "cargando") - } else { - Box( - modifier = Modifier - .fillMaxSize() - .background(color = colorOfBackground.value), - contentAlignment = Alignment.Center - ) { - Column() { - randomQuestion.value?.let { - Text ( - text = it.question - ) - } - Button(onClick = { - compareAnswer( - buttonEnabled, - shuffledResponses.value?.get(0) ?: "bb", - colorOfBackground, - counter, - score, - questionList.value, - randomQuestion, - shuffledResponses, - delayCoroutine, - viewModel - ) - }, - enabled = buttonEnabled.value - ) { - Text(text = shuffledResponses.value?.get(0) ?: "bb" ) - } - Button(onClick = { - compareAnswer( - buttonEnabled, - shuffledResponses.value?.get(1) ?: "bb", - colorOfBackground, - counter, - score, - questionList.value, - randomQuestion, - shuffledResponses, - delayCoroutine, - viewModel - ) - }, - enabled = buttonEnabled.value - ) { - Text(text = shuffledResponses.value?.get(1) ?: "bb" ) - } - - Button(onClick = { - compareAnswer( - buttonEnabled, - shuffledResponses.value?.get(2) ?: "bb", - colorOfBackground, - counter, - score, - questionList.value, - randomQuestion, - shuffledResponses, - delayCoroutine, - viewModel - ) - }, - enabled = buttonEnabled.value - ) { - Text(text = shuffledResponses.value?.get(2) ?: "bb" ) - } - - Text(text = "${score.value.toString()}/5") - Text(text = "time: ${counter.value.toString()}") - } - } - } - } - -} - -fun changeQuestion( - questionList: List, - randomQuestion: MutableState, - shuffledResponses: MutableState?>, - colorOfBackground: MutableState, - buttonEnabled: MutableState, - viewModel: PlayViewModel -) { - colorOfBackground.value = Color.White - randomQuestion.value = viewModel.getQuestion(questionList) - shuffledResponses.value = viewModel.shuffle(randomQuestion) - buttonEnabled.value = true -} - -fun compareAnswer( - buttonEnabled: MutableState, - s: String, - colorOfBackground: MutableState, - counter: MutableState, - score: MutableState, - questionList: List, - randomQuestion: MutableState, - shuffledResponses: MutableState?>, - delayCoroutine: CoroutineScope, - viewModel: PlayViewModel -) { - buttonEnabled.value = false - if(viewModel.compareAnswer(s, randomQuestion.value?.response1)){ - score.value++ - colorOfBackground.value = Color.Green - }else{ - counter.value += 10 - colorOfBackground.value = Color.Red - } - delayCoroutine.launch { -// delay(2000) - changeQuestion( - questionList, - randomQuestion, - shuffledResponses, - colorOfBackground, - buttonEnabled, - viewModel - ) - } -} - -fun startCounter( - counter: MutableState, - score: MutableState, - counterCoroutine: CoroutineScope, - viewModel: PlayViewModel, - id: Int, - scoreViewState: ScoreViewState, -) { - counterCoroutine.launch { - while (score.value < 5) { - counter.value++ - delay(1000) - } - // En vez de usar un contador deberia usar la cantidad de scores en la bd - viewModel.saveScore(Score(score = counter.value.toString(), category = id.toString())) - if(scoreViewState.scoresDone > 6){ - viewModel.saveTotalScore() - } - } -} \ No newline at end of file +package com.frannazario.proyectoandroid.presentation.screens + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.LinearEasing +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +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.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +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 kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + + +@Composable +fun PlayScreen( + id: Int, + viewModel: PlayViewModel, +){ + val context = LocalContext.current + val randomQuestion = remember { mutableStateOf(null) } + val shuffledResponses = remember {mutableStateOf?>(null)} + val questionsViewState by viewModel.questionsViewState.collectAsState() + val scoreViewState by viewModel.scoresViewState.collectAsState() + val questionList = remember { mutableStateOf(listOf()) } + var isLoading by remember {mutableStateOf(true)} // Initial loading state is true + var visibility = remember {mutableStateOf(false)} + val buttonEnabled = remember {mutableStateOf(true)} + val colorOfBackground = remember {mutableStateOf(Color.White)} + val score = remember {mutableStateOf(0)} + val counter = remember {mutableStateOf(-1)} + val counterCoroutine = rememberCoroutineScope() + val delayCoroutine = rememberCoroutineScope() + var badgeCount by remember { mutableStateOf(0) } + + LaunchedEffect(Unit) { + viewModel.getQuestionList(id) + } + + LaunchedEffect(questionsViewState.questions) { + questionsViewState.questions?.let { + questionList.value = it + changeQuestion(questionList.value, randomQuestion, shuffledResponses, colorOfBackground, buttonEnabled, viewModel) + isLoading = false + visibility.value = true + startCounter(counter, score, counterCoroutine, viewModel, id, scoreViewState) + } + } + + if (score.value > 4) { + Text(text = "felicidades tu puntuacion es de: ${counter.value}") + }else { + if (isLoading) { + // Show loader + Text( text = "cargando") + } else { + Box( + modifier = Modifier + .fillMaxSize() + .background(color = colorOfBackground.value) + .padding(horizontal = 16.dp, vertical = 24.dp), + contentAlignment = Alignment.Center + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.fillMaxHeight() + ) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + ) { + Text(text = "${score.value.toString()}/5") + Text(text = "time: ${counter.value.toString()}") + } + AnimatedVisibility( + visible = visibility.value, + //1 segundo + enter = fadeIn(animationSpec = tween(2000, easing = LinearEasing)), + exit = fadeOut(animationSpec = tween(2000, easing = LinearEasing)) + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(32.dp), + modifier = Modifier + .padding(top = 24.dp) + ) { + randomQuestion.value?.let { + Text(text = it.question, + style = TextStyle( + lineHeight = 40.sp // Increase the value to add more line height (adjust as needed) + ), + fontSize = 32.sp, + color = Color.Black, + textAlign = TextAlign.Center) + } + Button( + onClick = { + compareAnswer( + buttonEnabled, + shuffledResponses.value?.get(0) ?: "bb", + colorOfBackground, + counter, + score, + questionList.value, + randomQuestion, + shuffledResponses, + delayCoroutine, + visibility, + viewModel + ) + }, + enabled = buttonEnabled.value, + modifier = Modifier + .weight(1f) + .fillMaxWidth(), + ) { + Text(text = shuffledResponses.value?.get(0) ?: "bb", + fontSize = 32.sp, + color = Color.White, + textAlign = TextAlign.Center) + } + Button( + onClick = { + compareAnswer( + buttonEnabled, + shuffledResponses.value?.get(1) ?: "bb", + colorOfBackground, + counter, + score, + questionList.value, + randomQuestion, + shuffledResponses, + delayCoroutine, + visibility, + viewModel + ) + }, + modifier = Modifier + .fillMaxWidth() + .weight(1f), + enabled = buttonEnabled.value + ) { +// Text(text = shuffledResponses.value?.get(1) ?: "bb", + AutoSizeText(text = "aksldjflkasjdkfljalksdjflaksjdflkjasl;dkjflakjsdflkjasl;kdjfalksjdf;lkajsdl;kfjalksdjfkajsdjfhakjshdfjhajskdhfjkashdfkjhasjkdhfkajshdfkljhaskjdfhakjsdhf", + style = TextStyle( + fontSize = 32.sp, + color = Color.White, + textAlign = TextAlign.Center + ) + ) + } + + Button( + onClick = { + compareAnswer( + buttonEnabled, + shuffledResponses.value?.get(2) ?: "bb", + colorOfBackground, + counter, + score, + questionList.value, + randomQuestion, + shuffledResponses, + delayCoroutine, + visibility, + viewModel + ) + }, + modifier = Modifier + .fillMaxWidth() + .weight(1f), + enabled = buttonEnabled.value + ) { + Text(text = shuffledResponses.value?.get(2) ?: "bb", + fontSize = 32.sp, + color = Color.White, + textAlign = TextAlign.Center) + } + } + } + } + } + } + } + +} + +fun changeQuestion( + questionList: List, + randomQuestion: MutableState, + shuffledResponses: MutableState?>, + colorOfBackground: MutableState, + buttonEnabled: MutableState, + viewModel: PlayViewModel +) { + colorOfBackground.value = Color.White + randomQuestion.value = viewModel.getQuestion(questionList) + shuffledResponses.value = viewModel.shuffle(randomQuestion) + buttonEnabled.value = true +} + +fun compareAnswer( + buttonEnabled: MutableState, + s: String, + colorOfBackground: MutableState, + counter: MutableState, + score: MutableState, + questionList: List, + randomQuestion: MutableState, + shuffledResponses: MutableState?>, + delayCoroutine: CoroutineScope, + visibility: MutableState, + viewModel: PlayViewModel +) { + buttonEnabled.value = false + if(viewModel.compareAnswer(s, randomQuestion.value?.response1)){ + score.value++ + colorOfBackground.value = Color.Green + }else{ + counter.value += 10 + colorOfBackground.value = Color.Red + } + delayCoroutine.launch { + visibility.value = false + delay(2000) + changeQuestion( + questionList, + randomQuestion, + shuffledResponses, + colorOfBackground, + buttonEnabled, + viewModel + ) + visibility.value = true + } +} + +fun startCounter( + counter: MutableState, + score: MutableState, + counterCoroutine: CoroutineScope, + viewModel: PlayViewModel, + id: Int, + scoreViewState: ScoreViewState, +) { + counterCoroutine.launch { + + while (score.value < 5) { + counter.value++ + delay(1000) + } + // En vez de usar un contador deberia usar la cantidad de scores en la bd + viewModel.saveScore(Score(score = counter.value.toString(), category = id.toString())) + if((scoreViewState.scores?.size ?: 0) > 6){ + viewModel.saveTotalScore() + } + } +} + + +@Composable +fun AutoSizeText( + text: String, + modifier: Modifier = Modifier, + style: TextStyle +) { + + var scaledTextStyle by remember { mutableStateOf(style) } + var readyToDraw by remember{ mutableStateOf(false) } + + return ( + Text(text = text, + modifier.drawWithContent { + if (readyToDraw){ + drawContent() + } + }, + style = scaledTextStyle, + onTextLayout = { textLayoutResult -> + if(textLayoutResult.didOverflowHeight){ + scaledTextStyle = scaledTextStyle.copy(fontSize = scaledTextStyle.fontSize * 0.9) + }else{ + readyToDraw = true + } + } + ) + ) +} 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 c75d772..7c7ce2b 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 @@ -1,26 +1,26 @@ -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 - -@Composable -fun ScoreScreen(navController: NavController, viewModel: PlayViewModel){ - val scoreViewState = viewModel.scoresViewState.collectAsState() - - Column() { - scoreViewState.value.scores?.forEach { score -> - Row() { - Text(text = score.category) - Text(text = " ") - Text(text = score.score) - } - } - } - -} +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 + +@Composable +fun ScoreScreen(navController: NavController, viewModel: PlayViewModel){ + val scoreViewState = viewModel.scoresViewState.collectAsState() + + 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 f26d0c0..57f3b23 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,126 +1,238 @@ -package com.frannazario.proyectoandroid.presentation.screens - -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.UserViewModel -import com.frannazario.proyectoandroid.presentation.activities.AuthActivity - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -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 - ) { - - 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" -// ) -// } -} +package com.frannazario.proyectoandroid.presentation.screens + +import android.content.Intent +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.AlertDialog +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.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import coil.compose.AsyncImage +import coil.compose.AsyncImagePainter +import com.frannazario.proyectoandroid.R +import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel +import com.frannazario.proyectoandroid.presentation.activities.AuthActivity + + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +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 + val imageLoaded = remember { mutableStateOf(true) } + var isUsernameEditable by remember { mutableStateOf(false) } + var isUserImageEditable by remember { mutableStateOf(false) } + var showDialog by remember { mutableStateOf(false) } + val height = remember { mutableStateOf(0.dp) } + val density = LocalDensity.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 + ) { + + if( imageLoaded.value && userViewState.value.user.userimage != ""){ + AsyncImage( + model = userViewState.value.user.userimage, + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier + .fillMaxWidth(0.5f) + .onGloballyPositioned { + height.value = with(density){ + it.size.width.toDp() + } + } + .height(height.value) + .clip( + RoundedCornerShape(height.value) + ), + 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) + ), + ) + } + + OutlinedTextField( + value = username.value, + onValueChange = { + if (isUsernameEditable) { + username.value = it + } + }, + readOnly = !isUsernameEditable, // Use the state variable to control read-only state + trailingIcon = { + // Pencil icon as trailing image + Image( + painter = if (isUsernameEditable) painterResource(id = R.drawable.baseline_edit_24) else painterResource( id = R.drawable.baseline_edit_off_24), + contentDescription = "Edit User Image", + modifier = Modifier + .size(24.dp) + .clickable { + isUsernameEditable = !isUsernameEditable + } + ) + }, + 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) + ) + + OutlinedTextField( + value = userimage.value, + onValueChange = { + if (isUserImageEditable) { + userimage.value = it + } + }, + readOnly = !isUserImageEditable, // Use the state variable to control read-only state + trailingIcon = { + // Pencil icon as trailing image + Image( + painter = if (isUserImageEditable) painterResource(id = R.drawable.baseline_edit_24) else painterResource( id = R.drawable.baseline_edit_off_24), + contentDescription = "Edit User Image", + modifier = Modifier + .size(24.dp) + .clickable { + isUserImageEditable = !isUserImageEditable + } + ) + }, + 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) + ) +Row() { + Button( + onClick = { + showDialog = !showDialog + }, + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF008477)) + ) { + Text( + text = "Preview Image", + color = Color.Black + ) + } + Button( + onClick = { + viewModel.updateUsername(username.value) + viewModel.updateUserimage(userimage.value) + }, + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF008477)) + ) { + Text( + text = "Save", + color = Color.Black + ) + } +} + Button( + onClick = { + viewModel.signout() + }, + colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF008477)) + ) { + Text( + text = "Signout", + color = Color.Black + ) + } + } + if (showDialog) { + AlertDialog( + onDismissRequest = { + // Dismiss the dialog when the user clicks outside the dialog + showDialog = false + }, + confirmButton = { + // Confirm button (can be customized as needed) + Button( + onClick = { + // Close the dialog when the confirm button is clicked + showDialog = false + } + ) { + Text("OK") + } + }, + text = { + // Async image to be displayed in the dialog + AsyncImage( + model = userimage.value, + contentDescription = null, + contentScale = ContentScale.Crop, + modifier = Modifier + .size(height.value *2) + .clip( + RoundedCornerShape(height.value) + ), + ) + } + ) + } +} 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 ce3bc2b..879a979 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,29 +1,29 @@ -package com.frannazario.proyectoandroid.presentation.screens - -import androidx.compose.foundation.layout.Column -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.navigation.NavController -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: UserViewModel){ - - val userViewState = viewModel.userViewState.collectAsState() - - Column() { - 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) - } - } - -} - +package com.frannazario.proyectoandroid.presentation.screens + +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.navigation.NavController +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: UserViewModel){ + + val userViewState = viewModel.userViewState.collectAsState() + + Column() { + 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/theme/Color.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Color.kt index d31dad1..9c2a3cd 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Color.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Color.kt @@ -1,11 +1,11 @@ -package com.frannazario.proyectoandroid.presentation.ui.theme - -import androidx.compose.ui.graphics.Color - -val Purple80 = Color(0xFFD0BCFF) -val PurpleGrey80 = Color(0xFFCCC2DC) -val Pink80 = Color(0xFFEFB8C8) - -val Purple40 = Color(0xFF6650a4) -val PurpleGrey40 = Color(0xFF625b71) +package com.frannazario.proyectoandroid.presentation.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Theme.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Theme.kt index 4693ca1..84db69e 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Theme.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Theme.kt @@ -1,70 +1,70 @@ -package com.frannazario.proyectoandroid.presentation.ui.theme - -import android.app.Activity -import android.os.Build -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme -import androidx.compose.material3.lightColorScheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalView -import androidx.core.view.WindowCompat - -private val DarkColorScheme = darkColorScheme( - primary = Purple80, - secondary = PurpleGrey80, - tertiary = Pink80 -) - -private val LightColorScheme = lightColorScheme( - primary = Purple40, - secondary = PurpleGrey40, - tertiary = Pink40 - - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), - onPrimary = Color.White, - onSecondary = Color.White, - onTertiary = Color.White, - onBackground = Color(0xFF1C1B1F), - onSurface = Color(0xFF1C1B1F), - */ -) - -@Composable -fun ProyectoAndroidTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - // Dynamic color is available on Android 12+ - dynamicColor: Boolean = true, - content: @Composable () -> Unit -) { - val colorScheme = when { - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) - } - - darkTheme -> DarkColorScheme - else -> LightColorScheme - } - val view = LocalView.current - if (!view.isInEditMode) { - SideEffect { - val window = (view.context as Activity).window - window.statusBarColor = colorScheme.primary.toArgb() - WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme - } - } - - MaterialTheme( - colorScheme = colorScheme, - typography = Typography, - content = content - ) +package com.frannazario.proyectoandroid.presentation.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun ProyectoAndroidTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Type.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Type.kt index 5e3a43b..7c00770 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Type.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/theme/Type.kt @@ -1,34 +1,34 @@ -package com.frannazario.proyectoandroid.presentation.ui.theme - -import androidx.compose.material3.Typography -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp - -// Set of Material typography styles to start with -val Typography = Typography( - bodyLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 16.sp, - lineHeight = 24.sp, - letterSpacing = 0.5.sp - ) - /* Other default text styles to override - titleLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 22.sp, - lineHeight = 28.sp, - letterSpacing = 0.sp - ), - labelSmall = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Medium, - fontSize = 11.sp, - lineHeight = 16.sp, - letterSpacing = 0.5.sp - ) - */ +package com.frannazario.proyectoandroid.presentation.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ ) \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/BottomNav.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/BottomNav.kt index 81682da..ad65a67 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/BottomNav.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/BottomNav.kt @@ -1,39 +1,34 @@ -package com.frannazario.proyectoandroid.presentation.ui.widgets - -import androidx.compose.runtime.Composable -import androidx.compose.material.BottomNavigation -import androidx.compose.material.Button -import androidx.compose.material.Text -import androidx.navigation.NavController -import com.frannazario.proyectoandroid.presentation.navigation.AppScreens - -@Composable -fun BottomNav(navController: NavController) { - BottomNavigation() { - Button(onClick = { - navController.navigate(AppScreens.CategoryListScreen.route) - }) { - Text(text = "Categories") - } - Button(onClick = { - navController.navigate(AppScreens.ScoreScreen.route) - }) { - Text(text = "Score") - } - Button(onClick = { - navController.navigate(AppScreens.PlayListScreen.route) - }) { - Text(text = "Play") - } - Button(onClick = { - navController.navigate(AppScreens.SettingsScreen.route) - }) { - Text(text = "Settings") - } - Button(onClick = { - navController.navigate(AppScreens.TotalScoreScreen.route) - }) { - Text(text = "Total Score") - } - } +package com.frannazario.proyectoandroid.presentation.ui.widgets + +import androidx.compose.runtime.Composable +import androidx.compose.material.BottomNavigation +import androidx.compose.material.Button +import androidx.compose.material.Text +import androidx.navigation.NavController +import com.frannazario.proyectoandroid.presentation.navigation.AppScreens + +@Composable +fun BottomNav(navController: NavController) { + BottomNavigation() { + Button(onClick = { + navController.navigate(AppScreens.CategoryListScreen.route) + }) { + Text(text = "Categories") + } + Button(onClick = { + navController.navigate(AppScreens.ScoreScreen.route) + }) { + Text(text = "Score") + } + Button(onClick = { + navController.navigate(AppScreens.PlayListScreen.route) + }) { + Text(text = "Play") + } + Button(onClick = { + navController.navigate(AppScreens.TotalScoreScreen.route) + }) { + Text(text = "Total Score") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/CategoryCard.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/CategoryCard.kt index fb6973d..709786f 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/CategoryCard.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/CategoryCard.kt @@ -1,91 +1,91 @@ -package com.frannazario.proyectoandroid.presentation.ui.widgets - -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.shadow -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.frannazario.proyectoandroid.presentation.utils.CategoryEnum - -@Composable -fun CategoryCard( - modifier: Modifier = Modifier, - category: CategoryEnum, - onClick: (Int) -> Unit -) { - OutlinedButton( - modifier = modifier - .fillMaxWidth() - .padding( - horizontal = 24.dp, - vertical = 12.dp - ) - .shadow( - elevation = 4.dp, - shape = RoundedCornerShape(64.dp) - ) - .border( - border = BorderStroke( - 0.dp, Color.LightGray - ) - ) - .background(Color.White), - shape = RoundedCornerShape(64.dp), - onClick = { onClick(category.id) } - ) { - Row( - modifier = Modifier - .fillMaxWidth() - .padding( - horizontal = 8.dp, - vertical = 4.dp - ), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - Image( - painter = painterResource(id = category.icon), - contentDescription = null, - modifier = Modifier - .size(52.dp) - ) - - Spacer(modifier = Modifier) - - Text( - text = stringResource(id = category.title), - fontWeight = FontWeight.Bold, - style = TextStyle( - fontSize = 24.sp, - color = Color.Black - ) - ) - } - } -} - -@Preview -@Composable -private fun CategoryCardPreview() { - CategoryCard(category = CategoryEnum.GENERAL) {} +package com.frannazario.proyectoandroid.presentation.ui.widgets + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.frannazario.proyectoandroid.presentation.utils.CategoryEnum + +@Composable +fun CategoryCard( + modifier: Modifier = Modifier, + category: CategoryEnum, + onClick: (Int) -> Unit +) { + OutlinedButton( + modifier = modifier + .fillMaxWidth() + .padding( + horizontal = 24.dp, + vertical = 12.dp + ) + .shadow( + elevation = 4.dp, + shape = RoundedCornerShape(64.dp) + ) + .border( + border = BorderStroke( + 0.dp, Color.LightGray + ) + ) + .background(Color.White), + shape = RoundedCornerShape(64.dp), + onClick = { onClick(category.id) } + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding( + horizontal = 8.dp, + vertical = 4.dp + ), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + Image( + painter = painterResource(id = category.icon), + contentDescription = null, + modifier = Modifier + .size(52.dp) + ) + + Spacer(modifier = Modifier) + + Text( + text = stringResource(id = category.title), + fontWeight = FontWeight.Bold, + style = TextStyle( + fontSize = 24.sp, + color = Color.Black + ) + ) + } + } +} + +@Preview +@Composable +private fun CategoryCardPreview() { + CategoryCard(category = CategoryEnum.GENERAL) {} } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/CategorySmallCard.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/CategorySmallCard.kt index 0d78ab5..fae7c6f 100644 --- a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/CategorySmallCard.kt +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/CategorySmallCard.kt @@ -1,91 +1,91 @@ -package com.frannazario.proyectoandroid.presentation.ui.widgets - -import androidx.annotation.DrawableRes -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.border -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 -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.OutlinedButton -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.shadow -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.frannazario.proyectoandroid.R -import com.frannazario.proyectoandroid.presentation.utils.CategoryEnum - -@Composable -fun CategorySmallCard( - modifier: Modifier = Modifier, - category: CategoryEnum, - enabled: Boolean, - @DrawableRes image: Int, - onClick: (Int) -> Unit, -) { - OutlinedButton( - modifier = modifier - .shadow( - elevation = 4.dp, - shape = RoundedCornerShape(64.dp) - ) - .border( - border = BorderStroke( - 0.dp, Color.LightGray - ) - ) - .background( - if(enabled){ - Color.White - }else{ - Color.Green - } - ), - shape = RoundedCornerShape(64.dp), - enabled = enabled, - onClick = { onClick(category.id) } - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding( - horizontal = 8.dp, - vertical = 4.dp - ), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - Image( - painter = painterResource(id = category.icon), - contentDescription = null, - modifier = Modifier - .size(52.dp) - ) - Image( - painter = painterResource(id = image), - contentDescription = null, - modifier = Modifier - .size(52.dp) - ) - } - Row( - ) { - } - } +package com.frannazario.proyectoandroid.presentation.ui.widgets + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +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 +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.shadow +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.frannazario.proyectoandroid.R +import com.frannazario.proyectoandroid.presentation.utils.CategoryEnum + +@Composable +fun CategorySmallCard( + modifier: Modifier = Modifier, + category: CategoryEnum, + enabled: Boolean, + @DrawableRes image: Int, + onClick: (Int) -> Unit, +) { + OutlinedButton( + modifier = modifier + .shadow( + elevation = 4.dp, + shape = RoundedCornerShape(64.dp) + ) + .border( + border = BorderStroke( + 0.dp, Color.LightGray + ) + ) + .background( + if(enabled){ + Color.White + }else{ + Color.Green + } + ), + shape = RoundedCornerShape(64.dp), + enabled = enabled, + onClick = { onClick(category.id) } + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding( + horizontal = 8.dp, + vertical = 4.dp + ), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + Image( + painter = painterResource(id = category.icon), + contentDescription = null, + modifier = Modifier + .size(52.dp) + ) + Image( + painter = painterResource(id = image), + contentDescription = null, + modifier = Modifier + .size(52.dp) + ) + } + Row( + ) { + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/SettingsButton.kt b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/SettingsButton.kt new file mode 100644 index 0000000..65547b4 --- /dev/null +++ b/app/src/main/java/com/frannazario/proyectoandroid/presentation/ui/widgets/SettingsButton.kt @@ -0,0 +1,46 @@ +package com.frannazario.proyectoandroid.presentation.ui.widgets + +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import androidx.navigation.NavHostController +import com.frannazario.proyectoandroid.R +import com.frannazario.proyectoandroid.presentation.navigation.AppScreens +import kotlinx.coroutines.launch +import androidx.compose.animation.core.Animatable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.ui.draw.rotate + +@Composable +fun SettingsButton(bottomNavController: NavHostController) { + val coroutineScope = rememberCoroutineScope() + val animatableRotation = remember {Animatable(0f)} + + + Image( + painter = painterResource(id = R.drawable.baseline_settings_24), + contentDescription = null, + modifier = Modifier + .size(32.dp) + .rotate(animatableRotation.value) + .clickable( + indication = null, + interactionSource = remember { MutableInteractionSource() } + ) { + coroutineScope.launch { + animatableRotation.animateTo(360f + animatableRotation.value) + bottomNavController.navigate(AppScreens.SettingsScreen.route) + } + }, + colorFilter = ColorFilter.tint(Color.White) + ) + +} 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 f823bc5..c002455 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,76 +1,84 @@ -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 -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.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 coil.compose.AsyncImagePainter -import com.frannazario.proyectoandroid.R -import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel - - -@Composable -fun TopBar(userViewModel: UserViewModel) { - - val imageLoaded = remember { mutableStateOf(true) } - val userViewState = userViewModel.userViewState.collectAsState() - - 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 = userViewState.value.user.username)}, - navigationIcon = { - 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) - ) - ) - } - }, - ) - } - +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 +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.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.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import androidx.navigation.NavHostController +import coil.compose.AsyncImage +import coil.compose.AsyncImagePainter +import com.frannazario.proyectoandroid.R +import com.frannazario.proyectoandroid.data.viewmodels.UserViewModel + + +@Composable +fun TopBar(userViewModel: UserViewModel, bottomNavController: NavHostController) { + + val imageLoaded = remember { mutableStateOf(true) } + val userViewState = userViewModel.userViewState.collectAsState() + + 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 = userViewState.value.user.username) + }, + navigationIcon = { + 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) + ), + ) + } + }, + actions = { + SettingsButton(bottomNavController) + } + ) + } + } \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml index 2b068d1..cc14f03 100644 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -1,30 +1,30 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/baseline_edit_24.xml b/app/src/main/res/drawable/baseline_edit_24.xml new file mode 100644 index 0000000..1c9bd3e --- /dev/null +++ b/app/src/main/res/drawable/baseline_edit_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/baseline_edit_off_24.xml b/app/src/main/res/drawable/baseline_edit_off_24.xml new file mode 100644 index 0000000..f03dc42 --- /dev/null +++ b/app/src/main/res/drawable/baseline_edit_off_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/baseline_settings_24.xml b/app/src/main/res/drawable/baseline_settings_24.xml new file mode 100644 index 0000000..298a5a1 --- /dev/null +++ b/app/src/main/res/drawable/baseline_settings_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/button_background.xml b/app/src/main/res/drawable/button_background.xml index 1bd9052..e5c47ae 100644 --- a/app/src/main/res/drawable/button_background.xml +++ b/app/src/main/res/drawable/button_background.xml @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/button_clicked.xml b/app/src/main/res/drawable/button_clicked.xml index 30a43e9..55050c3 100644 --- a/app/src/main/res/drawable/button_clicked.xml +++ b/app/src/main/res/drawable/button_clicked.xml @@ -1,10 +1,10 @@ - - - - + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/button_stand.xml b/app/src/main/res/drawable/button_stand.xml index d918a01..6b1b92d 100644 --- a/app/src/main/res/drawable/button_stand.xml +++ b/app/src/main/res/drawable/button_stand.xml @@ -1,6 +1,6 @@ - - - - + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml index 07d5da9..a4f78de 100644 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,170 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/input_background.xml b/app/src/main/res/drawable/input_background.xml index c810750..a133933 100644 --- a/app/src/main/res/drawable/input_background.xml +++ b/app/src/main/res/drawable/input_background.xml @@ -1,4 +1,4 @@ - - - + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_auth.xml b/app/src/main/res/layout/activity_auth.xml index 96c4e45..9ad87be 100644 --- a/app/src/main/res/layout/activity_auth.xml +++ b/app/src/main/res/layout/activity_auth.xml @@ -1,16 +1,16 @@ - - - - - + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_login.xml b/app/src/main/res/layout/fragment_login.xml index 6360895..98a5a4a 100644 --- a/app/src/main/res/layout/fragment_login.xml +++ b/app/src/main/res/layout/fragment_login.xml @@ -1,124 +1,124 @@ - - - - - - - - - - - - - - - - - - - -