Compare commits

..

163 Commits

Author SHA1 Message Date
Renaud BEURET 3f04d9f57a [ADD] Test ScientifiqueDTO
1 year ago
Renaud BEURET d753c67fb3 [ADD] Test difficulte
1 year ago
Renaud BEURET 6c835b7195 [ADD] Test thematique
1 year ago
Renaud BEURET 528c15e63c [FIX] Points dans kahoot
1 year ago
Victor SOULIER 9e5a9b3b4d [Test] correction token secret name
1 year ago
Victor SOULIER b58fb80c63 [Test] ajout sonar
1 year ago
Gwenael PLANCHON 8a04d4e84f ajout .gitignore
1 year ago
Victor SOULIER 3b40fc7ee8 Merge branch 'master' into Android
1 year ago
Renaud BEURET b1200df54c [ADD] Tests ajout point
1 year ago
Renaud BEURET d5d5271fa8 [FIX] Probleme message
1 year ago
Renaud BEURET 1a3edfbdef [FIX] Lance exception si param incorrect
1 year ago
Renaud BEURET 42c9c4b2cd [ADD] Test ScientifiqueDecouvertVM
1 year ago
Renaud BEURET d2bdd5b20d [FIX] Nom paramètre
1 year ago
Renaud BEURET 1dc62918c0 [ADD] Cas test pour LoginVM
1 year ago
Renaud BEURET 34d852acb1 [ADD] Tests LoginVM
1 year ago
Renaud BEURET ac75980226 [FIX] Rechangement de repo dans la factory
1 year ago
Renaud BEURET 2d0e9022dd [ADD] Test de lancer partie pour kahoot mais test ne passe pas (semble mal observer le state)
1 year ago
Renaud BEURET 59168a1ecc [FIX] Changement comportement KahootVM pour éviter d'utiliser une question stubbé en premier
1 year ago
Renaud BEURET f1cdc05ebb [FIX] UiStates plus modifiables à l'exterieur des VM
1 year ago
Renaud BEURET be07bd7e07 [ADD] QuestionStubRepository
1 year ago
Renaud BEURET 54baae7303 [ADD] Test jouer 2 fois même action
1 year ago
Renaud BEURET 5c2a04fe9e [ADD] Test paramétré pour jouer une seule action
1 year ago
Renaud BEURET 39da627553 [ADD] Test jouer lettre sensible à la casse (NOTE : Test à refactoriser)
1 year ago
Renaud BEURET 9464dfb879 [ADD] Test InitPartie et PutGood/WrongLetter
1 year ago
Renaud BEURET b3665cc7f8 [FIX] ViewModels
1 year ago
Renaud BEURET 7cc9368a67 [ADD] Règle qui remplace le dispatcheur pour les tests
1 year ago
Renaud BEURET 08cd13867d Merge pull request 'RepositoryAndroid' (#25) from RepositoryAndroid into Android
1 year ago
Renaud BEURET a839310455 [FIX] Merge
1 year ago
Renaud BEURET a69a206844 [ADD] Scientifique Stub Repo
1 year ago
Alix JEUDI--LEMOINE 0134d8f861 Modification comportement si gagné/perdu, gel de l'input et affichage gagné/perdu
1 year ago
Alix JEUDI--LEMOINE 96b9e10b86 Ajout code DTO
1 year ago
Alix JEUDI--LEMOINE b25dc03a36 Modification URL API (passage vers le conteneur CodeFirst, 🚨 UTILISEZ EMULATEUR RECENT, SINON CERTIFICATS PAS A JOUR)
1 year ago
Alix JEUDI--LEMOINE 4f5fbb321d Ajout fetchScientifiquesInfos qui retourne le bloc page
1 year ago
Alix JEUDI--LEMOINE 94a1c3f84b Ajout route scientifiques sans pageId pour récupèrer les informations du bloc 'page'
1 year ago
Alix JEUDI--LEMOINE 18dfba47ec Modification ViewModel pour connexion à l'API complet, avec un random sur le nombre total de scientifiques
1 year ago
Alix JEUDI--LEMOINE 27d475c107 Ajout DTO ScientifiqueListInfos
1 year ago
Renaud BEURET 9462b539ea [FIX] Refactor factory
1 year ago
Renaud BEURET 7362763f9b [FIX] Meilleur repository pour Scientifique
1 year ago
Renaud BEURET 981afd5a3a [DEL] Vieux fetchQuestion
1 year ago
Renaud BEURET 3711a0934f [FIX] KahootUIState
1 year ago
Renaud BEURET 6d038ffe30 [FIX] Nom package pour respecter conventions de nommage
1 year ago
Lilian BRETON 56a191a11d Merge remote-tracking branch 'origin/Android' into Android
1 year ago
Lilian BRETON 6b7ec29f30 fix pendu
1 year ago
Renaud BEURET b22cee99e9 [FIX] Vues utilisent correctement ViewModels avec repo
1 year ago
Renaud BEURET 318c14bec3 [FIX] Factory et utilisent un repo injecté
1 year ago
Renaud BEURET 47a3fdecbd [FIX] NavHost n'instancie plus le KahootViewModel
1 year ago
Renaud BEURET 6a09993f23 [ADD] Reponse Simple
1 year ago
Renaud BEURET 66decf0486 [FIX] KahootUIState utilise QuestionWithSimpleReponse
1 year ago
Renaud BEURET 17eabbd9a5 [ADD] Repositories pour question
1 year ago
Renaud BEURET 1d5cc3e009 [ADD] Méthodes extension ToModel pour Question et Reponses simples
1 year ago
Renaud BEURET 01cb8d35eb [ADD] QuestionWithSimpleReponse model
1 year ago
Tom BIARD 36eecd7e8e Ajout qui-est-ce + idee
1 year ago
Renaud BEURET ae707b0494 [ADD] Reponse simple
1 year ago
Tom BIARD d99836112a Merge branch 'Android' of https://codefirst.iut.uca.fr/git/tom.biard/ScienceQuest into Android
1 year ago
Tom BIARD 80a1c3a301 Ajout de la page Qui-est-ce + description de l'idée pour la suite du jeu.
1 year ago
Lilian BRETON fe4e875c93 fix
1 year ago
Lilian BRETON 3288aa1ee1 Merge branch 'Android' of https://codefirst.iut.uca.fr/git/tom.biard/ScienceQuest into Android
1 year ago
Renaud BEURET 6e27dac780 [FIX] Factory fonctionnelle
1 year ago
Renaud BEURET dae9bb2064 [FIX] Typo
1 year ago
Renaud BEURET 0d022846c0 [ADD] Repo pour injecter fournisseur (et pouvoir tester vm)
1 year ago
Renaud BEURET 15a6829ee8 [ADD] Va chercher une liste de question sur l'API (index en dur)
1 year ago
Renaud BEURET a8a5925009 [FIX] Jouer majuscule = Jouer minuscule
1 year ago
Renaud BEURET d9ccdad5cb [FIX] Refactor entrée dans pendu pour code + lisible
1 year ago
Renaud BEURET 5bf379ad61 [ADD] Lancer kahoot depuis home fonctionne
1 year ago
Renaud BEURET a093d38820 [FIX] Ajoute les point, cependant recompose et relance une partie à chaque fois
1 year ago
Renaud BEURET a9fd6dbe74 [ADD] Début logique Kahoot (points fonctionnent pas)
1 year ago
Renaud BEURET 50d4a03973 [FIX] Context recup dans composant
1 year ago
Renaud BEURET b306915e68 [ADD] Kahoot change de question au bout de 10 secondes
1 year ago
Renaud BEURET a3972b743f [ADD] Partie/Joueur/MAJ DTOs
1 year ago
Renaud BEURET 506c1df396 [ADD] View Model pour le kahoot
1 year ago
Renaud BEURET 12988cb4a9 [ADD] View model basique pour la page de login
1 year ago
Renaud BEURET bbc03d891a [ADD] Coeurs pour vie dans pendu
1 year ago
Lilian BRETON 1766d0aae4 Merge remote-tracking branch 'origin/Android' into Android
1 year ago
Lilian BRETON 5bbc5537a9 fix pendu
1 year ago
Renaud BEURET 7385ab6d02 [FIX] Mot a trouver nom et pas prenom + nom
1 year ago
Renaud BEURET bfa62c02a3 [ADD] Va chercher nom dans l'api (va chercher un id inscrit en dur)
1 year ago
Renaud BEURET 11c1476334 [ADD] Toast quand gagné, retour home quand perdu
1 year ago
Renaud BEURET 028d60ee36 [FIX] Correction maj mot a trou
1 year ago
Renaud BEURET 08824e74f9 Merge branch 'Android' of codefirst.iut.uca.fr:tom.biard/ScienceQuest into Android
1 year ago
Renaud BEURET 8aed40fb8c [FIX] MAJ UIState quand lettre jouée
1 year ago
Alix JEUDI--LEMOINE a979a66de4 Merge branch 'Android' of https://codefirst.iut.uca.fr/git/tom.biard/ScienceQuest into Android
1 year ago
Alix JEUDI--LEMOINE 0f37eabdb4 Add no_account, inscription, continue_no_acc, no_account_details, coming_soon
1 year ago
Alix JEUDI--LEMOINE 61de9e805e Modification padding en utilisant un modifier directement (recommandé) + ajout bouton 'Je nai pas de compte' + popup
1 year ago
Renaud BEURET d0faf2e972 [ADD] Logique fonctionnelle
1 year ago
Renaud BEURET 042f9399af [FIX] Déplacer logique dans ViewModel
1 year ago
Renaud BEURET 1e6a25a5a3 [ADD] Logique partie pendu (a tester)
1 year ago
Renaud BEURET d40e946662 [ADD] Pendu UI State
1 year ago
Renaud BEURET ed845c4f21 [ADD] Séparation dans un UIState
1 year ago
Renaud BEURET 51056b2d92 Merge pull request 'ViewModel' (#24) from ViewModel into Android
1 year ago
Renaud BEURET d274a1e45f [FIX] ViewModel basique fonctionnel
1 year ago
Renaud BEURET de65dca150 [FIX] Requete API (a appler dans vue)
1 year ago
Renaud BEURET de7648ea42 [FIX] Typo
1 year ago
Renaud BEURET 7e8db33141 [MOVE] Services/Requestor réunis par package
1 year ago
Renaud BEURET d511505606 [ADD] QuestionListDTO
1 year ago
Renaud BEURET 84e0b906bb [ADD] Requetes questions avec reponse simple
1 year ago
Renaud BEURET 2b3b68761a [MOVE] Choses utilisés par tout les services dans un fichier pour éviter redondance
1 year ago
Renaud BEURET 3605dbcaee [FIX] Import
1 year ago
Renaud BEURET eb3c3fbe70 [FIX] Création module Scientifique dans dto
1 year ago
Renaud BEURET feeae3874d [FIX] Requete page de scientifique + changement DTO
1 year ago
Renaud BEURET ba13a6477f [ADD] ViewModel (fonctionne pas)
1 year ago
Renaud BEURET 5abf2a8bbb [ADD] Border pour container de scientifique
1 year ago
Renaud BEURET f61c350ff7 [MOD] Navigation pour ajouter liste de scientifiques (pour tests)
1 year ago
Renaud BEURET 3e3c72e0f2 [ADD] Composables vue liste scientifiques
1 year ago
Renaud BEURET 1242a19ab2 [FIX] prenom = photo dans la conversion
1 year ago
Renaud BEURET e5b3249c10 [MOD] id passés en instances
1 year ago
Renaud BEURET 48af7ac5be [ADD] ToModel Difficulte
1 year ago
Renaud BEURET 3103fac98f [ADD] ToModel Thematique
1 year ago
Renaud BEURET feee19a505 [ADD] Extension ToModel/ToModels pour scientifique
1 year ago
Alix JEUDI--LEMOINE 7f6ac91470 Correction stub
1 year ago
Alix JEUDI--LEMOINE 33b1efa908 Merge branch 'Android' of https://codefirst.iut.uca.fr/git/tom.biard/ScienceQuest into Android
1 year ago
Alix JEUDI--LEMOINE 07a84195a9 Correction du DTO (plantage car champs incorrects)
1 year ago
Alix JEUDI--LEMOINE b41d06791c Modification URL API
1 year ago
Alix JEUDI--LEMOINE 149862f090 Ajout permissions INTERNET pour accès API
1 year ago
Renaud BEURET ce7675f5ae [ADD] Stub liste scientifique
1 year ago
Renaud BEURET 9968d3cc2e [FIX] Type des dtos pour qu'objet en hérite dans le stub
1 year ago
Renaud BEURET 028a1c971c [ADD] StubScientifique
1 year ago
Victor SOULIER ca2ae68925 Merge remote-tracking branch 'origin/Android' into Android
1 year ago
Victor SOULIER 9955393b50 ajout toast au clic d'une reponse
1 year ago
Victor SOULIER 13f09af49a ajout navigation kahoot
1 year ago
Renaud BEURET 56384599b7 [ADD] RequestScientifiques (pareil, logcat veut pas logger, à tester quand mvvm ou trouver autre moyen de vérifier)
1 year ago
Renaud BEURET cdd8a72b18 Merge branch 'Android' of codefirst.iut.uca.fr:tom.biard/ScienceQuest into Android
1 year ago
Renaud BEURET e636f3dc9c [ADD] FetchScientifique (fonctione ? logcat ne veut pas log donc pas sûr ?)
1 year ago
Victor SOULIER c0cfd2014a ajout kahoot
1 year ago
Victor SOULIER 85084cbd1c ajout stub question/reponses
1 year ago
Victor SOULIER 9d39849675 ajout interface base kahoot
1 year ago
Victor SOULIER 63f60b34b0 extensible dto questionwithsimplereponse
1 year ago
Victor SOULIER cad113168f fix constructor
1 year ago
Victor SOULIER c8fb640d18 ajout dto simple pour question contenant uniquement une liste des reponses avec un string
1 year ago
Victor SOULIER 90947bcbfc dossier pour dto reponse et question
1 year ago
Victor SOULIER 189cde5ae3 ajout dto question / reponse
1 year ago
Renaud BEURET fe5734143f [FIX] Rename RequestService en ScientifiqueRequestService
1 year ago
Renaud BEURET e911683662 [ADD] Service de requêtes
1 year ago
Renaud BEURET 5ee5b88c6a [MAJ] Dependances
1 year ago
Renaud BEURET 1faa666b6d [ADD] DTO Scientifique/Difficulte/Thematique
1 year ago
Renaud BEURET b7f005c3e6 [ADD] Dep pour serialization
1 year ago
Renaud BEURET afa20b627d [ADD] Difficulte/Scientifique/Thematique model
1 year ago
Alix JEUDI--LEMOINE 1bad2c9329 Ajout code page Pendu (vraiment le début)
1 year ago
Alix JEUDI--LEMOINE 1d25d4dede Modification arguments TopBar (ajout text: String) et affichage du texte en lieu et place ScienceQuest (sauf si text pas donné, alors ScienceQuest s'affiche)
1 year ago
Alix JEUDI--LEMOINE 0820d244a7 Changement appel TopBar avec string Connexion dedans
1 year ago
Alix JEUDI--LEMOINE 90904fee09 Récupération goToPendu et passage à MainContent pour l'ouverture de la page au clic sur le bouton pendu
1 year ago
Alix JEUDI--LEMOINE 918a2808da Modification appel TopBar (ajout de la string compte en argument)
1 year ago
Alix JEUDI--LEMOINE e9120f5dcc Ajout goToPendu et route pendu
1 year ago
Alix JEUDI--LEMOINE 5c07150455 Correction maj + ajout string pendu
1 year ago
Alix JEUDI--LEMOINE 8ac0c9a46e Ajout de 3 colonnes dans la ligne de la navbar pour bien placer chaque item
1 year ago
Alix JEUDI--LEMOINE 6adcadcd52 Correction dp + ajout appels goToAccount & goToHome
1 year ago
Alix JEUDI--LEMOINE e237947f5c Ajout Toast sur les boutons qui affiche 'Coming Soon' + replacement des Dp(xf) par x.dp (pas beau du tout)
1 year ago
Alix JEUDI--LEMOINE d4bd57b378 Ajout padding pour éviter que le contenu soit collé à la barre de navigation
1 year ago
Alix JEUDI--LEMOINE 665659b875 Ajout liaisons router sur la page login
1 year ago
Alix JEUDI--LEMOINE ae1342b5ec Correction faute
1 year ago
Alix JEUDI--LEMOINE cd6de2dd25 Ajout fichier jeu Pendu
1 year ago
Renaud BEURET 5af744e45d [ADD] Page login avec text input réactif
1 year ago
Victor SOULIER 167c34c689 ajout choix jeu
1 year ago
Victor SOULIER d6203b0dbd fix missing column
1 year ago
Victor SOULIER a069a87d5e ajout preview
1 year ago
Victor SOULIER 110d031d8e centrage du titre de l'app
1 year ago
Victor SOULIER e11528db07 fix nom de convention pour les fonctions composables
1 year ago
Victor SOULIER ce4e4db97b ajout preview
1 year ago
Victor SOULIER f76537a7b7 fixfolder
1 year ago
Victor SOULIER df7f33cd87 rename folder
1 year ago
Victor SOULIER f9767af4ad fix dependency package name
1 year ago
Victor SOULIER a6d8eb26a9 fix package name
1 year ago
Victor SOULIER d11da40f0d package rename
1 year ago
Lilian BRETON 87331fbe3c Start android
1 year ago

@ -0,0 +1,18 @@
kind: pipeline
type: docker
name: ScienceQuestAndroid
trigger:
branch:
- Android
event:
- push
steps:
- name: code-analysis-android
image: aosapps/drone-sonar-plugin
settings:
sonar_host:
from_secret: sonar_host
sonar_token:
from_secret: sonar_sae_token

1
.gitignore vendored

@ -0,0 +1 @@
.idea/

3
.idea/.gitignore vendored

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<value>
<entry key="app">
<State />
</entry>
</value>
</component>
</project>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$/android" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$/android" />
<option value="$PROJECT_DIR$/android/app" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.0" />
</component>
</project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$/android" />
</set>
</option>
</component>
</project>

@ -0,0 +1,6 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

Binary file not shown.

15
android/.gitignore vendored

@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

@ -0,0 +1 @@
ScienceQuest

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AppInsightsSettings">
<option name="selectedTabId" value="Android Vitals" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<value>
<entry key="app">
<State />
</entry>
</value>
</component>
</project>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.0" />
</component>
</project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

@ -0,0 +1,9 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

@ -0,0 +1 @@
/build

@ -0,0 +1,79 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
kotlin("plugin.serialization") version "1.9.23"
}
android {
namespace = "fr.iut.sciencequest"
compileSdk = 34
defaultConfig {
applicationId = "fr.iut.sciencequest"
minSdk = 21
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = 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.5.1"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:1.7.3")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
implementation("androidx.navigation:navigation-compose:2.7.7")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0")
implementation("androidx.activity:activity-compose:1.8.2")
implementation(platform("androidx.compose:compose-bom:2023.08.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(platform("androidx.compose:compose-bom:2023.08.00"))
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
testImplementation("io.mockk:mockk:1.13.10")
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:2023.08.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.08.00"))
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}

@ -0,0 +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.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,24 @@
package fr.iut.sciencequest
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("fr.iut.sciencequest", appContext.packageName)
}
}

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ScienceQuest"
tools:targetApi="31">
<activity
android:name="fr.iut.sciencequest.MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.ScienceQuest">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

@ -0,0 +1,28 @@
package fr.iut.sciencequest
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 fr.iut.sciencequest.navigation.NavHost
import fr.iut.sciencequest.ui.theme.ScienceQuestTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ScienceQuestTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
NavHost()
}
}
}
}
}

