Compare commits

..

265 Commits

Author SHA1 Message Date
Dorian HODIN 2d20012fc3 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
Marc CHEVALDONNE 5d51df9ca9 Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
2 years ago
dorian.hodin dfb73d42ff Try to push to deploy containers
2 years ago
Dorian HODIN 41d1e8dbb3 Mise à jour de 'Sources/php_script/script/config.php'
continuous-integration/drone/push Build is passing Details
2 years ago
Dorian HODIN ab1c306f5b Mise à jour de 'Sources/php_script/script/config.php'
continuous-integration/drone/push Build is passing Details
2 years ago
Dorian HODIN da7fb93d90 Mise à jour de 'Sources/php_script/script/config.php'
continuous-integration/drone/push Build was killed Details
2 years ago
Dorian HODIN 56e5cd28a4 Mise à jour de 'Sources/php_script/script/config.php'
continuous-integration/drone/push Build was killed Details
2 years ago
Dorian HODIN 24771535f9 Mise à jour de 'Sources/php_script/script/config.php'
continuous-integration/drone/push Build was killed Details
2 years ago
Dorian HODIN 52ec509b3d Mise à jour de 'Sources/php_script/script/config.php'
continuous-integration/drone/push Build was killed Details
2 years ago
Audric SABATIER a063418d88 Mise à jour de 'Sources/db_script/sql/create.sql'
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER f3c678c23f Mise à jour de 'Sources/db_script/sql/create.sql'
continuous-integration/drone/push Build is passing Details
2 years ago
dorian.hodin 9da3c488d7 Deploy Containers
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK 4ceaba268f Merge
continuous-integration/drone/push Build is failing Details
2 years ago
Félix MIELCAREK 8a52e1dec4 Ajout route API pour les likes
2 years ago
Félix MIELCAREK 4238ba4c0a Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK 9e92bc0751 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK 8ccb7bc02b Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK 2c07f3a822 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK a906de80d4 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK a5e0024ae2 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build is failing Details
2 years ago
Félix MIELCAREK 764c01edf7 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK dedb583d58 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build is failing Details
2 years ago
Félix MIELCAREK fd8dc04fa7 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK cc5370c3da Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build is failing Details
2 years ago
Félix MIELCAREK 09c0124a65 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build is failing Details
2 years ago
Félix MIELCAREK e3c160b09b Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK e027ff7e1f Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK 4102ae0d1a Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build is failing Details
2 years ago
Félix MIELCAREK b138b70e03 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build is failing Details
2 years ago
Félix MIELCAREK ddb5d9fd11 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK bbd2544353 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK f195b57d4c Update '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK 3d744a0831 Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK d1e2516941 Update '.drone.yml'
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK 2a69902a3b Update 'Sources/api_database/Dockerfile'
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK a8f123ba2b Add 'Sources/api_database/Dock'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK 8a1a970c43 Ajout du build de l'image pour l'api
continuous-integration/drone/push Build is failing Details
2 years ago
Félix MIELCAREK 38fa515c08 Ajout déploiement base de données
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK 1c2d2acfb9 Ajout de la gestion des erreurs
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK f1b7bb2df5 Modification de l'API pour ajout d'un user et récupération d'informations sur un user
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK 437d16b25d Ajout de la base de données
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK d3f57ef522 Suite des routes
2 years ago
Félix MIELCAREK 0c2f54565d Ajout des sources
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK 5cfefd19ef Merge remote-tracking branch 'origin/master'
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK 56a2eb8158 Merge
2 years ago
Félix MIELCAREK 9f61e62329 Add 'Sources/api_database/.gitkeep'
2 years ago
Félix MIELCAREK 277edb2031 Changements et réorganisation des appels des méthodes en fonction de la temporalité des actions de l'utilisateur
2 years ago
Audric SABATIER a526982796 FIX : Log in work again
2 years ago
Félix MIELCAREK 7daeba3ff6 Merge
2 years ago
Dorian HODIN 338f6381cb setSpots now in controller.dart
2 years ago
Félix MIELCAREK 2ca2d71067 Résolution de toutes les erreurs pour le build, toutes les fonctionnalités ne sont quand même pas mise à jour
2 years ago
Félix MIELCAREK 2b1ad41178 Ajout classe data pour éviter au maximum les méthodes asynchrone et les requêtes.
2 years ago
Félix MIELCAREK e049a265cd Résolution d'erreurs
2 years ago
Félix MIELCAREK 7b3b514770 Amélioration de l'exception Http
2 years ago
Dorian HODIN 4f19c821e3 insertAndMakeListUser.php now delete afk user (10 min) / deleting test.php
2 years ago
Dorian HODIN 10cf8b1bac test.php update
2 years ago
Dorian HODIN 75fc0a87ab test.php update
2 years ago
Dorian HODIN 2907d89ec0 test.php update
2 years ago
Dorian HODIN 30d8fde0c9 insertAndMakeListUser.php update
2 years ago
Dorian HODIN fa12006e1c test.php update
2 years ago
Dorian HODIN a4c2c729db test.php update
2 years ago
Dorian HODIN 29db20b337 test.php update
2 years ago
Dorian HODIN d23b28be1c test.php update
2 years ago
Dorian HODIN c86d1005d7 test.php update
2 years ago
Dorian HODIN 3a28466b43 test.php and insertAndMakeListUser.php update
2 years ago
Dorian HODIN 4c71dd973a test.php and insertAndMakeListUser.php update
2 years ago
Dorian HODIN 9dcd52b65c test.php update
2 years ago
Lucas DELANIER 23faec1eb7 text on spot page when no spot available
2 years ago
Dorian HODIN 6543623795 PHP update, deleting every 10min
2 years ago
Lucas DELANIER 6724413e99 scroll name of the music when too long
2 years ago
Lucas DELANIER e207f545cd futur builder on current music
2 years ago
Dorian HODIN 48f60ce0c3 config.php update
2 years ago
Dorian HODIN 849cf586ad insertAndMakeListUser.php update
2 years ago
Dorian HODIN 9ccbb81ad8 Final test before delete
2 years ago
Dorian HODIN cf28bcc109 Final test before delete
2 years ago
Dorian HODIN 01749f3b3b insertAndMakeListUser.php update
2 years ago
Dorian HODIN 4488f03ef0 insertAndMakeListUser.php update
2 years ago
Dorian HODIN 5c8b320da9 insertAndMakeListUser.php update
2 years ago
Dorian HODIN 28a0c228d1 insertAndMakeListUser.php update
2 years ago
Dorian HODIN 98fa7d279f test.php update
2 years ago
Dorian HODIN 884900b378 test.php update
2 years ago
Dorian HODIN ce679955c9 insertAndMakeListUser.php update and testing
2 years ago
Dorian HODIN c648b67356 insertAndMakeListUser.php update
2 years ago
Dorian HODIN 35d378ffc4 insertAndMakeListUser.php update
2 years ago
Dorian HODIN 7f0ff0679e insertAndMakeListUser.php update
2 years ago
Dorian HODIN 62c494ce0d insertAndMakeListUser.php update
2 years ago
Dorian HODIN 3041472244 insertAndMakeListUser.php update
2 years ago
Dorian HODIN 320da5d4b6 insertAndMakeListUser.php update
2 years ago
Dorian HODIN 17c10df1a5 config.php and .drone.yml update
2 years ago
Dorian HODIN b4aa08ca78 config.php update
2 years ago
Dorian HODIN c9ecd6fdf8 config.php update
2 years ago
Dorian HODIN 0dae36e05f insertAndMakeListUser.php update
2 years ago
Dorian HODIN 29c0d074b0 config.php update
2 years ago
Dorian HODIN e1618f0664 config.php update
2 years ago
Dorian HODIN 45740065b2 config.php update
2 years ago
Dorian HODIN 8c8f689854 config.php update
2 years ago
Dorian HODIN 66d10f9115 config.php update
2 years ago
Dorian HODIN de56db7e22 config.php update
2 years ago
Dorian HODIN 408e3227eb config.php update
2 years ago
Dorian HODIN b7da1e9c31 config.php update
2 years ago
Dorian HODIN bcf5e51e2a config.php update
2 years ago
Dorian HODIN 7b38888835 config.php update
2 years ago
Dorian HODIN e00072ef24 config.php update
2 years ago
Dorian HODIN 82a2a019e5 config.php update
2 years ago
Dorian HODIN c986dbcd2a config.php update
2 years ago
Dorian HODIN 074b028e90 config.php update
2 years ago
Dorian HODIN 0b48ac4443 config.php update
2 years ago
Dorian HODIN 07647c5cb4 config.php update
2 years ago
Dorian HODIN 92cca4c945 Updating insertAndMakeListUser.php
2 years ago
Dorian HODIN 8faff77a5f config.php update
2 years ago
Dorian HODIN 94856079ec config.php update
2 years ago
Dorian HODIN bd316756b0 config.php update
2 years ago
Dorian HODIN d9fb499834 config.php update
2 years ago
Dorian HODIN b6a3a10694 config.php update
2 years ago
Dorian HODIN 204f787e77 config.php update
2 years ago
Dorian HODIN d52b8f22a0 config.php update
2 years ago
Dorian HODIN fa7ba3acc4 config.php update
2 years ago
Dorian HODIN c8eeb0f634 config.php and .drone.yml update
2 years ago
Dorian HODIN 41220d0303 config.php and .drone.yml update
2 years ago
Dorian HODIN c2bdb7c46b config.php update
2 years ago
Dorian HODIN 515f8350fd .drone.yml update
2 years ago
Dorian HODIN 1c11e88023 Mise à jour de 'Sources/php_script/script/config.php'
2 years ago
Dorian HODIN 7438ac8f8e Mise à jour de 'Sources/php_script/script/config.php'
2 years ago
Dorian HODIN 212b31efda .drone.yml update
2 years ago
Dorian HODIN c0669e5166 .drone.yml and location.sql update
2 years ago
Dorian HODIN 23fc0d4a4d php update
2 years ago
Dorian HODIN d595e0e235 .drone.yml, Dockerfile update and new location.sql script
2 years ago
Dorian HODIN e6b3373448 .drone.yml update
2 years ago
Dorian HODIN 6fdf0d9376 .drone.yml update
2 years ago
Dorian HODIN cca6bcf912 .drone.yml update
2 years ago
Dorian HODIN 12c43f894e Dockerfile update
2 years ago
Dorian HODIN 89c7b9c039 .drone.yml update
2 years ago
dorian.hodin 30e6024ec0 Dockerfile for SQL
2 years ago
Dorian HODIN 63c1481739 Updating insertAndMakeListUser.php
2 years ago
Dorian HODIN de25a596a0 Updating insertAndMakeListUser.php
2 years ago
Dorian HODIN 2ab49692c9 Deleting distance.php
2 years ago
dorian.hodin 81f8e9df3e Modification of location.dart with the error code returned by the php script
2 years ago
dorian.hodin 84763c2ee5 Make PHP look better and add error code
2 years ago
Dorian HODIN 49bf4c3f15 Add a SQL Script for the database
2 years ago
Dorian HODIN 6f65327096 .drone.yml update
2 years ago
Dorian HODIN c7ac3cf70d Dockerfile update
2 years ago
Dorian HODIN 9e8c7ca013 Dockerfile update
2 years ago
Dorian HODIN 9aab32f35d Dockerfile update
2 years ago
Dorian HODIN c5fc7cbd31 Dockerfile update
2 years ago
Dorian HODIN 58c22378e7 Dockerfile update
2 years ago
Dorian HODIN 34e5247bcd .drone.yml update
2 years ago
Dorian HODIN d5b4f4fb50 .drone.yml update
2 years ago
Dorian HODIN 844af9fb80 .drone.yml update
2 years ago
Dorian HODIN aa7a16eaf8 .drone.yml update
2 years ago
Dorian HODIN 2c686e3730 .drone.yml update
2 years ago
Dorian HODIN 95f7c4d463 .drone.yml update
2 years ago
Dorian HODIN 02a231da42 Dockerfile update
2 years ago
Dorian HODIN f9da7342a1 Dockerfile update
2 years ago
Dorian HODIN 8db4bc1299 Dockerfile update
2 years ago
Dorian HODIN 111c86e2ab Dockerfile update
2 years ago
Dorian HODIN 7e80e57c81 Remove the try
2 years ago
Dorian HODIN a4b927647a .drone.yml update
2 years ago
dorian.hodin a03edfb813 Try to include the database
2 years ago
Dorian HODIN 5788f68519 config.php last update
2 years ago
Dorian HODIN 2cfa127ca0 .drone.yml update
2 years ago
Dorian HODIN 5024bf48ea config.php update
2 years ago
Dorian HODIN dd65ca432f config.php update
2 years ago
Dorian HODIN 34c5d32294 config.php update
2 years ago
Dorian HODIN 9738a74cdb config.php update
2 years ago
Dorian HODIN b5c4b7a98c config.php update
2 years ago
Dorian HODIN 8bebc97f8a config.php update
2 years ago
Dorian HODIN 42641d9e70 config.php update
2 years ago
Dorian HODIN dea79392d3 config.php update
2 years ago
Dorian HODIN 6ac7ad2eda config.php update
2 years ago
Dorian HODIN 9714bdfc9b config.php update
2 years ago
Dorian HODIN 10e44b8446 .drone.yml update
2 years ago
Dorian HODIN e95824d834 .drone.yml update
2 years ago
Dorian HODIN f993f04fcb .drone.yml update
2 years ago
Dorian HODIN 3def006106 .drone.yml update
2 years ago
Dorian HODIN f5d2db8d23 .drone.yml update
2 years ago
Dorian HODIN d492df8092 .drone.yml update
2 years ago
Dorian HODIN a36f36d385 .drone.yml update
2 years ago
Dorian HODIN e0e5a549bb .drone.yml update
2 years ago
Dorian HODIN 61b2b2a20d .drone.yml update
2 years ago
Dorian HODIN e629225f89 .drone.yml update
2 years ago
Dorian HODIN 50c3020e5e .drone.yml update
2 years ago
Dorian HODIN 269b17947c Dockerfile update
2 years ago
Dorian HODIN fc355a52c2 location.dart update
2 years ago
Dorian HODIN 3b2be5a2da .drone.yml update
2 years ago
Dorian HODIN 59a389e333 Dockerfile update
2 years ago
Dorian HODIN 994ad41593 config.php update
2 years ago
dorian.hodin 9ac1eb3bcf Try to resolve connection problem
2 years ago
Dorian HODIN 7c25ad2463 config.php update
2 years ago
Dorian HODIN 4cc759e479 config.php update
2 years ago
Dorian HODIN e172d69c3a Error Management in Flutter
2 years ago
Dorian HODIN 5984cfbec0 .drone.yml update
2 years ago
Dorian HODIN ff39f1cb84 config.php update
2 years ago
Dorian HODIN 43275a8902 .drone.yml update
2 years ago
Dorian HODIN 41d6052ef6 Add index.php
2 years ago
Dorian HODIN 0f6e5e0f29 .drone.yml update
2 years ago
Dorian HODIN 7904b363ab .drone.yml update
2 years ago
dorian.hodin 993ffcf809 Location.dart update
2 years ago
dorian.hodin 038107886f Location.dart update
2 years ago
Dorian HODIN 20dddd3705 Make the PHP Script Better with error management
2 years ago
Dorian HODIN 9929a1cf03 Make the PHP Script better
2 years ago
Dorian HODIN dbd4ce6851 .drone.yaml update
2 years ago
Dorian HODIN e0723d761c .drone.yaml update
2 years ago
Dorian HODIN 84a81c74ef .drone.yaml update
2 years ago
Dorian HODIN 23c3b20580 .drone.yaml update
2 years ago
Dorian HODIN a6ce0fe507 .drone.yaml update
2 years ago
Dorian HODIN 98fa37aea7 .drone.yaml update
2 years ago
Dorian HODIN 8a0981001b .drone.yaml update and getting the environement variables in the pho script
2 years ago
Dorian HODIN 637586010a .drone.yaml update and getting the environement variables in the pho script
2 years ago
Dorian HODIN 57b9ff6a27 .drone.yaml update
2 years ago
Dorian HODIN eceb319de2 .drone.yaml update
2 years ago
Dorian HODIN dda85a0caa Hide password and host to the database by updating .drone.yaml
2 years ago
Dorian HODIN 86236ca7c7 Location.dart update with the new Docker Server
2 years ago
Dorian HODIN 9c5435b744 Dockerfile update
2 years ago
dorian.hodin 496fb854ce Dockerfile update
2 years ago
dorian.hodin 611adb84a2 Dockerfile update
2 years ago
dorian.hodin 22c27e7ac5 Dockerfile update
2 years ago
dorian.hodin f16e5461fb Dockerfile update
2 years ago
dorian.hodin fb58b2732d Dockerfile last update
2 years ago
dorian.hodin f00eb96910 Dockerfile last update
2 years ago
Dorian HODIN 80cc8623f8 Dockerfile update
2 years ago
Dorian HODIN e2a7d4f7f3 Dockerfile update
2 years ago
Dorian HODIN c629e9551a Dockerfile update
2 years ago
Dorian HODIN 17da217662 Dockerfile update
2 years ago
Dorian HODIN e862bbc7b0 Dockerfile update
2 years ago
Dorian HODIN 7924fa44c3 Dockerfile update
2 years ago
Dorian HODIN 1adf60f527 Dockerfile update
2 years ago
Dorian HODIN d99ac76452 Dockerfile update
2 years ago
Dorian HODIN 647e0a2c52 Dockerfile update
2 years ago
Dorian HODIN 1fbe0983d2 Dockerfile update
2 years ago
Dorian HODIN d0d91ada9f Dockerfile update
2 years ago
Dorian HODIN 6b91ca063a Merge tmp from master to actual branch + location.dart
2 years ago
Dorian HODIN 2c28ff03a5 Dockerfile update
2 years ago
Dorian HODIN b662107b96 Dockerfile update
2 years ago
Dorian HODIN 04661da9d1 Dockerfile update
2 years ago
Dorian HODIN 21b44ed3a3 Dockerfile update
2 years ago
Dorian HODIN 93b834ed49 Dockerfile update
2 years ago
Dorian HODIN 8d16854e96 .drone.yml update
2 years ago
Dorian HODIN 0b38d4d6af .drone.yml update and index.html
2 years ago
Dorian HODIN ed1d1df42f .drone.yml update
2 years ago
Dorian HODIN bb76fb94c2 .drone.yml update
2 years ago
Dorian HODIN 0dda975b49 Modification of .drone.yaml
2 years ago
Dorian HODIN 75c8c3d7fb Modification of .drone.yaml
2 years ago
Dorian HODIN e1cea21dcb Create a script directory
2 years ago
Dorian HODIN dfa3bebcc6 Create PHP Dockerfile and modify .drone.yml
2 years ago
Dorian HODIN b7be258ae9 Add php script to create docker image
2 years ago
Félix MIELCAREK d049586c27 Update '.drone.yml'
2 years ago
Félix MIELCAREK 832271d52d Update '.drone.yml'
2 years ago
Félix MIELCAREK 7d04f403de Change redirect url to use codefirst
2 years ago
Audric SABATIER 60505bf9a8 ADD : UserModifier class to modify user datas in database
2 years ago
Audric SABATIER 38f9d5a3c6 ADD : DatabaseService class to manage dataabse access
2 years ago
Félix MIELCAREK 3d3f092d8b Résolution d'erreurs.
2 years ago
Félix MIELCAREK a22b8c9872 Début implémentation MVC.
2 years ago
Dorian HODIN 24b7b69405 Test CI
continuous-integration/drone/push Build is passing Details
2 years ago
Dorian HODIN f95a60f6fe Supprimer 'Documentation/Images/backlog-1.png'
continuous-integration/drone/push Build was killed Details
2 years ago
Dorian HODIN 6267136714 Transférer les fichiers vers 'Documentation/Images'
continuous-integration/drone/push Build was killed Details
2 years ago
Audric SABATIER 6e533de298 MQTT final Schema
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 9240cb57ec Supprimer 'Documentation/Images/MQTT.png'
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER b4eb180086 Transférer les fichiers vers 'Documentation/Images'
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 5605b42dfb Supprimer 'Documentation/Images/MQTT.png'
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 5c2505f968 Transférer les fichiers vers 'Documentation/Images'
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 22aee92ad1 FIX : change MQTT schema
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 40efae3a7d Transférer les fichiers vers 'Documentation/Images'
continuous-integration/drone/push Build is passing Details
2 years ago
Félix MIELCAREK 6950e46d1c Update 'Sources/api_redirect/Dockerfile'
continuous-integration/drone/push Build was killed Details
2 years ago
Félix MIELCAREK eb0efda4b4 Update 'Sources/api_redirect/sources/index.html'
continuous-integration/drone/push Build is failing Details
2 years ago
Dorian HODIN 4528871a81 Modification of the location and user class to stop spamming the app
continuous-integration/drone/push Build is passing Details
2 years ago

