Compare commits

..

4 Commits

Author SHA1 Message Date
Lucas DELANIER 6762b29bef connected status send to server
continuous-integration/drone/push Build is passing Details
2 years ago
Lucas DELANIER d770616662 connected status send to server
2 years ago
Lucas DELANIER 5be7a32138 chat with socket.io on a js server
2 years ago
Lucas DELANIER 50bb10e610 chat with socket.io on a js server
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,705 @@
<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> </list>
</value> </value>
</entry> </entry>
<entry key="scroll_loop_auto_scroll"> <entry key="sky_engine">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/scroll_loop_auto_scroll-0.0.5/lib" /> <option value="$USER_HOME$/flutter/bin/cache/pkg/sky_engine/lib" />
</list> </list>
</value> </value>
</entry> </entry>
<entry key="sky_engine"> <entry key="socket_io_client">
<value>
<list>
<option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/socket_io_client-2.0.0/lib" />
</list>
</value>
</entry>
<entry key="socket_io_common">
<value> <value>
<list> <list>
<option value="$PROJECT_DIR$/../flutter/bin/cache/pkg/sky_engine/lib" /> <option value="$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/socket_io_common-2.0.2/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/socket_io_client-2.0.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/socket_io_common-2.0.2/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/source_span-1.9.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/stack_trace-1.10.0/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/stream_channel-2.1.0/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/string_scanner-1.1.1/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/postgresql2-1.0.3/lib" /> <root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.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/test_api-0.4.12/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/typed_data-1.3.1/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/universal_io-2.0.4/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/vector_math-2.1.2/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/rive-0.9.1/lib" /> <root url="file://$USER_HOME$/flutter/.pub-cache/hosted/pub.dartlang.org/vibration-1.7.6/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/win32-3.0.1/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.9.0/lib" /> <root url="file://$USER_HOME$/flutter/.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/stack_trace-1.10.0/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/stream_channel-2.1.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/string_scanner-1.1.1/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/term_glyph-1.2.1/lib" /> <root url="file://$USER_HOME$/flutter/packages/flutter/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_localizations/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/text_scroll-0.1.1/lib" /> <root url="file://$USER_HOME$/flutter/packages/flutter_test/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.1/lib" /> <root url="file://$USER_HOME$/flutter/packages/flutter_web_plugins/lib" />
<root url="file://$PROJECT_DIR$/../flutter/.pub-cache/hosted/pub.dartlang.org/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.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

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

@ -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/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