@ -0,0 +1,11 @@
package fr.iut.sciencequest.model.buisness.Question
import fr.iut.sciencequest.model.dto.question.QuestionListDTO
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query
interface QuestionRequestService {
@GET("questions?page")
suspend fun getQuestions(@Query("page") index: Int): QuestionListDTO
}

@ -0,0 +1,19 @@
package fr.iut.sciencequest.model.buisness.Scientifique
import fr.iut.sciencequest.model.dto.ScientifiqueDTOs.ScientifiqueDTO
import fr.iut.sciencequest.model.dto.ScientifiqueDTOs.ScientifiqueListDTO
import fr.iut.sciencequest.model.dto.ScientifiqueDTOs.ScientifiqueListInfosDTO
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query
interface ScientifiqueRequestService {
@GET("scientifiques?page")
suspend fun getScientifiques(@Query("page") index: Int): ScientifiqueListDTO
@GET("scientifiques")
suspend fun getScientifiquesListInfos(): ScientifiqueListInfosDTO
@GET("scientifiques/{id}")
suspend fun getScientifique(@Path("id") id: Int): ScientifiqueDTO
}

@ -0,0 +1,36 @@
package fr.iut.sciencequest.model.buisness.Scientifique
import android.util.Log
import fr.iut.sciencequest.model.buisness.createRequestService
import kotlinx.coroutines.flow.flow
import retrofit2.create
suspend fun fetchScientifiqueById(id: Int) = flow {
val serviceClient = createRequestService().create<ScientifiqueRequestService>()
try {
val response = serviceClient.getScientifique(id)
emit(response)
} catch (e: Exception) {
Log.e("Requete API",e.message.toString())
}
}
fun fetchScientifiques(index: Int) = flow {
val serviceClient = createRequestService().create<ScientifiqueRequestService>()
try {
val response = serviceClient.getScientifiques(index)
emit(response)
} catch (e: Exception) {
Log.e("Requete API",e.message.toString())
}
}
fun fetchScientifiquesInfos() = flow {
val serviceClient = createRequestService().create<ScientifiqueRequestService>()
try {
val response = serviceClient.getScientifiquesListInfos().page
emit(response)
} catch (e: Exception) {
Log.e("Requete API",e.message.toString())
}
}

