Compare commits

..

6 Commits

Author SHA1 Message Date
Audric SABATIER bd1e2efa2e ADD : Discplay messages in the views
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 27e970a3b9 ADD : controller call Firestore database accesser
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 77de0b8384 ADD : methods to get messages from Firestore
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 974b046f72 ADD : send message to firestore database with an unique chatID
continuous-integration/drone/push Build is passing Details
2 years ago
Audric SABATIER 308bfd95cd ADD : modify class message to have hashMap
continuous-integration/drone/push Build is failing Details
2 years ago
Audric SABATIER 32dd6c986c ADD : Firebase to project
continuous-integration/drone/push Build is passing Details
2 years ago

@ -2,7 +2,6 @@ kind: pipeline
type: docker type: docker
name: DAFLPipeline name: DAFLPipeline
trigger: trigger:
event: event:
- push - push
@ -53,56 +52,3 @@ 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,6 +98,7 @@
<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>

@ -1,62 +0,0 @@
<?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>

@ -1,10 +0,0 @@
<?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>

@ -1,12 +0,0 @@
<?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>

@ -1,13 +0,0 @@
<?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>

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

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

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

@ -1,417 +0,0 @@
<?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,801 +2,689 @@
<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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/animations-2.0.7/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/archive-3.3.2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/args-2.3.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/async-2.9.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.2.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.3.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/checked_yaml-2.0.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cli_util-0.3.5/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.16.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/convert-3.1.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/crypto-3.0.2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/csslib-0.17.2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-1.0.5/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.3.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/ffi-2.0.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/file-6.1.4/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/packages/flutter/lib" /> <option value="$USER_HOME$/flutter/packages/flutter/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="flutter_inappwebview"> <entry key="flutter_inappwebview">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_inappwebview-5.7.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_launcher_icons-0.10.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_lints-2.0.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/packages/flutter_localizations/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_native_splash-2.2.11/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/flutter_styled_toast-2.1.3/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/packages/flutter_test/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/packages/flutter_web_plugins/lib" /> <option value="$USER_HOME$/flutter/packages/flutter_web_plugins/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="fluttericon"> <entry key="fluttericon">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fluttericon-2.0.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/fluttertoast-8.1.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/font_awesome_flutter-10.2.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator-9.0.2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_android-4.1.4/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_apple-2.2.3/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_platform_interface-4.0.7/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_web-2.1.6/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/geolocator_windows-0.1.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/graphs-2.1.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/home_indicator-2.0.2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/html-0.15.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/http-0.13.5/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/http_parser-4.0.2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/image-3.2.2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/intl-0.17.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/js-0.6.4/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/json_annotation-4.7.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/lints-2.0.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/logging-1.1.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.12/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/material_color_utilities-0.1.5/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.8.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/mime-1.0.2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/nested-1.0.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/page_transition-2.0.9/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.11/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.21/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_platform_interface-2.0.5/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/petitparser-5.0.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/platform-3.1.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-2.1.3/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/postgresql2-1.0.3/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/process-4.2.4/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/provider-6.0.4/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/random_string-2.3.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/rikulo_commons-5.2.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/rive-0.9.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/bin/cache/pkg/sky_engine/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/universal_io-2.0.4/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/vibration-1.7.6/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/win32-3.0.1/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/xdg_directories-0.2.0+2/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/xml-6.1.0/lib" /> <option value="$USER_HOME$/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="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/lib" /> <option value="$USER_HOME$/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://$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/animations-2.0.7/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/archive-3.3.2/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/args-2.3.1/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/async-2.9.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/boolean_selector-2.1.0/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/characters-1.2.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/charcode-1.3.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/checked_yaml-2.0.1/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/cli_util-0.3.5/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/clock-1.1.1/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/collection-1.16.0/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/convert-3.1.1/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/crypto-3.0.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/csslib-0.17.2/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/cupertino_icons-1.0.5/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/fake_async-1.3.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/ffi-2.0.1/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/file-6.1.4/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_inappwebview-5.7.1/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_launcher_icons-0.10.0/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_lints-2.0.1/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_native_splash-2.2.11/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/flutter_styled_toast-2.1.3/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/fluttericon-2.0.0/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/fluttertoast-8.1.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/font_awesome_flutter-10.2.1/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-9.0.2/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_android-4.1.4/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_apple-2.2.3/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_platform_interface-4.0.7/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_web-2.1.6/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/geolocator_windows-0.1.1/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/graphs-2.1.0/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/home_indicator-2.0.2/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/html-0.15.1/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-0.13.5/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/http_parser-4.0.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/image-3.2.2/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/intl-0.17.0/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/js-0.6.4/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/json_annotation-4.7.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/lints-2.0.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/logging-1.1.0/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/matcher-0.12.12/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/material_color_utilities-0.1.5/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/meta-1.8.0/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/mime-1.0.2/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/nested-1.0.0/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/page_transition-2.0.9/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-1.8.2/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-2.0.11/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_android-2.0.21/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_ios-2.0.11/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_linux-2.1.7/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_macos-2.0.6/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_platform_interface-2.0.5/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/path_provider_windows-2.1.3/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/petitparser-5.0.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/platform-3.1.0/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/plugin_platform_interface-2.1.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/postgresql2-1.0.3/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/process-4.2.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/provider-6.0.4/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/random_string-2.3.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/rikulo_commons-5.2.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/rive-0.9.1/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/source_span-1.9.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/stack_trace-1.10.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/stream_channel-2.1.0/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/string_scanner-1.1.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/term_glyph-1.2.1/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/test_api-0.4.12/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/typed_data-1.3.1/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/universal_io-2.0.4/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/vector_math-2.1.2/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/vibration-1.7.6/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/win32-3.0.1/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/xdg_directories-0.2.0+2/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/xml-6.1.0/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/.pub-cache/hosted/pub.dartlang.org/yaml-3.1.1/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/bin/cache/pkg/sky_engine/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/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_localizations/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_test/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.4.12/lib" /> <root url="file://$USER_HOME$/flutter/packages/flutter_web_plugins/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://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/async" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/async" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/cli" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/cli" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/collection" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/collection" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/convert" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/convert" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/core" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/core" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/developer" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/developer" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/ffi" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/ffi" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/html" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/html" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/indexed_db" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/indexed_db" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/io" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/io" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/isolate" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/isolate" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/js" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/js" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/js_util" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/js_util" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/math" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/math" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/mirrors" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/mirrors" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/svg" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/svg" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/typed_data" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/typed_data" />
<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_audio" />
<root url="file://$PROJECT_DIR$/../flutter/bin/cache/dart-sdk/lib/web_gl" /> <root url="file://$USER_HOME$/flutter/bin/cache/dart-sdk/lib/web_gl" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES /> <SOURCES />