@ -9,7 +9,7 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
56603186FD0491FFC157C451 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D9F96A939E72163035AC6113 /* Pods_Runner.framework */; }; 7123E589E36F2A19292958EB /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D2A87B24F967E02E3AD8C23 /* Pods_Runner.framework */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
@ -30,13 +30,16 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
05FB6061F1FF29B3B9E4D028 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; 0A23FC45634EB07CAB0988E0 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
275ABD2DE0015FE53EA67016 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7A594B0F7D8FF0743F35FBAA /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7D2A87B24F967E02E3AD8C23 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -44,9 +47,6 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AA4D0BF17C9CFE7BC6080122 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
D9F96A939E72163035AC6113 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DF9436B870BC50F36A3F1BC8 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -54,7 +54,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
56603186FD0491FFC157C451 /* Pods_Runner.framework in Frameworks */, 7123E589E36F2A19292958EB /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -78,8 +78,8 @@
9740EEB11CF90186004384FC /* Flutter */, 9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
C12164027BBF046CA7CA1CE9 /* Pods */, B7E0DB4BE4F23040C6127914 /* Pods */,
D041563FF6043A51C062CD22 /* Frameworks */, D1F3815DE0E6B5B41D0FE2D8 /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -106,21 +106,21 @@
path = Runner; path = Runner;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C12164027BBF046CA7CA1CE9 /* Pods */ = { B7E0DB4BE4F23040C6127914 /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
AA4D0BF17C9CFE7BC6080122 /* Pods-Runner.debug.xcconfig */, 7A594B0F7D8FF0743F35FBAA /* Pods-Runner.debug.xcconfig */,
DF9436B870BC50F36A3F1BC8 /* Pods-Runner.release.xcconfig */, 0A23FC45634EB07CAB0988E0 /* Pods-Runner.release.xcconfig */,
05FB6061F1FF29B3B9E4D028 /* Pods-Runner.profile.xcconfig */, 275ABD2DE0015FE53EA67016 /* Pods-Runner.profile.xcconfig */,
); );
name = Pods; name = Pods;
path = Pods; path = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
D041563FF6043A51C062CD22 /* Frameworks */ = { D1F3815DE0E6B5B41D0FE2D8 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D9F96A939E72163035AC6113 /* Pods_Runner.framework */, 7D2A87B24F967E02E3AD8C23 /* Pods_Runner.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -132,14 +132,14 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
0CDF21A3B58AC238E2266285 /* [CP] Check Pods Manifest.lock */, F244868EE2BE1C55CDAEA7FA /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
9E2222998A7DFB19CABF432B /* [CP] Embed Pods Frameworks */, C8941F7290B9FCCA72A5780E /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -198,28 +198,6 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
0CDF21A3B58AC238E2266285 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
@ -248,7 +226,7 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
9E2222998A7DFB19CABF432B /* [CP] Embed Pods Frameworks */ = { C8941F7290B9FCCA72A5780E /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -265,6 +243,28 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
F244868EE2BE1C55CDAEA7FA /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */

@ -49,11 +49,5 @@
<true/> <true/>
<key>UIStatusBarHidden</key> <key>UIStatusBarHidden</key>
<false/> <false/>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location when in the background.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to location when open and in the background.</string>
</dict> </dict>
</plist> </plist>

@ -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,7 @@
import 'dart:io'; import 'dart:io';
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 +13,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 {
@ -24,16 +24,13 @@ class MyInAppBrowser extends InAppBrowser {
@override @override
Future onLoadStart(url) async { Future onLoadStart(url) async {
bool isError = false; if (url!.origin + url.path == MyApp.api.redirectUri) {
if (url!.origin + url.path == MyApp.controller.getApiRedirectUrl()) {
try { try {
await MyApp.controller.apiAuthorization(url); await MyApp.api.requestUserAuthorization(url);
} catch (e) { } on ApiException {
notify(5, MyApp.controller.navigatorKey); // TODO : add notification to show that an error occured
isError = true;
} finally { } finally {
close(); close();
if (!isError) notify(2, MyApp.controller.navigatorKey, isError: false);
} }
} }
} }

@ -1,135 +1,112 @@
import 'dart:async';
import 'dart:collection';
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:dafl_project_flutter/main.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 'package:socket_io_client/socket_io_client.dart' as IO;
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();
late User currentUser;
late BuildContext navigatorKey;
late IO.Socket _socket;
initUser() async {
await setCurrentMusic(); void _connectChat() {
await setDiscoveries(); _socket = IO.io(
} "http://localhost:3000",
IO.OptionBuilder().setTransports(['websocket']).setQuery(
beginRoutine() async { {'username': MyApp.controller.currentUser}).build());
await setSpots(); _socket.onConnect((data) => print('Connection established'));
Timer.periodic(const Duration(seconds: 10), (Timer t) => setSpots()); _socket.onConnectError((data) => print('Connect Error: $data'));
} _socket.onDisconnect((data) => print('Socket.io server disconnected'));
_socket.on('message', (data) => print(data));
// _socket.on('user', (data) => print(data));
// Methods to manage data }
//
sendMessage(String message, User destinataire) {
// Data that can change _socket.emit('message', {
'message': message.trim(),
bool getChoice() => _data.discoveriesSortChoice; 'sender': destinataire.usernameDafl,
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 {
LinkedHashMap<String, DateTime> tmpData =
await _api.requests.getPlaylistTracks();
LinkedHashMap<Music, DateTime> tmpCast = LinkedHashMap();
tmpData.forEach((key, value) async {
tmpCast[(await getCompleteMusic(key))] = value;
}); });
_data.discoveries = tmpCast;
}
//Data that can not change
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) { sendStatusConnected(User user, int isConnection) {
_api.requests.removeFromPlaylist(id); _socket
.emit('status', {'sender': user.usernameDafl, 'content': isConnection});
} }
addToPlaylist(String id) { Controller() {
_api.requests.addToPlaylist(id); currentUser = User('', ''); //TODO : remove this line
} }
playTrack(String id) { void save(User userToSave) {
_api.requests.playTrack(id); saver.save(userToSave);
} }
// DATABASE load(String username, String password) async {
void save(String idDafl, String passw) { _changeCurrentUser(await loader.load(username, password));
_dataBaseService.save(idDafl, passw); _connectChat();
} }
Future<bool> load(String username, String password) async { _changeCurrentUser(User user) {
User? newUser = await _dataBaseService.load(username, password); currentUser = user;
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, /*void chargeExample() {
String message) async { currentUser.spots = [
Spot(
User('Félix', '1234'),
Music('Couleurs', 'Khali',
'https://khaligidilit.com/assets/images/cover-LAI%CC%88LA-Khali.jpeg')),
Spot(
User('Audric', '1234'),
Music("J'suis PNL", 'PNL',
'https://m.media-amazon.com/images/I/61aUOMzwS8L._SL1440_.jpg')),
Spot(
User('Dorian', '1234'),
Music('Sundance', 'Nepal',
'https://pbs.twimg.com/media/ExJ-My-XMAE3Ko2.jpg')),
Spot(
User('Lucas', '1234'),
Music('Eternelle 2', 'So La Lune',
'https://cdns-images.dzcdn.net/images/cover/2818a661c6d533155ce6dffc256b1f51/500x500.jpg')),
Spot(
User('David', '1234'),
Music('M.I.L.S 3', 'Ninho',
'https://cdns-images.dzcdn.net/images/cover/b351f0e935c9c3901f8d893b92ab952a/500x500.jpg')),
Spot(
User('Hugo', '1234'),
Music('Deux frères', 'PNL',
'https://cdns-images.dzcdn.net/images/cover/65147b581f2ace9e0f0723ee76e70fda/500x500.jpg')),
Spot(
User('Alban', '1234'),
Music('Paradis', 'Sopico',
'https://cdns-images.dzcdn.net/images/cover/17a9747927ac3e5ea56f92f635d9180c/500x500.jpg')),
].reversed.toList();
}*/
Future sendEmail(
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 +122,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()}');
}
}
}

@ -9,6 +9,7 @@ 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';
@ -18,6 +19,7 @@ void main() {
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});
@ -25,14 +27,8 @@ class MyApp extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Paint.enableDithering = true; Paint.enableDithering = true;
SystemChrome.setEnabledSystemUIMode( SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
SystemUiMode.manual, overlays: [SystemUiOverlay.top]);
overlays: [SystemUiOverlay.top],
);
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarIconBrightness: Brightness.dark, // For Android (dark icons)
statusBarBrightness: Brightness.dark, // For iOS (dark icons)
));
return ChangeNotifierProvider( return ChangeNotifierProvider(
create: (context) => CardProvider(), create: (context) => CardProvider(),
child: const MaterialApp( child: const MaterialApp(
@ -46,11 +42,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 +153,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 +174,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 +189,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 +213,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 +327,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 +358,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 +370,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();
} }
} }
@ -463,12 +462,6 @@ Object notify(int index, context, {bool isError = true}) {
message = "Mot de passe incorrect ! Veuillez réessayer."; message = "Mot de passe incorrect ! Veuillez réessayer.";
break; break;
} }
case 5:
{
message =
"Une erreur est survenue lors de la liaison de votre compte. Veuillez réessayer.";
break;
}
default: default:
message = message =
"Une erreur est survenue pendant l'inscription. Veuillez réessayer."; "Une erreur est survenue pendant l'inscription. Veuillez réessayer.";
@ -545,11 +538,6 @@ Object notify(int index, context, {bool isError = true}) {
message = "Vous avez changer votre mot de passe avec succès"; message = "Vous avez changer votre mot de passe avec succès";
break; break;
} }
case 2:
{
message = "Vous avez relié votre compte Spotify avec succès";
break;
}
default: default:
message = "L'opération a bien été éxécutée"; message = "L'opération a bien été éxécutée";
break; break;