@ -2,6 +2,7 @@ kind: pipeline
type: docker type: docker
name: DAFLPipeline name: DAFLPipeline
trigger: trigger:
event: event:
- push - push
@ -52,3 +53,56 @@ steps:
COMMAND: create COMMAND: create
OVERWRITE: true OVERWRITE: true
depends_on: [ web-server ] depends_on: [ web-server ]
# docker image build
- name: php_script
image: plugins/docker
settings:
dockerfile: ./Sources/php_script/Dockerfile
context: Sources/php_script
registry: hub.codefirst.iut.uca.fr
repo: hub.codefirst.iut.uca.fr/dorian.hodin/dafl_music
username:
from_secret: SECRET_USERNAME
password:
from_secret: SECRET_PASSWD
# container deployment
- name: deploy-php
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: hub.codefirst.iut.uca.fr/dorian.hodin/dafl_music:latest
CONTAINERNAME: php_script
COMMAND: create
OVERWRITE: true
CODEFIRST_CLIENTDRONE_ENV_HOST:
from_secret: db_host
CODEFIRST_CLIENTDRONE_ENV_DATABASE:
from_secret: db_database
CODEFIRST_CLIENTDRONE_ENV_USER:
from_secret: db_user
CODEFIRST_CLIENTDRONE_ENV_PASSWORD:
from_secret: db_password
CODEFIRST_CLIENTDRONE_ENV_ROOT_PASSWORD:
from_secret: db_root_password
depends_on: [ php_script ]
# database container deployment
- name: db_location
image: hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: mariadb:10.5
CONTAINERNAME: mysql_location
COMMAND: create
# OVERWRITE: true
PRIVATE: true
CODEFIRST_CLIENTDRONE_ENV_MARIADB_ROOT_PASSWORD:
from_secret: db_root_password
CODEFIRST_CLIENTDRONE_ENV_MARIADB_DATABASE:
from_secret: db_database
CODEFIRST_CLIENTDRONE_ENV_MARIADB_USER:
from_secret: db_user
CODEFIRST_CLIENTDRONE_ENV_MARIADB_PASSWORD:
from_secret: db_password
depends_on: [ deploy-php ]

@ -98,7 +98,6 @@
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND> </AND>
</match> </match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule> </rule>
</section> </section>
<section> <section>

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Android">
<configuration />
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/geolocator_apple/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/geolocator_apple/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/geolocator_apple/example/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/fluttertoast/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/fluttertoast/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/fluttertoast/example/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_inappwebview/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_inappwebview/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_inappwebview/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_inappwebview/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_inappwebview/example/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_inappwebview/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_native_splash/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_native_splash/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_native_splash/example/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/geolocator_apple/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/geolocator_apple/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/geolocator_apple/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/home_indicator/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/home_indicator/example/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/home_indicator/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/path_provider_ios/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/path_provider_ios/example/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/path_provider_ios/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/vibration/example/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/vibration/example/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/vibration/example/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/path_provider_ios/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/path_provider_ios/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/path_provider_ios/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/vibration/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/vibration/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/vibration/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_native_splash/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_native_splash/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/flutter_native_splash/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/fluttertoast/.dart_tool" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/fluttertoast/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/fluttertoast/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/home_indicator/build" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/home_indicator/.pub" />
<excludeFolder url="file://$MODULE_DIR$/Sources/dafl_project_flutter/ios/.symlinks/plugins/home_indicator/.dart_tool" />
</content>
<orderEntry type="jdk" jdkName="Android API 33, extension level 3 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="dataSourceStorageLocal" created-in="PS-222.4345.15">
<data-source name="@localhost" uuid="f334e98a-3c30-4412-8c71-35fe124ed605">
<database-info product="" version="" jdbc-version="" driver-name="" driver-version="" dbms="MARIADB" exact-version="0" />
<secret-storage>forget</secret-storage>
<schema-mapping />
</data-source>
</component>
</project>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="@localhost" uuid="f334e98a-3c30-4412-8c71-35fe124ed605">
<driver-ref>mariadb</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.mariadb.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mariadb://localhost:3306</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<dataSource name="@localhost">
<database-model serializer="dbm" dbms="MARIADB" family-id="MARIADB" format-version="4.43">
<root id="1"/>
<schema id="2" parent="1" name="information_schema"/>
<schema id="3" parent="1" name="mysql"/>
<schema id="4" parent="1" name="performance_schema"/>
<schema id="5" parent="1" name="phpmyadmin"/>
<schema id="6" parent="1" name="positiondaflmusic"/>
<schema id="7" parent="1" name="projetphp"/>
<schema id="8" parent="1" name="test"/>
</database-model>
</dataSource>

@ -0,0 +1,2 @@
#n:information_schema
!<md> [null, 0, null, null, -2147483648, -2147483648]

@ -0,0 +1,2 @@
#n:mysql
!<md> [null, 0, null, null, -2147483648, -2147483648]

@ -0,0 +1,2 @@
#n:performance_schema
!<md> [null, 0, null, null, -2147483648, -2147483648]

@ -0,0 +1,417 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DataEditorManager">
<record-view-column-sorting-type value="BY_INDEX" />
<value-preview-text-wrapping value="true" />
<value-preview-pinned value="false" />
</component>
<component name="DBNavigator.Project.DatabaseFileManager">
<open-files />
</component>
<component name="DBNavigator.Project.EditorStateManager">
<last-used-providers />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>
<general>
<display-mode value="TABBED" />
<navigation-history-size value="100" />
<show-object-details value="false" />
</general>
<filters>
<object-type-filter>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="true" />
<object-type name="ROLE" enabled="true" />
<object-type name="PRIVILEGE" enabled="true" />
<object-type name="CHARSET" enabled="true" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED_VIEW" enabled="true" />
<object-type name="NESTED_TABLE" enabled="true" />
<object-type name="COLUMN" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET_TRIGGER" enabled="true" />
<object-type name="DATABASE_TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="true" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
<object-type name="ARGUMENT" enabled="true" />
<object-type name="DIMENSION" enabled="true" />
<object-type name="CLUSTER" enabled="true" />
<object-type name="DBLINK" enabled="true" />
</object-type-filter>
</filters>
<sorting>
<object-type name="COLUMN" sorting-type="NAME" />
<object-type name="FUNCTION" sorting-type="NAME" />
<object-type name="PROCEDURE" sorting-type="NAME" />
<object-type name="ARGUMENT" sorting-type="POSITION" />
<object-type name="TYPE ATTRIBUTE" sorting-type="POSITION" />
</sorting>
<default-editors>
<object-type name="VIEW" editor-type="SELECTION" />
<object-type name="PACKAGE" editor-type="SELECTION" />
<object-type name="TYPE" editor-type="SELECTION" />
</default-editors>
</browser-settings>
<navigation-settings>
<lookup-filters>
<lookup-objects>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="false" />
<object-type name="ROLE" enabled="false" />
<object-type name="PRIVILEGE" enabled="false" />
<object-type name="CHARSET" enabled="false" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED VIEW" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET TRIGGER" enabled="true" />
<object-type name="DATABASE TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="false" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="DIMENSION" enabled="false" />
<object-type name="CLUSTER" enabled="false" />
<object-type name="DBLINK" enabled="true" />
</lookup-objects>
<force-database-load value="false" />
<prompt-connection-selection value="true" />
<prompt-schema-selection value="true" />
</lookup-filters>
</navigation-settings>
<dataset-grid-settings>
<general>
<enable-zooming value="true" />
<enable-column-tooltip value="true" />
</general>
<sorting>
<nulls-first value="true" />
<max-sorting-columns value="4" />
</sorting>
<audit-columns>
<column-names value="" />
<visible value="true" />
<editable value="false" />
</audit-columns>
</dataset-grid-settings>
<dataset-editor-settings>
<text-editor-popup>
<active value="false" />
<active-if-empty value="false" />
<data-length-threshold value="100" />
<popup-delay value="1000" />
</text-editor-popup>
<values-actions-popup>
<show-popup-button value="true" />
<element-count-threshold value="1000" />
<data-length-threshold value="250" />
</values-actions-popup>
<general>
<fetch-block-size value="100" />
<fetch-timeout value="30" />
<trim-whitespaces value="true" />
<convert-empty-strings-to-null value="true" />
<select-content-on-cell-edit value="true" />
<large-value-preview-active value="true" />
</general>
<filters>
<prompt-filter-dialog value="true" />
<default-filter-type value="BASIC" />
</filters>
<qualified-text-editor text-length-threshold="300">
<content-types>
<content-type name="Text" enabled="true" />
<content-type name="Properties" enabled="true" />
<content-type name="XML" enabled="true" />
<content-type name="DTD" enabled="true" />
<content-type name="HTML" enabled="true" />
<content-type name="XHTML" enabled="true" />
<content-type name="Java" enabled="true" />
<content-type name="SQL" enabled="true" />
<content-type name="PL/SQL" enabled="true" />
<content-type name="JSON" enabled="true" />
<content-type name="JSON5" enabled="true" />
<content-type name="Groovy" enabled="true" />
<content-type name="AIDL" enabled="true" />
<content-type name="YAML" enabled="true" />
<content-type name="Manifest" enabled="true" />
</content-types>
</qualified-text-editor>
<record-navigation>
<navigation-target value="VIEWER" />
</record-navigation>
</dataset-editor-settings>
<code-editor-settings>
<general>
<show-object-navigation-gutter value="false" />
<show-spec-declaration-navigation-gutter value="true" />
<enable-spellchecking value="true" />
<enable-reference-spellchecking value="false" />
</general>
<confirmations>
<save-changes value="false" />
<revert-changes value="true" />
</confirmations>
</code-editor-settings>
<code-completion-settings>
<filters>
<basic-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="false" />
<filter-element type="OBJECT" id="view" selected="false" />
<filter-element type="OBJECT" id="materialized view" selected="false" />
<filter-element type="OBJECT" id="index" selected="false" />
<filter-element type="OBJECT" id="constraint" selected="false" />
<filter-element type="OBJECT" id="trigger" selected="false" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="false" />
<filter-element type="OBJECT" id="procedure" selected="false" />
<filter-element type="OBJECT" id="function" selected="false" />
<filter-element type="OBJECT" id="package" selected="false" />
<filter-element type="OBJECT" id="type" selected="false" />
<filter-element type="OBJECT" id="dimension" selected="false" />
<filter-element type="OBJECT" id="cluster" selected="false" />
<filter-element type="OBJECT" id="dblink" selected="false" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</basic-filter>
<extended-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</extended-filter>
</filters>
<sorting enabled="true">
<sorting-element type="RESERVED_WORD" id="keyword" />
<sorting-element type="RESERVED_WORD" id="datatype" />
<sorting-element type="OBJECT" id="column" />
<sorting-element type="OBJECT" id="table" />
<sorting-element type="OBJECT" id="view" />
<sorting-element type="OBJECT" id="materialized view" />
<sorting-element type="OBJECT" id="index" />
<sorting-element type="OBJECT" id="constraint" />
<sorting-element type="OBJECT" id="trigger" />
<sorting-element type="OBJECT" id="synonym" />
<sorting-element type="OBJECT" id="sequence" />
<sorting-element type="OBJECT" id="procedure" />
<sorting-element type="OBJECT" id="function" />
<sorting-element type="OBJECT" id="package" />
<sorting-element type="OBJECT" id="type" />
<sorting-element type="OBJECT" id="dimension" />
<sorting-element type="OBJECT" id="cluster" />
<sorting-element type="OBJECT" id="dblink" />
<sorting-element type="OBJECT" id="schema" />
<sorting-element type="OBJECT" id="role" />
<sorting-element type="OBJECT" id="user" />
<sorting-element type="RESERVED_WORD" id="function" />
<sorting-element type="RESERVED_WORD" id="parameter" />
</sorting>
<format>
<enforce-code-style-case value="true" />
</format>
</code-completion-settings>
<execution-engine-settings>
<statement-execution>
<fetch-block-size value="100" />
<execution-timeout value="20" />
<debug-execution-timeout value="600" />
<focus-result value="false" />
<prompt-execution value="false" />
</statement-execution>
<script-execution>
<command-line-interfaces />
<execution-timeout value="300" />
</script-execution>
<method-execution>
<execution-timeout value="30" />
<debug-execution-timeout value="600" />
<parameter-history-size value="10" />
</method-execution>
</execution-engine-settings>
<operation-settings>
<transactions>
<uncommitted-changes>
<on-project-close value="ASK" />
<on-disconnect value="ASK" />
<on-autocommit-toggle value="ASK" />
</uncommitted-changes>
<multiple-uncommitted-changes>
<on-commit value="ASK" />
<on-rollback value="ASK" />
</multiple-uncommitted-changes>
</transactions>
<session-browser>
<disconnect-session value="ASK" />
<kill-session value="ASK" />
<reload-on-filter-change value="false" />
</session-browser>
<compiler>
<compile-type value="KEEP" />
<compile-dependencies value="ASK" />
<always-show-controls value="false" />
</compiler>
<debugger>
<debugger-type value="ASK" />
<use-generic-runners value="true" />
</debugger>
</operation-settings>
<ddl-file-settings>
<extensions>
<mapping file-type-id="VIEW" extensions="vw" />
<mapping file-type-id="TRIGGER" extensions="trg" />
<mapping file-type-id="PROCEDURE" extensions="prc" />
<mapping file-type-id="FUNCTION" extensions="fnc" />
<mapping file-type-id="PACKAGE" extensions="pkg" />
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
<mapping file-type-id="TYPE" extensions="tpe" />
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
</extensions>
<general>
<lookup-ddl-files value="true" />
<create-ddl-files value="false" />
<synchronize-ddl-files value="true" />
<use-qualified-names value="false" />
<make-scripts-rerunnable value="true" />
</general>
</ddl-file-settings>
<general-settings>
<regional-settings>
<date-format value="MEDIUM" />
<number-format value="UNGROUPED" />
<locale value="SYSTEM_DEFAULT" />
<use-custom-formats value="false" />
</regional-settings>
<environment>
<environment-types>
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
</environment-types>
<visibility-settings>
<connection-tabs value="true" />
<dialog-headers value="true" />
<object-editor-tabs value="true" />
<script-editor-tabs value="false" />
<execution-result-tabs value="true" />
</visibility-settings>
</environment>
</general-settings>
</component>
<component name="DBNavigator.Project.StatementExecutionManager">
<execution-variables />
</component>
</project>