@ -0,0 +1,18 @@
package fr.iut.sciencequest.model.buisness
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import okhttp3.MediaType
import okhttp3.OkHttpClient
import retrofit2.Retrofit
const val API_BASE_URL = "https://codefirst.iut.uca.fr/containers/tombiard-api/api/v1/"
val httpClient = OkHttpClient()
fun createRequestService(): Retrofit =
Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(Json { ignoreUnknownKeys = true }.asConverterFactory(MediaType.get("application/json")))
.client(httpClient)
.build()

@ -0,0 +1,7 @@
package fr.iut.sciencequest.model.dto
class JeuDTO (
val id: Int,
val nom: String,
val nbrParties: UInt
)

@ -0,0 +1,11 @@
package fr.iut.sciencequest.model.dto
import fr.iut.sciencequest.model.dto.joueur.JoueurSimpleDTO
class PartieDTO (
val id: Int,
val codeInvitation: String,
val joueurs: List<JoueurSimpleDTO>,
val jeu: JeuDTO,
val thematiques: List<ThematiqueDTO>
)

@ -0,0 +1,20 @@
package fr.iut.sciencequest.model.dto.ScientifiqueDTOs
import fr.iut.sciencequest.model.dto.difficulte.DifficulteDTO
import fr.iut.sciencequest.model.dto.ThematiqueDTO
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
open class ScientifiqueDTO (
val id: Int,
val nom: String,
val prenom: String,
@SerialName("pathToPhoto")
val photo: String,
val descriptif: String,
val ratioTrouve: Float,
val sexe: Char,
val difficulte : DifficulteDTO,
val thematique : ThematiqueDTO
)

@ -0,0 +1,14 @@
package fr.iut.sciencequest.model.dto.ScientifiqueDTOs
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
open class ScientifiqueListDTO {
@SerialName("_embedded")
val scientifiques: List<ScientifiqueDTO>
constructor(scientifiques: List<ScientifiqueDTO>) {
this.scientifiques = scientifiques
}
}

@ -0,0 +1,21 @@
package fr.iut.sciencequest.model.dto.ScientifiqueDTOs
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
open class ScientifiqueListInfosPageDTO(
@SerialName("totalElements")
val nbScientfiques: Int,
@SerialName("totalPages")
val nbPages: Int,
@SerialName("size")
val nbScientifiquesParPage: Int
)
@Serializable
open class ScientifiqueListInfosDTO (
val page: ScientifiqueListInfosPageDTO
)

@ -0,0 +1,9 @@
package fr.iut.sciencequest.model.dto
import kotlinx.serialization.Serializable
@Serializable
data class ThematiqueDTO (
val id: Int,
val libelle: String
)

@ -0,0 +1,9 @@
package fr.iut.sciencequest.model.dto.difficulte
import kotlinx.serialization.Serializable
@Serializable
class DifficulteDTO (
val id: Int,
val libelle: String
)

@ -0,0 +1,6 @@
package fr.iut.sciencequest.model.dto.difficulte
class DifficulteSimpleDTO (
val id: Int,
val libelle: String
)

@ -0,0 +1,12 @@
package fr.iut.sciencequest.model.dto.extensions
import fr.iut.sciencequest.model.dto.difficulte.DifficulteDTO
import fr.iut.sciencequest.model.metier.Difficulte
fun DifficulteDTO.ToModel(): Difficulte {
val model = Difficulte(
id = this.id,
libelle = this.libelle
)
return model
}

@ -0,0 +1,30 @@
package fr.iut.sciencequest.model.dto.extensions
import fr.iut.sciencequest.model.dto.question.QuestionDTO
import fr.iut.sciencequest.model.dto.question.QuestionWithSimpleResponseDTO
import fr.iut.sciencequest.model.metier.question.Question
import fr.iut.sciencequest.model.metier.question.QuestionWithSimpleReponse
fun QuestionDTO.ToModel(): Question {
return Question(
this.id,
this.question,
this.reponses.ToModel()
)
}
fun List<QuestionDTO>.ToModel(): List<Question> {
val liste = mutableListOf<Question>()
for (question in this) {
liste.add(question.ToModel())
}
return liste
}
fun Question.ToQuestionWithSimpleReponse(): QuestionWithSimpleReponse {
return QuestionWithSimpleReponse(
this.id,
this.question,
this.reponses.ToSimpleReponses()
)
}