@ -1,6 +0,0 @@
<?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/dafl_music.iml" filepath="$PROJECT_DIR$/.idea/dafl_music.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/Daflv4.iml" filepath="$PROJECT_DIR$/.idea/Daflv4.iml" />
</modules> </modules>
</component> </component>
</project> </project>

@ -1,6 +0,0 @@
<?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>

@ -1,7 +0,0 @@
<?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.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

@ -2,7 +2,7 @@
<img src="https://codefirst.iut.uca.fr/git/DAFLDev/DAFLMusic/raw/branch/master/Documentation/Images/Banner_DAFL.png" /> <img src="https://codefirst.iut.uca.fr/git/DAFLDev/DAFLMusic/raw/branch/master/Documentation/Images/Banner_DAFL.png" />
</p> </p>
[![Build Status](https://codefirst.iut.uca.fr/api/badges/DAFLDev/DAFLMusic/status.svg)](https://codefirst.iut.uca.fr/DAFLDev/DAFLMusic) [![Build Status](https://codefirst.iut.uca.fr/api/badges/DAFLDev/DAFLMusic/status.svg)](https://codefirst.iut.uca.fr/DAFLDev/DAFLMusic)
[![Bugs](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=DAFLMusic&metric=bugs&token=d36308dfacfc3cb26e1944ec2441cd9563e0c912)](https://codefirst.iut.uca.fr/sonar/dashboard?id=DAFLMusic) [![Bugs](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=DAFLMusic&metric=bugs&token=d36308dfacfc3cb26e1944ec2441cd9563e0c912)](https://codefirst.iut.uca.fr/sonar/dashboard?id=DAFLMusic)
[![Code Smells](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=DAFLMusic&metric=code_smells&token=d36308dfacfc3cb26e1944ec2441cd9563e0c912)](https://codefirst.iut.uca.fr/sonar/dashboard?id=DAFLMusic) [![Code Smells](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=DAFLMusic&metric=code_smells&token=d36308dfacfc3cb26e1944ec2441cd9563e0c912)](https://codefirst.iut.uca.fr/sonar/dashboard?id=DAFLMusic)
[![Technical Debt](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=DAFLMusic&metric=sqale_index&token=d36308dfacfc3cb26e1944ec2441cd9563e0c912)](https://codefirst.iut.uca.fr/sonar/dashboard?id=DAFLMusic) [![Technical Debt](https://codefirst.iut.uca.fr/sonar/api/project_badges/measure?project=DAFLMusic&metric=sqale_index&token=d36308dfacfc3cb26e1944ec2441cd9563e0c912)](https://codefirst.iut.uca.fr/sonar/dashboard?id=DAFLMusic)
@ -55,7 +55,4 @@ tous les utilisateurs.
* Si l'utilisateur est consentant, après un "Match", il peut accepter de * Si l'utilisateur est consentant, après un "Match", il peut accepter de
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>.

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

@ -1,29 +0,0 @@
<?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>

@ -1,8 +0,0 @@
<?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>

@ -1,28 +0,0 @@
<?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>

@ -1,6 +0,0 @@
<?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>

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

@ -1,61 +0,0 @@
-- 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 */;

@ -1,36 +0,0 @@
<?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();
}
}
?>

@ -1,46 +0,0 @@
<?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']);
}
}

@ -1,35 +0,0 @@
<?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);
}
}

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

@ -1,26 +0,0 @@
<?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;
}
}

@ -1,24 +0,0 @@
<?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)));
}
}

@ -1,82 +0,0 @@
<?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;
});
*/