@ -2,689 +2,801 @@
<library name="Dart Packages" type="DartPackagesLibraryType"> <library name="Dart Packages" type="DartPackagesLibraryType">
<properties> <properties>
<option name="packageNameToDirsMap"> <option name="packageNameToDirsMap">
<entry key="_flutterfire_internals">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/_flutterfire_internals-1.0.12/lib" />
</list>
</value>
</entry>
<entry key="animations"> <entry key="animations">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/animations-2.0.7/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/animations-2.0.7/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="archive"> <entry key="archive">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/archive-3.3.2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/archive-3.3.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="args"> <entry key="args">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="async"> <entry key="async">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="boolean_selector"> <entry key="boolean_selector">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="characters"> <entry key="characters">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.2.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.2.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="charcode"> <entry key="charcode">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.3.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.3.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="checked_yaml"> <entry key="checked_yaml">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="cli_util"> <entry key="cli_util">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="clock"> <entry key="clock">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.1/lib" />
</list>
</value>
</entry>
<entry key="cloud_firestore">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-4.3.1/lib" />
</list>
</value>
</entry>
<entry key="cloud_firestore_platform_interface">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_platform_interface-5.10.1/lib" />
</list>
</value>
</entry>
<entry key="cloud_firestore_web">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-3.2.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="collection"> <entry key="collection">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="convert"> <entry key="convert">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/convert-3.1.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/convert-3.1.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="crypto"> <entry key="crypto">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="csslib"> <entry key="csslib">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/csslib-0.17.2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/csslib-0.17.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="cupertino_icons"> <entry key="cupertino_icons">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-1.0.5/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-1.0.5/lib" />
</list>
</value>
</entry>
<entry key="fading_edge_scrollview">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fading_edge_scrollview-3.0.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="fake_async"> <entry key="fake_async">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.3.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.3.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="ffi"> <entry key="ffi">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/ffi-2.0.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/ffi-2.0.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="file"> <entry key="file">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/lib" />
</list>
</value>
</entry>
<entry key="firebase_core">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core-2.4.1/lib" />
</list>
</value>
</entry>
<entry key="firebase_core_platform_interface">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_platform_interface-4.5.2/lib" />
</list>
</value>
</entry>
<entry key="firebase_core_web">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-2.1.0/lib" />
</list>
</value>
</entry>
<entry key="firebase_messaging">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-14.2.1/lib" />
</list>
</value>
</entry>
<entry key="firebase_messaging_platform_interface">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_messaging_platform_interface-4.2.10/lib" />
</list>
</value>
</entry>
<entry key="firebase_messaging_web">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_messaging_web-3.2.11/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter"> <entry key="flutter">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/packages/flutter/lib" /> <option value="$PROJECT_DIR$/../flutter/packages/flutter/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_inappwebview"> <entry key="flutter_inappwebview">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-5.7.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-5.7.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_launcher_icons"> <entry key="flutter_launcher_icons">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_launcher_icons-0.10.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_launcher_icons-0.10.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_lints"> <entry key="flutter_lints">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_lints-2.0.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_lints-2.0.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_localizations"> <entry key="flutter_localizations">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/packages/flutter_localizations/lib" /> <option value="$PROJECT_DIR$/../flutter/packages/flutter_localizations/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_native_splash"> <entry key="flutter_native_splash">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_native_splash-2.2.11/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_native_splash-2.2.11/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_styled_toast"> <entry key="flutter_styled_toast">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_styled_toast-2.1.3/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_styled_toast-2.1.3/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_test"> <entry key="flutter_test">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/packages/flutter_test/lib" /> <option value="$PROJECT_DIR$/../flutter/packages/flutter_test/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_web_plugins"> <entry key="flutter_web_plugins">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/packages/flutter_web_plugins/lib" /> <option value="$PROJECT_DIR$/../flutter/packages/flutter_web_plugins/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="fluttericon"> <entry key="fluttericon">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/fluttericon-2.0.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fluttericon-2.0.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="fluttertoast"> <entry key="fluttertoast">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/fluttertoast-8.1.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fluttertoast-8.1.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="font_awesome_flutter"> <entry key="font_awesome_flutter">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/font_awesome_flutter-10.2.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/font_awesome_flutter-10.2.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="geolocator"> <entry key="geolocator">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator-9.0.2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator-9.0.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="geolocator_android"> <entry key="geolocator_android">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_android-4.1.4/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_android-4.1.4/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="geolocator_apple"> <entry key="geolocator_apple">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_apple-2.2.3/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_apple-2.2.3/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="geolocator_platform_interface"> <entry key="geolocator_platform_interface">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_platform_interface-4.0.7/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_platform_interface-4.0.7/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="geolocator_web"> <entry key="geolocator_web">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_web-2.1.6/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_web-2.1.6/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="geolocator_windows"> <entry key="geolocator_windows">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_windows-0.1.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_windows-0.1.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="graphs"> <entry key="graphs">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/graphs-2.1.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/graphs-2.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="home_indicator"> <entry key="home_indicator">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/home_indicator-2.0.2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/home_indicator-2.0.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="html"> <entry key="html">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/html-0.15.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/html-0.15.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="http"> <entry key="http">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.13.5/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/http-0.13.5/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="http_parser"> <entry key="http_parser">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="image"> <entry key="image">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/image-3.2.2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/image-3.2.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="intl"> <entry key="intl">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/intl-0.17.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/intl-0.17.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="js"> <entry key="js">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/js-0.6.4/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/js-0.6.4/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="json_annotation"> <entry key="json_annotation">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="lints"> <entry key="lints">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/lints-2.0.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/lints-2.0.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="logging"> <entry key="logging">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/lib" />
</list>
</value>
</entry>
<entry key="marquee">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/marquee-2.2.3/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="matcher"> <entry key="matcher">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="material_color_utilities"> <entry key="material_color_utilities">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.5/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.5/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="meta"> <entry key="meta">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.8.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.8.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="mime"> <entry key="mime">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/mime-1.0.2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/mime-1.0.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="nested"> <entry key="nested">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/nested-1.0.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/nested-1.0.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="page_transition"> <entry key="page_transition">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/page_transition-2.0.9/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/page_transition-2.0.9/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="path"> <entry key="path">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="path_provider"> <entry key="path_provider">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.11/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.11/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="path_provider_android"> <entry key="path_provider_android">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.21/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.21/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="path_provider_ios"> <entry key="path_provider_ios">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="path_provider_linux"> <entry key="path_provider_linux">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="path_provider_macos"> <entry key="path_provider_macos">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="path_provider_platform_interface"> <entry key="path_provider_platform_interface">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_platform_interface-2.0.5/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_platform_interface-2.0.5/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="path_provider_windows"> <entry key="path_provider_windows">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="petitparser"> <entry key="petitparser">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/petitparser-5.0.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/petitparser-5.0.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="platform"> <entry key="platform">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/platform-3.1.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/platform-3.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="plugin_platform_interface"> <entry key="plugin_platform_interface">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-2.1.3/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-2.1.3/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="postgresql2"> <entry key="postgresql2">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/postgresql2-1.0.3/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/postgresql2-1.0.3/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="process"> <entry key="process">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/process-4.2.4/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/process-4.2.4/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="provider"> <entry key="provider">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/provider-6.0.4/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/provider-6.0.4/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="random_string"> <entry key="random_string">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/random_string-2.3.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/random_string-2.3.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="rikulo_commons"> <entry key="rikulo_commons">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/rikulo_commons-5.2.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/rikulo_commons-5.2.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="rive"> <entry key="rive">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/rive-0.9.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/rive-0.9.1/lib" />
</list>
</value>
</entry>
<entry key="scroll_loop_auto_scroll">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/scroll_loop_auto_scroll-0.0.5/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="sky_engine"> <entry key="sky_engine">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/bin/cache/pkg/sky_engine/lib" /> <option value="$PROJECT_DIR$/../flutter/bin/cache/pkg/sky_engine/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="source_span"> <entry key="source_span">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="stack_trace"> <entry key="stack_trace">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="stream_channel"> <entry key="stream_channel">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="string_scanner"> <entry key="string_scanner">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="term_glyph"> <entry key="term_glyph">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="test_api"> <entry key="test_api">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/lib" />
</list>
</value>
</entry>
<entry key="text_scroll">
<value>
<list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/text_scroll-0.1.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="typed_data"> <entry key="typed_data">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="universal_io"> <entry key="universal_io">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.4/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.4/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="vector_math"> <entry key="vector_math">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="vibration"> <entry key="vibration">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/vibration-1.7.6/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/vibration-1.7.6/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="win32"> <entry key="win32">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/win32-3.0.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/win32-3.0.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="xdg_directories"> <entry key="xdg_directories">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/xdg_directories-0.2.0+2/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/xdg_directories-0.2.0+2/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="xml"> <entry key="xml">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/xml-6.1.0/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/xml-6.1.0/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="yaml"> <entry key="yaml">
<value> <value>
<list> <list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/lib" /> <option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/lib" />
</list> </list>
</value> </value>
</entry> </entry>
</option> </option>
</properties> </properties>
<CLASSES> <CLASSES>
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/animations-2.0.7/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/_flutterfire_internals-1.0.12/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/archive-3.3.2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/animations-2.0.7/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/archive-3.3.2/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.2.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.3.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.2.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.3.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/convert-3.1.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-4.3.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_platform_interface-5.10.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/csslib-0.17.2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-3.2.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-1.0.5/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.3.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/convert-3.1.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/ffi-2.0.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/csslib-0.17.2/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-5.7.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-1.0.5/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_launcher_icons-0.10.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fading_edge_scrollview-3.0.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_lints-2.0.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.3.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_native_splash-2.2.11/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/ffi-2.0.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_styled_toast-2.1.3/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/fluttericon-2.0.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core-2.4.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/fluttertoast-8.1.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_platform_interface-4.5.2/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/font_awesome_flutter-10.2.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-2.1.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator-9.0.2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-14.2.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_android-4.1.4/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_messaging_platform_interface-4.2.10/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_apple-2.2.3/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/firebase_messaging_web-3.2.11/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_platform_interface-4.0.7/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-5.7.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_web-2.1.6/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_launcher_icons-0.10.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_windows-0.1.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_lints-2.0.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/graphs-2.1.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_native_splash-2.2.11/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/home_indicator-2.0.2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_styled_toast-2.1.3/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/html-0.15.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fluttericon-2.0.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.13.5/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fluttertoast-8.1.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/font_awesome_flutter-10.2.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/image-3.2.2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator-9.0.2/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/intl-0.17.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_android-4.1.4/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/js-0.6.4/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_apple-2.2.3/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_platform_interface-4.0.7/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/lints-2.0.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_web-2.1.6/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_windows-0.1.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/graphs-2.1.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.5/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/home_indicator-2.0.2/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.8.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/html-0.15.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/mime-1.0.2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/http-0.13.5/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/nested-1.0.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/page_transition-2.0.9/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/image-3.2.2/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/intl-0.17.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.11/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/js-0.6.4/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.21/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/lints-2.0.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/marquee-2.2.3/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_platform_interface-2.0.5/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.5/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/petitparser-5.0.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.8.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/platform-3.1.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/mime-1.0.2/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-2.1.3/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/nested-1.0.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/postgresql2-1.0.3/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/page_transition-2.0.9/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/process-4.2.4/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.2/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/provider-6.0.4/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.11/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/random_string-2.3.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.21/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/rikulo_commons-5.2.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/rive-0.9.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_platform_interface-2.0.5/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/petitparser-5.0.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/platform-3.1.0/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-2.1.3/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/postgresql2-1.0.3/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.4/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/process-4.2.4/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/provider-6.0.4/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/vibration-1.7.6/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/random_string-2.3.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/win32-3.0.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/rikulo_commons-5.2.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/xdg_directories-0.2.0+2/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/rive-0.9.1/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/xml-6.1.0/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/scroll_loop_auto_scroll-0.0.5/lib" />
<root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.0/lib" />
<root url="file://$USER_HOME$/flutter/bin/cache/pkg/sky_engine/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib" />
<root url="file://$USER_HOME$/flutter/packages/flutter/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib" />
<root url="file://$USER_HOME$/flutter/packages/flutter_localizations/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/lib" />
<root url="file://$USER_HOME$/flutter/packages/flutter_test/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib" />
<root url="file://$USER_HOME$/flutter/packages/flutter_web_plugins/lib" /> <root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/text_scroll-0.1.1/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.4/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/vibration-1.7.6/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/win32-3.0.1/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/xdg_directories-0.2.0+2/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/xml-6.1.0/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/lib" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/pkg/sky_engine/lib" />
<root url="file://$PROJECT_DIR$/../flutter/packages/flutter/lib" />
<root url="file://$PROJECT_DIR$/../flutter/packages/flutter_localizations/lib" />
<root url="file://$PROJECT_DIR$/../flutter/packages/flutter_test/lib" />
<root url="file://$PROJECT_DIR$/../flutter/packages/flutter_web_plugins/lib" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />

@ -1,25 +1,25 @@
<component name="libraryTable"> <component name="libraryTable">
<library name="Dart SDK"> <library name="Dart SDK">
<CLASSES> <CLASSES>
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/async" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/async" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/cli" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/cli" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/collection" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/collection" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/convert" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/convert" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/core" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/core" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/developer" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/developer" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/ffi" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/ffi" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/html" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/html" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/indexed_db" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/indexed_db" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/io" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/io" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/isolate" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/isolate" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/js" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/js" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/js_util" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/js_util" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/math" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/math" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/mirrors" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/mirrors" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/svg" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/svg" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/typed_data" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/typed_data" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/web_audio" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/web_audio" />
<root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/web_gl" /> <root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/web_gl" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -2,7 +2,7 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Daflv4.iml" filepath="$PROJECT_DIR$/.idea/Daflv4.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/dafl_music.iml" filepath="$PROJECT_DIR$/.idea/dafl_music.iml" />
</modules> </modules>
</component> </component>
</project> </project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpProjectSharedConfiguration" php_language_level="8.1">
<option name="suggestChangeDefaultLanguageLevel" value="false" />
</component>
</project>

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/Sources/php_script/script/insertAndMakeListUser.php" dialect="GenericSQL" />
<file url="file://$PROJECT_DIR$/Sources/php_script/script/test.php" dialect="GenericSQL" />
</component>
</project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