@ -0,0 +1,20 @@
package fr.iut.sciencequest.model.dto.extensions
import fr.iut.sciencequest.model.dto.question.QuestionWithSimpleResponseDTO
import fr.iut.sciencequest.model.metier.question.QuestionWithSimpleReponse
fun QuestionWithSimpleResponseDTO.ToModel(): QuestionWithSimpleReponse {
return QuestionWithSimpleReponse(
this.id,
this.question,
this.reponses.ToModel()
)
}
fun List<QuestionWithSimpleResponseDTO>.ToModel(): List<QuestionWithSimpleReponse> {
val liste = ArrayList<QuestionWithSimpleReponse>()
for (question in this) {
liste.add(question.ToModel())
}
return liste
}

@ -0,0 +1,37 @@
package fr.iut.sciencequest.model.dto.extensions
import fr.iut.sciencequest.model.dto.reponse.ReponseDTO
import fr.iut.sciencequest.model.metier.reponse.Reponse
import fr.iut.sciencequest.model.metier.reponse.ReponseSimple
fun ReponseDTO.ToModel(): Reponse {
return Reponse(
this.id,
this.reponse,
this.question.ToModel(),
this.scientifique.ToModel()
)
}
fun List<ReponseDTO>.ToModel(): List<Reponse> {
val liste = ArrayList<Reponse>()
for (reponse in this) {
liste.add(reponse.ToModel())
}
return liste
}
fun Reponse.ToSimpleReponse(): ReponseSimple {
return ReponseSimple(
this.id,
this.reponse
)
}
fun List<Reponse>.ToSimpleReponses(): List<ReponseSimple> {
val liste = ArrayList<ReponseSimple>()
for (reponse in this) {
liste.add(reponse.ToSimpleReponse())
}
return liste
}

@ -0,0 +1,27 @@
package fr.iut.sciencequest.model.dto.extensions
import fr.iut.sciencequest.model.dto.ScientifiqueDTOs.ScientifiqueDTO
import fr.iut.sciencequest.model.metier.Scientifique
fun ScientifiqueDTO.ToModel(): Scientifique {
val model = Scientifique(
id = this.id,
descriptif = this.descriptif,
nom = this.nom,
prenom = this.prenom,
photo = this.photo,
difficulte = this.difficulte.ToModel(),
sexe = this.sexe,
ratioTrouve = this.ratioTrouve,
thematique = this.thematique.ToModel()
)
return model
}
fun List<ScientifiqueDTO>.ToModel(): List<Scientifique> {
val liste = ArrayList<Scientifique>();
for (dto in this) {
liste.add(dto.ToModel())
}
return liste
}

@ -0,0 +1,19 @@
package fr.iut.sciencequest.model.dto.extensions
import fr.iut.sciencequest.model.dto.reponse.ReponseSimpleDTO
import fr.iut.sciencequest.model.metier.reponse.ReponseSimple
fun ReponseSimpleDTO.ToModel(): ReponseSimple {
return ReponseSimple(
this.id,
this.reponse
)
}
fun List<ReponseSimpleDTO>.ToModel(): List<ReponseSimple> {
val liste = ArrayList<ReponseSimple>()
for (reponse in this) {
liste.add(reponse.ToModel())
}
return liste
}

@ -0,0 +1,12 @@
package fr.iut.sciencequest.model.dto.extensions
import fr.iut.sciencequest.model.dto.ThematiqueDTO
import fr.iut.sciencequest.model.metier.Thematique
fun ThematiqueDTO.ToModel(): Thematique {
val model = Thematique(
id = this.id,
libelle = this.libelle
)
return model
}

@ -0,0 +1,9 @@
package fr.iut.sciencequest.model.dto.joueur
import fr.iut.sciencequest.model.dto.PartieDTO
class JoueurDTO (
val id: Int,
val pseudo: String,
val partie: PartieDTO
)

@ -0,0 +1,6 @@
package fr.iut.sciencequest.model.dto.joueur
class JoueurSimpleDTO (
val id: Int,
val pseudo: String,
)

@ -0,0 +1,11 @@
package fr.iut.sciencequest.model.dto.question
import fr.iut.sciencequest.model.dto.reponse.ReponseDTO
import kotlinx.serialization.Serializable
@Serializable
class QuestionDTO (
val id: Int,
val question: String,
val reponses: List<ReponseDTO>
)

@ -0,0 +1,14 @@
package fr.iut.sciencequest.model.dto.question
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
class QuestionListDTO {
@SerialName("_embedded")
val questions: List<QuestionWithSimpleResponseDTO>
constructor(questions: List<QuestionWithSimpleResponseDTO>) {
this.questions = questions
}
}

@ -0,0 +1,11 @@
package fr.iut.sciencequest.model.dto.question
import fr.iut.sciencequest.model.dto.reponse.ReponseSimpleDTO
import kotlinx.serialization.Serializable
@Serializable
open class QuestionWithSimpleResponseDTO(
val id: Int,
val question: String,
val reponses: List<ReponseSimpleDTO>
)

@ -0,0 +1,13 @@
package fr.iut.sciencequest.model.dto.reponse
import fr.iut.sciencequest.model.dto.question.QuestionDTO
import fr.iut.sciencequest.model.dto.ScientifiqueDTOs.ScientifiqueDTO
import kotlinx.serialization.Serializable
@Serializable
class ReponseDTO (
val id: Int,
val reponse: String,
val question: QuestionDTO,
val scientifique: ScientifiqueDTO
)

@ -0,0 +1,9 @@
package fr.iut.sciencequest.model.dto.reponse
import kotlinx.serialization.Serializable
@Serializable
class ReponseSimpleDTO(
val id: Int,
val reponse: String,
)

@ -0,0 +1,11 @@
package fr.iut.sciencequest.model.metier
class Difficulte {
val id: Int
val libelle: String
constructor(id: Int, libelle: String) {
this.id = id
this.libelle = libelle
}
}

@ -0,0 +1,33 @@
package fr.iut.sciencequest.model.metier
class Scientifique {
val id: Int
val nom: String
val prenom: String
val photo: String
val descriptif: String
val ratioTrouve: Float
val sexe: Char
val difficulte: Difficulte
val thematique: Thematique
constructor(id: Int,
nom: String,
prenom: String,
photo: String,
descriptif: String,
ratioTrouve: Float,
sexe: Char,
difficulte: Difficulte,
thematique: Thematique){
this.id = id
this.nom = nom
this.prenom = prenom
this.photo = photo
this.descriptif = descriptif
this.ratioTrouve = ratioTrouve
this.sexe = sexe
this.difficulte = difficulte
this.thematique = thematique
}
}

@ -0,0 +1,10 @@
package fr.iut.sciencequest.model.metier
class Thematique {
val id: Int
val libelle: String
constructor(id: Int, libelle: String) {
this.id = id
this.libelle = libelle
}
}

@ -0,0 +1,10 @@
package fr.iut.sciencequest.model.metier.question
import fr.iut.sciencequest.model.metier.reponse.Reponse
class Question(
val id: Int,
val question: String,
val reponses: List<Reponse>
) {}

@ -0,0 +1,10 @@
package fr.iut.sciencequest.model.metier.question
import fr.iut.sciencequest.model.metier.reponse.Reponse
import fr.iut.sciencequest.model.metier.reponse.ReponseSimple
class QuestionWithSimpleReponse (
val id: Int,
val question: String,
val reponses: List<ReponseSimple>
)

@ -0,0 +1,12 @@
package fr.iut.sciencequest.model.metier.reponse
import fr.iut.sciencequest.model.metier.question.Question
import fr.iut.sciencequest.model.metier.Scientifique
class Reponse (
val id: Int,
val reponse: String,
val question: Question,
val scientifique: Scientifique
) {}

@ -0,0 +1,11 @@
package fr.iut.sciencequest.model.metier.reponse
class ReponseSimple {
val id: Int
val reponse: String
constructor(id: Int, reponse: String) {
this.id = id
this.reponse = reponse
}
}

@ -0,0 +1,11 @@
package fr.iut.sciencequest.model.repositories.question
import fr.iut.sciencequest.model.metier.question.Question
import fr.iut.sciencequest.model.metier.question.QuestionWithSimpleReponse
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
interface IQuestionRepository {
val questions: StateFlow<List<QuestionWithSimpleReponse>>
suspend fun fetchQuestions(index: Int)
}