@ -1,12 +0,0 @@
{
"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

@ -1,15 +0,0 @@
<?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 ./sources/ /usr/local/apache2/htdocs/ COPY ./public-html/ /usr/local/apache2/htdocs/

@ -0,0 +1,39 @@
{
"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"
}

@ -0,0 +1,34 @@
<?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>

@ -0,0 +1,7 @@
{
"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"
}

@ -0,0 +1,300 @@
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,6 +1,8 @@
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 '../../main.dart'; import '../exceptions/api_exception.dart';
import '../main.dart';
class MyInAppBrowser extends InAppBrowser { class MyInAppBrowser extends InAppBrowser {
var options = InAppBrowserClassOptions( var options = InAppBrowserClassOptions(
@ -12,8 +14,7 @@ class MyInAppBrowser extends InAppBrowser {
MyInAppBrowser() { MyInAppBrowser() {
_debugBrowser(); _debugBrowser();
openUrlRequest( openUrlRequest(
urlRequest: URLRequest(url: MyApp.controller.getApiUrlAuthorize()), urlRequest: URLRequest(url: MyApp.api.urlAuthorize), options: options);
options: options);
} }
_debugBrowser() async { _debugBrowser() async {
@ -25,10 +26,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.controller.getApiRedirectUrl()) { if (url!.origin + url.path == MyApp.api.redirectUri) {
try { try {
await MyApp.controller.apiAuthorization(url); await MyApp.api.requestUserAuthorization(url);
} catch (e) { } on ApiException {
notify(5, MyApp.controller.navigatorKey); notify(5, MyApp.controller.navigatorKey);
isError = true; isError = true;
} finally { } finally {

@ -1,135 +1,67 @@
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 '../model/music.dart'; import '../persistence/database_loader.dart';
import '../model/spot.dart'; import '../persistence/database_saver.dart';
import '../persistence/database_searcher.dart';
import '../persistence/loader.dart';
import '../persistence/saver.dart';
import '../model/user.dart'; import '../model/user.dart';
import '../services/api/api_spotify.dart'; import '../persistence/searcher.dart';
import '../services/database/database_service.dart';
import '../services/position/location.dart';
import 'live_datas.dart';
class Controller { class Controller {
final ApiSpotify _api = ApiSpotify(); static Saver saver = DatabaseSaver();
late User _currentUser; static Loader loader = DatabaseLoader();
final DataBaseService _dataBaseService = DataBaseService(); static final Searcher _searcher = DatabaseSearcher();
final LiveData _data = LiveData(); final MessageDatabaseServices _messageAccess = MessageDatabaseServices();
final NotificationService _notificationService = NotificationService();
late BuildContext navigatorKey; late BuildContext navigatorKey;
initUser() async { late User currentUser;
await setCurrentMusic();
await setDiscoveries();
}
beginRoutine() async {
await setSpots();
Timer.periodic(const Duration(seconds: 10), (Timer t) => setSpots());
}
//
// Methods to manage data
//
// Data that can change
bool getChoice() => _data.discoveriesSortChoice;
setChoice(bool c) {
_data.discoveriesSortChoice = c;
}
Music getCurrentMusic() => _data.userCurrentMusic;
setCurrentMusic() async {
_data.userCurrentMusic =
await getCompleteMusic(await _api.requests.getCurrentlyPlayingTrack());
}
List<Spot> getSpots() => _data.spots;
setSpots() async {
_data.spots = await Location.sendCurrentLocation();
}
LinkedHashMap<Music, DateTime> getDiscoveries() => _data.discoveries;
setDiscoveries() async { Controller() {
LinkedHashMap<String, DateTime> tmpData = currentUser = User('', ''); //TODO : remove this line
await _api.requests.getPlaylistTracks(); NotificationService.initialize();
LinkedHashMap<Music, DateTime> tmpCast = LinkedHashMap();
tmpData.forEach((key, value) async {
tmpCast[(await getCompleteMusic(key))] = value;
});
_data.discoveries = tmpCast;
} }
//Data that can not change void sendMessage(Message message, String idSender, String idReceiver) {
_messageAccess.sendMessage(message, idSender, idReceiver);
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) { Stream<List<Message>> getMessage(String idSender, String idReceiver) {
_api.requests.removeFromPlaylist(id); return _messageAccess.getMessage(idSender, idReceiver);
} }
addToPlaylist(String id) { void save(User userToSave) {
_api.requests.addToPlaylist(id); saver.save(userToSave);
} }
playTrack(String id) { load(String username, String password) async {
_api.requests.playTrack(id); _changeCurrentUser(await loader.load(username, password));
} }
// DATABASE _changeCurrentUser(User user) {
void save(String idDafl, String passw) { currentUser = user;
_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;
} }
changeUsername(String newName) { changeCurrentUsername(String newName) {
_dataBaseService.changeUsername(newName); currentUser.usernameDafl = newName;
} }
changeCurrentPassword(String newPass) { changeCurrentPassword(String newPass) {
_dataBaseService.changeCurrentPassword(newPass); currentUser.passwDafl = newPass;
} }
Future<bool> searchUser(String username) async { Future<bool> searchByUsername(String username) async {
return await _dataBaseService.searchUser(username); return await _searcher.searchByUsername(username);
} }
Future sendEmail(String reporterId, String reportedId, String reason, Future sendEmail(
String message) async { User reporter, User reported, String reason, 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';
@ -145,8 +77,8 @@ class Controller {
'template_id': templateId, 'template_id': templateId,
'user_id': userId, 'user_id': userId,
'template_params': { 'template_params': {
'from_name': reporterId, 'from_name': reporter.usernameDafl,
'to_name': reportedId, 'to_name': reported.usernameDafl,
'reason': reason, 'reason': reason,
'message': message, 'message': message,
}, },

@ -1,11 +0,0 @@
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;
}

@ -0,0 +1,13 @@
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.');
}
}
}

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

@ -1,12 +0,0 @@
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()}');
}
}
}

@ -0,0 +1,69 @@
// 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',
);
}

@ -0,0 +1,58 @@
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);
}
}

@ -0,0 +1,21 @@
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,23 +1,40 @@
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});
@ -29,7 +46,7 @@ class MyApp extends StatelessWidget {
SystemUiMode.manual, SystemUiMode.manual,
overlays: [SystemUiOverlay.top], overlays: [SystemUiOverlay.top],
); );
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( SystemChrome.setSystemUIOverlayStyle(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)
)); ));
@ -46,11 +63,14 @@ 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;
@ -154,7 +174,7 @@ class CardProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void discovery(BuildContext context) async { void discovery(BuildContext context) {
dev.log("discovery"); dev.log("discovery");
_angle = 0; _angle = 0;
_position -= Offset(0, -_screenSize.height); _position -= Offset(0, -_screenSize.height);
@ -175,8 +195,8 @@ class CardProvider extends ChangeNotifier {
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
MyApp.controller.getDiscoveries().containsKey( MyApp.controller.currentUser.discovery.contains(
MyApp.controller.getSpots().last.music) MyApp.controller.currentUser.spots.last.music)
? const Icon( ? const Icon(
Icons.info_rounded, Icons.info_rounded,
size: 40, size: 40,
@ -190,8 +210,8 @@ class CardProvider extends ChangeNotifier {
const SizedBox( const SizedBox(
width: 10, width: 10,
), ),
MyApp.controller.getDiscoveries().containsKey( MyApp.controller.currentUser.discovery.contains(
MyApp.controller.getSpots().last.music) MyApp.controller.currentUser.spots.last.music)
? const Text( ? const Text(
"Déjà dans vos discovery", "Déjà dans vos discovery",
style: TextStyle( style: TextStyle(
@ -214,10 +234,11 @@ class CardProvider extends ChangeNotifier {
curve: Curves.linear, curve: Curves.linear,
reverseCurve: Curves.linear, reverseCurve: Curves.linear,
); );
if (!MyApp.controller if (!MyApp.controller.currentUser.discovery
.getDiscoveries() .contains(MyApp.controller.currentUser.spots.last.music)) {
.containsKey(MyApp.controller.getSpots().last.music)) { MyApp.controller.currentUser.spots.last.music.defineDate();
MyApp.controller.addToPlaylist(MyApp.controller.getSpots().last.music.id); MyApp.controller.currentUser
.addDiscovery(MyApp.controller.currentUser.spots.last.music);
notifyListeners(); notifyListeners();
} }
} }
@ -327,7 +348,7 @@ class CardProvider extends ChangeNotifier {
child: ElevatedButton( child: ElevatedButton(
onPressed: () { onPressed: () {
sendMessage(messageTextField.text, sendMessage(messageTextField.text,
MyApp.controller.getSpots().last.userId); MyApp.controller.currentUser.spots.last.userId);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF3F1DC3), backgroundColor: const Color(0xFF3F1DC3),
@ -358,7 +379,7 @@ class CardProvider extends ChangeNotifier {
} }
void sendMessage(String message, String userId) { void sendMessage(String message, String userId) {
dev.log(MyApp.controller.getSpots().last.userId); dev.log(MyApp.controller.currentUser.spots.last.userId);
} }
void like(context) { void like(context) {
@ -370,15 +391,14 @@ class CardProvider extends ChangeNotifier {
} }
Future _nextCard() async { Future _nextCard() async {
List<Spot> spots = MyApp.controller.getSpots(); dev.log(_spotsList.length.toString());
dev.log(spots.length.toString()); if (_spotsList.isEmpty) {
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(spots.last.music.name); dev.log(_spotsList.last.music.name);
spots.removeLast(); _spotsList.removeLast();
resetPosition(); resetPosition();
} }
} }

@ -1,8 +1,34 @@
import 'user.dart'; import 'user.dart';
class Message { class Message {
String senderId; String idSender;
String idReceiver;
String content; String content;
Message(this.senderId, this.content); Message({
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,22 +1,32 @@
import '../exceptions/api_state_exception.dart'; import '../exceptions/api_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;
final String _name; late DateTime date;
final String _artist;
final String _linkCover;
Music(this._id, this._name, this._artist, this._linkCover); Music(this._id) {
_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) ||
@ -27,4 +37,8 @@ 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,8 +1,74 @@
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
String idDafl; late String usernameDafl;
late String idSpotify; late String passwDafl;
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.idDafl); User(this.usernameDafl, this.passwDafl) {
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,25 +1,26 @@
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 implements Loader { class DatabaseLoader extends 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 username from utilisateur where username = @username AND password = @password', 'select * 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); return User(username, password);
} else { } else {
return null; return User("", "");
} }
}) })
.whenComplete(() { .whenComplete(() {

@ -1,15 +1,20 @@
import 'database_connexion.dart'; import 'database_connexion.dart';
import 'saver.dart'; import 'saver.dart';
import '../model/user.dart';
class DatabaseSaver implements Saver { class DatabaseSaver extends Saver {
// Save user in the database // Save user in the database
@override @override
void save(String idDafl, String passw) async { void save(User userToSave) 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,12 +1,15 @@
import 'database_connexion.dart'; import 'database_connexion.dart';
import 'searcher.dart'; import 'searcher.dart';
class DatabaseSearcher implements Searcher { class DatabaseSearcher extends 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> searchUser(String? username) async { Future<bool> searchByUsername(String? username) async {
final connection = await DatabaseConnexion.initConnexion(); final connection = await DatabaseConnexion.initConnexion();
bool queryResult = await connection bool queryResult = await connection

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

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

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

@ -0,0 +1,40 @@
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();
}
}

@ -1,20 +0,0 @@
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());
}
}

@ -1,83 +0,0 @@
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']);
}
}

@ -1,184 +0,0 @@
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,41 +0,0 @@
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,37 +0,0 @@
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
}
}

@ -1,15 +0,0 @@
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();
}
}

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

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

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

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

@ -1,17 +0,0 @@
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;
}
}

@ -1,50 +0,0 @@
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,4 +1,3 @@
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,21 +12,25 @@ class ConversationPage extends StatefulWidget {
} }
class _ConversationPageState extends State<ConversationPage> { class _ConversationPageState extends State<ConversationPage> {
String destinataire = 'test'; User receiver = User("test1", '1234');
List<Widget> messages = []; List<Widget> messages = [];
bool isNull = true; bool isNull = true;
final messageTextField = TextEditingController(); final messageTextField = TextEditingController();
void sendMessage(String content) { void sendMessage(String content, String idSender, String idReceiver) {
Message messageToSend =
Message(idSender: idSender, idReceiver: idReceiver, content: content);
MyApp.controller.sendMessage(messageToSend, idSender, idReceiver);
setState(() { setState(() {
messages.add(messageWidget( messages.add(messageWidget(messageToSend));
Message(MyApp.controller.getIdDafl().toString(), content)));
}); });
} }
Widget messageWidget(Message message) { Widget messageWidget(Message message) {
if (message.senderId != MyApp.controller.getIdDafl().toString()) { if (message.idSender != MyApp.controller.currentUser.usernameDafl) {
return Align( return Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Container( child: Container(
@ -165,18 +169,34 @@ class _ConversationPageState extends State<ConversationPage> {
), ),
), ),
body: SingleChildScrollView( body: SingleChildScrollView(
child: Container( child: Container(
color: const Color(0xFF141414), color: const Color(0xFF141414),
height: height * 0.92, height: height * 0.92,
width: double.infinity, width: double.infinity,
child: ListView.builder( child: Flexible(
controller: listScrollController, child: StreamBuilder<List<Message>>(
physics: const BouncingScrollPhysics(), stream: MyApp.controller.getMessage(
itemCount: messages.length, MyApp.controller.currentUser.usernameDafl,
itemBuilder: (context, index) { receiver.usernameDafl),
return messages[index]; 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,
);
} else {
return Center(child: Container());
}
},
),
))),
bottomSheet: BottomAppBar( bottomSheet: BottomAppBar(
color: const Color(0xFF141414), color: const Color(0xFF141414),
child: Row( child: Row(
@ -218,7 +238,10 @@ class _ConversationPageState extends State<ConversationPage> {
onTap: isNull onTap: isNull
? null ? null
: () { : () {
sendMessage(messageTextField.text); sendMessage(
messageTextField.text,
MyApp.controller.currentUser.usernameDafl,
receiver.usernameDafl);
if (listScrollController.hasClients) { if (listScrollController.hasClients) {
final position = final position =
listScrollController.position.maxScrollExtent; listScrollController.position.maxScrollExtent;
@ -374,11 +397,8 @@ class _ConversationPageState extends State<ConversationPage> {
height: 70, height: 70,
child: ElevatedButton( child: ElevatedButton(
onPressed: () { onPressed: () {
MyApp.controller.sendEmail( MyApp.controller.sendEmail(MyApp.controller.currentUser,
MyApp.controller.getIdDafl().toString(), receiver, currentValue, messageTextField.text);
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 '../../../main.dart'; import '../../../presentation/custom_icons_icons.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,6 +8,8 @@ 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);
@ -28,14 +30,9 @@ 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,6 +1,5 @@
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;
@ -31,7 +30,7 @@ class _DiscoveryWidgetState extends State<DiscoveryWidget> {
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Text( Text(
'Playlist découverte', 'Playlist découverte',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
@ -40,17 +39,17 @@ class _DiscoveryWidgetState extends State<DiscoveryWidget> {
), ),
OutlinedButton( OutlinedButton(
onPressed: () { onPressed: () {
MyApp.controller MyApp.controller.currentUser.sortChoise =
.setChoice(!MyApp.controller.getChoice()); !MyApp.controller.currentUser.sortChoise;
rebuildAllChildren(context); rebuildAllChildren(context);
setState(() {}); setState(() {});
}, },
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
foregroundColor: Colors.grey,
shadowColor: Colors.black, shadowColor: Colors.black,
shape: const CircleBorder(), shape: CircleBorder(),
padding: const EdgeInsets.all(24)), padding: EdgeInsets.all(24),
child: MyApp.controller.getChoice() primary: Colors.grey),
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,
@ -71,7 +70,7 @@ class _DiscoveryWidgetState extends State<DiscoveryWidget> {
), ),
), ),
Expanded( Expanded(
child: MyApp.controller.getDiscoveries().isEmpty child: MyApp.controller.currentUser.discovery.isEmpty
? Center( ? Center(
child: Image.asset( child: Image.asset(
'assets/images/EmptyDiscovery-Hint.png', 'assets/images/EmptyDiscovery-Hint.png',
@ -119,23 +118,16 @@ class _DiscoveryListState extends State<DiscoveryList> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
late LinkedHashMap<Music, DateTime> listDiscoveries; List<Music> listDiscovery = MyApp.controller.currentUser.discovery;
if (MyApp.controller.getChoice()) { if (MyApp.controller.currentUser.sortChoise) {
//TODO : implement sort by date listDiscovery.sort((a, b) {
listDiscoveries = LinkedHashMap(); return a.date.compareTo(b.date);
});
} else { } else {
//TODO : implement sort by name listDiscovery.sort((a, b) {
/* var sortedKeys = MyApp.controller return a.name.compareTo(b.name);
.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();
@ -143,29 +135,25 @@ class _DiscoveryListState extends State<DiscoveryList> {
}, },
key: refreshKey, key: refreshKey,
child: ListView.builder( child: ListView.builder(
itemCount: listDiscoveries.length, itemCount: listDiscovery.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
int itemCount = listDiscoveries.length; int itemCount = listDiscovery.length;
int reversedIndex = itemCount - 1 - index; int reversedIndex = itemCount - 1 - index;
return Dismissible( return Dismissible(
movementDuration: const Duration(milliseconds: 400), movementDuration: Duration(milliseconds: 400),
key: Key(listDiscoveries.keys.toList()[index].name), key: Key(listDiscovery[index].name),
confirmDismiss: (direction) async { confirmDismiss: (direction) async {
if (direction == DismissDirection.endToStart) { if (direction == DismissDirection.endToStart) {
dev.log(listDiscoveries.keys.toList()[reversedIndex].id); print(listDiscovery[reversedIndex].id);
dev.log( print(listDiscovery[reversedIndex].name);
listDiscoveries.keys.toList()[reversedIndex].name); MyApp.controller.currentUser.discovery
MyApp.controller.removeFromPlaylist( .remove(listDiscovery[reversedIndex]);
listDiscoveries.keys.toList()[reversedIndex].id);
listDiscoveries = MyApp.controller.getDiscoveries();
return true; return true;
} }
if (direction == DismissDirection.startToEnd) { if (direction == DismissDirection.startToEnd) {
dev.log( print(listDiscovery[reversedIndex].name);
listDiscoveries.keys.toList()[reversedIndex].name); print('play');
dev.log('play'); MyApp.api.playTrack(listDiscovery[reversedIndex].id);
MyApp.controller.playTrack(
listDiscoveries.keys.toList()[reversedIndex].id);
setState(() {}); setState(() {});
} }
return false; return false;
@ -203,11 +191,8 @@ class _DiscoveryListState extends State<DiscoveryList> {
child: FadeInImage.assetNetwork( child: FadeInImage.assetNetwork(
placeholder: placeholder:
"assets/images/loadingPlaceholder.gif", "assets/images/loadingPlaceholder.gif",
image: MyApp.controller image: MyApp.controller.currentUser
.getDiscoveries() .discovery[reversedIndex].linkCover),
.keys
.toList()[reversedIndex]
.linkCover),
), ),
Container( Container(
margin: margin:
@ -219,11 +204,8 @@ class _DiscoveryListState extends State<DiscoveryList> {
MainAxisAlignment.center, MainAxisAlignment.center,
children: [ children: [
Text( Text(
MyApp.controller MyApp.controller.currentUser
.getDiscoveries() .discovery[reversedIndex].name,
.keys
.toList()[reversedIndex]
.name,
style: TextStyle( style: TextStyle(
fontFamily: 'DMSans', fontFamily: 'DMSans',
color: color:
@ -232,10 +214,10 @@ class _DiscoveryListState extends State<DiscoveryList> {
fontWeight: FontWeight.w800), fontWeight: FontWeight.w800),
), ),
Text( Text(
MyApp.controller MyApp
.getDiscoveries() .controller
.keys .currentUser
.toList()[reversedIndex] .discovery[reversedIndex]
.artist, .artist,
style: TextStyle( style: TextStyle(
fontFamily: 'DMSans', fontFamily: 'DMSans',

@ -1,6 +1,5 @@
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,4 +1,5 @@
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';
@ -26,317 +27,316 @@ class MainPageProfil extends StatefulWidget {
} }
class _MainPageProfilState extends State<MainPageProfil> { class _MainPageProfilState extends State<MainPageProfil> {
String username = MyApp.controller.getIdDafl().toString(); String? username = MyApp.controller.currentUser.usernameDafl;
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
Widget build(BuildContext context) { Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height; double height = MediaQuery.of(context).size.height;
return Container( return Container(
color: const Color(0xFF141414), color: const Color(0xFF141414),
child: SizedBox( child: SizedBox(
width: double.infinity, width: double.infinity,
height: double.infinity, height: double.infinity,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Container( Container(
width: double.infinity, width: double.infinity,
margin: const EdgeInsets.fromLTRB(30, 50, 0, 0), margin: const EdgeInsets.fromLTRB(30, 50, 0, 0),
child: const Text("Profil", child: const Text("Profil",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w600,
color: Colors.white,
fontFamily: "DMSans")),
),
Container(
margin: const EdgeInsets.fromLTRB(0, 10, 0, 10),
height: height * 0.14,
width: height * 0.14,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100.0),
color: Colors.blue,
border: Border.all(width: 6.0, color: Colors.white),
boxShadow: const [
BoxShadow(
offset: Offset(0, 0),
spreadRadius: 5,
blurRadius: 10,
color: Color.fromRGBO(0, 0, 0, 1),
),
],
),
child: Center(
child: Text(username![0],
style: const TextStyle(
color: Colors.white,
fontSize: 60,
fontWeight: FontWeight.w500),
textAlign: TextAlign.center))),
Text(
username!,
style: const TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w400),
textAlign: TextAlign.center,
),
Container(
height: 55,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.transparent,
),
margin: const EdgeInsets.fromLTRB(30, 40, 30, 0),
child: SizedBox(
height: 55,
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor:
const Color(0xFFD9D9D9).withOpacity(0.08),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
), // background// foreground
),
onPressed: () {},
child: Row(
children: [
Image.asset(
'assets/images/fav_logo.png',
height: 25,
),
const SizedBox(
width: 12,
),
const Text(
"Préférences musicales",
style: TextStyle( style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w600,
color: Colors.white, color: Colors.white,
fontFamily: "DMSans"))), fontSize: 17,
Container( fontWeight: FontWeight.w400),
margin: const EdgeInsets.fromLTRB(0, 10, 0, 10), textAlign: TextAlign.center,
height: height * 0.14, ),
width: height * 0.14, const Spacer(),
decoration: BoxDecoration( Icon(
borderRadius: BorderRadius.circular(100.0), Icons.arrow_forward_ios,
color: Colors.blue, color: Colors.white.withOpacity(0.3),
border: Border.all(width: 6.0, color: Colors.white), ),
boxShadow: const [ ],
BoxShadow( )),
offset: Offset(0, 0), ),
spreadRadius: 5, ),
blurRadius: 10, Container(
color: Color.fromRGBO(0, 0, 0, 1), height: 55,
), width: double.infinity,
], decoration: BoxDecoration(
), borderRadius: BorderRadius.circular(10.0),
child: Center( color: Colors.transparent,
child: Text(username[0], ),
style: const TextStyle( margin: const EdgeInsets.fromLTRB(30, 10, 30, 0),
color: Colors.white, child: SizedBox(
fontSize: 60, height: 55,
fontWeight: FontWeight.w500), width: double.infinity,
textAlign: TextAlign.center))), child: ElevatedButton(
Text( style: ElevatedButton.styleFrom(
username, backgroundColor:
style: const TextStyle( const Color(0xFFD9D9D9).withOpacity(0.08),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
), // background// foreground
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DisplayInfoWidget()));
},
child: Row(
children: [
const Icon(
Icons.remove_red_eye,
color: Colors.white,
size: 30,
),
const SizedBox(
width: 12,
),
const Text(
"Aperçu de mon profil",
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w400),
textAlign: TextAlign.center,
),
const Spacer(),
Icon(
Icons.arrow_forward_ios,
color: Colors.white.withOpacity(0.3),
),
],
)),
),
),
Container(
height: height * 0.27,
width: double.infinity,
margin: const EdgeInsets.fromLTRB(30, 15, 30, 0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Icon(
Icons.wifi_tethering,
color: Colors.white, color: Colors.white,
fontSize: 17, size: 35,
fontWeight: FontWeight.w400), ),
textAlign: TextAlign.center, SizedBox(
width: 10,
),
Text(
"En cours d'écoute",
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w400),
textAlign: TextAlign.center,
),
Padding(
padding: EdgeInsets.fromLTRB(1, 9, 0, 0),
child: SizedBox(
width: 25,
height: 25,
child: riv.RiveAnimation.asset(
'assets/images/playing_animation.riv'),
),
),
],
), ),
Container( Container(
height: 55, margin: const EdgeInsets.fromLTRB(0, 10, 0, 0),
width: double.infinity, height: height * 0.14,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0), borderRadius: BorderRadius.circular(15.0),
color: Colors.transparent, color: const Color(0xFFD9D9D9).withOpacity(0.08),
), ),
margin: const EdgeInsets.fromLTRB(30, 40, 30, 0), child: Row(
child: SizedBox( mainAxisAlignment: MainAxisAlignment.start,
height: 55, crossAxisAlignment: CrossAxisAlignment.center,
width: double.infinity, children: [
child: ElevatedButton( Container(
style: ElevatedButton.styleFrom( margin: const EdgeInsets.fromLTRB(15, 0, 0, 0),
backgroundColor: child: ClipRRect(
const Color(0xFFD9D9D9).withOpacity(0.08), borderRadius: BorderRadius.circular(15),
shape: RoundedRectangleBorder( child: FadeInImage.assetNetwork(
borderRadius: BorderRadius.circular(10.0), height: 90,
), // background// foreground width: 90,
), placeholder:
onPressed: () {}, "assets/images/loadingPlaceholder.gif",
child: Row( image: currentmusic.linkCover))),
Container(
margin: const EdgeInsets.fromLTRB(12, 20, 0, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Image.asset( Text(
'assets/images/fav_logo.png', currentmusic.name,
height: 25, style: const TextStyle(
), fontSize: 18,
const SizedBox( fontWeight: FontWeight.w500,
width: 12, color: Colors.white),
),
const Text(
"Préférences musicales",
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w400),
textAlign: TextAlign.center,
), ),
const Spacer(), Text(
Icon( currentmusic.artist,
Icons.arrow_forward_ios, style: const TextStyle(
color: Colors.white.withOpacity(0.3), fontSize: 16,
fontWeight: FontWeight.w400,
color: Colors.grey),
), ),
], ],
)),
),
),
Container(
height: 55,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.transparent,
),
margin: const EdgeInsets.fromLTRB(30, 10, 30, 0),
child: SizedBox(
height: 55,
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor:
const Color(0xFFD9D9D9).withOpacity(0.08),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
), // background// foreground
), ),
onPressed: () { )
Navigator.push( ],
context,
MaterialPageRoute(
builder: (context) =>
const DisplayInfoWidget()));
},
child: Row(
children: [
const Icon(
Icons.remove_red_eye,
color: Colors.white,
size: 30,
),
const SizedBox(
width: 12,
),
const Text(
"Aperçu de mon profil",
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.w400),
textAlign: TextAlign.center,
),
const Spacer(),
Icon(
Icons.arrow_forward_ios,
color: Colors.white.withOpacity(0.3),
),
],
)),
), ),
), ),
Container( ],
height: height * 0.27, ),
width: double.infinity, ),
margin: const EdgeInsets.fromLTRB(30, 15, 30, 0), const Spacer(),
child: Column(children: [ Container(
Row( height: 55,
mainAxisAlignment: MainAxisAlignment.start, width: double.infinity,
crossAxisAlignment: CrossAxisAlignment.center, decoration: BoxDecoration(
children: const [ borderRadius: BorderRadius.circular(10.0),
Icon( color: Colors.transparent,
Icons.wifi_tethering, ),
color: Colors.white, margin: const EdgeInsets.fromLTRB(30, 0, 30, 0),
size: 35, child: SizedBox(
), height: 55,
SizedBox( width: double.infinity,
width: 10, child: ElevatedButton(
), style: ElevatedButton.styleFrom(
Text( backgroundColor:
"En cours d'écoute", const Color(0xFFD9D9D9).withOpacity(0.08),
style: TextStyle( shape: RoundedRectangleBorder(
color: Colors.white, borderRadius: BorderRadius.circular(10.0),
fontSize: 17, ), // background// foreground
fontWeight: FontWeight.w400), ),
textAlign: TextAlign.center, onPressed: () {
), Navigator.push(
Padding( context,
padding: EdgeInsets.fromLTRB(1, 9, 0, 0), MaterialPageRoute(
child: SizedBox( builder: (context) => const SettingsWidget()))
width: 25, .then((value) => setState(() {
height: 25, username =
child: riv.RiveAnimation.asset( MyApp.controller.currentUser.usernameDafl;
'assets/images/playing_animation.riv'))) }));
]), },
Container( child: Row(
margin: const EdgeInsets.fromLTRB(0, 10, 0, 0), children: [
height: height * 0.14, const Icon(
decoration: BoxDecoration( Icons.settings,
borderRadius: BorderRadius.circular(15.0), color: Colors.white,
color: const Color(0xFFD9D9D9).withOpacity(0.08), size: 30,
), ),
child: Row( const SizedBox(
mainAxisAlignment: MainAxisAlignment.start, width: 12,
crossAxisAlignment: CrossAxisAlignment.center, ),
children: [ const Text(
Container( "Paramètres",
margin: const EdgeInsets.fromLTRB( style: TextStyle(
15, 0, 0, 0), color: Colors.white,
child: ClipRRect( fontSize: 17,
borderRadius: fontWeight: FontWeight.w400),
BorderRadius.circular(15), textAlign: TextAlign.center,
child: FadeInImage.assetNetwork( ),
height: 90, const Spacer(),
width: 90, Icon(
placeholder: Icons.arrow_forward_ios,
"assets/images/loadingPlaceholder.gif", color: Colors.white.withOpacity(0.3),
image: MyApp.controller ),
.getCurrentMusic() ],
.linkCover))), )),
Container( ),
margin: const EdgeInsets.fromLTRB( ),
12, 20, 0, 0), const Spacer(),
child: Column( ],
mainAxisAlignment: ),
MainAxisAlignment.start, ),
crossAxisAlignment: );
CrossAxisAlignment.start,
children: [
Text(
MyApp.controller
.getCurrentMusic()
.name,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w500,
color: Colors.white),
),
Text(
MyApp.controller
.getCurrentMusic()
.artist,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
color: Colors.grey))
])),
const Spacer(),
Container(
height: 55,
width: double.infinity,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10.0),
color: Colors.transparent,
),
margin: const EdgeInsets.fromLTRB(
30, 0, 30, 0),
child: SizedBox(
height: 55,
width: double.infinity,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor:
const Color(0xFFD9D9D9)
.withOpacity(0.08),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(
10.0),
), // background// foreground
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const SettingsWidget()))
.then(
(value) => setState(() {
username = MyApp
.controller
.getIdDafl()
.toString();
}));
},
child: Row(children: [
const Icon(
Icons.settings,
color: Colors.white,
size: 30,
),
const SizedBox(
width: 12,
),
const Text(
"Paramètres",
style: TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight:
FontWeight.w400),
textAlign: TextAlign.center,
),
const Spacer(),
Icon(
Icons.arrow_forward_ios,
color: Colors.white
.withOpacity(0.3),
)
])))),
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.getIdDafl().toString()); TextEditingController(text: MyApp.controller.currentUser.usernameDafl);
final passwordTextField = final passwordTextField =
TextEditingController(text: MyApp.controller.getIdDafl().toString()); TextEditingController(text: MyApp.controller.currentUser.passwDafl);
@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,9 +31,11 @@ class _SpotsWidgetState extends State<SpotsWidget> {
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: NetworkImage(MyApp.controller.getSpots().isEmpty image: NetworkImage(
? "https://i.imgur.com/Uovh293.png" MyApp.controller.currentUser.spots.isEmpty
: MyApp.controller.getSpots().last.music.linkCover), ? "https://i.imgur.com/Uovh293.png"
: MyApp.controller.currentUser.spots.last.music
.linkCover),
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
), ),
@ -47,19 +49,21 @@ class _SpotsWidgetState extends State<SpotsWidget> {
), ),
), ),
Align( Align(
alignment: FractionalOffset.bottomCenter, alignment: FractionalOffset.bottomCenter,
child: MyApp.controller.getSpots().isEmpty child: MyApp.controller.currentUser.spots.isEmpty
? Container() ? Container()
: OpenContainer( : OpenContainer(
closedColor: Colors.transparent, closedColor: Colors.transparent,
closedElevation: 0, closedElevation: 0,
transitionDuration: const Duration(milliseconds: 400), transitionDuration: const Duration(milliseconds: 400),
closedBuilder: (context, openWidget) { closedBuilder: (context, openWidget) {
return const PreviewInfoWidget(); return const PreviewInfoWidget();
}, },
openBuilder: (context, closeWidget) { openBuilder: (context, closeWidget) {
return const DisplayInfoWidget(); return const DisplayInfoWidget();
})), },
),
),
const Center( const Center(
child: SizedBox( child: SizedBox(
width: 300, width: 300,
@ -71,7 +75,7 @@ class _SpotsWidgetState extends State<SpotsWidget> {
Positioned( Positioned(
top: height * 0.68, top: height * 0.68,
width: width, width: width,
child: MyApp.controller.getSpots().isEmpty child: MyApp.controller.currentUser.spots.isEmpty
? Container() ? Container()
: Row( : Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@ -162,77 +166,46 @@ class _SpotsWidgetState extends State<SpotsWidget> {
)), )),
), ),
), ),
MyApp.controller.getSpots().isEmpty Padding(
? SafeArea( padding: const EdgeInsets.fromLTRB(20, 60, 0, 0),
child: Center( child: Column(
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, children: [
children: [ Text(
MyApp.controller.getSpots().isEmpty MyApp.controller.currentUser.spots.isEmpty
? Column( ? ''
crossAxisAlignment: : MyApp.controller.currentUser.spots.last.music.name,
CrossAxisAlignment.start, style: TextStyle(
children: [ fontFamily: 'DMSans',
const Text( color: Colors.white.withOpacity(1),
'Quelques instants...', fontSize: 20,
style: TextStyle( fontWeight: FontWeight.w800),
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),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
MyApp.controller.getSpots().isEmpty
? ''
: MyApp.controller.getSpots().last.music.name,
style: TextStyle(
fontFamily: 'DMSans',
color: Colors.white.withOpacity(1),
fontSize: 20,
fontWeight: FontWeight.w800),
),
Text(
MyApp.controller.getSpots().isEmpty
? ''
: MyApp.controller.getSpots().last.music.artist,
style: TextStyle(
fontFamily: 'DMSans',
color: Colors.white.withOpacity(1),
fontSize: 17,
fontWeight: FontWeight.w200),
),
],
),
), ),
Text(
MyApp.controller.currentUser.spots.isEmpty
? ''
: MyApp
.controller.currentUser.spots.last.music.artist,
style: TextStyle(
fontFamily: 'DMSans',
color: Colors.white.withOpacity(1),
fontSize: 17,
fontWeight: FontWeight.w200),
),
],
),
),
Positioned( Positioned(
top: 115, top: 115,
right: 0, right: 0,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
MyApp.controller MyApp.api.playTrack(
.playTrack(MyApp.controller.getSpots().last.music.id); MyApp.controller.currentUser.spots.last.music.id);
}, },
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: MyApp.controller.getSpots().isEmpty child: !MyApp.controller.currentUser.spots.isEmpty
? Image.asset("assets/images/play_spotify_button.png") ? Image.asset("assets/images/play_spotify_button.png")
: Container(), : Container(),
), ),
@ -244,7 +217,7 @@ class _SpotsWidgetState extends State<SpotsWidget> {
Widget buildCards() { Widget buildCards() {
final provider = Provider.of<CardProvider>(context); final provider = Provider.of<CardProvider>(context);
final urlImages = MyApp.controller.getSpots(); final urlImages = provider.spotsList;
return Stack( return Stack(
children: urlImages children: urlImages

@ -257,17 +257,20 @@ class _SignInPageState extends State<SignInPage> {
notify(2, context); notify(2, context);
} else if (password == "") { } else if (password == "") {
notify(4, context); notify(4, context);
} else if (await MyApp.controller
.load(userNameTextField.text, passwordTextField.text)) {
MyApp.controller.initUser();
Navigator.of(context).push(
PageTransition(
type: PageTransitionType.fade,
childCurrent: widget,
child: const Splash()),
);
} else { } else {
notify(2, context); await MyApp.controller
.load(userNameTextField.text, passwordTextField.text);
if (MyApp.controller.currentUser.usernameDafl != "") {
Navigator.of(context).push(
PageTransition(
type: PageTransitionType.fade,
childCurrent: widget,
child: const Splash()),
);
} else {
notify(2, context);
}
} }
} }
} }

@ -1,7 +1,8 @@
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 '../../../services/api/in_app_browser.dart'; import '../../../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';
@ -333,7 +334,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.searchUser(username)) { } else if (!await MyApp.controller.searchByUsername(username)) {
notify(0, context); notify(0, context);
} }
if (password == "" || confirmPassword == "") { if (password == "" || confirmPassword == "") {
@ -343,7 +344,7 @@ class _SignUpPageState extends State<SignUpPage> {
} else if (password != confirmPassword) { } else if (password != confirmPassword) {
notify(1, context); notify(1, context);
} else { } else {
// create user in database MyApp.controller.save(User(username, password));
Navigator.of(context).push( Navigator.of(context).push(
PageTransition( PageTransition(

@ -1,6 +1,13 @@
# 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:
@ -71,6 +78,27 @@ 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:
@ -106,13 +134,6 @@ 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:
@ -134,6 +155,48 @@ 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
@ -329,13 +392,6 @@ 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:
@ -497,13 +553,6 @@ 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
@ -551,13 +600,6 @@ 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
marquee: ^2.2.3 firebase_core: ^2.3.0
text_scroll: ^0.1.1 firebase_messaging: ^14.1.1
scroll_loop_auto_scroll: ^0.0.2 cloud_firestore: ^4.1.0
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:

@ -1,56 +0,0 @@
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)
);

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

@ -1,20 +0,0 @@
<?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
}
}

@ -1,96 +0,0 @@
<?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