@ -1,8 +1,8 @@
import 'user.dart'; import 'user.dart';
class Message { class Message {
String senderId; User sender;
String content; String content;
Message(this.senderId, this.content); Message(this.sender, this.content);
} }

@ -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,72 @@
import 'dart:async';
import '../../../position/location.dart';
import '../exceptions/api_exception.dart';
import '../main.dart';
import 'music.dart';
import 'spot.dart';
class User { class User {
Timer? timer;
int test = 0;
//attributes from DAFL //attributes from DAFL
String idDafl; late int idDafl;
late String idSpotify; late String usernameDafl;
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() {
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,22 @@ class ConversationPage extends StatefulWidget {
} }
class _ConversationPageState extends State<ConversationPage> { class _ConversationPageState extends State<ConversationPage> {
String destinataire = 'test'; User destinataire = 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, User destinataire) {
setState(() { setState(() {
messages.add(messageWidget( messages
Message(MyApp.controller.getIdDafl().toString(), content))); .add(messageWidget(Message(MyApp.controller.currentUser, content)));
}); });
MyApp.controller.sendMessage(content, destinataire);
} }
Widget messageWidget(Message message) { Widget messageWidget(Message message) {
if (message.senderId != MyApp.controller.getIdDafl().toString()) { if (message.sender != MyApp.controller.currentUser) {
return Align( return Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Container( child: Container(
@ -88,12 +89,13 @@ class _ConversationPageState extends State<ConversationPage> {
void initState() { void initState() {
super.initState(); super.initState();
messageTextField.addListener(_checkIfNull); messageTextField.addListener(_checkIfNull);
MyApp.controller.sendStatusConnected(MyApp.controller.currentUser, 1);
dev.log("INITSATE"); dev.log("INITSATE");
} }
@override @override
void dispose() { void dispose() {
messageTextField.dispose(); MyApp.controller.sendStatusConnected(MyApp.controller.currentUser, 0);
super.dispose(); super.dispose();
} }
@ -218,7 +220,7 @@ class _ConversationPageState extends State<ConversationPage> {
onTap: isNull onTap: isNull
? null ? null
: () { : () {
sendMessage(messageTextField.text); sendMessage(messageTextField.text, destinataire);
if (listScrollController.hasClients) { if (listScrollController.hasClients) {
final position = final position =
listScrollController.position.maxScrollExtent; listScrollController.position.maxScrollExtent;
@ -374,11 +376,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(), destinataire, currentValue, messageTextField.text);
destinataire,
currentValue,
messageTextField.text);
Navigator.pop(context); Navigator.pop(context);
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(

@ -1,12 +1,13 @@
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';
import './w_profile.dart'; import './w_profile.dart';
import './w_messages.dart'; import './w_messages.dart';
import 'w_top.dart'; import 'w_top.dart';
import 'package:socket_io_client/socket_io_client.dart' as IO;
class MainPage extends StatefulWidget { class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key); const MainPage({Key? key}) : super(key: key);
@ -30,12 +31,12 @@ class _MainPageState extends State<MainPage> {
@override @override
void initState() { void initState() {
MyApp.controller.beginRoutine();
super.initState(); 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,19 @@ 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 +72,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',
@ -84,13 +85,11 @@ class _DiscoveryWidgetState extends State<DiscoveryWidget> {
), ),
); );
} }
void rebuildAllChildren(BuildContext context) { void rebuildAllChildren(BuildContext context) {
void rebuild(Element el) { void rebuild(Element el) {
el.markNeedsBuild(); el.markNeedsBuild();
el.visitChildren(rebuild); el.visitChildren(rebuild);
} }
(context as Element).visitChildren(rebuild); (context as Element).visitChildren(rebuild);
} }
} }
@ -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,32 +135,26 @@ 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].name);
dev.log( MyApp.controller.currentUser.discovery
listDiscoveries.keys.toList()[reversedIndex].name); .remove(listDiscovery[reversedIndex]);
MyApp.controller.removeFromPlaylist( setState(() {});
listDiscoveries.keys.toList()[reversedIndex].id);
listDiscoveries = MyApp.controller.getDiscoveries();
return true;
} }
},
onDismissed: (direction) {
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.controller.playTrack(
listDiscoveries.keys.toList()[reversedIndex].id);
setState(() {});
} }
return false;
}, },
background: Container( background: Container(
decoration: const BoxDecoration( decoration: const BoxDecoration(
@ -203,11 +189,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 +202,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 +212,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',

@ -2,7 +2,6 @@ import '../../../main.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';
import 'package:rive/rive.dart' as riv;
class ProfileWidget extends StatefulWidget { class ProfileWidget extends StatefulWidget {
const ProfileWidget({Key? key}) : super(key: key); const ProfileWidget({Key? key}) : super(key: key);
@ -26,11 +25,11 @@ 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;
@override @override
initState() { initState() {
username = MyApp.controller.getIdDafl(); username = MyApp.controller.currentUser.usernameDafl;
super.initState(); super.initState();
} }
@ -38,305 +37,294 @@ class _MainPageProfilState extends State<MainPageProfil> {
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,
),
],
), ),
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: MyApp.controller.currentUser
.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', MyApp.controller.currentUser.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( MyApp
Icons.arrow_forward_ios, .controller.currentUser.currentMusic.artist,
color: Colors.white.withOpacity(0.3), style: const TextStyle(
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(

@ -1,4 +1,3 @@
import 'dart:async';
import 'dart:ui'; import 'dart:ui';
import 'package:rive/rive.dart' as riv; import 'package:rive/rive.dart' as riv;
@ -31,9 +30,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 +48,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 +74,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,81 +165,35 @@ 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),
),
],
),
), ),
Positioned( Text(
top: 115, MyApp.controller.currentUser.spots.isEmpty
right: 0, ? ''
child: GestureDetector( : MyApp
onTap: () { .controller.currentUser.spots.last.music.artist,
MyApp.controller style: TextStyle(
.playTrack(MyApp.controller.getSpots().last.music.id); fontFamily: 'DMSans',
}, color: Colors.white.withOpacity(1),
child: SizedBox( fontSize: 17,
height: 40, fontWeight: FontWeight.w200),
child: MyApp.controller.getSpots().isEmpty
? Image.asset("assets/images/play_spotify_button.png")
: Container(),
), ),
)) ],
),
),
], ],
), ),
)); ));
@ -244,7 +201,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