@ -0,0 +1,31 @@
package fr.iut.sciencequest.model.repositories.question
import android.util.Log
import fr.iut.sciencequest.model.buisness.Question.QuestionRequestService
import fr.iut.sciencequest.model.buisness.createRequestService
import fr.iut.sciencequest.model.dto.extensions.ToModel
import fr.iut.sciencequest.model.metier.question.Question
import fr.iut.sciencequest.model.metier.question.QuestionWithSimpleReponse
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.update
import retrofit2.create
class QuestionAPIRepository : IQuestionRepository {
private val _questions = MutableStateFlow<List<QuestionWithSimpleReponse>>(emptyList())
override val questions: StateFlow<List<QuestionWithSimpleReponse>>
get() = _questions.asStateFlow()
override suspend fun fetchQuestions(index: Int) {
val serviceClient = createRequestService().create<QuestionRequestService>()
try {
_questions.value = serviceClient.getQuestions(index).questions.ToModel()
} catch (e: Exception) {
Log.e("Requete API Question", e.message.toString())
}
}
}

@ -0,0 +1,32 @@
package fr.iut.sciencequest.model.repositories.question
import android.util.Log
import fr.iut.sciencequest.model.buisness.Question.QuestionRequestService
import fr.iut.sciencequest.model.buisness.createRequestService
import fr.iut.sciencequest.model.dto.extensions.ToModel
import fr.iut.sciencequest.model.metier.question.Question
import fr.iut.sciencequest.model.metier.question.QuestionWithSimpleReponse
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import retrofit2.create
class QuestionStubRepository: IQuestionRepository {
private val _questions = MutableStateFlow<List<QuestionWithSimpleReponse>>(emptyList())
override val questions: StateFlow<List<QuestionWithSimpleReponse>>
get() = _questions.asStateFlow()
// NOTE : la méthode fait volontairement rien,
// Il faut override mais le scientifique est déjà set
// avec la méthode setScientifiqueStubList
// Et hors contexte de test, cette implémentation ne
// sert à rien
override suspend fun fetchQuestions(index: Int) {
}
fun setQuestionsStub(questions: List<QuestionWithSimpleReponse>) {
_questions.value = questions
}
}

@ -0,0 +1,14 @@
package fr.iut.sciencequest.model.repositories.scientifique
import fr.iut.sciencequest.model.metier.Scientifique
import fr.iut.sciencequest.model.metier.question.QuestionWithSimpleReponse
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
interface IScientifiqueRepository {
val scientifique: StateFlow<Scientifique>
val scientifiques: StateFlow<List<Scientifique>>
suspend fun fetchScientifiques(index: Int)
suspend fun fetchScientifiqueById(id: Int)
}

@ -0,0 +1,44 @@
package fr.iut.sciencequest.model.repositories.scientifique
import android.util.Log
import fr.iut.sciencequest.model.buisness.Question.QuestionRequestService
import fr.iut.sciencequest.model.buisness.Scientifique.ScientifiqueRequestService
import fr.iut.sciencequest.model.buisness.createRequestService
import fr.iut.sciencequest.model.dto.extensions.ToModel
import fr.iut.sciencequest.model.metier.Scientifique
import fr.iut.sciencequest.stub.StubScientifique1
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.flow
import retrofit2.create
class ScientifiqueAPIRepository: IScientifiqueRepository {
private val _scientifique = MutableStateFlow(StubScientifique1.ToModel())
override val scientifique: StateFlow<Scientifique>
get() = _scientifique.asStateFlow()
private val _scientifiques = MutableStateFlow<List<Scientifique>>(emptyList())
override val scientifiques: StateFlow<List<Scientifique>>
get() = _scientifiques.asStateFlow()
override suspend fun fetchScientifiqueById(id: Int) {
val serviceClient = createRequestService().create<ScientifiqueRequestService>()
try {
_scientifique.value = serviceClient.getScientifique(id).ToModel()
} catch (e: Exception) {
Log.e("Requete API Scientifiqu", e.message.toString())
}
}
override suspend fun fetchScientifiques(index: Int) {
val serviceClient = createRequestService().create<ScientifiqueRequestService>()
try {
_scientifiques.value = serviceClient.getScientifiques(index).scientifiques.ToModel()
} catch (e: Exception) {
Log.e("Requete API Scientifiqu", e.message.toString())
}
}
}

@ -0,0 +1,46 @@
package fr.iut.sciencequest.model.repositories.scientifique
import android.content.res.Resources.NotFoundException
import fr.iut.sciencequest.model.dto.extensions.ToModel
import fr.iut.sciencequest.model.metier.Scientifique
import fr.iut.sciencequest.stub.StubScientifique1
import fr.iut.sciencequest.stub.StubScientifique2
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
class ScientifiqueStubRepostory : IScientifiqueRepository {
private val _scientifique = MutableStateFlow(StubScientifique1.ToModel())
override val scientifique: StateFlow<Scientifique>
get() = _scientifique.asStateFlow()
private val _scientifiques = MutableStateFlow<List<Scientifique>>(emptyList())
override val scientifiques: StateFlow<List<Scientifique>>
get() = _scientifiques.asStateFlow()
// NOTE : la méthode fait volontairement rien,
// Il faut override mais le scientifique est déjà set
// avec la méthode setScientifiqueStubList
// Et hors contexte de test, cette implémentation ne
// sert à rien
override suspend fun fetchScientifiques(index: Int) {
}
// NOTE : la méthode fait volontairement rien,
// Il faut override mais le scientifique est déjà set
// avec la méthode setScientifiqueStub
// Et hors contexte de test, cette implémentation ne
// sert à rien
override suspend fun fetchScientifiqueById(id: Int) {
}
fun setScientifiqueStubList(scientifiques: MutableList<Scientifique>) {
_scientifiques.value = scientifiques
}
fun setScientifiqueStub(scientifique: Scientifique) {
_scientifique.value = scientifique
}
}

@ -0,0 +1,110 @@
package fr.iut.sciencequest.navigation
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import fr.iut.sciencequest.view.AccountScreen
import fr.iut.sciencequest.view.HomeScreen
import fr.iut.sciencequest.view.LoginScreen
import fr.iut.sciencequest.view.games.KahootScreen
import fr.iut.sciencequest.view.games.PenduScreen
import fr.iut.sciencequest.view.games.QuiScreen
import fr.iut.sciencequest.view.scientifiques.scientifiqueListeScreen
@Composable
fun NavHost() {
val navController = rememberNavController()
NavHost(
modifier = Modifier.fillMaxSize(),
navController = navController,
startDestination = "home"
) {
composable(route = "home") {
HomeScreen(
goToAccount = {
navController.navigate("account")
},
goToHome = {
navController.navigate("home")
},
goToPendu = {
navController.navigate("pendu")
},
goToKahoot = {
navController.navigate("kahoot")
},
goToQui = {
navController.navigate("qui")
}
)
}
composable(route = "account") {
AccountScreen(
goToAccount = {
navController.navigate("account")
},
goToHome = {
navController.navigate("home")
}
)
}
composable(route = "login") {
LoginScreen(
goToAccount = {
navController.navigate("account")
},
goToHome = {
navController.navigate("home")
}
)
}
composable(route = "pendu") {
PenduScreen(
goToAccount = {
navController.navigate("account")
},
goToHome = {
navController.navigate("home")
}
)
}
composable(route= "kahoot"){
KahootScreen(
goToAccount = {
navController.navigate("account")
},
goToHome = {
navController.navigate("home")
}
)
}
composable(route= "qui"){
QuiScreen(goToAccount = {
navController.navigate("account")
},
goToHome = {
navController.navigate("home")
})
}
composable(route = "listeScientifiques") {
scientifiqueListeScreen(
goToAccount = {
navController.navigate("account")
},
goToHome = {
navController.navigate("home")
}
)
}
}
}

@ -0,0 +1,27 @@
package fr.iut.sciencequest.stub
import fr.iut.sciencequest.model.dto.question.QuestionWithSimpleResponseDTO
import fr.iut.sciencequest.model.dto.reponse.ReponseSimpleDTO
object StubQuestionWithReponses: QuestionWithSimpleResponseDTO(
id = 0,
question = "Ceci est une question ?",
reponses = listOf<ReponseSimpleDTO>(
ReponseSimpleDTO(id=0, "Reponse 1"),
ReponseSimpleDTO(id=1, "Reponse 2"),
ReponseSimpleDTO(id=2, "Reponse 3"),
ReponseSimpleDTO(id=3, "Reponse 4"),
)
)
{}
object StubQuestionWithReponses2: QuestionWithSimpleResponseDTO(
id = 1,
question = "Ceci est une autre question ?",
reponses = listOf(
ReponseSimpleDTO(id = 4, "Moi une reponse?"),
ReponseSimpleDTO(id = 5, "La réponse A"),
ReponseSimpleDTO(id = 6, "Je suis faux"),
ReponseSimpleDTO(id = 5, "Toutes les réponses")
)
)