@ -56,3 +56,6 @@ tous les utilisateurs.
révéler quelques informations personnelles (nom, âge, sexe). révéler quelques informations personnelles (nom, âge, sexe).
Le but est qu'une mise en contact entre 2 personnes se base uniquement Le but est qu'une mise en contact entre 2 personnes se base uniquement
sur des critères musicaux et non personnels. sur des critères musicaux et non personnels.
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />Ce(tte) œuvre est mise à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Licence Creative Commons Attribution - Pas d&#39;Utilisation Commerciale - Pas de Modification 4.0 International</a>.

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/symfony/translation" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/nesbot/carbon" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/pimple/pimple" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/psr/simple-cache" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/psr/http-message" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/illuminate/support" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/psr/container" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/doctrine/inflector" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/illuminate/contracts" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/slim/slim" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/illuminate/database" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/illuminate/container" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/nikic/fast-route" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/symfony/polyfill-php80" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/kylekatarnls/update-helper" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/symfony/translation-contracts" />
<excludeFolder url="file://$MODULE_DIR$/sources/vendor/symfony/polyfill-mbstring" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/api_database.iml" filepath="$PROJECT_DIR$/.idea/api_database.iml" />
</modules>
</component>
</project>

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/sources/vendor/symfony/translation" />
<path value="$PROJECT_DIR$/sources/vendor/nesbot/carbon" />
<path value="$PROJECT_DIR$/sources/vendor/pimple/pimple" />
<path value="$PROJECT_DIR$/sources/vendor/psr/simple-cache" />
<path value="$PROJECT_DIR$/sources/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/sources/vendor/illuminate/support" />
<path value="$PROJECT_DIR$/sources/vendor/psr/container" />
<path value="$PROJECT_DIR$/sources/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/sources/vendor/illuminate/contracts" />
<path value="$PROJECT_DIR$/sources/vendor/slim/slim" />
<path value="$PROJECT_DIR$/sources/vendor/illuminate/database" />
<path value="$PROJECT_DIR$/sources/vendor/illuminate/container" />
<path value="$PROJECT_DIR$/sources/vendor/nikic/fast-route" />
<path value="$PROJECT_DIR$/sources/vendor/composer" />
<path value="$PROJECT_DIR$/sources/vendor/symfony/polyfill-php80" />
<path value="$PROJECT_DIR$/sources/vendor/kylekatarnls/update-helper" />
<path value="$PROJECT_DIR$/sources/vendor/symfony/translation-contracts" />
<path value="$PROJECT_DIR$/sources/vendor/symfony/polyfill-mbstring" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.4">
<option name="suggestChangeDefaultLanguageLevel" value="false" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/database/dafl_music.sql" dialect="MariaDB" />
</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,61 @@
-- phpMyAdmin SQL Dump
-- version 5.2.0
-- https://www.phpmyadmin.net/
--
-- Host: localhost
-- Generation Time: Dec 25, 2022 at 09:09 PM
-- Server version: 10.9.4-MariaDB
-- PHP Version: 8.1.13
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT = @@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS = @@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION = @@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `dafl_music`
--
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE `users`
(
`idDafl` varchar(25) NOT NULL,
`idSpotify` varchar(25) NOT NULL,
`password` varchar(250) NOT NULL
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci;
--
-- Dumping data for table `users`
--
INSERT INTO `users` (`idDafl`, `idSpotify`, `password`)
VALUES ('felix', 'idspotfelix', 'mdp'),
('lucas', 'spottest', 'pwdtest');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `users`
--
ALTER TABLE `users`
ADD PRIMARY KEY (`idDafl`),
ADD UNIQUE KEY `idSpotify` (`idSpotify`);
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT = @OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS = @OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION = @OLD_COLLATION_CONNECTION */;

@ -0,0 +1,36 @@
<?php
class Connection extends PDO
{
private $stmt;
public function __construct(string $dsn, string $username, string $password)
{
parent::__construct($dsn, $username, $password);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
/** * @param string $query
* @param array $parameters *
* @return bool Returns `true` on success, `false` otherwise
*/
public function executeQuery(string $query, array $parameters = []): bool
{
$this->stmt = parent::prepare($query);
foreach ($parameters as $name => $value) {
$this->stmt->bindValue($name, $value[0], $value[1]);
}
return $this->stmt->execute();
}
public function getResults(): array
{
return $this->stmt->fetchall();
}
}
?>

@ -0,0 +1,46 @@
<?php
require "gateways/UserGateway.php";
require "gateways/LikesGateway.php";
require "business/User.php";
class Model
{
public function getInformationsUser($id): array
{
global $app;
$db = $app->getContainer()['settings']['db'];
$id = filter_var($id, FILTER_SANITIZE_STRING);
$gw = new UserGateway(new Connection($db['dsn'], $db['user'], $db['pass']));
$userDb = $gw->getInformations($id);
if (count($userDb) != 1) {
throw new Exception("no user matches id");
}
$user = new User($userDb[0][0], $userDb[0][1]);
return $user->getInformations();
}
public function addUser($idDafl, $idSpotify, $passw): void
{
global $app;
$db = $app->getContainer()['settings']['db'];
$data = [];
$data['idDafl'] = filter_var($idDafl, FILTER_SANITIZE_STRING);
$data['idSpotify'] = filter_var($idSpotify, FILTER_SANITIZE_STRING);
$data['passw'] = filter_var($passw, FILTER_SANITIZE_STRING);
$gw = new UserGateway(new Connection($db['dsn'], $db['user'], $db['pass']));
$gw->addUser($data['idDafl'], $data['idSpotify'], $data['passw']);
}
public function like($user,$liked) : bool {
global $app;
$db = $app->getContainer()['settings']['db'];
$data = [];
$data['user'] = filter_var($user, FILTER_SANITIZE_STRING);
$data['liked'] = filter_var($liked, FILTER_SANITIZE_STRING);
$gw = new LikesGateway(new Connection($db['dsn'], $db['user'], $db['pass']));
return $gw->addUser($data['idDafl'], $data['idSpotify'], $data['passw']);
}
}

@ -0,0 +1,35 @@
<?php
class User
{
private string $idDafl;
private string $idSpotify;
public function __construct(string $idDafl, string $idSpotify)
{
$this->idDafl = $idDafl;
$this->idSpotify = $idSpotify;
}
/**
* @return string
*/
public function getIdDafl(): string
{
return $this->idDafl;
}
/**
* @return string
*/
public function getIdSpotify(): string
{
return $this->idSpotify;
}
public function getInformations(): array
{
return array($this->idDafl, $this->idSpotify);
}
}

@ -0,0 +1,8 @@
<?php
$config['displayErrorDetails'] = true;
$config['addContentLengthHeader'] = false;
$config['db']['dsn'] = 'mysql:host=localhost;dbname=dafl_music';
$config['db']['user'] = 'root';
$config['db']['pass'] = 'root';

@ -0,0 +1,26 @@
<?php
class LikesGateway
{
private Connection $con;
public function __construct(Connection $con)
{
$this->con = $con;
}
public function addLike($user,$liked):bool
{
$query = 'INSERT INTO likes VALUES (:user,:liked)';
$this->con->executeQuery($query,array(':user'=>array($user,PDO::PARAM_STR),':liked'=>array($liked,PDO::PARAM_STR)));
$query = 'SELECT * FROM likes WHERE (user=:user AND liked=:liked) OR (liked=:liked AND user=:user )';
$this->con->executeQuery($query,array(':user'=>array($user,PDO::PARAM_STR),':liked'=>array($liked,PDO::PARAM_STR)));
$res=$this->con->getResults();
if(count($res) == 2) {
$query = 'INSERT INTO matches VALUES (:user,:liked)';
$this->con->executeQuery($query,array(':user'=>array($user,PDO::PARAM_STR),':liked'=>array($liked,PDO::PARAM_STR)));
return true;
}
return false;
}
}

@ -0,0 +1,24 @@
<?php
class UserGateway
{
private Connection $con;
public function __construct(Connection $con)
{
$this->con = $con;
}
public function getInformations($id): array
{
$query = 'SELECT idDafl,idSpotify FROM users WHERE idDafl=:id';
$this->con->executeQuery($query, array(':id' => array($id, PDO::PARAM_STR)));
return $this->con->getResults();
}
public function addUser($idDafl, $idSpotify, $passw)
{
$query = 'INSERT INTO users VALUES (:idDafl,:idSpotify,:passw)';
$this->con->executeQuery($query, array(':idDafl' => array($idDafl, PDO::PARAM_STR), ':idSpotify' => array($idSpotify, PDO::PARAM_STR), ':passw' => array($passw, PDO::PARAM_STR)));
}
}

@ -0,0 +1,82 @@
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require "Model.php";
require "Connection.php";
// Get information about a user
$app->get('/users/{id}', function (Request $request, Response $response, array $args) {
try {
$mdl = new Model();
$res = $mdl->getInformationsUser($args['id']);
} catch (Exception $e) {
$res = array("Error: " . $e->getMessage());
} finally {
$response->getBody()->write(json_encode($res));
return $response;
}
});
// Add a user
$app->post('/users/new', function (Request $request, Response $response, array $args) {
try {
$mdl = new Model();
$data = $request->getParsedBody();
if (!isset($data['idDafl']) || !isset($data['idSpotify']) || !isset($data['passw'])) {
throw new Exception("missing arguments");
}
$mdl->addUser($data['idDafl'], $data['idSpotify'], $data['passw']);
$res = "Ok";
} catch (Exception $e) {
$res = array("Error: " . $e->getMessage());
} finally {
$response->getBody()->write(json_encode($res));
return $response;
}
});
/*
// Update information about a user
$app->put('/users/{id}', function (Request $request, Response $response, array $args) {
$res = "Update infos of user " . $args['id'];
$response->getBody()->write($res);
return $response;
});
// Delete a user
$app->delete('/users/{id}', function (Request $request, Response $response, array $args) {
$res = "Delete user " . $args['id'];
$response->getBody()->write($res);
return $response;
});
*/
// Like someone
$app->post('/user/{id}/like', function (Request $request, Response $response, array $args) {
try {
$mdl = new Model();
$data = $request->getParsedBody();
if (!isset($data['liked'])) {
throw new Exception("missing arguments");
}
$res=($mdl->like($args["id"],$data["liked"])) ? "Match" : "Ok";
} catch (Exception $e) {
$res = array("Error: " . $e->getMessage());
} finally {
$response->getBody()->write(json_encode($res));
return $response;
}
});
/*
// Add a new song as a preference for a situation
$app->post('/users/{id}/preferences', function (Request $request, Response $response, array $args) {
$res = "User " . $args['id'] . " add music " . $args['music'] . " to his preferences for category " . $args['categ'];
$response->getBody()->write($res);
return $response;
});
*/

@ -0,0 +1,12 @@
{
"require": {
"slim/slim": "3.*",
"illuminate/database": "~5.1",
"ext-json": "*"
},
"config": {
"allow-plugins": {
"kylekatarnls/update-helper": true
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,15 @@
<?php
// Files auto-loading
require '../vendor/autoload.php';
// Configuration
require '../app/config.php';
// App instantiation
$app = new \Slim\App(['settings' => $config]);
// Routes
require '../app/routes.php';
// Run
$app->run();

@ -1,2 +1,2 @@
FROM httpd:2.4 FROM httpd:2.4
COPY ./public-html/ /usr/local/apache2/htdocs/ COPY ./sources/ /usr/local/apache2/htdocs/

@ -1,39 +0,0 @@
{
"project_info": {
"project_number": "943188299704",
"project_id": "daflmusic-b3b74",
"storage_bucket": "daflmusic-b3b74.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:943188299704:android:995199bd5229a330a9c94d",
"android_client_info": {
"package_name": "com.example.dafl_project_flutter"
}
},
"oauth_client": [
{
"client_id": "943188299704-qp12a784hmdo97v7qq78ekasgrfkmo52.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyBehHyqsXbBm1I7fBSG2bPOQvpDX-8Rm7I"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "943188299704-qp12a784hmdo97v7qq78ekasgrfkmo52.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>943188299704-h4035qno57lll2km151rdh3bgbb22vk7.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.943188299704-h4035qno57lll2km151rdh3bgbb22vk7</string>
<key>API_KEY</key>
<string>AIzaSyCnQnCeu7gdc1_uIOxXVNQT1pG8xjD_tB8</string>
<key>GCM_SENDER_ID</key>
<string>943188299704</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.example.daflProjectFlutter</string>
<key>PROJECT_ID</key>
<string>daflmusic-b3b74</string>
<key>STORAGE_BUCKET</key>
<string>daflmusic-b3b74.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:943188299704:ios:bd6866b329aebb64a9c94d</string>
</dict>
</plist>

@ -1,7 +0,0 @@
{
"file_generated_by": "FlutterFire CLI",
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
"GOOGLE_APP_ID": "1:943188299704:ios:bd6866b329aebb64a9c94d",
"FIREBASE_PROJECT_ID": "daflmusic-b3b74",
"GCM_SENDER_ID": "943188299704"
}

@ -1,300 +0,0 @@
import 'dart:convert';
import 'dart:math';
import 'package:dafl_project_flutter/main.dart';
import 'package:http/http.dart' as http;
import 'package:crypto/crypto.dart';
import 'dart:developer' as dev;
import '../exceptions/api_exception.dart';
class Api {
//from dashboard
final _clientId = '7ceb49d874b9404492246027e4d68cf8';
final _clientSecret = '98f9cb960bf54ebbb9ad306e7ff919cb';
//for web api
get redirectUri => 'https://daflmusic.000webhostapp.com/callback/';
final _scopes =
'user-read-playback-state user-read-currently-playing user-read-recently-played playlist-modify-public ugc-image-upload user-modify-playback-state';
late String _state;
dynamic _codeVerifier;
dynamic _codeChallenge;
late String _encodedLogs;
final _tokenType = 'Bearer ';
late http.Response _response; //use _setResponse() as kind of a private setter
final _playlistName = "Dafl's discovery";
//from web api
String? _code;
int? _expiresIn;
String? _refreshToken;
String? _accessToken; //use _getAccessToken() as kind of a private getter
//other
final _client = http.Client();
late Uri _urlAuthorize;
get urlAuthorize => _urlAuthorize;
DateTime? _tokenEnd;
Api() {
_state = _generateRandomString(16);
_codeVerifier = _generateRandomString(_generateRandomInt(43, 128));
_codeChallenge = _generateCodeChallenge();
_encodedLogs = base64.encode(utf8.encode("$_clientId:$_clientSecret"));
_urlAuthorize = Uri.https('accounts.spotify.com', 'authorize', {
'client_id': _clientId,
'response_type': 'code',
'redirect_uri': redirectUri,
'state': _state,
'scope': _scopes,
'show_dialog': 'false',
'code_challenge_method': 'S256',
'code_challenge': _codeChallenge
});
}
//PKCE generations
_generateRandomInt(int min, int max) {
return min + Random().nextInt(max - min);
}
_generateRandomString(int length) {
const chars =
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
return String.fromCharCodes(Iterable.generate(
length, (_) => chars.codeUnitAt(Random().nextInt(chars.length))));
}
_generateCodeChallenge() {
return base64Encode(sha256.convert(utf8.encode(_codeVerifier)).bytes)
.replaceAll('+', '-')
.replaceAll('/', '_')
.replaceAll('=', '');
}
//session management
requestUserAuthorization(Uri url) async {
if (url.queryParameters['state'] != _state.toString()) {
throw ApiException('state');
}
_code = url.queryParameters['code'];
await _requestAccessToken();
}
_requestAccessToken() async {
var urlToken = Uri.https('accounts.spotify.com', 'api/token', {
'code': _code,
'redirect_uri': redirectUri,
'grant_type': 'authorization_code',
'client_id': _clientId,
'code_verifier': _codeVerifier
});
_setResponse(await _client.post(urlToken, headers: <String, String>{
'Authorization': 'Basic $_encodedLogs',
'Content-Type': 'application/x-www-form-urlencoded'
}));
var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
_accessToken = decodedResponse['access_token'];
_expiresIn = decodedResponse['expires_in'];
_tokenEnd = DateTime.now().add(Duration(seconds: _expiresIn!));
_refreshToken = decodedResponse['refresh_token'];
}
Future<String?> _getAccessToken() async {
if (DateTime.now().isAfter(_tokenEnd!)) {
await _getRefreshedAccessToken();
}
return _accessToken;
}
_setResponse(value) {
int sc = value.statusCode;
if (sc >= 300) {
dev.log(value.body.toString());
throw ApiException(sc);
}
_response = value;
}
_getRefreshedAccessToken() async {
var urlToken = Uri.https('accounts.spotify.com', 'api/token', {
'grant_type': 'refresh_token',
'refresh_token': _refreshToken,
'client_id': _clientId
});
_setResponse(await _client.post(urlToken, headers: <String, String>{
'Content-Type': 'application/x-www-form-urlencoded'
}));
var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
_accessToken = decodedResponse['access_token'];
_expiresIn = decodedResponse['expires_in'];
_tokenEnd = DateTime.now().add(Duration(seconds: _expiresIn!));
}
//functional methods
Future<String> getCurrentlyPlayingTrack() async {
var url = Uri.https('api.spotify.com', 'v1/me/player/currently-playing');
var token = await _getAccessToken();
var response = await _client.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
});
if (response.statusCode == 204) {
return _getRecentlyPlayedTrack();
}
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
return decodedResponse['item']['id'];
}
Future<String> _getRecentlyPlayedTrack() async {
var url = Uri.https(
'api.spotify.com', 'v1/me/player/recently-played', {'limit': '1'});
var token = await _getAccessToken();
_setResponse(await _client.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
return decodedResponse['items'][0]['track']['id'];
}
Future<Map> getTrackInfo(String id) async {
var url = Uri.https('api.spotify.com', 'v1/tracks/$id');
var token = await _getAccessToken();
_setResponse(await _client.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
Map<String, String> info = {
'artist': decodedResponse['artists'][0]['name'],
'name': decodedResponse['name'],
'cover': decodedResponse['album']['images'][0]['url']
};
return info;
}
Future<bool> _isInPlaylist(String idTrack, String idPlaylist) async {
var url = Uri.https('api.spotify.com', 'v1/playlists/$idPlaylist/tracks',
{'limit': '50', 'fields': 'items(track(id))'});
var token = await _getAccessToken();
_setResponse(await _client.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
var res = decodedResponse['items']
.where((element) => element['track']['id'] == idTrack)
.toList();
if (res.length >= 1) {
return true;
}
return false;
}
addToPLaylist(String idTrack) async {
var idPlaylist = await _getPlaylist();
if (idPlaylist == null) {
idPlaylist = await _createPlaylist();
} else {
if (await _isInPlaylist(idTrack, idPlaylist)) {
return;
}
}
var token = await _getAccessToken();
var url = Uri.https('api.spotify.com', 'v1/playlists/$idPlaylist/tracks',
{'uris': 'spotify:track:$idTrack'});
_setResponse(await _client.post(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
}
Future<String?> _getPlaylist() async {
var url = Uri.https('api.spotify.com', 'v1/me/playlists', {'limit': '50'});
var token = await _getAccessToken();
_setResponse(await _client.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
var daflplaylist = decodedResponse['items']
.where((element) => element['name'] == _playlistName)
.toList();
if (daflplaylist.length == 1) {
return daflplaylist[0]['uri'].substring(
17); //17 char because format is 'spotify:playlist:MYPLAYLISTID'
}
return null;
}
Future<String> _createPlaylist() async {
var idUser = await MyApp.controller.currentUser.getIdSpotify();
var token = await _getAccessToken();
var url = Uri.https('api.spotify.com', 'v1/users/$idUser/playlists');
_setResponse(await _client.post(url,
headers: <String, String>{
'Accept': 'application/json',
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
},
body: jsonEncode(<String, String>{
'name': _playlistName,
'description':
'Retrouvez toutes vos découvertes faites sur DaflMusic 🎵',
'public': 'true'
})));
var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
var idPlaylist = decodedResponse['id'];
return idPlaylist;
}
playTrack(String idTrack) async {
var token = await _getAccessToken();
var url = Uri.https('api.spotify.com', 'v1/me/player/play');
_setResponse(await _client.put(url,
headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
},
body: jsonEncode(<String, List>{
'uris': ['spotify:track:$idTrack']
})));
}
removeFromPlaylist(String idTrack) async {
var idPlaylist = await _getPlaylist();
if (idPlaylist != null) {
if (await _isInPlaylist(idTrack, idPlaylist)) {
var token = await _getAccessToken();
var url =
Uri.https('api.spotify.com', 'v1/playlists/$idPlaylist/tracks');
var jsonVar = jsonEncode(<String, List>{
'tracks': [
{'uri': 'spotify:track:$idTrack'}
]
});
_setResponse(await _client.delete(url,
headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
},
body: jsonVar));
}
}
}
Future<String> getIdUser() async {
var url = Uri.https('api.spotify.com', 'v1/me');
var token = await _getAccessToken();
_setResponse(await _client.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(_response.bodyBytes)) as Map;
return decodedResponse['id'];
}
}

@ -1,67 +1,135 @@
import 'dart:async';
import 'dart:collection';
import 'dart:convert'; import 'dart:convert';
import 'package:dafl_project_flutter/firebase_services/notification_service.dart';
import 'package:dafl_project_flutter/model/message.dart';
import 'package:dafl_project_flutter/firebase_services/message_database_services.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import '../persistence/database_loader.dart'; import '../model/music.dart';
import '../persistence/database_saver.dart'; import '../model/spot.dart';
import '../persistence/database_searcher.dart';
import '../persistence/loader.dart';
import '../persistence/saver.dart';
import '../model/user.dart'; import '../model/user.dart';
import '../persistence/searcher.dart'; import '../services/api/api_spotify.dart';
import '../services/database/database_service.dart';
import '../services/position/location.dart';
import 'live_datas.dart';
class Controller { class Controller {
static Saver saver = DatabaseSaver(); final ApiSpotify _api = ApiSpotify();
static Loader loader = DatabaseLoader(); late User _currentUser;
static final Searcher _searcher = DatabaseSearcher(); final DataBaseService _dataBaseService = DataBaseService();
final MessageDatabaseServices _messageAccess = MessageDatabaseServices(); final LiveData _data = LiveData();
final NotificationService _notificationService = NotificationService();
late BuildContext navigatorKey; late BuildContext navigatorKey;
late User currentUser; initUser() async {
await setCurrentMusic();
await setDiscoveries();
}
Controller() { beginRoutine() async {
currentUser = User('', ''); //TODO : remove this line await setSpots();
NotificationService.initialize(); Timer.periodic(const Duration(seconds: 10), (Timer t) => setSpots());
} }
void sendMessage(Message message, String idSender, String idReceiver) { //
_messageAccess.sendMessage(message, idSender, idReceiver); // Methods to manage data
//
// Data that can change
bool getChoice() => _data.discoveriesSortChoice;
setChoice(bool c) {
_data.discoveriesSortChoice = c;
} }
Stream<List<Message>> getMessage(String idSender, String idReceiver) { Music getCurrentMusic() => _data.userCurrentMusic;
return _messageAccess.getMessage(idSender, idReceiver);
setCurrentMusic() async {
_data.userCurrentMusic =
await getCompleteMusic(await _api.requests.getCurrentlyPlayingTrack());
} }
void save(User userToSave) { List<Spot> getSpots() => _data.spots;
saver.save(userToSave);
setSpots() async {
_data.spots = await Location.sendCurrentLocation();
} }
load(String username, String password) async { LinkedHashMap<Music, DateTime> getDiscoveries() => _data.discoveries;
_changeCurrentUser(await loader.load(username, password));
setDiscoveries() async {
LinkedHashMap<String, DateTime> tmpData =
await _api.requests.getPlaylistTracks();
LinkedHashMap<Music, DateTime> tmpCast = LinkedHashMap();
tmpData.forEach((key, value) async {
tmpCast[(await getCompleteMusic(key))] = value;
});
_data.discoveries = tmpCast;
} }
_changeCurrentUser(User user) { //Data that can not change
currentUser = user;
Uri getApiUrlAuthorize() => _api.identification.urlAuthorize;
String getApiRedirectUrl() => _api.identification.redirectUri;
String getIdSpotify() => _currentUser.idSpotify;
String getIdDafl() => _currentUser.idDafl;
//
//Other methods
//
apiAuthorization(url) {
_api.apiAuthorization(url);
}
Future<Music> getCompleteMusic(String id) async {
Map info = await _api.requests.getTrackInfo(id);
return Music(id, info['name'], info['artist'], info['cover']);
}
removeFromPlaylist(String id) {
_api.requests.removeFromPlaylist(id);
}
addToPlaylist(String id) {
_api.requests.addToPlaylist(id);
}
playTrack(String id) {
_api.requests.playTrack(id);
}
// DATABASE
void save(String idDafl, String passw) {
_dataBaseService.save(idDafl, passw);
}
Future<bool> load(String username, String password) async {
User? newUser = await _dataBaseService.load(username, password);
if (newUser == null) {
return false;
}
_currentUser = newUser;
return true;
} }
changeCurrentUsername(String newName) { changeUsername(String newName) {
currentUser.usernameDafl = newName; _dataBaseService.changeUsername(newName);
} }
changeCurrentPassword(String newPass) { changeCurrentPassword(String newPass) {
currentUser.passwDafl = newPass; _dataBaseService.changeCurrentPassword(newPass);
} }
Future<bool> searchByUsername(String username) async { Future<bool> searchUser(String username) async {
return await _searcher.searchByUsername(username); return await _dataBaseService.searchUser(username);
} }
Future sendEmail( Future sendEmail(String reporterId, String reportedId, String reason,
User reporter, User reported, String reason, String message) async { String message) async {
const serviceId = 'service_dzyndyb'; const serviceId = 'service_dzyndyb';
const templateId = 'template_idgriw2'; const templateId = 'template_idgriw2';
const userId = 'hy7HxL5QGV6gpdqry'; const userId = 'hy7HxL5QGV6gpdqry';
@ -77,8 +145,8 @@ class Controller {
'template_id': templateId, 'template_id': templateId,
'user_id': userId, 'user_id': userId,
'template_params': { 'template_params': {
'from_name': reporter.usernameDafl, 'from_name': reporterId,
'to_name': reported.usernameDafl, 'to_name': reportedId,
'reason': reason, 'reason': reason,
'message': message, 'message': message,
}, },

@ -0,0 +1,11 @@
import 'dart:collection';
import '../model/music.dart';
import '../model/spot.dart';
class LiveData {
bool discoveriesSortChoice = true;
late LinkedHashMap<Music, DateTime> discoveries;
late List<Spot> spots;
late Music userCurrentMusic;
}

@ -1,13 +0,0 @@
import 'dart:developer' as dev;
class ApiException implements Exception {
final String mess = 'Api exception raised,';
ApiException(dynamic code) {
if (code.runtimeType == String) {
dev.log('$mess state verification failed.');
} else {
dev.log('$mess status code : $code.');
}
}
}

@ -0,0 +1,7 @@
import 'dart:developer' as dev;
class ApiStateException implements Exception {
ApiStateException() {
dev.log('State verification failed.');
}
}

@ -0,0 +1,12 @@
import 'dart:developer' as dev;
import 'package:http/http.dart';
class HttpException implements Exception {
HttpException(var value) {
dev.log('Http request failed');
if (value.runtimeType == Response) {
dev.log('Status code : ${value.statusCode.toString()}');
dev.log('Body : ${value.body.toString()}');
}
}
}

@ -1,69 +0,0 @@
// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyBehHyqsXbBm1I7fBSG2bPOQvpDX-8Rm7I',
appId: '1:943188299704:android:995199bd5229a330a9c94d',
messagingSenderId: '943188299704',
projectId: 'daflmusic-b3b74',
storageBucket: 'daflmusic-b3b74.appspot.com',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyCnQnCeu7gdc1_uIOxXVNQT1pG8xjD_tB8',
appId: '1:943188299704:ios:bd6866b329aebb64a9c94d',
messagingSenderId: '943188299704',
projectId: 'daflmusic-b3b74',
storageBucket: 'daflmusic-b3b74.appspot.com',
iosClientId: '943188299704-h4035qno57lll2km151rdh3bgbb22vk7.apps.googleusercontent.com',
iosBundleId: 'com.example.daflProjectFlutter',
);
}

@ -1,58 +0,0 @@
import 'package:dafl_project_flutter/model/message.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class MessageDatabaseServices {
// Make an unique chat ID between 2 client. Look like 'User1-User2'
String _getChatId(String idSender, String idReceiver) {
// Test to always have the same id
if (idSender.hashCode <= idReceiver.hashCode)
return '$idSender-${idReceiver}';
else
return '${idReceiver}-$idSender';
}
// Send a message from an user to an other
void sendMessage(Message message, String idSender, String idReceiver) {
String chatId = _getChatId(idSender, idReceiver);
var documentReference = FirebaseFirestore.instance
.collection('messages')
.doc(chatId)
.collection(chatId)
.doc(DateTime
.now()
.millisecondsSinceEpoch
.toString());
FirebaseFirestore.instance.runTransaction((transaction) async {
transaction.set(documentReference, message.toHashMap());
});
}
// Get a message from a snapshot Firestore
Message _getMessage(DocumentSnapshot<Map<String, dynamic>> snapshot) {
var data = snapshot.data();
if (data == null) throw Exception("no data in database");
return Message.fromMap(data);
}
// Get a list of messages from Firestore
List<Message> _getAllMessages(QuerySnapshot<Map<String, dynamic>> snapshot) {
return snapshot.docs.map((doc) {
return _getMessage(doc);
}).toList();
}
// Get the massages from Firestore
Stream<List<Message>> getMessage(String idSender, String idReceiver) {
String chatId = _getChatId(idSender, idReceiver);
return FirebaseFirestore.instance
.collection('messages')
.doc(chatId)
.collection(chatId)
.snapshots()
.map(_getAllMessages);
}
}

@ -1,21 +0,0 @@
import 'package:firebase_messaging/firebase_messaging.dart';
class NotificationService {
static void initialize() {
FirebaseMessaging.instance.requestPermission();
FirebaseMessaging.onMessage.listen((event) {
print('A new onMessage event was published!');
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('A new onMessageOpenedApp event was published!');
});
}
static Future<String?> getToken() async {
return FirebaseMessaging.instance.getToken(
vapidKey:
"BOxfduRivQnT8TS1h9WRGEk4gV2IOzJpTCcoKxVTMgVWjxi6TUcQBng2mqM7fUfNy51esFrRGE68coa0XZaKdHc");
}
}

@ -1,40 +1,23 @@
import 'dart:async'; import 'dart:async';
import 'dart:ui'; import 'dart:ui';
import 'dart:math'; import 'dart:math';
import 'package:dafl_project_flutter/firebase_options.dart';
import './views/pages/home/p_home.dart'; import './views/pages/home/p_home.dart';
import './views/pages/main/p_main.dart'; import './views/pages/main/p_main.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:rive/rive.dart' as riv; import 'package:rive/rive.dart' as riv;
import 'controller/controller.dart'; import '../controller/controller.dart';
import 'model/spot.dart'; import 'model/spot.dart';
import 'api/api.dart';
import 'dart:developer' as dev; import 'dart:developer' as dev;
import 'package:flutter_styled_toast/flutter_styled_toast.dart'; import 'package:flutter_styled_toast/flutter_styled_toast.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print('Background message ${message.messageId}');
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
void main() {
runApp(const MyApp()); runApp(const MyApp());
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
static Controller controller = Controller(); static Controller controller = Controller();
static Api api = Api();
const MyApp({super.key}); const MyApp({super.key});
@ -46,7 +29,7 @@ class MyApp extends StatelessWidget {
SystemUiMode.manual, SystemUiMode.manual,
overlays: [SystemUiOverlay.top], overlays: [SystemUiOverlay.top],
); );
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarIconBrightness: Brightness.dark, // For Android (dark icons) statusBarIconBrightness: Brightness.dark, // For Android (dark icons)
statusBarBrightness: Brightness.dark, // For iOS (dark icons) statusBarBrightness: Brightness.dark, // For iOS (dark icons)
)); ));
@ -63,14 +46,11 @@ class MyApp extends StatelessWidget {
enum CardStatus { like, disLike, discovery, message } enum CardStatus { like, disLike, discovery, message }
class CardProvider extends ChangeNotifier { class CardProvider extends ChangeNotifier {
final List<Spot> _spotsList = MyApp.controller.currentUser.spots;
bool _isDragging = false; bool _isDragging = false;
double _angle = 0; double _angle = 0;
Offset _position = Offset.zero; Offset _position = Offset.zero;
Size _screenSize = Size.zero; Size _screenSize = Size.zero;
List<Spot> get spotsList => _spotsList;
bool get isDragging => _isDragging; bool get isDragging => _isDragging;
Offset get position => _position; Offset get position => _position;
@ -174,7 +154,7 @@ class CardProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void discovery(BuildContext context) { void discovery(BuildContext context) async {
dev.log("discovery"); dev.log("discovery");
_angle = 0; _angle = 0;
_position -= Offset(0, -_screenSize.height); _position -= Offset(0, -_screenSize.height);
@ -195,8 +175,8 @@ class CardProvider extends ChangeNotifier {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
MyApp.controller.currentUser.discovery.contains( MyApp.controller.getDiscoveries().containsKey(
MyApp.controller.currentUser.spots.last.music) MyApp.controller.getSpots().last.music)
? const Icon( ? const Icon(
Icons.info_rounded, Icons.info_rounded,
size: 40, size: 40,
@ -210,8 +190,8 @@ class CardProvider extends ChangeNotifier {
const SizedBox( const SizedBox(
width: 10, width: 10,
), ),
MyApp.controller.currentUser.discovery.contains( MyApp.controller.getDiscoveries().containsKey(
MyApp.controller.currentUser.spots.last.music) MyApp.controller.getSpots().last.music)
? const Text( ? const Text(
"Déjà dans vos discovery", "Déjà dans vos discovery",
style: TextStyle( style: TextStyle(
@ -234,11 +214,10 @@ class CardProvider extends ChangeNotifier {
curve: Curves.linear, curve: Curves.linear,
reverseCurve: Curves.linear, reverseCurve: Curves.linear,
); );
if (!MyApp.controller.currentUser.discovery if (!MyApp.controller
.contains(MyApp.controller.currentUser.spots.last.music)) { .getDiscoveries()
MyApp.controller.currentUser.spots.last.music.defineDate(); .containsKey(MyApp.controller.getSpots().last.music)) {
MyApp.controller.currentUser MyApp.controller.addToPlaylist(MyApp.controller.getSpots().last.music.id);
.addDiscovery(MyApp.controller.currentUser.spots.last.music);
notifyListeners(); notifyListeners();
} }
} }
@ -348,7 +327,7 @@ class CardProvider extends ChangeNotifier {
child: ElevatedButton( child: ElevatedButton(
onPressed: () { onPressed: () {
sendMessage(messageTextField.text, sendMessage(messageTextField.text,
MyApp.controller.currentUser.spots.last.userId); MyApp.controller.getSpots().last.userId);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF3F1DC3), backgroundColor: const Color(0xFF3F1DC3),
@ -379,7 +358,7 @@ class CardProvider extends ChangeNotifier {
} }
void sendMessage(String message, String userId) { void sendMessage(String message, String userId) {
dev.log(MyApp.controller.currentUser.spots.last.userId); dev.log(MyApp.controller.getSpots().last.userId);
} }
void like(context) { void like(context) {
@ -391,14 +370,15 @@ class CardProvider extends ChangeNotifier {
} }
Future _nextCard() async { Future _nextCard() async {
dev.log(_spotsList.length.toString()); List<Spot> spots = MyApp.controller.getSpots();
if (_spotsList.isEmpty) { dev.log(spots.length.toString());
if (spots.isEmpty) {
dev.log('dernier'); dev.log('dernier');
return; return;
} else { } else {
await Future.delayed(const Duration(milliseconds: 200)); await Future.delayed(const Duration(milliseconds: 200));
dev.log(_spotsList.last.music.name); dev.log(spots.last.music.name);
_spotsList.removeLast(); spots.removeLast();
resetPosition(); resetPosition();
} }
} }

@ -1,34 +1,8 @@
import 'user.dart'; import 'user.dart';
class Message { class Message {
String idSender; String senderId;
String idReceiver;
String content; String content;
Message({ Message(this.senderId, this.content);
required this.idSender,
required this.idReceiver,
required this.content,
});
Map<String, dynamic> toHashMap() {
return {
'idSender': idSender,
'idReceiver': idReceiver,
'content': content,
};
}
factory Message.fromMap(Map<String, dynamic> data) {
return Message(
idSender: data['idSender'],
idReceiver: data['idReceiver'],
content: data['content'],
);
}
@override
String toString() {
return "idSender : $idSender " + "Content : $content \n";
}
} }

@ -1,32 +1,22 @@
import '../exceptions/api_exception.dart'; import '../exceptions/api_state_exception.dart';
import '../main.dart'; import '../main.dart';
class Music { class Music {
late String _name;
late String _artist;
late String _linkCover;
final String _id; final String _id;
late DateTime date; final String _name;
final String _artist;
final String _linkCover;
Music(this._id) { Music(this._id, this._name, this._artist, this._linkCover);
_completeInfo();
} String get id => _id;
String get name => _name; String get name => _name;
String get artist => _artist; String get artist => _artist;
String get linkCover => _linkCover; String get linkCover => _linkCover;
String get id => _id;
_completeInfo() async {
try {
var info = await MyApp.api.getTrackInfo(_id);
_name = info['name'];
_artist = info['artist'];
_linkCover = info['cover'];
} on ApiException {
// TODO : add notification to show that an error occured
}
}
@override @override
bool operator ==(Object other) => bool operator ==(Object other) =>
identical(this, other) || identical(this, other) ||
@ -37,8 +27,4 @@ class Music {
@override @override
int get hashCode => name.hashCode ^ artist.hashCode; int get hashCode => name.hashCode ^ artist.hashCode;
void defineDate() {
this.date = new DateTime.now();
}
} }

@ -1,74 +1,8 @@
import 'dart:async';
import '../position/location.dart';
import '../exceptions/api_exception.dart';
import '../main.dart';
import 'music.dart';
import 'spot.dart';
import 'package:collection/collection.dart';
class User { class User {
Timer? timer;
int test = 0;
//attributes from DAFL //attributes from DAFL
late String usernameDafl; String idDafl;
late String passwDafl; late String idSpotify;
List<Music> discovery = [];
List<Spot> spots = [];
//attributes with Spotify API
String? _idSpotify; //use _getIdUser() as kind of a private getter
late Music _currentMusic;
bool sortChoise = true;
//constructors //constructors
User(this.usernameDafl, this.passwDafl) { User(this.idDafl);
actualiseCurrentMusic();
}
Music get currentMusic => _currentMusic; //lists
Future<String> getIdSpotify() async {
_idSpotify ??= await MyApp.api.getIdUser();
return _idSpotify!;
}
addDiscovery(Music music) {
discovery.add(music);
}
actualiseCurrentMusic() async {
try {
_currentMusic = Music(await MyApp.api.getCurrentlyPlayingTrack());
} on ApiException {
// TODO : add notification to show that an error occurred
}
}
listSpots() {
print('ajout test');
Future<String> rep = Location.sendCurrentLocation();
//ex : dorian-2d2s52a15d2a5,audric-2x5s2az3d1s5wx5s1,lucas-s2a5d25a2a25d
rep.then((String result) {
List<String> tab = result.split(",");
//ex : [dorian-2d2s52a15d2a5 , audric-2x5s2az3d1s5wx5s1 , lucas-s2a5d25a2a25d]
for (var element in tab) {
List<String> tab2 = element.split("-");
spots.add(Spot(tab2[0], Music(tab2[1])));
}
});
}
getListSpots() {
if (test == 0) {
test = 1;
listSpots();
} else {
timer =
Timer.periodic(const Duration(seconds: 72), (Timer t) => listSpots());
}
}
} }

@ -1,6 +0,0 @@
import 'dart:async';
import '../model/user.dart';
abstract class Loader {
Future<User> load(String username, String password);
}

@ -1,5 +0,0 @@
import '../model/user.dart';
abstract class Saver{
void save(User userToSave);
}

@ -1,5 +0,0 @@
abstract class Searcher {
Future<bool> searchUser(String? username, String? password);
Future<bool> searchByUsername(String? username);
}

@ -1,40 +0,0 @@
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import '../main.dart';
class Location {
static Future<String> sendCurrentLocation() async {
Uri uri = Uri.parse("http://89.83.53.34/phpmyadmin/dafldev/insert.php");
LocationPermission permission;
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.deniedForever) {
//faire l'interface gra pour gérer ça
return Future.error('Location Not Available');
}
}
String actualUser = MyApp.controller.currentUser.usernameDafl;
String actualSong = await MyApp.api.getCurrentlyPlayingTrack();
Position current = await Geolocator.getCurrentPosition();
await http.post(uri, body: {
"id": actualUser.toString(),
"latitude": current.latitude.toString(),
"longitude": current.longitude.toString(),
"idMusic": actualSong.toString(),
});
return getData();
}
static Future<String> getData() async {
String actualUser = MyApp.controller.currentUser.usernameDafl;
Uri uri = Uri.parse("http://89.83.53.34/phpmyadmin/dafldev/distance.php");
http.Response response = await http.post(uri, body: {
"id": actualUser,
});
var data = jsonDecode(response.body);
return data.toString();
}
}

@ -0,0 +1,20 @@
import 'package:dafl_project_flutter/services/api/api_spotify_identification.dart';
import 'package:dafl_project_flutter/services/api/api_spotify_requests.dart';
class ApiSpotify {
late ApiSpotifyIdentification _identification;
late ApiSpotifyRequests _requests;
ApiSpotify() {
_identification = ApiSpotifyIdentification();
}
ApiSpotifyIdentification get identification => _identification;
ApiSpotifyRequests get requests => _requests;
apiAuthorization(url) async {
await _identification.setCode(url);
_requests = ApiSpotifyRequests(await _identification.createToken());
}
}

@ -0,0 +1,83 @@
import 'dart:convert';
import 'dart:math';
import '../../exceptions/api_state_exception.dart';
import 'package:http/http.dart' as http;
import 'package:crypto/crypto.dart';
import '../http_response_verification.dart';
import 'token_spotify.dart';
class ApiSpotifyIdentification extends HttpResponseVerification {
static const String clientId = '7ceb49d874b9404492246027e4d68cf8';
final String _clientSecret = '98f9cb960bf54ebbb9ad306e7ff919cb';
final String _scopes =
'user-read-playback-state user-read-currently-playing user-read-recently-played playlist-modify-public ugc-image-upload user-modify-playback-state';
late String _state;
late String _codeVerifier;
late String _codeChallenge;
late String _encodedLogs;
String? _code;
String get redirectUri => 'https://codefirst.iut.uca.fr/containers/apiredirect-felixmielcarek/';
Uri get urlAuthorize => Uri.https('accounts.spotify.com', 'authorize', {
'client_id': clientId,
'response_type': 'code',
'redirect_uri': redirectUri,
'state': _state,
'scope': _scopes,
'show_dialog': 'false',
'code_challenge_method': 'S256',
'code_challenge': _codeChallenge
});
ApiSpotifyIdentification() {
_state = _generateRandomString(16);
_codeVerifier = _generateRandomString(_generateRandomInt(43, 128));
_codeChallenge = _generateCodeChallenge();
_encodedLogs = base64.encode(utf8.encode("$clientId:$_clientSecret"));
}
_generateRandomInt(int min, int max) {
return min + Random().nextInt(max - min);
}
_generateRandomString(int length) {
const chars =
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
return String.fromCharCodes(Iterable.generate(
length, (_) => chars.codeUnitAt(Random().nextInt(chars.length))));
}
_generateCodeChallenge() {
return base64Encode(sha256.convert(utf8.encode(_codeVerifier)).bytes)
.replaceAll('+', '-')
.replaceAll('/', '_')
.replaceAll('=', '');
}
setCode(Uri url) async {
if (url.queryParameters['state'] != _state.toString()) {
throw ApiStateException();
}
_code = url.queryParameters['code'];
}
Future<TokenSpotify> createToken() async {
var urlToken = Uri.https('accounts.spotify.com', 'api/token', {
'code': _code,
'redirect_uri': redirectUri,
'grant_type': 'authorization_code',
'client_id': clientId,
'code_verifier': _codeVerifier
});
setResponse(await http.post(urlToken, headers: <String, String>{
'Authorization': 'Basic $_encodedLogs',
'Content-Type': 'application/x-www-form-urlencoded'
}));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
return TokenSpotify(decodedResponse['access_token'],
decodedResponse['refresh_token'], decodedResponse['expires_in']);
}
}

@ -0,0 +1,184 @@
import 'dart:collection';
import 'dart:convert';
import 'package:dafl_project_flutter/services/api/token_spotify.dart';
import 'package:http/http.dart' as http;
import '../../main.dart';
import '../http_response_verification.dart';
class ApiSpotifyRequests extends HttpResponseVerification {
final String _tokenType = 'Bearer ';
final String _playlistName = "Dafl's discovery";
final TokenSpotify _token;
ApiSpotifyRequests(this._token);
Future<String> getCurrentlyPlayingTrack() async {
var url = Uri.https('api.spotify.com', 'v1/me/player/currently-playing');
var token = await _token.getAccessToken();
var response = await http.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
});
if (response.statusCode == 204) {
return _getRecentlyPlayedTrack();
}
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
return decodedResponse['item']['id'];
}
Future<String> _getRecentlyPlayedTrack() async {
var url = Uri.https(
'api.spotify.com', 'v1/me/player/recently-played', {'limit': '1'});
var token = await _token.getAccessToken();
setResponse(await http.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
return decodedResponse['items'][0]['track']['id'];
}
Future<Map> getTrackInfo(String id) async {
var url = Uri.https('api.spotify.com', 'v1/tracks/$id');
var token = await _token.getAccessToken();
setResponse(await http.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
Map<String, String> infos = {
'artist': decodedResponse['artists'][0]['name'],
'name': decodedResponse['name'],
'cover': decodedResponse['album']['images'][0]['url']
};
return infos;
}
Future<String> getIdUser() async {
var url = Uri.https('api.spotify.com', 'v1/me');
var token = await _token.getAccessToken();
setResponse(await http.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
return decodedResponse['id'];
}
playTrack(String idTrack) async {
var token = await _token.getAccessToken();
var url = Uri.https('api.spotify.com', 'v1/me/player/play');
setResponse(await http.put(url,
headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
},
body: jsonEncode(<String, List>{
'uris': ['spotify:track:$idTrack']
})));
}
Future<String> _getPlaylistId() async {
var url = Uri.https('api.spotify.com', 'v1/me/playlists', {'limit': '50'});
var token = await _token.getAccessToken();
setResponse(await http.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
var daflPlaylist = decodedResponse['items']
.where((element) => element['name'] == _playlistName)
.toList();
if (daflPlaylist.length == 1) {
return daflPlaylist[0]['uri'].substring(
17); //17 char because format is 'spotify:playlist:MYPLAYLISTID'
}
return await _createPlaylist();
}
Future<String> _createPlaylist() async {
var idUser = MyApp.controller.getIdSpotify();
var token = await _token.getAccessToken();
var url = Uri.https('api.spotify.com', 'v1/users/$idUser/playlists');
setResponse(await http.post(url,
headers: <String, String>{
'Accept': 'application/json',
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
},
body: jsonEncode(<String, String>{
'name': _playlistName,
'description':
'Retrouvez toutes vos découvertes faites sur DaflMusic 🎵',
'public': 'true'
})));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
var idPlaylist = decodedResponse['id'];
return idPlaylist;
}
addToPlaylist(String idTrack) async {
var idPlaylist = await _getPlaylistId();
if (await _isInPlaylist(idTrack, idPlaylist)) {
return;
}
var token = await _token.getAccessToken();
var url = Uri.https('api.spotify.com', 'v1/playlists/$idPlaylist/tracks',
{'uris': 'spotify:track:$idTrack'});
setResponse(await http.post(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
}
Future<bool> _isInPlaylist(String idTrack, String idPlaylist) async {
var url = Uri.https('api.spotify.com', 'v1/playlists/$idPlaylist/tracks',
{'limit': '50', 'fields': 'items(track(id))'});
var token = await _token.getAccessToken();
setResponse(await http.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
var res = decodedResponse['items']
.where((element) => element['track']['id'] == idTrack)
.toList();
return (res.length >= 1) ? true : false;
}
removeFromPlaylist(String idTrack) async {
var idPlaylist = await _getPlaylistId();
if (await _isInPlaylist(idTrack, idPlaylist)) {
var token = await _token.getAccessToken();
var url = Uri.https('api.spotify.com', 'v1/playlists/$idPlaylist/tracks');
var jsonVar = jsonEncode(<String, List>{
'tracks': [
{'uri': 'spotify:track:$idTrack'}
]
});
setResponse(await http.delete(url,
headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
},
body: jsonVar));
}
}
Future<LinkedHashMap<String, DateTime>> getPlaylistTracks() async {
var idPlaylist = await _getPlaylistId();
var url = Uri.https('api.spotify.com', 'v1/playlists/$idPlaylist/tracks',
{'fields': 'items(track(id),added_at)'});
var token = await _token.getAccessToken();
setResponse(await http.get(url, headers: <String, String>{
'Authorization': '$_tokenType $token',
'Content-Type': 'application/json'
}));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
LinkedHashMap<String, DateTime> mapRes = LinkedHashMap();
decodedResponse['items'].toList().forEach((elem) =>
{mapRes[elem['track']['id']] = DateTime.parse(elem['added_at'])});
return mapRes;
}
}

@ -1,8 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import '../exceptions/api_exception.dart'; import '../../main.dart';
import '../main.dart';
class MyInAppBrowser extends InAppBrowser { class MyInAppBrowser extends InAppBrowser {
var options = InAppBrowserClassOptions( var options = InAppBrowserClassOptions(
@ -14,7 +12,8 @@ class MyInAppBrowser extends InAppBrowser {
MyInAppBrowser() { MyInAppBrowser() {
_debugBrowser(); _debugBrowser();
openUrlRequest( openUrlRequest(
urlRequest: URLRequest(url: MyApp.api.urlAuthorize), options: options); urlRequest: URLRequest(url: MyApp.controller.getApiUrlAuthorize()),
options: options);
} }
_debugBrowser() async { _debugBrowser() async {
@ -26,10 +25,10 @@ class MyInAppBrowser extends InAppBrowser {
@override @override
Future onLoadStart(url) async { Future onLoadStart(url) async {
bool isError = false; bool isError = false;
if (url!.origin + url.path == MyApp.api.redirectUri) { if (url!.origin + url.path == MyApp.controller.getApiRedirectUrl()) {
try { try {
await MyApp.api.requestUserAuthorization(url); await MyApp.controller.apiAuthorization(url);
} on ApiException { } catch (e) {
notify(5, MyApp.controller.navigatorKey); notify(5, MyApp.controller.navigatorKey);
isError = true; isError = true;
} finally { } finally {

@ -0,0 +1,41 @@
import 'dart:convert';
import 'package:dafl_project_flutter/services/api/api_spotify_identification.dart';
import '../http_response_verification.dart';
import 'package:http/http.dart' as http;
class TokenSpotify extends HttpResponseVerification {
String _accessToken;
final String _refreshToken;
late DateTime _tokenEnd;
TokenSpotify(this._accessToken, this._refreshToken, int expiresIn) {
_setTokenEnd(expiresIn);
}
_setTokenEnd(int expiresIn) {
_tokenEnd = DateTime.now().add(Duration(seconds: expiresIn));
}
Future<String> getAccessToken() async {
if (DateTime.now().isAfter(_tokenEnd)) {
await _actualiseToken();
}
return _accessToken;
}
_actualiseToken() async {
var urlToken = Uri.https('accounts.spotify.com', 'api/token', {
'grant_type': 'refresh_token',
'refresh_token': _refreshToken,
'client_id': ApiSpotifyIdentification.clientId
});
setResponse(await http.post(urlToken, headers: <String, String>{
'Content-Type': 'application/x-www-form-urlencoded'
}));
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
_accessToken = decodedResponse['access_token'];
_setTokenEnd(decodedResponse['expires_in']);
}
}

@ -1,26 +1,25 @@
import 'dart:async'; import 'dart:async';
import 'loader.dart'; import 'loader.dart';
import '../model/user.dart'; import '../../model/user.dart';
import 'database_connexion.dart'; import 'database_connexion.dart';
import 'dart:developer' as dev; import 'dart:developer' as dev;
class DatabaseLoader extends Loader { class DatabaseLoader implements Loader {
// Load an user from database // Load an user from database
@override @override
Future<User> load(String username, String password) async { Future<User?> load(String username, String password) async {
final connection = await DatabaseConnexion.initConnexion(); final connection = await DatabaseConnexion.initConnexion();
var queryResult = await connection var queryResult = await connection
.query( .query(
'select * from utilisateur where username = @username AND password = @password', 'select username from utilisateur where username = @username AND password = @password',
{'username': username, 'password': password}) {'username': username, 'password': password})
.toList() .toList()
.then((result) { .then((result) {
dev.log(result.toString()); dev.log(result.toString());
if (result.isNotEmpty) { if (result.isNotEmpty) {
return User(username, password); return User(username);
} else { } else {
return User("", ""); return null;
} }
}) })
.whenComplete(() { .whenComplete(() {

@ -1,20 +1,15 @@
import 'database_connexion.dart'; import 'database_connexion.dart';
import 'saver.dart'; import 'saver.dart';
import '../model/user.dart';
class DatabaseSaver extends Saver { class DatabaseSaver implements Saver {
// Save user in the database // Save user in the database
@override @override
void save(User userToSave) async { void save(String idDafl, String passw) async {
final connection = await DatabaseConnexion.initConnexion(); final connection = await DatabaseConnexion.initConnexion();
connection.execute( connection.execute(
'insert into utilisateur (username, password) values (@username, @password)', 'insert into utilisateur (username, password) values (@username, @password)',
{ {'id': '', 'username': idDafl, 'password': passw}).whenComplete(() {
'id': '',
'username': userToSave.usernameDafl,
'password': userToSave.passwDafl
}).whenComplete(() {
connection.close(); connection.close();
}); });
} }

@ -1,15 +1,12 @@
import 'database_connexion.dart'; import 'database_connexion.dart';
import 'searcher.dart'; import 'searcher.dart';
class DatabaseSearcher extends Searcher { class DatabaseSearcher implements Searcher {
@override
Future<bool> searchUser(String? username, String? password) async {
return true;
}
// Search an user in the database by username // Search an user in the database by username
@override @override
Future<bool> searchByUsername(String? username) async { Future<bool> searchUser(String? username) async {
final connection = await DatabaseConnexion.initConnexion(); final connection = await DatabaseConnexion.initConnexion();
bool queryResult = await connection bool queryResult = await connection

@ -0,0 +1,37 @@
import 'package:dafl_project_flutter/services/database/database_loader.dart';
import 'package:dafl_project_flutter/services/database/database_user_modifier.dart';
import 'package:dafl_project_flutter/services/database/database_saver.dart';
import 'package:dafl_project_flutter/services/database/database_searcher.dart';
import 'package:dafl_project_flutter/services/database/loader.dart';
import 'package:dafl_project_flutter/services/database/user_modifier.dart';
import 'package:dafl_project_flutter/services/database/saver.dart';
import 'package:dafl_project_flutter/services/database/searcher.dart';
import '../../model/user.dart';
class DataBaseService {
static final Loader _loader = DatabaseLoader();
static final Searcher _searcher = DatabaseSearcher();
static final Saver _saver = DatabaseSaver();
static final UserModifier _userModifier = DatabaseUserModifier();
void save(String idDafl, String passw) {
_saver.save(idDafl, passw);
}
Future<User?> load(String username, String password) async {
return _loader.load(username, password);
}
Future<bool> searchUser(String username) async {
return await _searcher.searchUser(username);
}
changeUsername(String newName) {
//TODO : call database method
}
changeCurrentPassword(String newPass) {
//TODO : call database method
}
}

@ -0,0 +1,15 @@
import 'package:dafl_project_flutter/services/database/user_modifier.dart';
class DatabaseUserModifier implements UserModifier {
@override
changeCurrentPassword(String userToModify, String newPass) {
// TODO: implement changeCurrentPassword
throw UnimplementedError();
}
@override
changeUsername(String userToModify, String newName) {
// TODO: implement changeUsername
throw UnimplementedError();
}
}

@ -0,0 +1,6 @@
import 'dart:async';
import '../../model/user.dart';
abstract class Loader {
Future<User?> load(String username, String password);
}

@ -0,0 +1,3 @@
abstract class Saver {
void save(String idDafl, String passw);
}

@ -0,0 +1,3 @@
abstract class Searcher {
Future<bool> searchUser(String? username);
}

@ -0,0 +1,10 @@
import 'package:dafl_project_flutter/model/user.dart';
abstract class UserModifier{
changeUsername(String userToModify, String newName);
changeCurrentPassword(String userToModify, String newPass);
}

@ -0,0 +1,17 @@
import 'package:flutter/cupertino.dart';
import '../exceptions/http_exception.dart';
import 'package:http/http.dart' as http;
abstract class HttpResponseVerification {
@protected
late http.Response response;
@protected
setResponse(var value) {
if (value.statusCode >= 300) {
throw HttpException(value);
}
response = value;
}
}

@ -0,0 +1,50 @@
import 'package:dafl_project_flutter/model/spot.dart';
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import '../../main.dart';
class Location {
static Future<List<Spot>> sendCurrentLocation() async {
Uri uri = Uri.parse(
"https://codefirst.iut.uca.fr/containers/php_script-dorianhodin/insertAndMakeListUser.php");
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.deniedForever) {
//TODO : handle this case
}
}
String actualUser = MyApp.controller.getIdDafl();
String actualSong = MyApp.controller.getCurrentMusic().id;
Position current = await Geolocator.getCurrentPosition();
http.Response response = await http.post(uri, body: {
"id": actualUser,
"latitude": current.latitude.toString(),
"longitude": current.longitude.toString(),
"idMusic": actualSong,
});
var data = jsonDecode(response.body);
Map<String, String> spotsData = {};
List<Spot> spots = [];
if (data == 2) {
return Future.error("Failed to connect, connection timeout");
} else if (data == 3) {
return Future.error("POST method failed");
} else {
data.forEach((s) => spotsData.putIfAbsent(s['user'], () => s['music']));
}
spotsData.forEach((key, value) async {
spots.add(Spot(key, await MyApp.controller.getCompleteMusic(value)));
});
return spots;
}
}

@ -1,3 +1,4 @@
import 'package:dafl_project_flutter/main.dart';
import 'package:page_transition/page_transition.dart'; import 'package:page_transition/page_transition.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../sign_in/p_sign_in.dart'; import '../sign_in/p_sign_in.dart';

@ -12,25 +12,21 @@ class ConversationPage extends StatefulWidget {
} }
class _ConversationPageState extends State<ConversationPage> { class _ConversationPageState extends State<ConversationPage> {
User receiver = User("test1", '1234'); String destinataire = 'test';
List<Widget> messages = []; List<Widget> messages = [];
bool isNull = true; bool isNull = true;
final messageTextField = TextEditingController(); final messageTextField = TextEditingController();
void sendMessage(String content, String idSender, String idReceiver) { void sendMessage(String content) {
Message messageToSend =
Message(idSender: idSender, idReceiver: idReceiver, content: content);
MyApp.controller.sendMessage(messageToSend, idSender, idReceiver);
setState(() { setState(() {
messages.add(messageWidget(messageToSend)); messages.add(messageWidget(
Message(MyApp.controller.getIdDafl().toString(), content)));
}); });
} }
Widget messageWidget(Message message) { Widget messageWidget(Message message) {
if (message.idSender != MyApp.controller.currentUser.usernameDafl) { if (message.senderId != MyApp.controller.getIdDafl().toString()) {
return Align( return Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Container( child: Container(
@ -173,30 +169,14 @@ class _ConversationPageState extends State<ConversationPage> {
color: const Color(0xFF141414), color: const Color(0xFF141414),
height: height * 0.92, height: height * 0.92,
width: double.infinity, width: double.infinity,
child: Flexible( child: ListView.builder(
child: StreamBuilder<List<Message>>(
stream: MyApp.controller.getMessage(
MyApp.controller.currentUser.usernameDafl,
receiver.usernameDafl),
builder: (BuildContext context,
AsyncSnapshot<List<Message>> snapshot) {
if (snapshot.hasData) {
List<Message> listMessage =
snapshot.data ?? List.from([]);
return ListView.builder(
padding: EdgeInsets.all(10.0),
itemBuilder: (context, index) =>
messageWidget(listMessage[index]),
itemCount: listMessage.length,
reverse: true,
controller: listScrollController, controller: listScrollController,
); physics: const BouncingScrollPhysics(),
} else { itemCount: messages.length,
return Center(child: Container()); itemBuilder: (context, index) {
} return messages[index];
}, })),
), ),
))),
bottomSheet: BottomAppBar( bottomSheet: BottomAppBar(
color: const Color(0xFF141414), color: const Color(0xFF141414),
child: Row( child: Row(
@ -238,10 +218,7 @@ class _ConversationPageState extends State<ConversationPage> {
onTap: isNull onTap: isNull
? null ? null
: () { : () {
sendMessage( sendMessage(messageTextField.text);
messageTextField.text,
MyApp.controller.currentUser.usernameDafl,
receiver.usernameDafl);
if (listScrollController.hasClients) { if (listScrollController.hasClients) {
final position = final position =
listScrollController.position.maxScrollExtent; listScrollController.position.maxScrollExtent;
@ -397,8 +374,11 @@ class _ConversationPageState extends State<ConversationPage> {
height: 70, height: 70,
child: ElevatedButton( child: ElevatedButton(
onPressed: () { onPressed: () {
MyApp.controller.sendEmail(MyApp.controller.currentUser, MyApp.controller.sendEmail(
receiver, currentValue, messageTextField.text); MyApp.controller.getIdDafl().toString(),
destinataire,
currentValue,
messageTextField.text);
Navigator.pop(context); Navigator.pop(context);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(

@ -1,6 +1,6 @@
import 'package:dafl_project_flutter/main.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../presentation/custom_icons_icons.dart'; import '../../../main.dart';
import '../../presentation/custom_icons_icons.dart';
import './w_settings.dart'; import './w_settings.dart';
import './w_spot.dart'; import './w_spot.dart';
import './w_discovery.dart'; import './w_discovery.dart';
@ -8,8 +8,6 @@ import './w_profile.dart';
import './w_messages.dart'; import './w_messages.dart';
import 'w_top.dart'; import 'w_top.dart';
class MainPage extends StatefulWidget { class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key); const MainPage({Key? key}) : super(key: key);
@ -30,9 +28,14 @@ class _MainPageState extends State<MainPage> {
const SettingsWidget(), const SettingsWidget(),
]; ];
@override
void initState() {
MyApp.controller.beginRoutine();
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MyApp.controller.currentUser.getListSpots();
double height = MediaQuery.of(context).size.height; double height = MediaQuery.of(context).size.height;
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,

@ -1,5 +1,6 @@
import 'dart:collection';
import 'package:dafl_project_flutter/main.dart'; import 'package:dafl_project_flutter/main.dart';
import 'package:fluttericon/font_awesome5_icons.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'dart:developer' as dev; import 'dart:developer' as dev;
@ -30,7 +31,7 @@ class _DiscoveryWidgetState extends State<DiscoveryWidget> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( const Text(
'Playlist découverte', 'Playlist découverte',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
@ -39,17 +40,17 @@ class _DiscoveryWidgetState extends State<DiscoveryWidget> {
), ),
OutlinedButton( OutlinedButton(
onPressed: () { onPressed: () {
MyApp.controller.currentUser.sortChoise = MyApp.controller
!MyApp.controller.currentUser.sortChoise; .setChoice(!MyApp.controller.getChoice());
rebuildAllChildren(context); rebuildAllChildren(context);
setState(() {}); setState(() {});
}, },
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
foregroundColor: Colors.grey,
shadowColor: Colors.black, shadowColor: Colors.black,
shape: CircleBorder(), shape: const CircleBorder(),
padding: EdgeInsets.all(24), padding: const EdgeInsets.all(24)),
primary: Colors.grey), child: MyApp.controller.getChoice()
child: MyApp.controller.currentUser.sortChoise
? Image.asset( ? Image.asset(
'assets/images/date_sort_icon.png', 'assets/images/date_sort_icon.png',
height: 25, height: 25,
@ -70,7 +71,7 @@ class _DiscoveryWidgetState extends State<DiscoveryWidget> {
), ),
), ),
Expanded( Expanded(
child: MyApp.controller.currentUser.discovery.isEmpty child: MyApp.controller.getDiscoveries().isEmpty
? Center( ? Center(
child: Image.asset( child: Image.asset(
'assets/images/EmptyDiscovery-Hint.png', 'assets/images/EmptyDiscovery-Hint.png',
@ -118,16 +119,23 @@ class _DiscoveryListState extends State<DiscoveryList> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
List<Music> listDiscovery = MyApp.controller.currentUser.discovery; late LinkedHashMap<Music, DateTime> listDiscoveries;
if (MyApp.controller.currentUser.sortChoise) { if (MyApp.controller.getChoice()) {
listDiscovery.sort((a, b) { //TODO : implement sort by date
return a.date.compareTo(b.date); listDiscoveries = LinkedHashMap();
});
} else { } else {
listDiscovery.sort((a, b) { //TODO : implement sort by name
return a.name.compareTo(b.name); /* var sortedKeys = MyApp.controller
}); .getDiscoveries()
.values
.toList(growable: false)
..sort((v1, v2) => v1.compareTo(v2));
listDiscoveries = LinkedHashMap.fromIterable(sortedKeys,
key: (k) => k, value: (k) => sortedKeys[k]); */
listDiscoveries = LinkedHashMap();
} }
//TODO : remove next line
listDiscoveries = MyApp.controller.getDiscoveries();
return RefreshIndicator( return RefreshIndicator(
onRefresh: () async { onRefresh: () async {
refreshList(); refreshList();
@ -135,25 +143,29 @@ class _DiscoveryListState extends State<DiscoveryList> {
}, },
key: refreshKey, key: refreshKey,
child: ListView.builder( child: ListView.builder(
itemCount: listDiscovery.length, itemCount: listDiscoveries.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
int itemCount = listDiscovery.length; int itemCount = listDiscoveries.length;
int reversedIndex = itemCount - 1 - index; int reversedIndex = itemCount - 1 - index;
return Dismissible( return Dismissible(
movementDuration: Duration(milliseconds: 400), movementDuration: const Duration(milliseconds: 400),
key: Key(listDiscovery[index].name), key: Key(listDiscoveries.keys.toList()[index].name),
confirmDismiss: (direction) async { confirmDismiss: (direction) async {
if (direction == DismissDirection.endToStart) { if (direction == DismissDirection.endToStart) {
print(listDiscovery[reversedIndex].id); dev.log(listDiscoveries.keys.toList()[reversedIndex].id);
print(listDiscovery[reversedIndex].name); dev.log(
MyApp.controller.currentUser.discovery listDiscoveries.keys.toList()[reversedIndex].name);
.remove(listDiscovery[reversedIndex]); MyApp.controller.removeFromPlaylist(
listDiscoveries.keys.toList()[reversedIndex].id);
listDiscoveries = MyApp.controller.getDiscoveries();
return true; return true;
} }
if (direction == DismissDirection.startToEnd) { if (direction == DismissDirection.startToEnd) {
print(listDiscovery[reversedIndex].name); dev.log(
print('play'); listDiscoveries.keys.toList()[reversedIndex].name);
MyApp.api.playTrack(listDiscovery[reversedIndex].id); dev.log('play');
MyApp.controller.playTrack(
listDiscoveries.keys.toList()[reversedIndex].id);
setState(() {}); setState(() {});
} }
return false; return false;
@ -191,8 +203,11 @@ class _DiscoveryListState extends State<DiscoveryList> {
child: FadeInImage.assetNetwork( child: FadeInImage.assetNetwork(
placeholder: placeholder:
"assets/images/loadingPlaceholder.gif", "assets/images/loadingPlaceholder.gif",
image: MyApp.controller.currentUser image: MyApp.controller
.discovery[reversedIndex].linkCover), .getDiscoveries()
.keys
.toList()[reversedIndex]
.linkCover),
), ),
Container( Container(
margin: margin:
@ -204,8 +219,11 @@ class _DiscoveryListState extends State<DiscoveryList> {
MainAxisAlignment.center, MainAxisAlignment.center,
children: [ children: [
Text( Text(
MyApp.controller.currentUser MyApp.controller
.discovery[reversedIndex].name, .getDiscoveries()
.keys
.toList()[reversedIndex]
.name,
style: TextStyle( style: TextStyle(
fontFamily: 'DMSans', fontFamily: 'DMSans',
color: color:
@ -214,10 +232,10 @@ class _DiscoveryListState extends State<DiscoveryList> {
fontWeight: FontWeight.w800), fontWeight: FontWeight.w800),
), ),
Text( Text(
MyApp MyApp.controller
.controller .getDiscoveries()
.currentUser .keys
.discovery[reversedIndex] .toList()[reversedIndex]
.artist, .artist,
style: TextStyle( style: TextStyle(
fontFamily: 'DMSans', fontFamily: 'DMSans',

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:page_transition/page_transition.dart'; import 'package:page_transition/page_transition.dart';
import 'p_conversation.dart'; import 'p_conversation.dart';
class MessagesWidget extends StatefulWidget { class MessagesWidget extends StatefulWidget {

@ -1,5 +1,4 @@
import '../../../main.dart'; import '../../../main.dart';
import '../../../model/music.dart';
import './w_settings.dart'; import './w_settings.dart';
import './w_spot.dart'; import './w_spot.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -27,15 +26,12 @@ class MainPageProfil extends StatefulWidget {
} }
class _MainPageProfilState extends State<MainPageProfil> { class _MainPageProfilState extends State<MainPageProfil> {
String? username = MyApp.controller.currentUser.usernameDafl; String username = MyApp.controller.getIdDafl().toString();
late Music currentmusic;
@override @override
initState() { initState() {
username = MyApp.controller.getIdDafl();
super.initState(); super.initState();
username = MyApp.controller.currentUser.usernameDafl;
MyApp.controller.currentUser.actualiseCurrentMusic();
currentmusic = MyApp.controller.currentUser.currentMusic;
} }
@override @override
@ -57,8 +53,7 @@ class _MainPageProfilState extends State<MainPageProfil> {
fontSize: 25, fontSize: 25,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Colors.white, color: Colors.white,
fontFamily: "DMSans")), fontFamily: "DMSans"))),
),
Container( Container(
margin: const EdgeInsets.fromLTRB(0, 10, 0, 10), margin: const EdgeInsets.fromLTRB(0, 10, 0, 10),
height: height * 0.14, height: height * 0.14,
@ -77,14 +72,14 @@ class _MainPageProfilState extends State<MainPageProfil> {
], ],
), ),
child: Center( child: Center(
child: Text(username![0], child: Text(username[0],
style: const TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 60, fontSize: 60,
fontWeight: FontWeight.w500), fontWeight: FontWeight.w500),
textAlign: TextAlign.center))), textAlign: TextAlign.center))),
Text( Text(
username!, username,
style: const TextStyle( style: const TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 17, fontSize: 17,
@ -160,7 +155,8 @@ class _MainPageProfilState extends State<MainPageProfil> {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => const DisplayInfoWidget())); builder: (context) =>
const DisplayInfoWidget()));
}, },
child: Row( child: Row(
children: [ children: [
@ -193,8 +189,7 @@ class _MainPageProfilState extends State<MainPageProfil> {
height: height * 0.27, height: height * 0.27,
width: double.infinity, width: double.infinity,
margin: const EdgeInsets.fromLTRB(30, 15, 30, 0), margin: const EdgeInsets.fromLTRB(30, 15, 30, 0),
child: Column( child: Column(children: [
children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
@ -221,11 +216,8 @@ class _MainPageProfilState extends State<MainPageProfil> {
width: 25, width: 25,
height: 25, height: 25,
child: riv.RiveAnimation.asset( child: riv.RiveAnimation.asset(
'assets/images/playing_animation.riv'), 'assets/images/playing_animation.riv')))
), ]),
),
],
),
Container( Container(
margin: const EdgeInsets.fromLTRB(0, 10, 0, 0), margin: const EdgeInsets.fromLTRB(0, 10, 0, 0),
height: height * 0.14, height: height * 0.14,
@ -238,76 +230,86 @@ class _MainPageProfilState extends State<MainPageProfil> {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Container( Container(
margin: const EdgeInsets.fromLTRB(15, 0, 0, 0), margin: const EdgeInsets.fromLTRB(
15, 0, 0, 0),
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(15), borderRadius:
BorderRadius.circular(15),
child: FadeInImage.assetNetwork( child: FadeInImage.assetNetwork(
height: 90, height: 90,
width: 90, width: 90,
placeholder: placeholder:
"assets/images/loadingPlaceholder.gif", "assets/images/loadingPlaceholder.gif",
image: currentmusic.linkCover))), image: MyApp.controller
.getCurrentMusic()
.linkCover))),
Container( Container(
margin: const EdgeInsets.fromLTRB(12, 20, 0, 0), margin: const EdgeInsets.fromLTRB(
12, 20, 0, 0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment:
crossAxisAlignment: CrossAxisAlignment.start, MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [ children: [
Text( Text(
currentmusic.name, MyApp.controller
.getCurrentMusic()
.name,
style: const TextStyle( style: const TextStyle(
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: Colors.white), color: Colors.white),
), ),
Text( Text(
currentmusic.artist, MyApp.controller
.getCurrentMusic()
.artist,
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Colors.grey), color: Colors.grey))
), ])),
],
),
)
],
),
),
],
),
),
const Spacer(), const Spacer(),
Container( Container(
height: 55, height: 55,
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0), borderRadius:
BorderRadius.circular(10.0),
color: Colors.transparent, color: Colors.transparent,
), ),
margin: const EdgeInsets.fromLTRB(30, 0, 30, 0), margin: const EdgeInsets.fromLTRB(
30, 0, 30, 0),
child: SizedBox( child: SizedBox(
height: 55, height: 55,
width: double.infinity, width: double.infinity,
child: ElevatedButton( child: ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: backgroundColor:
const Color(0xFFD9D9D9).withOpacity(0.08), const Color(0xFFD9D9D9)
.withOpacity(0.08),
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0), borderRadius:
BorderRadius.circular(
10.0),
), // background// foreground ), // background// foreground
), ),
onPressed: () { onPressed: () {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) => const SettingsWidget())) builder: (context) =>
.then((value) => setState(() { const SettingsWidget()))
username = .then(
MyApp.controller.currentUser.usernameDafl; (value) => setState(() {
username = MyApp
.controller
.getIdDafl()
.toString();
})); }));
}, },
child: Row( child: Row(children: [
children: [
const Icon( const Icon(
Icons.settings, Icons.settings,
color: Colors.white, color: Colors.white,
@ -321,22 +323,20 @@ class _MainPageProfilState extends State<MainPageProfil> {
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 17, fontSize: 17,
fontWeight: FontWeight.w400), fontWeight:
FontWeight.w400),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
const Spacer(), const Spacer(),
Icon( Icon(
Icons.arrow_forward_ios, Icons.arrow_forward_ios,
color: Colors.white.withOpacity(0.3), color: Colors.white
), .withOpacity(0.3),
], )
)), ])))),
), const Spacer()
), ]))
const Spacer(), ]))
], ])));
),
),
);
} }
} }

@ -11,9 +11,9 @@ class SettingsWidget extends StatefulWidget {
class _SettingsWidgetState extends State<SettingsWidget> { class _SettingsWidgetState extends State<SettingsWidget> {
final userNameTextField = final userNameTextField =
TextEditingController(text: MyApp.controller.currentUser.usernameDafl); TextEditingController(text: MyApp.controller.getIdDafl().toString());
final passwordTextField = final passwordTextField =
TextEditingController(text: MyApp.controller.currentUser.passwDafl); TextEditingController(text: MyApp.controller.getIdDafl().toString());
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -83,8 +83,8 @@ class _SettingsWidgetState extends State<SettingsWidget> {
const Spacer(), const Spacer(),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
MyApp.controller /*MyApp.controller
.changeCurrentUsername(userNameTextField.text); .changeCurrentUsername(userNameTextField.text);*/
notify(0, context, isError: false); notify(0, context, isError: false);
}, },
child: const Padding( child: const Padding(
@ -143,8 +143,8 @@ class _SettingsWidgetState extends State<SettingsWidget> {
const Spacer(), const Spacer(),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
MyApp.controller /*MyApp.controller
.changeCurrentPassword(passwordTextField.text); .changeCurrentPassword(passwordTextField.text);*/
notify(1, context, isError: false); notify(1, context, isError: false);
}, },
child: const Padding( child: const Padding(

@ -31,11 +31,9 @@ class _SpotsWidgetState extends State<SpotsWidget> {
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: NetworkImage( image: NetworkImage(MyApp.controller.getSpots().isEmpty
MyApp.controller.currentUser.spots.isEmpty
? "https://i.imgur.com/Uovh293.png" ? "https://i.imgur.com/Uovh293.png"
: MyApp.controller.currentUser.spots.last.music : MyApp.controller.getSpots().last.music.linkCover),
.linkCover),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
@ -50,7 +48,7 @@ class _SpotsWidgetState extends State<SpotsWidget> {
), ),
Align( Align(
alignment: FractionalOffset.bottomCenter, alignment: FractionalOffset.bottomCenter,
child: MyApp.controller.currentUser.spots.isEmpty child: MyApp.controller.getSpots().isEmpty
? Container() ? Container()
: OpenContainer( : OpenContainer(
closedColor: Colors.transparent, closedColor: Colors.transparent,
@ -61,9 +59,7 @@ class _SpotsWidgetState extends State<SpotsWidget> {
}, },
openBuilder: (context, closeWidget) { openBuilder: (context, closeWidget) {
return const DisplayInfoWidget(); return const DisplayInfoWidget();
}, })),
),
),
const Center( const Center(
child: SizedBox( child: SizedBox(
width: 300, width: 300,
@ -75,7 +71,7 @@ class _SpotsWidgetState extends State<SpotsWidget> {
Positioned( Positioned(
top: height * 0.68, top: height * 0.68,
width: width, width: width,
child: MyApp.controller.currentUser.spots.isEmpty child: MyApp.controller.getSpots().isEmpty
? Container() ? Container()
: Row( : Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@ -166,15 +162,47 @@ class _SpotsWidgetState extends State<SpotsWidget> {
)), )),
), ),
), ),
Padding( MyApp.controller.getSpots().isEmpty
? SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
MyApp.controller.getSpots().isEmpty
? Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
const Text(
'Quelques instants...',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w500,
fontSize: 25),
),
const Padding(
padding:
EdgeInsets.fromLTRB(0, 5, 0, 0)),
Text(
'Nous cherchons des profils a vous proposer.',
style: TextStyle(
color: Colors.grey.withOpacity(0.4),
fontSize: 15),
),
],
)
: Container(),
])),
)
: Padding(
padding: const EdgeInsets.fromLTRB(20, 60, 0, 0), padding: const EdgeInsets.fromLTRB(20, 60, 0, 0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
MyApp.controller.currentUser.spots.isEmpty MyApp.controller.getSpots().isEmpty
? '' ? ''
: MyApp.controller.currentUser.spots.last.music.name, : MyApp.controller.getSpots().last.music.name,
style: TextStyle( style: TextStyle(
fontFamily: 'DMSans', fontFamily: 'DMSans',
color: Colors.white.withOpacity(1), color: Colors.white.withOpacity(1),
@ -182,10 +210,9 @@ class _SpotsWidgetState extends State<SpotsWidget> {
fontWeight: FontWeight.w800), fontWeight: FontWeight.w800),
), ),
Text( Text(
MyApp.controller.currentUser.spots.isEmpty MyApp.controller.getSpots().isEmpty
? '' ? ''
: MyApp : MyApp.controller.getSpots().last.music.artist,
.controller.currentUser.spots.last.music.artist,
style: TextStyle( style: TextStyle(
fontFamily: 'DMSans', fontFamily: 'DMSans',
color: Colors.white.withOpacity(1), color: Colors.white.withOpacity(1),
@ -200,12 +227,12 @@ class _SpotsWidgetState extends State<SpotsWidget> {
right: 0, right: 0,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
MyApp.api.playTrack( MyApp.controller
MyApp.controller.currentUser.spots.last.music.id); .playTrack(MyApp.controller.getSpots().last.music.id);
}, },
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: !MyApp.controller.currentUser.spots.isEmpty child: MyApp.controller.getSpots().isEmpty
? Image.asset("assets/images/play_spotify_button.png") ? Image.asset("assets/images/play_spotify_button.png")
: Container(), : Container(),
), ),
@ -217,7 +244,7 @@ class _SpotsWidgetState extends State<SpotsWidget> {
Widget buildCards() { Widget buildCards() {
final provider = Provider.of<CardProvider>(context); final provider = Provider.of<CardProvider>(context);
final urlImages = provider.spotsList; final urlImages = MyApp.controller.getSpots();
return Stack( return Stack(
children: urlImages children: urlImages

@ -257,11 +257,9 @@ class _SignInPageState extends State<SignInPage> {
notify(2, context); notify(2, context);
} else if (password == "") { } else if (password == "") {
notify(4, context); notify(4, context);
} else { } else if (await MyApp.controller
await MyApp.controller .load(userNameTextField.text, passwordTextField.text)) {
.load(userNameTextField.text, passwordTextField.text); MyApp.controller.initUser();
if (MyApp.controller.currentUser.usernameDafl != "") {
Navigator.of(context).push( Navigator.of(context).push(
PageTransition( PageTransition(
type: PageTransitionType.fade, type: PageTransitionType.fade,
@ -273,4 +271,3 @@ class _SignInPageState extends State<SignInPage> {
} }
} }
} }
}

@ -1,8 +1,7 @@
import 'package:dafl_project_flutter/main.dart'; import 'package:dafl_project_flutter/main.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:page_transition/page_transition.dart'; import 'package:page_transition/page_transition.dart';
import '../../../api/in_app_browser.dart'; import '../../../services/api/in_app_browser.dart';
import '../../../model/user.dart';
import '../home/p_home.dart'; import '../home/p_home.dart';
import '../sign_in/p_sign_in.dart'; import '../sign_in/p_sign_in.dart';
@ -334,7 +333,7 @@ class _SignUpPageState extends State<SignUpPage> {
String username, String password, String confirmPassword) async { String username, String password, String confirmPassword) async {
if (username == "") { if (username == "") {
notify(2, context); notify(2, context);
} else if (!await MyApp.controller.searchByUsername(username)) { } else if (!await MyApp.controller.searchUser(username)) {
notify(0, context); notify(0, context);
} }
if (password == "" || confirmPassword == "") { if (password == "" || confirmPassword == "") {
@ -344,7 +343,7 @@ class _SignUpPageState extends State<SignUpPage> {
} else if (password != confirmPassword) { } else if (password != confirmPassword) {
notify(1, context); notify(1, context);
} else { } else {
MyApp.controller.save(User(username, password)); // create user in database
Navigator.of(context).push( Navigator.of(context).push(
PageTransition( PageTransition(

@ -1,13 +1,6 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_flutterfire_internals:
dependency: transitive
description:
name: _flutterfire_internals
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.9"
animations: animations:
dependency: "direct main" dependency: "direct main"
description: description:
@ -78,27 +71,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1" version: "1.1.1"
cloud_firestore:
dependency: "direct main"
description:
name: cloud_firestore
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.0"
cloud_firestore_platform_interface:
dependency: transitive
description:
name: cloud_firestore_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "5.9.0"
cloud_firestore_web:
dependency: transitive
description:
name: cloud_firestore_web
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@ -134,6 +106,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.5" version: "1.0.5"
fading_edge_scrollview:
dependency: transitive
description:
name: fading_edge_scrollview
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -155,48 +134,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.1.4" version: "6.1.4"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.5.2"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
url: "https://pub.dartlang.org"
source: hosted
version: "14.1.1"
firebase_messaging_platform_interface:
dependency: transitive
description:
name: firebase_messaging_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.7"
firebase_messaging_web:
dependency: transitive
description:
name: firebase_messaging_web
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.7"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -392,6 +329,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
marquee:
dependency: "direct main"
description:
name: marquee
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.3"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -553,6 +497,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.1" version: "0.9.1"
scroll_loop_auto_scroll:
dependency: "direct main"
description:
name: scroll_loop_auto_scroll
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.5"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -600,6 +551,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.12" version: "0.4.12"
text_scroll:
dependency: "direct main"
description:
name: text_scroll
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:

@ -29,9 +29,9 @@ dependencies:
home_indicator: ^2.0.2 home_indicator: ^2.0.2
geolocator: ^9.0.2 geolocator: ^9.0.2
flutter_styled_toast: ^2.1.3 flutter_styled_toast: ^2.1.3
firebase_core: ^2.3.0 marquee: ^2.2.3
firebase_messaging: ^14.1.1 text_scroll: ^0.1.1
cloud_firestore: ^4.1.0 scroll_loop_auto_scroll: ^0.0.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

@ -0,0 +1,56 @@
DROP TABLE IF EXISTS Musique;
DROP TABLE IF EXISTS Matchs;
DROP TABLE IF EXISTS LikeDafl;
DROP TABLE IF EXISTS UserDafl;
CREATE TABLE UserDafl(
idDafl INT PRIMARY KEY,
pseudo varchar(50) NOT NULL,
idSpotify varchar(150) NOT NULL,
profilPicture varchar(200) NOT NULL
);
CREATE TABLE Musique(
idUser INT REFERENCES UserDafl(idDafl),
idMusic INT,
title varchar(50) NOT NULL,
artist varchar(50) NOT NULL,
album varchar(50) NOT NULL,
category varchar(100),
PRIMARY KEY(idUser,idMusic)
);
CREATE TABLE Matchs(
idUserA INT REFERENCES UserDafl(idDafl),
idUserB INT REFERENCES UserDafl(idDafl),
dateMatch date NOT NULL,
PRIMARY KEY(idUserA,idUserB)
);
CREATE TABLE LikeDafl(
idUserWhoLike INT REFERENCES UserDafl(idDafl),
idUserWhoGetLike INT REFERENCES UserDafl(idDafl),
dateLike date NOT NULL,
PRIMARY KEY(idUserWhoLike,idUserWhoGetLike)
);
CREATE TABLE MessageDafl(
senderID INT NOT NULL REFERENCES UserDafl(idDafl) ,
idMessage INT PRIMARY KEY,
content varchar(500),
dateMess date NOT NULL
);
CREATE TABLE ConversationDafl(
idUserA INT NOT NULL REFERENCES UserDafl(idDafl),
idUserB INT NOT NULL REFERENCES UserDafl(idDafl),
idConversation INT PRIMARY KEY,
waiting BOOLEAN NOT NULL CHECK (waiting=1 OR waiting=0)
);
CREATE TABLE MessToConv(
idConv INT REFERENCES Conversation(idConversation),
idMsg INT REFERENCES Message(idMessage),
PRIMARY KEY (idConv,idMsg)
);

@ -0,0 +1,4 @@
FROM php:8.1-apache
RUN apt-get update && apt-get upgrade -y
RUN docker-php-ext-install mysqli
COPY ./script /var/www/html

@ -0,0 +1,20 @@
<?php
function connection(): bool|int|mysqli
{
$username = $_ENV["USER"]; //Get the username
$host = $_ENV["HOST"]; //Get the url of the database
$password = $_ENV["PASSWORD"]; //Get the password for the user selected
$db_name = $_ENV["DATABASE"]; //Get the name of the database
try { //Try to connect to the database
return mysqli_connect($host, $username, $password,$db_name); //Connecting to database
}catch (mysqli_sql_exception) { //If the connection failed
return -1; //Send a return code as -1, so insertAndMakeListUser.php can know if the connection is successful
}
}

@ -0,0 +1,96 @@
<?php
function metersBetweenTwoUser($lat1, $lng1, $lat2, $lng2): float
{
$earth_radius = 6378137; // Radius of the Earth in meters :
$rlo1 = deg2rad($lng1); //Transform the coordinate longitude1 from degree to radian
$rla1 = deg2rad($lat1); //Transform the coordinate latitude1 from degree to radian
$rlo2 = deg2rad($lng2); //Transform the coordinate longitude2 from degree to radian
$rla2 = deg2rad($lat2); //Transform the coordinate latitude2 from degree to radian
$dlo = ($rlo2 - $rlo1) / 2; //Stock in $dlo the result of the calcul : ($rlo2 - $rlo1) / 2
$dla = ($rla2 - $rla1) / 2; //Stock in $dla the result of the calcul : ($rla2 - $rla1) / 2
$a = (sin($dla) * sin($dla)) + cos($rla1) * cos($rla2) * (sin($dlo) * sin($dlo)); //Do some operations to return the distance in meters
$d = 2 * atan2(sqrt($a), sqrt(1 - $a)); //Do some operations to return the distance in meters
return round($earth_radius * $d); // Return the distance in meters between 2 GPS points
}
function insertUserAndReturnList(): array|int
{
include "config.php";
$res = connection();
if (strcmp(gettype($res),"integer")==0) {
return 2;
}
$query = "CREATE TABLE IF NOT EXISTS gps (
id varchar(30) PRIMARY KEY,
latitude double NOT NULL,
longitude double NOT NULL,
idMusic varchar(100) NOT NULL,
dateLog date NOT NULL
);";
mysqli_query($res, $query);
if (!empty($_POST)) { //Check if the method POST return something
$id = $_POST['id']; //Get the result of POST method
$latitude = $_POST['latitude']; //Get the result of POST method
$longitude = $_POST['longitude']; //Get the result of POST method
$idMusic = $_POST['idMusic']; //Get the result of POST method
$latitude = doubleval($latitude); //Convert a string to a double
$longitude = doubleval($longitude); //Convert a string to a double
$query = "DELETE FROM gps WHERE (TIMESTAMPDIFF(MINUTE,dateLog,NOW())>10);";
mysqli_query($res, $query);
$query = "SELECT id FROM gps WHERE id = '$id' ";
$results = mysqli_query($res, $query); //Execute the SQL command
if (empty($results->fetch_row()[0])){
$query = "INSERT INTO gps(id,latitude,longitude,idMusic,dateLog) VALUES('$id','$latitude','$longitude','$idMusic',NOW());"; //Insert into the database the new data and new information about this user
}else{
$query = "UPDATE gps SET latitude='$latitude', longitude='$longitude', idMusic='$idMusic', dateLog=NOW() WHERE id='$id'"; //Delete the actual line and replace this line with the next lines
}
mysqli_query($res, $query);
$query = "SELECT * FROM gps WHERE id != '$id'"; //Browse all the database
$results = mysqli_query($res, $query); //Execute the SQL command
$listUser = []; //Set the listUser to an empty list
while ($row = $results->fetch_row()) { //For all the row in the database
$lat2 = $row[1]; //Set $lat2 to the latitude of the user who is in the actual row
$lng2 = $row[2]; //Set $lng2 to the latitude of the user who is in the actual row
$userID = $row[0]; //Set $userID to the username of the user who is in the actual row
$idMusic = $row[3]; //Set $idMusic to the id of the actual song of the user who is in the actual row
$dist = metersBetweenTwoUser($latitude, $longitude, $lat2, $lng2); //With the function meters, determinate the distance between the current user and the user who is in the actual row
if ($dist <= 100) { //If the user in the actual row is less than 100 meters away of the current user
$listUser[] = ['user' => $userID, 'music' => $idMusic]; //Add the username and the ID of the song that user who is in the actual row is listening
}
}
return $listUser; //Return an array
} else { //If the method POST return nothing
return 3; //Return a code error
}
}
print(json_encode(insertUserAndReturnList()));
Loading…
Cancel
Save