@ -79,7 +79,6 @@ class _SignInPageState extends State<SignInPage> {
Padding( Padding(
padding: const EdgeInsets.fromLTRB(50, 0, 20, 0), padding: const EdgeInsets.fromLTRB(50, 0, 20, 0),
child: TextField( child: TextField(
keyboardAppearance: Brightness.dark,
controller: userNameTextField, controller: userNameTextField,
decoration: const InputDecoration( decoration: const InputDecoration(
border: InputBorder.none, border: InputBorder.none,
@ -124,7 +123,6 @@ class _SignInPageState extends State<SignInPage> {
Padding( Padding(
padding: const EdgeInsets.fromLTRB(50, 0, 20, 0), padding: const EdgeInsets.fromLTRB(50, 0, 20, 0),
child: TextField( child: TextField(
keyboardAppearance: Brightness.dark,
controller: passwordTextField, controller: passwordTextField,
obscureText: true, obscureText: true,
decoration: const InputDecoration( decoration: const InputDecoration(
@ -257,17 +255,21 @@ 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 != "") {
//MyApp.controller.chargeExample();
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';
@ -224,7 +225,6 @@ class _SignUpPageState extends State<SignUpPage> {
), // background// foreground ), // background// foreground
), ),
onPressed: () { onPressed: () {
MyApp.controller.navigatorKey = context;
MyInAppBrowser(); MyInAppBrowser();
}, },
child: Row( child: Row(
@ -333,7 +333,7 @@ class _SignUpPageState extends State<SignUpPage> {
String username, String password, String confirmPassword) async { String username, String password, String confirmPassword) async {
if (username == "") { if (username == "") {
notify(2, context); notify(2, context);
} else if (!await MyApp.controller.searchUser(username)) { } else if (!await MyApp.controller.searchByUsername(username)) {
notify(0, context); notify(0, context);
} }
if (password == "" || confirmPassword == "") { if (password == "" || confirmPassword == "") {
@ -343,7 +343,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(

@ -106,13 +106,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:
@ -329,13 +322,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,18 +483,25 @@ 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
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
socket_io_client:
dependency: "direct main"
description:
name: socket_io_client
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
socket_io_common:
dependency: transitive
description:
name: socket_io_common
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@ -551,13 +544,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,7 @@ 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 socket_io_client: ^2.0.0
text_scroll: ^0.1.1
scroll_loop_auto_scroll: ^0.0.2
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