@ -0,0 +1,36 @@
package fr.iut.sciencequest.stub
import fr.iut.sciencequest.model.dto.difficulte.DifficulteDTO
import fr.iut.sciencequest.model.dto.ScientifiqueDTOs.ScientifiqueDTO
import fr.iut.sciencequest.model.dto.ThematiqueDTO
object StubScientifique1: ScientifiqueDTO(
id = 1,
descriptif = "description",
nom = "Jean",
prenom = "Jean",
photo = "photo",
sexe = 'H',
difficulte = DifficulteDTO(1, "Facile"),
thematique = ThematiqueDTO(1, "Nucléaire"),
ratioTrouve = 0f
)
object StubScientifique2: ScientifiqueDTO(
id = 2,
descriptif = "autre description",
nom = "Jean2",
prenom = "Jean2",
photo = "photo2",
sexe = 'F',
difficulte = DifficulteDTO(1, "Facile"),
thematique = ThematiqueDTO(1, "Nucléaire"),
ratioTrouve = 0f
)
fun getScientifiqueListeStub(): List<ScientifiqueDTO>{
val liste = ArrayList<ScientifiqueDTO>()
liste.add(StubScientifique2)
liste.add(StubScientifique1)
return liste
}

@ -0,0 +1,11 @@
package fr.iut.sciencequest.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)

@ -0,0 +1,70 @@
package fr.iut.sciencequest.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 ScienceQuestTheme(
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
)
}

@ -0,0 +1,34 @@
package fr.iut.sciencequest.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
)
*/
)

@ -0,0 +1,25 @@
package fr.iut.sciencequest.view
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import fr.iut.sciencequest.R
@Composable
fun AccountScreen(goToAccount: () -> Unit, goToHome: () -> Unit) {
Column(modifier = Modifier.fillMaxWidth()) {
TopBar(goToAccount, goToHome, stringResource(id = R.string.compte))
//Text(text = stringResource(id = R.string.compte), modifier = Modifier.padding(top=10.dp))
}
}
@Preview
@Composable
fun AccountScreenPreview(){
AccountScreen(goToAccount = {}) {
}
}

@ -0,0 +1,53 @@
package fr.iut.sciencequest.view
import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
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.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Composable
fun HomeScreen(goToHome: () -> Unit,
goToAccount: () -> Unit,
goToPendu: () -> Unit,
goToKahoot: () -> Unit,
goToQui: () -> Unit) {
Column (modifier = Modifier.fillMaxWidth()){
TopBar(goToAccount, goToHome)
MainContent(goToPendu, goToKahoot, goToQui)
}
}
@Preview
@Composable
fun HomeScreenPreview() {
HomeScreen({},{},{},{},{})
}
@Composable
fun MainContent(goToPendu: () -> Unit, goToKahoot: () -> Unit, goToQui: () -> Unit) {
val context = LocalContext.current;
val comingSoon = Toast.makeText(context, "Coming soon", Toast.LENGTH_SHORT);
Column (modifier = Modifier.fillMaxWidth().padding(30.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(15.dp
)){
Button(onClick = goToPendu, Modifier.fillMaxWidth()) {
Text(text = "Pendu", fontSize = 13.sp)
}
Button(onClick = goToKahoot, Modifier.fillMaxWidth()) {
Text(text = "Kahoot", fontSize = 13.sp)
}
Button(onClick = goToQui, Modifier.fillMaxWidth()) {
Text(text = "Qui est ce ?", fontSize = 13.sp)
}
}
}

@ -0,0 +1,120 @@
package fr.iut.sciencequest.view
import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import fr.iut.sciencequest.R
import fr.iut.sciencequest.viewModels.LoginViewModel
@Composable
fun LoginScreen(viewModel: LoginViewModel = viewModel(),
goToAccount: () -> Unit,
goToHome: () -> Unit) {
Scaffold(
topBar = {
TopBar(goToAccount, goToHome, stringResource(id = R.string.connection))
},
) { innerPadding ->
LoginContainer(viewModel, Modifier.padding(innerPadding))
}
}
@Composable
fun LoginContainer(viewModel: LoginViewModel,
modifier: Modifier) {
val state = viewModel.uiState.collectAsState()
Column(
modifier = modifier.fillMaxHeight(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
//Text(text = stringResource(id = R.string.connection))
TextField(value = state.value.pseudo,
onValueChange = { viewModel.setPseudo(it) },
modifier = Modifier
.padding(20.dp)
.fillMaxWidth(),
)
TextField(value = state.value.mdp,
onValueChange = { viewModel.setMdp(it) },
modifier = Modifier
.padding(20.dp)
.fillMaxWidth()
)
Button(onClick = { /*TODO*/ },
modifier = Modifier.padding(20.dp),
) {
Text(text = stringResource(id = R.string.connection))
}
ClickableText(
text = AnnotatedString(stringResource(id = R.string.no_account)),
style = TextStyle(
textDecoration = TextDecoration.Underline,
color = colorResource(id = R.color.purple_200)
),
onClick = { }/*TODO*/ //registerPopup()
)
}
}
@Composable
fun registerClick(text: Int): () -> Unit {
Toast.makeText(LocalContext.current, text, Toast.LENGTH_SHORT).show()
return {}
}
@Composable
fun registerPopup(): (Int) -> Unit {
AlertDialog(
onDismissRequest = { },
title = {
Text(text = stringResource(id = R.string.no_account))
},
text = {
Text(text = stringResource(id = R.string.no_account_details))
},
confirmButton = {
Button(onClick = registerClick(R.string.coming_soon)) {
Text(text = stringResource(id = R.string.inscription))
}
},
dismissButton = {
Button(onClick = { /*TODO*/ }) {
Text(text = stringResource(id = R.string.continue_no_acc))
}
}
)
return {}
}
@Composable
@Preview
fun LoginScreenPreview(){
LoginScreen(goToAccount = {}, goToHome = {})
}

@ -0,0 +1,41 @@
package fr.iut.sciencequest.view
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.FilledIconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import fr.iut.sciencequest.R
@Composable
fun TopBar(goToAccount: () -> Unit, goToHome: () -> Unit, text: String = stringResource(id = R.string.app_name), modifier: Modifier? = Modifier.fillMaxWidth()) {
Row(horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()) {
Column(horizontalAlignment = Alignment.Start) {
FilledIconButton(onClick = { goToHome() }) {
Image(painter = painterResource(id = R.drawable.menu), contentDescription = "Menu")
}
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(text = text)
}
Column(horizontalAlignment = Alignment.End) {
FilledIconButton(onClick = { goToAccount() }) {
Image(painter = painterResource(id = R.drawable.account_circle_outline), contentDescription = "Account")
}
}
}
}
@Preview
@Composable
fun TopBarPreview(){
TopBar(goToAccount = {}, goToHome = {})
}

@ -0,0 +1,104 @@
package fr.iut.sciencequest.view.games
import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import fr.iut.sciencequest.R
import fr.iut.sciencequest.viewModels.KahootViewModel
import fr.iut.sciencequest.model.dto.extensions.ToModel
import fr.iut.sciencequest.model.metier.question.QuestionWithSimpleReponse
import fr.iut.sciencequest.model.metier.reponse.ReponseSimple
import fr.iut.sciencequest.stub.StubQuestionWithReponses
import fr.iut.sciencequest.view.TopBar
@Composable
fun KahootScreen(viewModel: KahootViewModel = viewModel(factory = KahootViewModel.ApiFactory),
goToAccount: () -> Unit,
goToHome: () -> Unit) {
val state = viewModel.uiState.collectAsState()
LaunchedEffect(key1 = Unit) {
viewModel.lancerPartie()
}
Column(modifier = Modifier.fillMaxWidth()) {
TopBar(goToAccount, goToHome, stringResource(id = R.string.kahoot))
KahootPlayer(state.value.question) {
viewModel.ajouterPoints(it)
}
}
}
@Preview
@Composable
fun KahootScreenPreview(){
KahootScreen(goToAccount = {}, goToHome = {})
}
@Preview
@Composable
fun KahootPlayerPreview(){
val i = 0
KahootPlayer(question = StubQuestionWithReponses.ToModel()) {}
}
@Composable
fun KahootPlayer(question: QuestionWithSimpleReponse,
sendReponse: (Long) -> Unit){
val context = LocalContext.current;
val currTime = System.currentTimeMillis()
Column (
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceEvenly,
modifier = Modifier.fillMaxHeight()
) {
KahootQuestion(question = question.question)
KahootReponses(reponses = question.reponses) {
sendReponse(System.currentTimeMillis() - currTime)
Toast.makeText(context, it.reponse, Toast.LENGTH_SHORT).show()
}
}
}
@Composable
fun KahootReponses(reponses : List<ReponseSimple>, action: (ReponseSimple)->Unit) {
LazyVerticalGrid(columns = GridCells.Fixed(2),
contentPadding = PaddingValues(12.dp),
verticalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp)) {
reponses.forEach {
item() {
Button(onClick = {action(it)}){
Text(it.reponse)
}
}
}
}
}
@Composable
fun KahootQuestion(question: String){
Text(question, textAlign = TextAlign.Center, fontSize = 20.sp)
}

@ -0,0 +1,100 @@
package fr.iut.sciencequest.view.games
import android.content.Context
import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
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.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import fr.iut.sciencequest.R
import fr.iut.sciencequest.viewModels.PenduViewModel
import fr.iut.sciencequest.view.TopBar
@Composable
fun PenduScreen(viewModel: PenduViewModel = viewModel(factory = PenduViewModel.ApiFactory),
goToAccount: () -> Unit,
goToHome: () -> Unit
) {
val state = viewModel.uiState.collectAsState()
val context = LocalContext.current;
Column(modifier = Modifier.fillMaxWidth()) {
TopBar(goToAccount, goToHome, stringResource(id = R.string.pendu))
//Text(text = stringResource(id = R.string.pendu), modifier = Modifier.padding(top=10.dp))
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceAround,
modifier = Modifier.fillMaxSize()
) {
Text(text = state.value.motATrou, fontSize = 20.sp)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween,
) {
TextField(value = "",
onValueChange = { onLetterEntered(it, viewModel, context, goToHome) },
modifier = Modifier.padding(20.dp),
enabled = !state.value.isWon && state.value.nbViesRestantes > 0,
placeholder = { Text(if(!state.value.isWon) "Entrez une lettre" else "Cliquez sur Nouvelle Partie") }
)
afficherVies(state.value.nbViesRestantes)
Text("Lettres utilisées: " + state.value.lettresUtilises)
if(state.value.isWon) {
Text(modifier = Modifier.padding(top=10.dp), text = "Vous avez gagné !")
} else if (state.value.nbViesRestantes == 0) {
Text(modifier = Modifier.padding(top=10.dp), text = "Vous avez perdu :(")
}
}
Button(onClick = { viewModel.InitPartie() }) {
Text(text = stringResource(id = R.string.reset_game))
}
}
}
}
fun onLetterEntered(entered: String,
vm: PenduViewModel,
context: Context,
goToHome: () -> Unit) {
val state = vm.uiState
if (entered.isNotEmpty()) {
vm.PlayAction(entered[0])
if ((!state.value.isWon) && (state.value.nbViesRestantes == 0)) {
Toast.makeText(context,"Vous avez perdu :(",Toast.LENGTH_LONG).show()
} else if (state.value.isWon) {
Toast.makeText(context,"Vous avez gagné !",Toast.LENGTH_LONG).show()
}
}
}
@Preview
@Composable
fun afficherVies(nbVies : Int = 10) {
Row {
for (i in 1..nbVies) {
Text("\u2665 ")
}
}
}
@Preview
@Composable
fun PenduPreview(){
//PenduScreen(goToAccount = {}) {
//
//}
}

@ -0,0 +1,95 @@
package fr.iut.sciencequest.view.games
import android.widget.Toast
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import fr.iut.sciencequest.R
import fr.iut.sciencequest.model.dto.extensions.ToModel
import fr.iut.sciencequest.model.dto.question.QuestionWithSimpleResponseDTO
import fr.iut.sciencequest.model.dto.reponse.ReponseSimpleDTO
import fr.iut.sciencequest.model.metier.question.QuestionWithSimpleReponse
import fr.iut.sciencequest.model.metier.reponse.ReponseSimple
import fr.iut.sciencequest.stub.StubQuestionWithReponses
import fr.iut.sciencequest.view.TopBar
import fr.iut.sciencequest.viewModels.KahootViewModel
import java.util.Timer
@Composable
fun QuiScreen(viewModel: KahootViewModel = viewModel(),
goToAccount: () -> Unit,
goToHome: () -> Unit) {
val state = viewModel.uiState.collectAsState()
Column(modifier = Modifier.fillMaxWidth()) {
TopBar(goToAccount, goToHome, stringResource(id = R.string.kahoot))
QuiPlayer(state.value.question) {
viewModel.ajouterPoints(it)
}
}
}
@Preview
@Composable
fun QuiScreenPreview(){
QuiScreen(goToAccount = {}, goToHome = {})
}
@Preview
@Composable
fun QuiPlayerPreview(){
val i = 0
QuiPlayer(question = StubQuestionWithReponses.ToModel()) {}
}
@Composable
fun QuiPlayer(question: QuestionWithSimpleReponse,
sendReponse: (Long) -> Unit){
val context = LocalContext.current;
val currTime = System.currentTimeMillis()
Column (horizontalAlignment = Alignment.CenterHorizontally){
QuiQuestion(question = question.question)
QuiReponses(reponses = question.reponses) {
sendReponse(currTime - System.currentTimeMillis())
Toast.makeText(context, it.reponse, Toast.LENGTH_SHORT).show()
}
}
}
@Composable
fun QuiReponses(reponses : List<ReponseSimple>, action: (ReponseSimple)->Unit) {
LazyVerticalGrid(columns = GridCells.Fixed(2),
contentPadding = PaddingValues(12.dp),
verticalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp)) {
reponses.forEach {
item() {
Button(onClick = {action(it)}){
Text(it.reponse)
}
}
}
}
}
@Composable
fun QuiQuestion(question: String){
Text(question, textAlign = TextAlign.Center)
}

@ -0,0 +1,32 @@
package fr.iut.sciencequest.view.scientifiques
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import fr.iut.sciencequest.model.dto.extensions.ToModel
import fr.iut.sciencequest.model.metier.Scientifique
import fr.iut.sciencequest.stub.StubScientifique1
@Preview
@Composable
fun scientifiqueContainer(scientifique: Scientifique = StubScientifique1.ToModel()) {
Row (
modifier = Modifier.border(4.dp, Color.Blue)
){
Column {
Text(scientifique.nom, modifier = Modifier.padding(Dp(3f)))
Text(scientifique.prenom, modifier = Modifier.padding(Dp(3f)))
}
Text(scientifique.descriptif, modifier = Modifier.padding(Dp(3f)))
Text(scientifique.sexe.toString(), modifier = Modifier.padding(Dp(3f)))
}
}

@ -0,0 +1,26 @@
package fr.iut.sciencequest.view.scientifiques
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import fr.iut.sciencequest.model.dto.extensions.ToModel
import fr.iut.sciencequest.model.metier.Scientifique
import fr.iut.sciencequest.stub.getScientifiqueListeStub
@Preview
@Composable
fun scientifiqueListeContainer(scientifiques: List<Scientifique> = getScientifiqueListeStub().ToModel(),
innerPadding : PaddingValues = PaddingValues(Dp(0f))) {
LazyColumn (
modifier = Modifier.padding(innerPadding)
){
items(scientifiques) {
scientifiqueContainer(it)
}
}
}

@ -0,0 +1,29 @@
package fr.iut.sciencequest.view.scientifiques
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
import fr.iut.sciencequest.R
import fr.iut.sciencequest.viewModels.ScientifiquesDecouvertsVM
import fr.iut.sciencequest.view.TopBar
@Composable
fun scientifiqueListeScreen(viewModel: ScientifiquesDecouvertsVM = viewModel(factory = ScientifiquesDecouvertsVM.ApiFactory),
goToAccount: () -> Unit,
goToHome: () -> Unit) {
val liste by viewModel.listeScientifique.collectAsState()
Scaffold(
topBar = {
TopBar(goToAccount, goToHome, stringResource(id = R.string.sc_decouverts))
},
) { innerPadding ->
LaunchedEffect(key1 = Unit) {
viewModel.getScientifiques(1)
}
scientifiqueListeContainer(liste.scientifiques, innerPadding)
}
}

@ -0,0 +1,79 @@
package fr.iut.sciencequest.viewModels
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import fr.iut.sciencequest.model.repositories.question.IQuestionRepository
import fr.iut.sciencequest.model.repositories.question.QuestionAPIRepository
import fr.iut.sciencequest.viewModels.uixStates.KahootUIState
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
class KahootViewModel(
val questionRepo: IQuestionRepository
): ViewModel() {
private val _uiState = MutableStateFlow(KahootUIState())
val uiState = _uiState.asStateFlow()
private val handler = Handler(Looper.getMainLooper())
fun lancerPartie() {
viewModelScope.launch {
questionRepo.fetchQuestions(2)
_uiState.value = KahootUIState(
questionRepo.questions.value.get(0),
dureePartie = uiState.value.dureePartie,
nbPoints = uiState.value.nbPoints,
reponseChoisie = false
)
for (index: Int in 1..questionRepo.questions.value.size) {
handler.postDelayed(
{
_uiState.value = KahootUIState(
questionRepo.questions.value.get(index),
dureePartie = uiState.value.dureePartie,
nbPoints = uiState.value.nbPoints,
reponseChoisie = false
)
},
uiState.value.dureePartie * index
)
}
}
}
// NOTE : tpsReponse en ms
fun ajouterPoints(tpsReponse: Long) {
if (tpsReponse < 0) {
throw IllegalArgumentException("ERREUR: Temps négatif donné à l'ajout de points")
} else if (tpsReponse > uiState.value.dureePartie) {
throw IllegalArgumentException("ERREUR: Utilsateur à répondu trop lentement")
}
if (uiState.value.reponseChoisie) {
return
}
val nbPoints: Int = (uiState.value.dureePartie - tpsReponse).toInt()
_uiState.value = KahootUIState(uiState.value.question,
dureePartie = uiState.value.dureePartie,
nbPoints = uiState.value.nbPoints + nbPoints,
reponseChoisie = true)
}
companion object {
val ApiFactory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>
): T {
return KahootViewModel(
QuestionAPIRepository()
) as T
}
}
}
}

@ -0,0 +1,19 @@
package fr.iut.sciencequest.viewModels
import androidx.lifecycle.ViewModel
import fr.iut.sciencequest.viewModels.uiStates.LoginUIState
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
class LoginViewModel: ViewModel() {
private val _uiState = MutableStateFlow(LoginUIState())
val uiState = _uiState.asStateFlow()
fun setPseudo(pseudo: String) {
_uiState.value = LoginUIState(pseudo, uiState.value.mdp)
}
fun setMdp(mdp: String) {
_uiState.value = LoginUIState(uiState.value.pseudo, mdp)
}
}

@ -0,0 +1,94 @@
package fr.iut.sciencequest.viewModels
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import fr.iut.sciencequest.viewModels.uiStates.PenduUIState
import fr.iut.sciencequest.model.repositories.scientifique.IScientifiqueRepository
import fr.iut.sciencequest.model.repositories.scientifique.ScientifiqueAPIRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
class PenduViewModel(
val scientifiqueRepo: IScientifiqueRepository
) : ViewModel() {
private val _uiState = MutableStateFlow(PenduUIState())
val uiState = _uiState.asStateFlow()
fun InitPartie() {
viewModelScope.launch {
scientifiqueRepo.fetchScientifiqueById(1)
val scientifique = scientifiqueRepo.scientifique.value
val nomComplet = scientifique.prenom + " " + scientifique.nom
var motATrou = ""
for (chr in nomComplet) {
motATrou += if (chr == ' ') {
' '
} else {
'_'
}
_uiState.value = PenduUIState(
isActionGood = true,
motATrouver = nomComplet,
motATrou = motATrou
)
}
}
}
// mot : mot à trouver
// motAct : état actuel du mot trouvé par l'utilisateur
fun PlayAction(lettre: Char) {
val lowerCaseLetter = lettre.lowercaseChar()
if (lettre == ' ' || _uiState.value.lettresUtilises.contains(lowerCaseLetter)) {
_uiState.value = PenduUIState(false,
false,
_uiState.value.nbViesRestantes,
_uiState.value.motATrouver,
_uiState.value.motATrou,
_uiState.value.lettresUtilises
)
return
} else if (_uiState.value.motATrouver.lowercase().contains(lowerCaseLetter)) {
var nvMotATrou = _uiState.value.motATrou
for (index in _uiState.value.motATrouver.indices) {
val letterToCheck = _uiState.value.motATrouver[index]
if (letterToCheck.lowercaseChar() == lowerCaseLetter) {
nvMotATrou = nvMotATrou.replaceRange(index,index + 1, letterToCheck.toString())
}
}
val isWon = nvMotATrou == _uiState.value.motATrouver
_uiState.value = PenduUIState(isWon,
true,
_uiState.value.nbViesRestantes,
_uiState.value.motATrouver,
nvMotATrou,
_uiState.value.lettresUtilises.plus(lowerCaseLetter)
)
} else {
_uiState.value = PenduUIState(false,
true,
_uiState.value.nbViesRestantes - 1,
_uiState.value.motATrouver,
_uiState.value.motATrou,
_uiState.value.lettresUtilises.plus(lowerCaseLetter)
)
}
}
companion object {
val ApiFactory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>
): T {
return PenduViewModel(
ScientifiqueAPIRepository()
) as T
}
}
}
}

@ -0,0 +1,39 @@
package fr.iut.sciencequest.viewModels
import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import fr.iut.sciencequest.viewModels.uiStates.ScientifiqueDecouvertsUIState
import fr.iut.sciencequest.model.repositories.scientifique.IScientifiqueRepository
import fr.iut.sciencequest.model.repositories.scientifique.ScientifiqueAPIRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
class ScientifiquesDecouvertsVM(
val repository: IScientifiqueRepository
) : ViewModel() {
private val _listeScientifique: MutableStateFlow<ScientifiqueDecouvertsUIState> = MutableStateFlow(ScientifiqueDecouvertsUIState())
val listeScientifique = _listeScientifique.asStateFlow()
fun getScientifiques(page: Int) {
viewModelScope.launch {
repository.fetchScientifiques(page)
_listeScientifique.value = ScientifiqueDecouvertsUIState(repository.scientifiques.value.toMutableList())
}
}
companion object {
val ApiFactory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>
): T {
return ScientifiquesDecouvertsVM(
ScientifiqueAPIRepository()
) as T
}
}
}
}

@ -0,0 +1,13 @@
package fr.iut.sciencequest.viewModels.uixStates
import fr.iut.sciencequest.model.dto.extensions.ToModel
import fr.iut.sciencequest.model.metier.question.QuestionWithSimpleReponse
import fr.iut.sciencequest.stub.StubQuestionWithReponses
data class KahootUIState (
val question: QuestionWithSimpleReponse = StubQuestionWithReponses.ToModel(),
val reponseChoisie: Boolean = false,
// NOTE : Supposé en millisecondes
val dureePartie: Long = 10_000,
val nbPoints: Int = 0
)

@ -0,0 +1,6 @@
package fr.iut.sciencequest.viewModels.uiStates
data class LoginUIState (
val pseudo: String = "Pseudo",
val mdp: String = "Mot de passe"
)

@ -0,0 +1,10 @@
package fr.iut.sciencequest.viewModels.uiStates
data class PenduUIState(
val isWon: Boolean = false,
val isActionGood: Boolean = false,
val nbViesRestantes: Int = 10,
val motATrouver: String = "Mot",
val motATrou: String = "___",
val lettresUtilises: String = ""
)

@ -0,0 +1,15 @@
package fr.iut.sciencequest.viewModels.uiStates
import fr.iut.sciencequest.model.metier.Scientifique
class ScientifiqueDecouvertsUIState {
var scientifiques: MutableList<Scientifique>
constructor() {
scientifiques = ArrayList<Scientifique>().toMutableList()
}
constructor(scientifiques : MutableList<Scientifique>) {
this.scientifiques = scientifiques
}
}

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

@ -0,0 +1 @@
<!-- drawable/account_circle_outline.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#ffffff" android:pathData="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M7.07,18.28C7.5,17.38 10.12,16.5 12,16.5C13.88,16.5 16.5,17.38 16.93,18.28C15.57,19.36 13.86,20 12,20C10.14,20 8.43,19.36 7.07,18.28M18.36,16.83C16.93,15.09 13.46,14.5 12,14.5C10.54,14.5 7.07,15.09 5.64,16.83C4.62,15.5 4,13.82 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,13.82 19.38,15.5 18.36,16.83M12,6C10.06,6 8.5,7.56 8.5,9.5C8.5,11.44 10.06,13 12,13C13.94,13 15.5,11.44 15.5,9.5C15.5,7.56 13.94,6 12,6M12,11A1.5,1.5 0 0,1 10.5,9.5A1.5,1.5 0 0,1 12,8A1.5,1.5 0 0,1 13.5,9.5A1.5,1.5 0 0,1 12,11Z" /></vector>

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

@ -0,0 +1 @@
<!-- drawable/menu.xml --><vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24"><path android:fillColor="#ffffff" android:pathData="M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z" /></vector>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save