Browse Source

Merge pull request #66 from WildCodeSchool/dev

Merge dev sur master
Bastien Krettly 3 years ago
parent
commit
aba77a24d3
100 changed files with 5348 additions and 1216 deletions
  1. 0 0
      .gitignore
  2. 0 0
      .idea/gradle.xml
  3. 0 0
      .idea/runConfigurations.xml
  4. 0 0
      app/.gitignore
  5. 16 7
      app/build.gradle
  6. 16 0
      app/google-services.json
  7. 0 0
      app/keystore.jks
  8. 0 0
      app/proguard-rules.pro
  9. 1 1
      app/release/output.json
  10. 0 0
      app/src/androidTest/java/fr/wildcodeschool/steeryfit/ExampleInstrumentedTest.java
  11. 0 0
      app/src/debug/res/values/google_maps_api.xml
  12. 88 84
      app/src/main/AndroidManifest.xml
  13. BIN
      app/src/main/ic_launcher-web.png
  14. 21 3
      app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/AuthController.java
  15. 4 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/ConversationsController.java
  16. 3 1
      app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/EventsDetailsController.java
  17. 0 166
      app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/EventsQuery.java
  18. 197 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/EventsQueryController.java
  19. 0 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/LocationController.java
  20. 0 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/MessagesController.java
  21. 139 9
      app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/UserController.java
  22. 217 187
      app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/UserEventsController.java
  23. 39 39
      app/src/main/java/fr/wildcodeschool/steeryfit/Models/ConversationModel.java
  24. 15 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Models/EventModel.java
  25. 22 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Models/Gender.java
  26. 22 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Models/MessageModel.java
  27. 2 1
      app/src/main/java/fr/wildcodeschool/steeryfit/Models/Sports.java
  28. 6 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Models/UserModel.java
  29. 149 0
      app/src/main/java/fr/wildcodeschool/steeryfit/SearchEventResultActivity.java
  30. 225 0
      app/src/main/java/fr/wildcodeschool/steeryfit/SearchEventResultAdapter.java
  31. 119 17
      app/src/main/java/fr/wildcodeschool/steeryfit/Services/NotificationsService.java
  32. 0 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Services/TokenService.java
  33. 0 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/ConversationsActivity.java
  34. 14 17
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/EditoActivity.java
  35. 76 11
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/MainActivity.java
  36. 14 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/MessagesActivity.java
  37. 307 131
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/ModifyEventActivity.java
  38. 0 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/PhoneConfirmationActivity.java
  39. 26 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/ProfilActivity.java
  40. 1 1
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/SignInActivity.java
  41. 3 2
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/SignInMailActivity.java
  42. 0 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/SignUpMailActivity.java
  43. 71 5
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/Splashscreen.java
  44. 35 4
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Adapters/ConversationsAdapter.java
  45. 78 20
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Adapters/EventAdapter.java
  46. 63 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Adapters/MessagesAdapter.java
  47. 1 1
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Adapters/ParticipantsAdapter.java
  48. 0 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Adapters/PlaceAutocompleteAdapter.java
  49. 147 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Adapters/SportAdapter.java
  50. 31 14
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Adapters/SwipeDeckAdapter.java
  51. 89 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Adapters/UserSportAdapter.java
  52. 81 49
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/CreateEvent/CreateEventActivityPart1.java
  53. 179 85
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/CreateEvent/CreateEventActivityPart2.java
  54. 248 115
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/CreateEvent/CreateEventFragment.java
  55. 0 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/Behaviors/AvatarBehavior.java
  56. 0 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/Behaviors/RecyclerViewBehavior.java
  57. 143 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/Behaviors/SwipeItemTouchHelperCallback.java
  58. 9 2
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/ConversationsFragment.java
  59. 180 21
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/LocationPickerFragment.java
  60. 56 17
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/MainFragment.java
  61. 206 53
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/MessagesFragment.java
  62. 145 31
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/PlanningFragment.java
  63. 380 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/ProfileFragment.java
  64. 481 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/SearchEventFragment.java
  65. 300 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/Fragments/SportPickerFragment.java
  66. 22 13
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/LevelPickerDialogFragment.java
  67. 24 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserAccountCreatedConfirmationActivity.java
  68. 26 15
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserAliasConfigurationActivity.java
  69. 12 3
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserAvatarConfigurationActivity.java
  70. 7 1
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserDateOfBirthConfigurationActivity.java
  71. 35 6
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserEmailConfigurationActivity.java
  72. 23 1
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserFirstnameConfigurationActivity.java
  73. 20 13
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserGenderConfigurationActivity.java
  74. 21 3
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserLastnameConfigurationActivity.java
  75. 12 36
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserLocationConfigurationActivity.java
  76. 75 0
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserOptionalDescriptionConfigurationActivity.java
  77. 64 10
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserPasswordConfigurationActivity.java
  78. 1 1
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserPhoneConfigurationActivity.java
  79. 32 14
      app/src/main/java/fr/wildcodeschool/steeryfit/UI/ProfileConfiguration/UserSportsConfirgurationActivity.java
  80. 5 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Utils/Constants.java
  81. 0 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Utils/FirebaseGlideModule.java
  82. 1 1
      app/src/main/java/fr/wildcodeschool/steeryfit/Utils/FirebaseHelper.java
  83. 98 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Utils/HttpRequest.java
  84. 4 4
      app/src/main/java/fr/wildcodeschool/steeryfit/Utils/UserConfigurationHelper.java
  85. 72 1
      app/src/main/java/fr/wildcodeschool/steeryfit/Utils/Utils.java
  86. 47 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Utils/ViewUtil.java
  87. 55 0
      app/src/main/java/fr/wildcodeschool/steeryfit/Utils/WeakCollection.java
  88. 9 0
      app/src/main/res/drawable-anydpi/ic_home.xml
  89. 9 0
      app/src/main/res/drawable-anydpi/ic_mail.xml
  90. 9 0
      app/src/main/res/drawable-anydpi/ic_mode_edit.xml
  91. BIN
      app/src/main/res/drawable-hdpi/ball_nb.png
  92. BIN
      app/src/main/res/drawable-hdpi/bike_nb.png
  93. 0 0
      app/src/main/res/drawable-hdpi/blank_avatar.png
  94. BIN
      app/src/main/res/drawable-hdpi/event_arm.png
  95. BIN
      app/src/main/res/drawable-hdpi/event_ball.png
  96. BIN
      app/src/main/res/drawable-hdpi/event_bike.png
  97. BIN
      app/src/main/res/drawable-hdpi/event_calendar.png
  98. BIN
      app/src/main/res/drawable-hdpi/event_clock.png
  99. BIN
      app/src/main/res/drawable-hdpi/event_gender_female.png
  100. 0 0
      app/src/main/res/drawable-hdpi/event_gender_female_bw.png

+ 0 - 0
.gitignore


+ 0 - 0
.idea/gradle.xml


+ 0 - 0
.idea/runConfigurations.xml


+ 0 - 0
app/.gitignore


+ 16 - 7
app/build.gradle

@@ -6,9 +6,10 @@ android {
         applicationId "fr.wildcodeschool.steeryfit"
         minSdkVersion 16
         targetSdkVersion 26
-        versionCode 2
-        versionName "0.01"
+        versionCode 4
+        versionName "1.00"
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        multiDexEnabled true
     }
     buildTypes {
         release {
@@ -60,24 +61,32 @@ dependencies {
     // Glide
     compile 'com.github.bumptech.glide:glide:4.3.0'
     annotationProcessor 'com.github.bumptech.glide:compiler:4.3.0'
-
+    // Blur images
+    compile 'jp.wasabeef:glide-transformations:3.0.1'
+    // If you want to use the GPU Filters
+    compile 'jp.co.cyberagent.android.gpuimage:gpuimage-library:1.4.1'
     // Galery Image Picker
     compile 'com.github.jkwiecien:EasyImage:1.3.1'
-
     // Circle Image View
     compile 'de.hdodenhof:circleimageview:2.2.0'
-
     // Date & Time Pickers
     compile 'com.wdullaer:materialdatetimepicker:3.4.0'
-
     //Crop image
     compile 'com.theartofdev.edmodo:android-image-cropper:2.5.+'
-
     // Cards
     compile 'link.fls:swipestack:0.3.0'
+    //RecyclerView
+    compile 'com.android.support:recyclerview-v7:26.1.0'
+    compile 'com.android.support:cardview-v7:26.1.0'
+    compile 'com.android.support:design:26.1.0'
 
     // Notifications Badge
     compile 'com.nex3z:notification-badge:0.3.0'
 
+    // Async Http Client
+    compile 'com.loopj.android:android-async-http:1.4.9'
+
+    // Gson
+    compile 'com.google.code.gson:gson:2.8.2'
 }
 apply plugin: 'com.google.gms.google-services'

+ 16 - 0
app/google-services.json

@@ -15,6 +15,22 @@
       },
       "oauth_client": [
         {
+          "client_id": "729255598479-85k442g0hrooqjqv43s17k8uobnsplgj.apps.googleusercontent.com",
+          "client_type": 1,
+          "android_info": {
+            "package_name": "fr.wildcodeschool.steeryfit",
+            "certificate_hash": "88582105e52afa40bdc1db0bb06cb29b551fc87e"
+          }
+        },
+        {
+          "client_id": "729255598479-lfn9agpqds1e33s3ec7r08g311h3sbq6.apps.googleusercontent.com",
+          "client_type": 1,
+          "android_info": {
+            "package_name": "fr.wildcodeschool.steeryfit",
+            "certificate_hash": "98d661ce289f1045c6f3aa7c6515d500113ba2a9"
+          }
+        },
+        {
           "client_id": "729255598479-19ss3rkcia2hqkla7akk025vq34jtc6b.apps.googleusercontent.com",
           "client_type": 1,
           "android_info": {

+ 0 - 0
app/keystore.jks


+ 0 - 0
app/proguard-rules.pro


+ 1 - 1
app/release/output.json

@@ -1 +1 @@
-[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":2},"path":"app-release.apk","properties":{"packageId":"fr.wildcodeschool.steeryfit","split":"","minSdkVersion":"16"}}]
+[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":4},"path":"app-release.apk","properties":{"packageId":"fr.wildcodeschool.steeryfit","split":"","minSdkVersion":"16"}}]

+ 0 - 0
app/src/androidTest/java/fr/wildcodeschool/steeryfit/ExampleInstrumentedTest.java


+ 0 - 0
app/src/debug/res/values/google_maps_api.xml


+ 88 - 84
app/src/main/AndroidManifest.xml

@@ -1,19 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          xmlns:tools="http://schemas.android.com/tools"
-          package="fr.wildcodeschool.steeryfit">
+    xmlns:tools="http://schemas.android.com/tools"
+    package="fr.wildcodeschool.steeryfit">
 
     <!--
          The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
          Google Maps Android API v2, but you must specify either coarse or fine
          location permissions for the 'MyLocation' functionality.
     -->
-    <uses-permission android:name="android.permission.INTERNET"/>
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 
     <application
         android:allowBackup="true"
@@ -24,10 +24,11 @@
         android:theme="@style/AppTheme">
         <meta-data
             android:name="com.google.android.geo.API_KEY"
-            android:value="@string/google_maps_key"/>
-        <meta-data tools:replace="android:value"
-                   android:name="com.google.android.gms.version"
-                   android:value="@integer/google_play_services_version" />
+            android:value="@string/google_maps_key" />
+        <meta-data
+            android:name="com.google.android.gms.version"
+            android:value="@integer/google_play_services_version"
+            tools:replace="android:value" />
         <!--
              The API key for Google Maps-based APIs is defined as a string resource.
              (See the file "res/values/google_maps_api.xml").
@@ -37,123 +38,126 @@
              You can define the keys for the debug and release targets in src/debug/ and src/release/.
         -->
 
-        <!--Facebook SignIn-->
-        <meta-data android:name="com.facebook.sdk.ApplicationId"
-                   android:value="@string/facebook_app_id"/>
 
-        <activity android:name="com.facebook.FacebookActivity"
-                  android:configChanges=
-                      "keyboard|keyboardHidden|screenLayout|screenSize|orientation"
-                  android:label="@string/app_name" />
+        <!-- Facebook SignIn -->
+        <meta-data
+            android:name="com.facebook.sdk.ApplicationId"
+            android:value="@string/facebook_app_id" />
+
+        <activity
+            android:name="com.facebook.FacebookActivity"
+            android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
+            android:label="@string/app_name" />
         <activity
             android:name="com.facebook.CustomTabActivity"
             android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
+
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.BROWSABLE" />
+
                 <data android:scheme="@string/fb_login_protocol_scheme" />
             </intent-filter>
         </activity>
 
-        <!--Application-->
+        <!-- Application -->
         <activity
             android:name=".UI.Activities.Splashscreen"
             android:label="@string/app_name"
             android:noHistory="true">
             <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
+                <action android:name="android.intent.action.MAIN" />
 
-                <category android:name="android.intent.category.LAUNCHER"/>
+                <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
         <activity
-            android:name=".UI.Activities.EditoActivity">
-        </activity>
-        <activity
-            android:name=".UI.Activities.SignInActivity">
-        </activity>
-        <activity
-            android:name=".UI.Activities.SignInMailActivity">
-        </activity>
-        <activity
-            android:name=".UI.Activities.SignUpMailActivity">
-        </activity>
-        <activity
-            android:name=".UI.Activities.PhoneConfirmationActivity">
-        </activity>
-        <activity
-            android:name=".UI.ProfileConfiguration.UserEmailConfigurationActivity">
-        </activity>
-        <activity
-            android:name=".UI.ProfileConfiguration.UserPasswordConfigurationActivity">
-        </activity>
-        <activity
-            android:name=".UI.Activities.MainActivity"/>
-        <activity
-            android:name=".UI.CreateEvent.CreateEventActivityPart1"/>
-        <activity
-            android:name=".UI.CreateEvent.CreateEventActivityPart2"/>
-        <activity
-            android:name=".UI.ProfileConfiguration.UserPhoneConfigurationActivity">
-        </activity>
-        <activity
-            android:name=".UI.ProfileConfiguration.UserFirstnameConfigurationActivity">
-        </activity>
-        <activity
-            android:name=".UI.ProfileConfiguration.UserLastnameConfigurationActivity">
-        </activity>
-        <activity
-            android:name=".UI.ProfileConfiguration.UserAliasConfigurationActivity">
-        </activity>
-        <activity
-            android:name=".UI.ProfileConfiguration.UserDateOfBirthConfigurationActivity">
-        </activity>
-        <activity
-            android:name=".UI.ProfileConfiguration.UserGenderConfigurationActivity">
-        </activity>
-        <activity
-            android:name=".UI.ProfileConfiguration.UserAvatarConfigurationActivity">
-        </activity>
+            android:name=".UI.Activities.ProfilActivity"
+            android:windowSoftInputMode="stateHidden">
+        </activity>
+        <activity android:name=".UI.Activities.EditoActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.Activities.SignInActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.Activities.SignInMailActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.Activities.SignUpMailActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.Activities.PhoneConfirmationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.ProfileConfiguration.UserEmailConfigurationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.ProfileConfiguration.UserPasswordConfigurationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity
+            android:name=".UI.Activities.MainActivity"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".UI.CreateEvent.CreateEventActivityPart1"
+            android:screenOrientation="portrait" />
+        <activity
+            android:name=".UI.CreateEvent.CreateEventActivityPart2"
+            android:screenOrientation="portrait" />
+        <activity android:name=".UI.ProfileConfiguration.UserPhoneConfigurationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.ProfileConfiguration.UserFirstnameConfigurationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.ProfileConfiguration.UserLastnameConfigurationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.ProfileConfiguration.UserAliasConfigurationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.ProfileConfiguration.UserDateOfBirthConfigurationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.ProfileConfiguration.UserGenderConfigurationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.ProfileConfiguration.UserAvatarConfigurationActivity"
+                  android:screenOrientation="portrait"/>
         <activity
             android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
-            android:theme="@style/Base.Theme.AppCompat"/> <!-- optional (needed if default theme has no action bar) -->
-        <activity android:name=".UI.ProfileConfiguration.UserSportsConfirgurationActivity">
-        </activity>
-        <activity
-            android:name=".UI.ProfileConfiguration.UserLocationConfigurationActivity">
-        </activity>
-        <activity
-            android:name=".UI.Activities.ConversationsActivity">
-        </activity>
+            android:theme="@style/Base.Theme.AppCompat" /> <!-- optional (needed if default theme has no action bar) -->
+
+        <activity android:name=".UI.ProfileConfiguration.UserSportsConfirgurationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.ProfileConfiguration.UserLocationConfigurationActivity"
+                  android:screenOrientation="portrait"/>
+        <activity android:name=".UI.Activities.ConversationsActivity" />
         <activity
             android:name=".UI.Activities.MessagesActivity">
         </activity>
+        <activity android:name=".SearchEventResultActivity">
+        </activity>
         <activity
-            android:name=".UI.Activities.ModifyEventActivity">
+            android:name=".UI.Activities.ModifyEventActivity"
+            android:noHistory="true">
         </activity>
         <service
             android:name=".Services.NotificationsService">
             <intent-filter>
-                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
+                <action android:name="com.google.firebase.MESSAGING_EVENT" />
             </intent-filter>
         </service>
-
         <service
             android:name=".Services.TokenService"
             android:exported="false">
             <intent-filter>
-                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
+                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
             </intent-filter>
         </service>
+
         <meta-data
             android:name="com.google.firebase.messaging.default_notification_icon"
             android:resource="@drawable/ic_launcher_foreground" />
-        <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
-             notification message. See README(https://goo.gl/6BKBk7) for more. -->
+        <!--
+             Set color used with incoming notification messages. This is used when no color is set for the incoming
+             notification message. See README(https://goo.gl/6BKBk7) for more.
+        -->
         <meta-data
             android:name="com.google.firebase.messaging.default_notification_color"
             android:resource="@color/accentRed" />
+
+        <activity android:name=".UI.ProfileConfiguration.UserAccountCreatedConfirmationActivity" />
+        <activity android:name=".UI.ProfileConfiguration.UserOptionalDescriptionConfigurationActivity"></activity>
     </application>
 
 </manifest>

BIN
app/src/main/ic_launcher-web.png


+ 21 - 3
app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/AuthController.java

@@ -30,6 +30,7 @@ import com.google.firebase.auth.FirebaseUser;
 import com.google.firebase.auth.GoogleAuthProvider;
 import com.google.firebase.auth.PhoneAuthCredential;
 import com.google.firebase.auth.PhoneAuthProvider;
+import com.google.firebase.iid.FirebaseInstanceId;
 
 import java.util.Arrays;
 import java.util.concurrent.TimeUnit;
@@ -70,6 +71,8 @@ public class AuthController {
     private String mPassword;
     private String mConfirmPassword;
 
+    private String mAuthTokenId = "";
+
     /**
      * Private Constructor of the UserController AuthController
      */
@@ -97,7 +100,12 @@ public class AuthController {
             @Override
             public void onSuccess(LoginResult loginResult) {
                 AuthCredential credential = FacebookAuthProvider.getCredential(loginResult.getAccessToken().getToken());
-                mAuth.signInWithCredential(credential).addOnCompleteListener(mFirebaseAuthCompleteListener);
+                mAuth.signInWithCredential(credential).addOnCompleteListener(task -> {
+                    if(!task.isSuccessful()) {
+                        connectionFailure(task.getException().getMessage());
+                        Log.d(TAG, "FirebaseAuth with Facebook: " + task.getException().getMessage());
+                    }
+                });
             }
 
             @Override
@@ -118,6 +126,11 @@ public class AuthController {
                 mUser = firebaseAuth.getCurrentUser();
                 if (mUser != null) {
                     // User is signed in
+                    mUser.getIdToken(true).addOnSuccessListener(getTokenResult -> {
+                        mAuthTokenId = getTokenResult.getToken();
+                        Log.d(TAG, "onAuthStateChanged: TokenId: " + mAuthTokenId);
+                    });
+                    Log.d(TAG, "onAuthStateChanged: Notification Token: " + FirebaseInstanceId.getInstance().getToken());
                     Log.d(TAG, "onAuthStateChanged:signed_in UID:" + mUser.getUid());
                     Log.d(TAG, "onAuthStateChanged:signed_in Phone Number:" + mUser.getPhoneNumber());
                     mUser = mAuth.getCurrentUser();
@@ -127,6 +140,7 @@ public class AuthController {
                         connectionSuccess(false);
                     }
                     else {
+
                         connectionSuccess(false);
                     }
 
@@ -155,7 +169,6 @@ public class AuthController {
                     }
                 } else {
                     // If sign in fails, display a message to the user.
-                    Log.w(TAG, "signInWithEmail:failure", task.getException());
                     connectionFailure(task.getException().getMessage().toString());
                 }
             }
@@ -273,7 +286,12 @@ public class AuthController {
         Log.d(TAG, "firebaseAuthWithGoogle:" + account.getId());
         AuthCredential credential = GoogleAuthProvider.getCredential(account.getIdToken(), null);
         mAuth.signInWithCredential(credential)
-                .addOnCompleteListener(mFirebaseAuthCompleteListener);
+                .addOnCompleteListener(task -> {
+                    if(!task.isSuccessful()) {
+                        connectionFailure(task.getException().getMessage());
+                        Log.d(TAG, "firebaseAuthWithGoogle: " + task.getException().getMessage());
+                    }
+                });
     }
 
     public void getAuthWithFacebook(int requestCode, int resultCode, Intent data) {

+ 4 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/ConversationsController.java

@@ -296,8 +296,12 @@ public class ConversationsController {
     public static void destroy(){
         sInstance = null;
     }
+    public static boolean isInstanciated() {
+        return sInstance != null;
+    }
 
     private void getUnreadMessagesCount(ConversationModel conversation) {
+        if(conversation.getUid() == null) return;
         mDatabase.getReference(MESSAGES_ENTRY).child(conversation.getUid())
                 .addListenerForSingleValueEvent(new ValueEventListener() {
                     @Override

+ 3 - 1
app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/EventsDetailsController.java

@@ -30,7 +30,9 @@ public class EventsDetailsController {
         DatabaseReference rootReference = FirebaseHelper.getDatabase().getReference(USERS_ENTRY);
         references.add(rootReference.child(event.getCreatorUid()));
         for(String uid : event.getParticipants().keySet()) {
-            references.add(rootReference.child(uid));
+            if(event.getParticipants().get(uid)) {
+                references.add(rootReference.child(uid));
+            }
         }
         FirebaseHelper.request(references).setOnCompleteListener((results, e) -> {
             ArrayList<UserModel> users = new ArrayList<>();

+ 0 - 166
app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/EventsQuery.java

@@ -1,166 +0,0 @@
-package fr.wildcodeschool.steeryfit.Controllers;
-
-import android.support.annotation.Nullable;
-import android.util.Log;
-
-import com.google.android.gms.maps.model.LatLng;
-import com.google.firebase.database.DataSnapshot;
-import com.google.firebase.database.DatabaseError;
-import com.google.firebase.database.DatabaseReference;
-import com.google.firebase.database.FirebaseDatabase;
-import com.google.firebase.database.Query;
-import com.google.firebase.database.ValueEventListener;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-import fr.wildcodeschool.steeryfit.Models.EventModel;
-import fr.wildcodeschool.steeryfit.Models.Sports;
-import fr.wildcodeschool.steeryfit.Models.UserModel;
-import fr.wildcodeschool.steeryfit.Utils.FirebaseHelper;
-import fr.wildcodeschool.steeryfit.Utils.Utils;
-
-import static fr.wildcodeschool.steeryfit.Utils.Constants.EVENTS_ENTRY;
-import static fr.wildcodeschool.steeryfit.Utils.Constants.LATITUDE_ENTRY;
-import static fr.wildcodeschool.steeryfit.Utils.Constants.LONGITUDE_ENTRY;
-import static fr.wildcodeschool.steeryfit.Utils.Constants.SPORT_ENTRY;
-
-/**
- * Created by Philippe-Adrien on 08/12/2017.
- */
-
-public class EventsQuery {
-    private final String TAG = Utils.getTAG(this);
-    // Sort Flags
-    public static final int DISTANCE = 2;
-    public static final int DATE = 4;
-
-    private UserEventsController mUserEventsController;
-    private UserModel mUser;
-    private HashMap<String, Boolean> mUserEvents;
-
-    private DatabaseReference mEventsReference;
-
-    private OnCompleteListener mOnCompleteListener = null;
-
-    private Sports.Type mSport = null;
-    private Sports.Level mLevel = null;
-    private LatLng mLocation;
-    private double mDistance = 0;
-    private long mDate = System.currentTimeMillis();
-    private int mSortFlags = 0;
-
-    private Query mQuery;
-    private ArrayList<EventModel> mResults = new ArrayList<>();
-
-    public EventsQuery(){
-        mUser = UserController.getInstance().getUser();
-        mUserEventsController = UserEventsController.getInstance();
-        mUserEvents = UserEventsController.getInstance().getUserEventsReferenceMap();
-        FirebaseDatabase database = FirebaseHelper.getDatabase();
-        mEventsReference = database.getReference(EVENTS_ENTRY);
-
-        mLocation = mUser.getLocation();
-        mDistance = mUser.getDistance();
-    }
-
-    public EventsQuery sport(Sports.Type sport) {
-        mSport = sport;
-        return this;
-    }
-
-    public EventsQuery level(Sports.Level level) {
-        mLevel = level;
-        return this;
-    }
-
-    public EventsQuery location(LatLng location) {
-        mLocation = location;
-        return this;
-    }
-
-    public EventsQuery distance(double distance) {
-        mDistance = distance;
-        return this;
-    }
-
-    public EventsQuery date(long date) {
-        mDate = date;
-        return this;
-    }
-
-    public EventsQuery sort(int sortFlags){
-        mSortFlags = sortFlags;
-        return this;
-    }
-
-    public EventsQuery get() {
-        if(mSport == null) throw new RuntimeException("The sport must be informed.");
-        mQuery = mEventsReference.orderByChild(SPORT_ENTRY).equalTo(mSport.toString());
-        mQuery.addListenerForSingleValueEvent(new ValueEventListener() {
-            @Override
-            public void onDataChange(DataSnapshot dataSnapshot) {
-                for(DataSnapshot data : dataSnapshot.getChildren()) {
-                    EventModel event = data.getValue(EventModel.class);
-                    LatLng eventLocation = new LatLng(event.getLocation().get(LATITUDE_ENTRY), event.getLocation().get
-                            (LONGITUDE_ENTRY));
-                    // TODO : Proper Participants Count
-                    int participantsCount = 0;
-                    HashMap<String, Boolean> participants = event.getParticipants();
-                    for(String userUid : participants.keySet()) {
-                        if(participants.get(userUid)) {
-                            participantsCount++;
-                        }
-                    }
-
-                    if (!mUserEvents.containsKey(event.getUid())
-                            && event.getDate() >= mDate
-                            && Utils.getDistanceInMeter(mLocation, eventLocation) <= mDistance
-                            && event.getUsersLimit() != participantsCount) {
-                        if (mLevel == null || event.getLevel().equals(mLevel)) {
-                            Log.d(TAG, "onDataChange: Event found " + event);
-                            mResults.add(event);
-                        }
-                    }
-                }
-
-                // TODO: sort
-                Log.d(TAG, "onDataChange: " + EventsQuery.this);
-                if(mOnCompleteListener != null) {
-                    mOnCompleteListener.onComplete(mResults, null);
-                }
-            }
-
-            @Override
-            public void onCancelled(DatabaseError databaseError) {
-                if(mOnCompleteListener != null) {
-                    mOnCompleteListener.onComplete(mResults, databaseError.toException());
-                }
-            }
-        });
-        return this;
-    }
-
-    public EventsQuery setOnCompleteListener(OnCompleteListener listener) {
-        mOnCompleteListener = listener;
-        return this;
-    }
-
-    public interface OnCompleteListener {
-        void onComplete(ArrayList<EventModel> results, @Nullable Exception e);
-    }
-
-    @Override
-    public String toString() {
-        return "EventsQuery{" +
-                "mSport=" + mSport +
-                ", mLevel=" + mLevel +
-                ", mLocation=" + mLocation +
-                ", mDistance=" + mDistance +
-                ", mDate=" + mDate +
-                ", mSortFlags=" + mSortFlags +
-                '}';
-    }
-}
-
-

+ 197 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/EventsQueryController.java

@@ -0,0 +1,197 @@
+package fr.wildcodeschool.steeryfit.Controllers;
+
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import com.google.android.gms.maps.model.LatLng;
+import com.google.firebase.database.DatabaseReference;
+import com.google.firebase.database.FirebaseDatabase;
+import com.google.gson.Gson;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+
+import fr.wildcodeschool.steeryfit.Models.EventModel;
+import fr.wildcodeschool.steeryfit.Models.Sports;
+import fr.wildcodeschool.steeryfit.Models.UserModel;
+import fr.wildcodeschool.steeryfit.Utils.FirebaseHelper;
+import fr.wildcodeschool.steeryfit.Utils.HttpRequest;
+import fr.wildcodeschool.steeryfit.Utils.Utils;
+
+import static fr.wildcodeschool.steeryfit.Utils.Constants.EVENTS_ENTRY;
+import static fr.wildcodeschool.steeryfit.Utils.HttpRequest.EVENT_SEARCH;
+
+/**
+ * Created by Philippe-Adrien on 08/12/2017.
+ */
+
+public class EventsQueryController {
+
+    private static EventsQueryController sInstance;
+
+    private DatabaseReference mEventsReference;
+    private EventsQuery mEventsQuery = null;
+    private ArrayList<EventModel> mResults = null;
+    private UserModel mUser;
+
+
+    private EventsQueryController() {
+        mUser = UserController.getInstance().getUser();
+        FirebaseDatabase database = FirebaseHelper.getDatabase();
+        mEventsReference = database.getReference(EVENTS_ENTRY);
+    }
+
+    public static EventsQueryController getInstance() {
+        if (sInstance == null) {
+            sInstance = new EventsQueryController();
+        }
+        return sInstance;
+    }
+
+    public EventsQuery getQuery() {
+        mResults = null;
+        mEventsQuery = new EventsQuery();
+        return mEventsQuery;
+    }
+
+    public EventsQuery getLastQuery() {
+        if(mEventsQuery == null) {
+            throw new RuntimeException("No previous query");
+        }
+        return mEventsQuery;
+    }
+
+    public ArrayList<EventModel> getResults() {
+        return mResults;
+    }
+
+    public interface OnCompleteListener {
+        void onComplete(ArrayList<EventModel> results, @Nullable Exception e);
+    }
+
+    public class EventsQuery {
+        private final String TAG = Utils.getTAG(this);
+        // Sort Flags
+        public static final int DISTANCE = 2;
+        public static final int TIME = 4;
+
+        private OnCompleteListener mOnCompleteListener = null;
+
+        private Sports.Type mSport = null;
+        private Sports.Level mLevel = null;
+        private LatLng mLocation;
+        private double mDistance = 0;
+        private long mDate;
+        private int mSortFlags = 0;
+
+        public EventsQuery() {
+            mDate = new Date().getTime();
+            mResults = new ArrayList<>();
+        }
+
+        public EventsQuery sport(Sports.Type sport) {
+            mSport = sport;
+            return this;
+        }
+
+        public EventsQuery level(Sports.Level level) {
+            mLevel = level;
+            return this;
+        }
+
+        public EventsQuery location(LatLng location) {
+            mLocation = location;
+            return this;
+        }
+
+        public EventsQuery distance(double distance) {
+            mDistance = distance;
+            return this;
+        }
+
+        public EventsQuery date(long date) {
+            mDate = date;
+            return this;
+        }
+
+        public EventsQuery sort(int sortFlags) {
+            mSortFlags = sortFlags;
+            return this;
+        }
+
+        public EventsQuery refresh() {
+            mResults.clear();
+            get();
+            return this;
+        }
+
+        public EventsQuery get() {
+            if(mLocation == null || mDistance == 0) throw new RuntimeException("Location and Distance required.");
+            HttpRequest.Builder request = new HttpRequest.Builder().path(EVENT_SEARCH);
+            if(mSport != null) request.addParam("sport", mSport.toString());
+            if(mLevel != null) request.addParam("level", mLevel.toString());
+            request.addParam("longitude", String.valueOf(mLocation.longitude))
+                    .addParam("latitude", String.valueOf(mLocation.latitude))
+                    .addParam("distance", String.valueOf(mDistance))
+                    .addParam("time", String.valueOf(mDate))
+                    .get((resultString, e) -> {
+                        Log.d(TAG, "get() called" + resultString);
+                        if(e == null && resultString != null) {
+                            Gson gson = new Gson();
+                            mResults.addAll(Arrays.asList(gson.fromJson(resultString, EventModel[].class)));
+                            if (mOnCompleteListener != null) {
+                                mOnCompleteListener.onComplete(mResults, null);
+                            }
+                        }
+                        else {
+                            if (mOnCompleteListener != null) {
+                                mOnCompleteListener.onComplete(mResults, e);
+                            }
+                        }
+                    });
+            return this;
+        }
+
+        public EventsQuery getDefault() {
+            new HttpRequest.Builder().path(EVENT_SEARCH).get((resultString, e) -> {
+                Log.d(TAG, "getDefault: " + resultString);
+                if(e == null && resultString != null) {
+                    Gson gson = new Gson();
+                    mResults = new ArrayList<>(
+                            Arrays.asList(gson.fromJson(resultString, EventModel[].class))
+                    );
+                    if (mOnCompleteListener != null) {
+                        mOnCompleteListener.onComplete(mResults, null);
+                    }
+                }
+                else {
+                    if (mOnCompleteListener != null) {
+                        mOnCompleteListener.onComplete(mResults, e);
+                    }
+                }
+            });
+
+            return this;
+        }
+
+        public EventsQuery setOnClompleteListener(OnCompleteListener listener) {
+            mOnCompleteListener = listener;
+            return this;
+        }
+
+        @Override
+        public String toString() {
+            return "EventsQuery{" +
+                    "mSport=" + mSport +
+                    ", mLevel=" + mLevel +
+                    ", mLocation=" + mLocation +
+                    ", mDistance=" + mDistance +
+                    ", mDate=" + mDate +
+                    ", mSortFlags=" + mSortFlags +
+                    '}';
+        }
+    }
+}
+
+

+ 0 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/LocationController.java


+ 0 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/MessagesController.java


+ 139 - 9
app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/UserController.java

@@ -1,5 +1,7 @@
 package fr.wildcodeschool.steeryfit.Controllers;
 
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.util.Log;
@@ -15,6 +17,7 @@ import com.google.firebase.iid.FirebaseInstanceId;
 
 import java.util.HashMap;
 
+import fr.wildcodeschool.steeryfit.Models.Gender;
 import fr.wildcodeschool.steeryfit.Models.Sports;
 import fr.wildcodeschool.steeryfit.Models.UserModel;
 import fr.wildcodeschool.steeryfit.Utils.FirebaseHelper;
@@ -95,11 +98,9 @@ public class UserController implements OnSuccessListener, OnFailureListener{
     }
 
     public UserController sendToken() {
-        String token = sNotificationsToken;
-        if(sNotificationsToken.isEmpty()) {
-            token = FirebaseInstanceId.getInstance().getToken();
-        }
-        mUserReference.child(FIREBASE_TOKEN_ENTRY).setValue(token)
+        String notificationToken = FirebaseInstanceId.getInstance().getToken();
+        Log.d(TAG, "sendToken() Notification token: " + notificationToken);
+        mUserReference.child(FIREBASE_TOKEN_ENTRY).setValue(notificationToken)
                 .addOnSuccessListener(this).addOnFailureListener(this);
         return sInstance;
     }
@@ -122,14 +123,12 @@ public class UserController implements OnSuccessListener, OnFailureListener{
     public void setFirstName(String firstName) {
         mUser.setFirstName(firstName);
         mUserReference.child("firstName").setValue(firstName).addOnSuccessListener(this).addOnFailureListener(this);
-
     }
 
 
     public void setLastName(String lastName) {
         mUser.setName(lastName);
         mUserReference.child("lastName").setValue(lastName).addOnSuccessListener(this).addOnFailureListener(this);
-
     }
 
 
@@ -140,10 +139,10 @@ public class UserController implements OnSuccessListener, OnFailureListener{
     }
 
 
-    public void setGender(String gender) {
+    public void setGender(Gender gender) {
         // As it is the first element in the profile we need to init some elements
         mUser.setUid(mAuthController.getUser().getUid());
-        mUser.setGender(gender);
+        mUser.setGender(gender.toString());
         HashMap<String, Object> data = new HashMap<>();
         data.put("uid", mUser.getUid());
         data.put("gender", mUser.getGender());
@@ -224,6 +223,10 @@ public class UserController implements OnSuccessListener, OnFailureListener{
         mUserReference.child("location").setValue(l).addOnSuccessListener(this).addOnFailureListener(this);
     }
 
+    public void setUser(UserModel user) {
+        mUser = user;
+    }
+
     @Override
     public void onFailure(@NonNull Exception e) {
         if(mUpdateProfileListener != null){
@@ -272,4 +275,131 @@ public class UserController implements OnSuccessListener, OnFailureListener{
     public static void destroy(){
         sInstance = null;
     }
+
+    public UserUpdateBuilder getUpdateBuilder() {
+        return new UserUpdateBuilder();
+    }
+
+
+    public class UserUpdateBuilder {
+
+        private HashMap<String, Object> mUpdates;
+        private OnUpdateResultListener mOnUpdateResultListener = null;
+        private Drawable mAvatar = null;
+
+        public UserUpdateBuilder() {
+            mUpdates = new HashMap<>();
+        }
+
+        public UserUpdateBuilder name(String name){
+            mUpdates.put("name", name);
+            return this;
+        }
+
+        public UserUpdateBuilder firstName(String firstName) {
+            mUpdates.put("firstName", firstName);
+            return this;
+        }
+
+        public UserUpdateBuilder lastName(String lastName) {
+            mUpdates.put("lastName", lastName);
+            return this;
+        }
+
+        public UserUpdateBuilder avatar(Drawable drawable) {
+            mAvatar = drawable;
+            return this;
+        }
+
+        public UserUpdateBuilder gender(Gender gender) {
+            mUpdates.put("gender", gender.toString());
+            return this;
+        }
+
+        public UserUpdateBuilder city(String city) {
+            mUpdates.put("city", city);
+            return this;
+        }
+
+        public UserUpdateBuilder description(String description) {
+            mUpdates.put("description", description);
+            return this;
+        }
+
+        public UserUpdateBuilder dateOfBirth(long dateOfBirth) {
+            mUpdates.put("dateOfBirth", dateOfBirth);
+            return this;
+        }
+
+        public UserUpdateBuilder distance(int distance) {
+            mUpdates.put("distance", distance);
+            return this;
+        }
+
+        public UserUpdateBuilder location(HashMap<String, Double> location) {
+            mUpdates.put("location", location);
+            return this;
+        }
+
+        public UserUpdateBuilder sports(HashMap<Sports.Type, Sports.Level> sports) {
+            HashMap<String, String> s = new HashMap<>();
+            for(Sports.Type t : sports.keySet()) {
+                s.put(t.toString(), sports.get(t).toString());
+            }
+            mUpdates.put("sports", s);
+            return this;
+        }
+
+        public UserUpdateBuilder build() {
+            if(mUpdates.isEmpty()) {
+                Log.w(TAG, "build: No update have been set.");
+                return this;
+            }
+            if(mAvatar != null) {
+                FirebaseHelper.uploadAvatar(mAvatar, mUser.getUid())
+                        .setUploadImageListener(new FirebaseHelper.UploadImageListener() {
+                    @Override
+                    public void onSuccess(Uri imageUri) {
+                        mUpdates.put("avatar", imageUri.toString());
+                        mUser.setAvatar(imageUri.toString());
+                        Log.d(TAG, "onSuccess() called with: imageUri = [" + imageUri + "]");
+                        update();
+                    }
+
+                    @Override
+                    public void onFailure(String error) {
+                        if(mOnUpdateResultListener != null){
+                            mOnUpdateResultListener.onUpdateResultListener(new Exception(error));
+                        }
+                    }
+                });
+            }
+            else {
+                update();
+            }
+
+            return this;
+        }
+
+        public UserUpdateBuilder setOnUpdateResultListener(OnUpdateResultListener onUpdateResultListener) {
+            mOnUpdateResultListener = onUpdateResultListener;
+            return this;
+        }
+
+        private void update() {
+            mUserReference.updateChildren(mUpdates).addOnCompleteListener(task -> {
+                if(task.isSuccessful() && mOnUpdateResultListener != null) {
+                    mOnUpdateResultListener.onUpdateResultListener(null);
+                }
+                else if(mOnUpdateResultListener != null){
+                    mOnUpdateResultListener.onUpdateResultListener(task.getException());
+                }
+            });
+        }
+    }
+
+    public interface OnUpdateResultListener {
+        void onUpdateResultListener(@Nullable Exception e);
+    }
+
 }

+ 217 - 187
app/src/main/java/fr/wildcodeschool/steeryfit/Controllers/UserEventsController.java

@@ -4,6 +4,7 @@ import android.graphics.Bitmap;
 import android.net.Uri;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.text.format.DateUtils;
 import android.util.Log;
 
 import com.google.android.gms.tasks.OnCompleteListener;
@@ -17,29 +18,36 @@ import com.google.firebase.database.DatabaseReference;
 import com.google.firebase.database.FirebaseDatabase;
 import com.google.firebase.database.ValueEventListener;
 import com.google.firebase.storage.StorageReference;
+import com.google.gson.Gson;
 
+import java.util.Calendar;
 import java.util.HashMap;
-import java.util.Map;
 
+import fr.wildcodeschool.steeryfit.Models.ConversationModel;
 import fr.wildcodeschool.steeryfit.Models.EventModel;
+import fr.wildcodeschool.steeryfit.Models.Gender;
 import fr.wildcodeschool.steeryfit.Models.Sports;
 import fr.wildcodeschool.steeryfit.Models.UserModel;
 import fr.wildcodeschool.steeryfit.Utils.FirebaseHelper;
+import fr.wildcodeschool.steeryfit.Utils.HttpRequest;
 import fr.wildcodeschool.steeryfit.Utils.Utils;
 
 import static fr.wildcodeschool.steeryfit.Utils.Constants.EVENTS_ENTRY;
-import static fr.wildcodeschool.steeryfit.Utils.Constants.EVENTS_PARTICIPANTS_ENTRY;
 import static fr.wildcodeschool.steeryfit.Utils.Constants.EVENTS_PREVIEW_ENTRY;
 import static fr.wildcodeschool.steeryfit.Utils.Constants.USERS_EVENTS_ENTRY;
+import static fr.wildcodeschool.steeryfit.Utils.HttpRequest.EVENT_CANCEL;
+import static fr.wildcodeschool.steeryfit.Utils.HttpRequest.EVENT_CONFIRM;
+import static fr.wildcodeschool.steeryfit.Utils.HttpRequest.EVENT_DELETE;
+import static fr.wildcodeschool.steeryfit.Utils.HttpRequest.EVENT_MATCH;
+import static fr.wildcodeschool.steeryfit.Utils.HttpRequest.EVENT_REJECT;
 
 /**
  * Created by apprenti on 11/16/17.
  */
 
-public class UserEventsController implements OnSuccessListener, OnFailureListener{
-    private final String TAG = Utils.getTAG(this);
+public class UserEventsController implements OnSuccessListener, OnFailureListener {
     private static volatile UserEventsController sInstance = null;
-
+    private final String TAG = Utils.getTAG(this);
     private FirebaseDatabase mDatabase;
     private DatabaseReference mEventsRef;
     private DatabaseReference mUsersEventsReference;
@@ -56,10 +64,115 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
     // Listeners
     private EventsListener mEventsListener = null;
     private UpdateEventListener mUpdateEventListener = null;
+    private OnEventMatchedListener mOnEventMatchedListener = null;
+
+
+    private ValueEventListener mGlobalEventsListener = new ValueEventListener() {
+        @Override
+        public void onDataChange(DataSnapshot snapshot) {
+            EventModel event = snapshot.getValue(EventModel.class);
+            if (event == null) {
+                if(mEventsListener != null) {
+                    mEventsListener.onEventRemoved(mUserEvents.get(snapshot.getKey()));
+                }
+                mUserEventsReferenceMap.remove(snapshot.getKey());
+                return;
+            }
+            if(mUserEvents.containsKey(event.getUid())) {
+                boolean passed = (event.getDate() + DateUtils.DAY_IN_MILLIS) < Calendar.getInstance().getTimeInMillis();
+                if(passed) {
+                    mUserEvents.remove(event.getUid());
+                    mUserEventsReferenceMap.remove(event.getUid());
+                    if(mEventsListener != null) {
+                        mEventsListener.onEventRemoved(event);
+                    }
+                }
+                else {
+                    mUserEvents.put(event.getUid(), event);
+                    if(mEventsListener != null) {
+                        mEventsListener.onEventChanged(event);
+                    }
+                    if(event.equals(mSelectedEvent)) {
+                        mSelectedEvent = event;
+                    }
+                }
+            }
+            else {
+                boolean passed = (event.getDate() + DateUtils.DAY_IN_MILLIS) < Calendar.getInstance().getTimeInMillis();
+                if(passed) {
+                    mUserEvents.remove(event.getUid());
+                    mUserEventsReferenceMap.remove(event.getUid());
+                    if(mEventsListener != null) {
+                        mEventsListener.onEventRemoved(event);
+                    }
+                }
+                else {
+                    mUserEvents.put(event.getUid(), event);
+                }
+            }
+
+        }
+
+        @Override
+        public void onCancelled(DatabaseError error) {
+
+        }
+    };
+    private ChildEventListener mDatabaseUserEventsListener = new ChildEventListener() {
+        @Override
+        public void onChildAdded(DataSnapshot snapshot, String s) {
+            Log.d(TAG, "onChildAdded() called with: snapshot = [" + snapshot + "], s = [" + s + "]");
+            // Set in the event's references's map
+            String eventUid = snapshot.getKey();
+            final Boolean valid = snapshot.getValue(Boolean.class);
+            mUserEventsReferenceMap.put(eventUid, valid);
+
+            if (valid) {
+                // Start listening on Event changes
+                mEventsRef.child(eventUid).addValueEventListener(mGlobalEventsListener);
+            }
+        }
+
+        @Override
+        public void onChildChanged(DataSnapshot snapshot, String s) {
+            Log.d(TAG, "onChildChanged() called with: snapshot = [" + snapshot + "], s = [" + s + "]");
+            String eventUid = snapshot.getKey();
+            Boolean valid = snapshot.getValue(Boolean.class);
+            mUserEventsReferenceMap.put(eventUid, valid);
+            if (!valid) {
+                mEventsRef.child(eventUid).removeEventListener(mGlobalEventsListener);
+                EventModel event = mUserEvents.remove(eventUid);
+                if (mEventsListener != null) {
+                    mEventsListener.onEventRemoved(event);
+                }
+            }
+        }
+
+        @Override
+        public void onChildRemoved(DataSnapshot snapshot) {
+            Log.d(TAG, "onChildRemoved() called with: snapshot = [" + snapshot + "]");
+            String eventUid = snapshot.getKey();
+            mUserEventsReferenceMap.remove(snapshot.getKey());
+            if (mEventsListener != null) {
+                mEventsListener.onEventRemoved(mUserEvents.get(eventUid));
+            }
+            mUserEvents.remove(eventUid);
+        }
+
+        @Override
+        public void onChildMoved(DataSnapshot snapshot, String s) {
+
+        }
+
+        @Override
+        public void onCancelled(DatabaseError error) {
+
+        }
+    };
 
     private UserEventsController() {
         // Prevent from the reflection API.
-        if(sInstance != null) {
+        if (sInstance != null) {
             throw new RuntimeException("Use getInstance() to get the single instance of this class.");
         }
 
@@ -74,13 +187,15 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
         mUserEventsRef.addChildEventListener(mDatabaseUserEventsListener);
     }
 
+    // Pick Events Actions
+
     public static UserEventsController getInstance() {
         // Check for the first time
-        if(sInstance == null) {
+        if (sInstance == null) {
             // Check for the second time
             synchronized (UserEventsController.class) {
                 // If no Instance available create new One
-                if(sInstance == null) {
+                if (sInstance == null) {
                     sInstance = new UserEventsController();
                 }
             }
@@ -92,55 +207,47 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
         sInstance = null;
     }
 
-    // Pick Events Actions
+    public static boolean isInstantiated() {
+        return sInstance != null;
+    }
+
+
+    // Events Administration Actions
+
     /**
      * Method handling the User Matching an Event(Swipe event card right)
+     *
      * @param event
      */
     public void matchEvent(EventModel event) {
-        // Add User to Global Events Table
-        String globalEventPath = String.format("%s/%s/%s/%s", EVENTS_ENTRY, event.getUid(),
-                EVENTS_PARTICIPANTS_ENTRY, mUserUid);
-
-        // Add event in this events Table
-        String userEventPath = String.format("%s/%s/%s", USERS_EVENTS_ENTRY, mUserUid, event.getUid());
-        Map<String, Object> data = new HashMap<>();
-        // Waiting for confirmation
-        data.put(globalEventPath, false);
-        // Applying to Event
-        data.put(userEventPath, true);
-        mDatabase.getReference().updateChildren(data).addOnSuccessListener(this).addOnFailureListener(this);
-
-        mSelectedEvent = event;
-        mUserEvents.put(event.getUid(), event);
-        // Create the Conversation
-        ConversationsController conversationsController = ConversationsController.getInstance();
-        conversationsController.startConversation(event);
+        new HttpRequest.Builder().path(EVENT_MATCH)
+                .addEventId(event.getUid()).get((resultString, e) -> {
+            Log.d(TAG, "matchEvent: " + resultString);
+            mUserEvents.put(event.getUid(), event);
+            Gson gson = new Gson();
+            ConversationModel conversation = gson.fromJson(resultString, ConversationModel.class);
+            if(mOnEventMatchedListener != null) {
+                mOnEventMatchedListener.onEventMatched(conversation);
+            }
+        });
     }
 
     /**
      * A User cancel his willing to participate to an event
      * or cancel his participation to an event
+     *
      * @param event
      */
     public void cancelEventParticipation(EventModel event) {
-        String uid = event.getUid();
-        ConversationsController.getInstance().deleteConversation(event);
-        HashMap<String, Object> data = new HashMap<>();
-        // Remove User from Events Table
-        mEventsRef.child(uid).removeEventListener(mGlobalEventsListener);
-        String userEventPath = Utils.getReferencePath(mEventsRef.child(uid).child(EVENTS_PARTICIPANTS_ENTRY).child(mUserUid));
-        data.put(userEventPath, null);
-        // Mark Event as unavailable in User's Events Table
-        String userPath = Utils.getReferencePath(mUserEventsRef.child(uid));
-        data.put(userPath, false);
-        mDatabase.getReference().updateChildren(data).addOnSuccessListener(this).addOnFailureListener(this);
+        new HttpRequest.Builder().path(EVENT_CANCEL)
+                .addEventId(event.getUid()).get(((resultString, e) -> {
+            Log.d(TAG, "cancelEventParticipation() " + resultString);
+        }));
     }
 
-
-    // Events Administration Actions
     /**
      * Method to send an event to firebase Events Entry
+     *
      * @param event
      */
     public void createEvent(final EventModel event, Bitmap mapPreview) {
@@ -162,15 +269,15 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
                         // Write in User's Event Table
                         mUserEventsRef.child(eventUid).setValue(true);
                         mEventBuilder = null;
-                        if(mUpdateEventListener != null) {
-                            mUpdateEventListener.onUpdateEventResult(true, null);
+                        if (mUpdateEventListener != null) {
+                            mUpdateEventListener.onUpdateEventResult(true, event, null);
                         }
                     }
 
                     @Override
                     public void onFailure(String error) {
-                        if(mUpdateEventListener != null) {
-                            mUpdateEventListener.onUpdateEventResult(false, new Exception(error));
+                        if (mUpdateEventListener != null) {
+                            mUpdateEventListener.onUpdateEventResult(false, null, new Exception(error));
                         }
                     }
                 });
@@ -179,66 +286,32 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
 
     /**
      * Method handling the user cancelling an event that he created.
+     *
      * @param event
      */
     public void cancelEvent(EventModel event) {
-        String uid = event.getUid();
-        ConversationsController conversationsController = ConversationsController.getInstance();
-        conversationsController.deleteConversation(event);
-
-        mEventsRef.child(uid).removeEventListener(mGlobalEventsListener);
-        HashMap<String, Object> deletionMap = new HashMap<>();
-        // Remove in Global Events Table
-        String globalEventPath = Utils.getReferencePath(mEventsRef.child(uid));
-        deletionMap.put(globalEventPath, null);
-
-        // Remove in author table
-        String authorEventPath = Utils.getReferencePath(mUserEventsRef.child(uid));
-        deletionMap.put(authorEventPath, null);
-
-        // Remove in each User Events Table
-        HashMap<String, Boolean> participants = event.getParticipants();
-        for(String userUid : participants.keySet()) {
-            String userEventPath = Utils.getReferencePath(mDatabase.getReference(USERS_EVENTS_ENTRY).child(userUid)
-                    .child(uid));
-            deletionMap.put(userEventPath, null);
-        }
-        mDatabase.getReference().updateChildren(deletionMap)
-                .addOnSuccessListener(this).addOnFailureListener(this);
+        new HttpRequest.Builder().path(EVENT_DELETE).addEventId(event.getUid())
+                .get((resultString, e) -> Log.d(TAG, "cancelEvent() " + resultString));
     }
 
     /**
      * Method handling the validation of a user participation
+     *
      * @param event
      */
     public void acceptEventUserParticipation(EventModel event, String userUid) {
-        HashMap<String, Object> data = new HashMap<>();
-        // Accept in Global Events Table
-        String path = Utils.getReferencePath(
-                mEventsRef.child(event.getUid()).child(EVENTS_PARTICIPANTS_ENTRY).child(userUid));
-        data.put(path, true);
-        mDatabase.getReference().updateChildren(data)
-                .addOnSuccessListener(this).addOnFailureListener(this);
+        new HttpRequest.Builder().path(EVENT_CONFIRM).addEventId(event.getUid()).addUserId(userUid)
+                .get((resultString, e) -> Log.d(TAG, "acceptEventUserParticipation() " + resultString));
     }
 
     /**
      * Method that reject the user's participation
+     *
      * @param event
      */
     public void rejectEventUserParticipation(EventModel event, String userUid) {
-        // Delete Conversation
-        ConversationsController.getInstance().deleteConversation(event);
-
-        HashMap<String, Object> deletionMap = new HashMap<>();
-        // Remove User From Global Events Table
-        String globalEventPath = Utils.getReferencePath(mEventsRef
-                .child(event.getUid()).child(EVENTS_PARTICIPANTS_ENTRY).child(userUid));
-        deletionMap.put(globalEventPath, null);
-        // Set to False in user's event Table
-        String userEventPath = Utils.getReferencePath(mUsersEventsReference.child(userUid).child(event.getUid()));
-        deletionMap.put(userEventPath, false);
-        mDatabase.getReference().updateChildren(deletionMap)
-                .addOnSuccessListener(this).addOnFailureListener(this);
+        new HttpRequest.Builder().path(EVENT_REJECT).addEventId(event.getUid()).addUserId(userUid)
+                .get((resultString, e) -> Log.d(TAG, "rejectEventUserParticipation() " + resultString));
     }
 
     public HashMap<String, EventModel> getUserEvents() {
@@ -249,58 +322,6 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
         return mSelectedEvent;
     }
 
-    private ChildEventListener mDatabaseUserEventsListener = new ChildEventListener() {
-        @Override
-        public void onChildAdded(DataSnapshot snapshot, String s) {
-            Log.d(TAG, "onChildAdded() called with: snapshot = [" + snapshot + "], s = [" + s + "]");
-            // Set in the event's references's map
-            String eventUid = snapshot.getKey();
-            final Boolean valid = snapshot.getValue(Boolean.class);
-            mUserEventsReferenceMap.put(eventUid, valid);
-
-            if(valid) {
-                // Start listening on Event changes
-                mEventsRef.child(eventUid).addValueEventListener(mGlobalEventsListener);
-            }
-        }
-
-        @Override
-        public void onChildChanged(DataSnapshot snapshot, String s) {
-            Log.d(TAG, "onChildChanged() called with: snapshot = [" + snapshot + "], s = [" + s + "]");
-            String eventUid = snapshot.getKey();
-            Boolean valid = snapshot.getValue(Boolean.class);
-            mUserEventsReferenceMap.put(eventUid, valid);
-            if(!valid) {
-                mEventsRef.child(eventUid).removeEventListener(mGlobalEventsListener);
-                EventModel event = mUserEvents.remove(eventUid);
-                if(mEventsListener != null) {
-                    mEventsListener.onEventRemoved(event);
-                }
-            }
-        }
-
-        @Override
-        public void onChildRemoved(DataSnapshot snapshot) {
-            Log.d(TAG, "onChildRemoved() called with: snapshot = [" + snapshot + "]");
-            String eventUid = snapshot.getKey();
-            mUserEventsReferenceMap.remove(snapshot.getKey());
-            if(mEventsListener != null) {
-                mEventsListener.onEventRemoved(mUserEvents.get(eventUid));
-            }
-            mUserEvents.remove(eventUid);
-        }
-
-        @Override
-        public void onChildMoved(DataSnapshot snapshot, String s) {
-
-        }
-
-        @Override
-        public void onCancelled(DatabaseError error) {
-
-        }
-    };
-
     public void setSelectedEvent(EventModel selectedEvent) {
         mSelectedEvent = selectedEvent;
     }
@@ -312,69 +333,82 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
     /**
      * Method returning the User's Event's reference map.
      * The hashmap contains the Event's reference and a boolean:
-     *      true if the event is pending or accepted
-     *      false if the event was refused or canceled.
+     * true if the event is pending or accepted
+     * false if the event was refused or canceled.
+     *
      * @return
      */
     public HashMap<String, Boolean> getUserEventsReferenceMap() {
         return mUserEventsReferenceMap;
     }
 
-    public interface EventsListener {
-        void onEventAdded(EventModel event);
-        void onEventRemoved(EventModel event);
-        void onEventChanged(EventModel event);
-        void onEventError(String error);
-    }
-
     public void setUpdateEventListener(UpdateEventListener updateEventListener) {
         mUpdateEventListener = updateEventListener;
     }
 
-    public interface UpdateEventListener {
-        void onUpdateEventResult(boolean success, @Nullable Exception e);
+    public void setOnEventMatchedListener(OnEventMatchedListener onEventMatchedListener) {
+        mOnEventMatchedListener = onEventMatchedListener;
     }
 
-    private ValueEventListener mGlobalEventsListener = new ValueEventListener() {
-        @Override
-        public void onDataChange(DataSnapshot snapshot) {
-            EventModel event = snapshot.getValue(EventModel.class);
-            if(event == null) {
-                mUserEventsReferenceMap.remove(snapshot.getKey());
-            }
-            else {
-                mUserEvents.put(event.getUid(), event);
-            }
-
-        }
-
-        @Override
-        public void onCancelled(DatabaseError error) {
-
-        }
-    };
-
     @Override
     public void onSuccess(Object o) {
-        if(mUpdateEventListener != null) {
-            mUpdateEventListener.onUpdateEventResult(true, null);
+        if (mUpdateEventListener != null) {
+            mUpdateEventListener.onUpdateEventResult(true, null, null);
         }
     }
 
     @Override
     public void onFailure(@NonNull Exception e) {
-        if(mUpdateEventListener != null) {
-            mUpdateEventListener.onUpdateEventResult(false, e);
+        if (mUpdateEventListener != null) {
+            mUpdateEventListener.onUpdateEventResult(false, null, e);
         }
     }
 
     public EventBuilder getEventBuilder() {
-        if(mEventBuilder == null) {
+        if (mEventBuilder == null) {
             mEventBuilder = new EventBuilder();
         }
         return mEventBuilder;
     }
 
+    public UpdateEventBuilder getUpdateEventBuilder(EventModel mEvent) {
+        return new UpdateEventBuilder(mEvent);
+    }
+
+    public interface EventsListener {
+        void onEventAdded(EventModel event);
+
+        void onEventRemoved(EventModel event);
+
+        void onEventChanged(EventModel event);
+
+        void onEventError(String error);
+    }
+
+    public interface UpdateEventListener {
+        void onUpdateEventResult(boolean success, @Nullable EventModel event, @Nullable Exception e);
+    }
+
+    public interface OnEventMatchedListener {
+        void onEventMatched(ConversationModel conversation);
+    }
+
+    public interface OnEventParticipationAcceptedListener {
+        void OnEventParticipationAccepted(EventModel event);
+    }
+
+    public interface OnEventParticipationRejectedListener {
+        void onEventParticipationRejected(String eventUid);
+    }
+
+    public interface OnEventCanceledListener {
+        void onEventCanceled(String eventUid);
+    }
+
+    public interface OnEventParticipationCanceledListener {
+        void onEventParticipationCanceled(String eventUid, String userUid);
+    }
+
     public class EventBuilder {
 
         private Sports.Type mSport;
@@ -384,7 +418,7 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
         private long mDate;
         private long mTime;
         private long mDuration;
-        private String mGender;
+        private Gender mGender;
         private int mUsersLimit;
         private HashMap<String, Double> mLocation;
         private Bitmap mMapPreview;
@@ -428,7 +462,7 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
             return this;
         }
 
-        public EventBuilder gender(String gender) {
+        public EventBuilder gender(Gender gender) {
             mGender = gender;
             return this;
         }
@@ -455,15 +489,11 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
 
         public void build() {
             EventModel eventModel = new EventModel(mSport.toString(), mName, mLevel.toString(), mInfo, mDate, mTime,
-                    mDuration, mGender, mUsersLimit, mLocation, mAddress);
+                    mDuration, mGender.toString(), mUsersLimit, mLocation, mAddress);
             createEvent(eventModel, mMapPreview);
         }
     }
 
-    public UpdateEventBuilder getUpdateEventBuilder(EventModel mEvent) {
-        return new UpdateEventBuilder(mEvent);
-    }
-
     public class UpdateEventBuilder {
         EventModel mEvent = null;
         HashMap<String, Object> mUpdateMap = null;
@@ -509,8 +539,8 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
             return this;
         }
 
-        public UpdateEventBuilder gender(String gender) {
-            mUpdateMap.put("gender", gender);
+        public UpdateEventBuilder gender(Gender gender) {
+            mUpdateMap.put("gender", gender.toString());
             return this;
         }
 
@@ -535,9 +565,9 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
         }
 
         public UpdateEventBuilder build() {
-            if(mUpdateMap.containsKey("bitmap")){
+            if (mUpdateMap.containsKey("bitmap")) {
                 StorageReference previewReference = FirebaseHelper.getsStorage().getReference().child(EVENTS_PREVIEW_ENTRY).child(mEvent.getUid());
-                FirebaseHelper.uploadImage(previewReference,(Bitmap)mUpdateMap.get("bitmap")).setUploadImageListener(new FirebaseHelper.UploadImageListener() {
+                FirebaseHelper.uploadImage(previewReference, (Bitmap) mUpdateMap.get("bitmap")).setUploadImageListener(new FirebaseHelper.UploadImageListener() {
                     @Override
                     public void onSuccess(Uri imageUri) {
                         mUpdateMap.remove("bitmap");
@@ -550,12 +580,12 @@ public class UserEventsController implements OnSuccessListener, OnFailureListene
                             }
                         });
                     }
+
                     @Override
                     public void onFailure(String error) {
                     }
                 });
-            }
-            else {
+            } else {
                 mEventsRef.child(mEvent.getUid()).updateChildren(mUpdateMap).addOnCompleteListener(new OnCompleteListener<Void>() {
                     @Override
                     public void onComplete(@NonNull Task<Void> task) {

+ 39 - 39
app/src/main/java/fr/wildcodeschool/steeryfit/Models/ConversationModel.java

@@ -9,12 +9,12 @@ import java.util.HashMap;
  */
 
 public class ConversationModel {
-    private String mUid;
-    private String mEventUid = "";
-    private HashMap<String, Boolean> mUsers = new HashMap<>();
-    private MessageModel mLastMessage = null;
+    private String uid;
+    private String eventUid = "";
+    private HashMap<String, Boolean> users = new HashMap<>();
+    private MessageModel lastMessage = null;
 
-    private HashMap<String, User> mUsersData = new HashMap<>();
+    private HashMap<String, User> usersData = new HashMap<>();
 
     @Exclude
     public int unreadCount = 0;
@@ -23,102 +23,102 @@ public class ConversationModel {
     }
 
     public ConversationModel(String conversationUid) {
-        mUid = conversationUid;
+        uid = conversationUid;
     }
 
     public ConversationModel(String conversationUid, String userUid, String userOtherUid) {
-        mUid = conversationUid;
-        mUsers.put(userUid, true);
-        mUsers.put(userOtherUid, true);
+        uid = conversationUid;
+        users.put(userUid, true);
+        users.put(userOtherUid, true);
     }
 
     public void addUserData(String uid, String name, String avatar) {
-        mUsersData.put(uid, new User(name, avatar));
+        usersData.put(uid, new User(name, avatar));
     }
 
     public User getUserData(String uid) {
-        return mUsersData.get(uid);
+        return usersData.get(uid);
     }
 
     public HashMap<String, User> getUsersData() {
-        return mUsersData;
+        return usersData;
     }
 
     public void setUsersData(HashMap<String, User> usersData) {
-        mUsersData = usersData;
+        this.usersData = usersData;
     }
 
     public void addUser(String userUid) {
-        mUsers.put(userUid, true);
+        users.put(userUid, true);
     }
 
     public static class User {
-        private String mName = "";
-        private String mAvatar = "";
+        private String name = "";
+        private String avatar = "";
 
         public User() {
         }
 
         public User(String name, String avatar) {
-            mName = name;
-            mAvatar = avatar;
+            this.name = name;
+            this.avatar = avatar;
         }
 
         public String getName() {
-            return mName;
+            return name;
         }
 
         public void setName(String name) {
-            mName = name;
+            this.name = name;
         }
 
         public String getAvatar() {
-            return mAvatar;
+            return avatar;
         }
 
         public void setAvatar(String avatar) {
-            mAvatar = avatar;
+            this.avatar = avatar;
         }
 
         @Override
         public String toString() {
             return "User{" +
-                    "mName='" + mName + '\'' +
-                    ", mAvatar='" + mAvatar + '\'' +
+                    "name='" + name + '\'' +
+                    ", avatar='" + avatar + '\'' +
                     '}';
         }
     }
 
     public String getUid() {
-        return mUid;
+        return uid;
     }
 
     public void setUid(String uid) {
-        mUid = uid;
+        this.uid = uid;
     }
 
     public HashMap<String, Boolean> getUsers() {
-        return mUsers;
+        return users;
     }
 
     public void setUsers(HashMap<String, Boolean> users) {
-        mUsers = users;
+        this.users = users;
     }
 
     public MessageModel getLastMessage() {
-        return mLastMessage;
+        return lastMessage;
     }
 
     public void setLastMessage(MessageModel lastMessage) {
-        mLastMessage = lastMessage;
+        this.lastMessage = lastMessage;
     }
 
     public String getEventUid() {
-        return mEventUid;
+        return eventUid;
     }
 
     public void setEventUid(String eventUid) {
-        mEventUid = eventUid;
+        this.eventUid = eventUid;
     }
 
     @Override
@@ -128,22 +128,22 @@ public class ConversationModel {
 
         ConversationModel that = (ConversationModel) o;
 
-        return mUid != null ? mUid.equals(that.mUid) : that.mUid == null;
+        return uid != null ? uid.equals(that.uid) : that.uid == null;
     }
 
     @Override
     public int hashCode() {
-        return mUid != null ? mUid.hashCode() : 0;
+        return uid != null ? uid.hashCode() : 0;
     }
 
     @Override
     public String toString() {
         return "ConversationModel{" +
-                "mUid='" + mUid + '\'' +
-                ", mEventUid='" + mEventUid + '\'' +
-                ", mUsers=" + mUsers +
-                ", mLastMessage=" + mLastMessage +
-                ", mUsersData=" + mUsersData +
+                "uid='" + uid + '\'' +
+                ", eventUid='" + eventUid + '\'' +
+                ", users=" + users +
+                ", lastMessage=" + lastMessage +
+                ", usersData=" + usersData +
                 '}';
     }
 }

+ 15 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/Models/EventModel.java

@@ -2,6 +2,8 @@ package fr.wildcodeschool.steeryfit.Models;
 
 import android.location.Location;
 
+import com.google.firebase.database.Exclude;
+
 import java.util.Comparator;
 import java.util.HashMap;
 
@@ -22,6 +24,7 @@ public class EventModel {
     private long time;
     private long duration;
     private String gender;
+    @Exclude Gender genderEnum = null;
     private int usersLimit;
     private String uid = "";
     private String creatorUid = "";
@@ -183,6 +186,18 @@ public class EventModel {
         this.participants.remove(uid);
     }
 
+    public Gender getGenderEnum() {
+        return Gender.valueOf(gender);
+    }
+
+    public int getConfirmParticipantsCount() {
+        int count = 1;
+        for(String p : participants.keySet()) {
+            if(participants.get(p)) count++;
+        }
+        return count;
+    }
+
     @Override
     public String toString() {
         return "EventModel{" +

+ 22 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/Models/Gender.java

@@ -0,0 +1,22 @@
+package fr.wildcodeschool.steeryfit.Models;
+
+/**
+ * Created by wilderjm on 08/01/18.
+ */
+
+public enum Gender {
+
+    MALE("MALE"),
+    FEMALE("FEMALE"),
+    MIXTE("MIXTE");
+
+    private final String stringValue;
+
+    Gender(final String s) {
+        stringValue = s;
+    }
+    public String toString() {
+        return stringValue;
+    }
+
+}

+ 22 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/Models/MessageModel.java

@@ -54,6 +54,28 @@ public class MessageModel {
     }
 
     @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        MessageModel that = (MessageModel) o;
+
+        if (mTimestamp != that.mTimestamp) return false;
+        if (mAuthorUid != null ? !mAuthorUid.equals(that.mAuthorUid) : that.mAuthorUid != null) return false;
+        if (mMessage != null ? !mMessage.equals(that.mMessage) : that.mMessage != null) return false;
+        return mReadBy != null ? mReadBy.equals(that.mReadBy) : that.mReadBy == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = mAuthorUid != null ? mAuthorUid.hashCode() : 0;
+        result = 31 * result + (mMessage != null ? mMessage.hashCode() : 0);
+        result = 31 * result + (int) (mTimestamp ^ (mTimestamp >>> 32));
+        result = 31 * result + (mReadBy != null ? mReadBy.hashCode() : 0);
+        return result;
+    }
+
+    @Override
     public String toString() {
         return "MessageModel{" +
                 "mAuthorUid='" + mAuthorUid + '\'' +

+ 2 - 1
app/src/main/java/fr/wildcodeschool/steeryfit/Models/Sports.java

@@ -11,7 +11,8 @@ public class Sports {
         RACKET("RACKET"),
         BIKE("BIKE"),
         BALL("BALL"),
-        GOLF("GOLF");
+        GOLF("GOLF"),
+        WALK("WALK");
 
         private final String stringValue;
 

+ 6 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/Models/UserModel.java

@@ -184,6 +184,10 @@ public class UserModel {
         return mSports;
     }
 
+    public Gender getGenderEnum() {
+        return Gender.valueOf(mGender);
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
@@ -231,6 +235,8 @@ public class UserModel {
         return result;
     }
 
+
+
     @Override
     public String toString() {
         return "UserModel{" +

+ 149 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/SearchEventResultActivity.java

@@ -0,0 +1,149 @@
+package fr.wildcodeschool.steeryfit;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.design.widget.BaseTransientBottomBar;
+import android.support.design.widget.CoordinatorLayout;
+import android.support.design.widget.Snackbar;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.Toolbar;
+import android.support.v7.widget.helper.ItemTouchHelper;
+import android.text.Html;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+import fr.wildcodeschool.steeryfit.Controllers.ConversationsController;
+import fr.wildcodeschool.steeryfit.Controllers.EventsQueryController;
+import fr.wildcodeschool.steeryfit.Controllers.UserEventsController;
+import fr.wildcodeschool.steeryfit.Models.EventModel;
+import fr.wildcodeschool.steeryfit.UI.Activities.MessagesActivity;
+import fr.wildcodeschool.steeryfit.UI.Fragments.Behaviors.SwipeItemTouchHelperCallback;
+import fr.wildcodeschool.steeryfit.Utils.Utils;
+
+public class SearchEventResultActivity extends AppCompatActivity {
+    private static final int SNAKBAR_TIME = 5000;
+    private final String TAG = Utils.getTAG(this);
+
+    private ArrayList<EventModel> mResults = new ArrayList<>();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_search_event_result);
+
+        UserEventsController userEventsController = UserEventsController.getInstance();
+
+        final CoordinatorLayout rootLayout = findViewById(R.id.coordinatorLayoutSearchEventResults);
+
+        EventsQueryController eventsQueryController = EventsQueryController.getInstance();
+        mResults = eventsQueryController.getResults();
+
+        Toolbar toolbar = findViewById(R.id.toolbarSearchEventResult);
+        setSupportActionBar(toolbar);
+        ActionBar actionBar = getSupportActionBar();
+        actionBar.setTitle(R.string.search_results_title);
+        actionBar.setDisplayHomeAsUpEnabled(true);
+
+        TextView textViewNoEvent = findViewById(R.id.textViewResultsNoEventsFound);
+        TextView textViewRefresh = findViewById(R.id.textViewResultsSwipeRefresh);
+        textViewNoEvent.setVisibility(mResults.isEmpty() ? View.VISIBLE : View.INVISIBLE);
+        textViewRefresh.setVisibility(mResults.isEmpty() ? View.VISIBLE : View.INVISIBLE);
+
+        RecyclerView recyclerView = findViewById(R.id.recyclerViewShowResultSearchEvent);
+        final SearchEventResultAdapter adapter = new SearchEventResultAdapter(mResults, recyclerView, this);
+        recyclerView.setLayoutManager(new LinearLayoutManager(this));
+        recyclerView.setAdapter(adapter);
+
+        SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swipeRefreshSearchEventResult);
+        swipeRefreshLayout.setEnabled(mResults.isEmpty());
+        EventsQueryController.EventsQuery query = eventsQueryController.getLastQuery();
+        swipeRefreshLayout.setOnRefreshListener(() -> {
+            textViewNoEvent.setVisibility(View.INVISIBLE);
+            textViewRefresh.setVisibility(View.INVISIBLE);
+            query.setOnClompleteListener((results, e) -> {
+                swipeRefreshLayout.setRefreshing(false);
+                mResults = results;
+                adapter.notifyDataSetChanged();
+                textViewNoEvent.setVisibility(mResults.isEmpty() ? View.VISIBLE : View.INVISIBLE);
+                textViewRefresh.setVisibility(mResults.isEmpty() ? View.VISIBLE : View.INVISIBLE);
+                swipeRefreshLayout.setEnabled(mResults.isEmpty());
+            }).refresh();
+        });
+
+        Snackbar snackbar = Snackbar.make(rootLayout,
+                Html.fromHtml(getString(R.string.search_results_instructions)),
+                BaseTransientBottomBar.LENGTH_INDEFINITE);
+        snackbar.show();
+        new Handler().postDelayed(snackbar::dismiss, SNAKBAR_TIME);
+
+        Drawable match = getResources().getDrawable(R.drawable.messages_valid_participation);
+        Drawable decline = getResources().getDrawable(R.drawable.messages_reject_participation);
+        match.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
+        decline.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
+
+        ItemTouchHelper.Callback swipeCallback = new SwipeItemTouchHelperCallback
+                .Builder(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)
+                .bgColorSwipeLeft(getResources().getColor(R.color.colorAccent))
+                .drawableLeft(match)
+                .bgColorSwipeRight(getResources().getColor(R.color.accentRed))
+                .drawableRight(decline)
+                .setSwipeEnabled(true)
+                .onItemSwipeLeftListener(position -> {
+                    Snackbar.make(rootLayout, Html.fromHtml(getString(R.string.event_declined_snackbar)), Snackbar.LENGTH_SHORT).show();
+                    mResults.remove(position);
+                    adapter.notifyDataSetChanged();
+                    swipeRefreshLayout.setEnabled(mResults.isEmpty());
+                    if(mResults.isEmpty()) textViewRefresh.setVisibility(View.VISIBLE);
+                })
+                .onItemSwipeRightListener(position ->
+                        Snackbar.make(rootLayout, Html.fromHtml(getString(R.string.event_match_confirm)), Snackbar.LENGTH_LONG)
+                                .setActionTextColor(Color.argb(255, 0, 255, 0))
+                                .setAction(getString(R.string.confirm_message), v -> {
+                                    userEventsController.matchEvent(mResults.get(position));
+                                    mResults.remove(position);
+                                    if(mResults.isEmpty()) textViewRefresh.setVisibility(View.VISIBLE);
+                                    adapter.notifyDataSetChanged();
+                                    userEventsController.setOnEventMatchedListener(conversation -> {
+                                        ConversationsController.getInstance().setSelectedConversation(conversation);
+                                        startActivity(new Intent(SearchEventResultActivity.this, MessagesActivity.class));
+                                    });
+                                    Snackbar.make(rootLayout, Html.fromHtml(getString(R.string.event_matched_snackbar)), Snackbar.LENGTH_LONG).show();
+                                }).addCallback(new Snackbar.Callback() {
+
+                            @Override
+                            public void onDismissed(Snackbar snackbar, int event) {
+                                adapter.notifyDataSetChanged();
+                            }
+
+                            @Override
+                            public void onShown(Snackbar snackbar) {
+
+                            }
+                        }).show())
+                .build();
+
+        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(swipeCallback);
+        itemTouchHelper.attachToRecyclerView(recyclerView);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case android.R.id.home:
+                onBackPressed();
+                return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}

+ 225 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/SearchEventResultAdapter.java

@@ -0,0 +1,225 @@
+package fr.wildcodeschool.steeryfit;
+
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.bumptech.glide.Glide;
+import com.google.firebase.storage.FirebaseStorage;
+import com.google.firebase.storage.StorageReference;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.wildcodeschool.steeryfit.Controllers.EventsDetailsController;
+import fr.wildcodeschool.steeryfit.Controllers.UserController;
+import fr.wildcodeschool.steeryfit.Models.EventModel;
+import fr.wildcodeschool.steeryfit.Models.Gender;
+import fr.wildcodeschool.steeryfit.Models.UserModel;
+import fr.wildcodeschool.steeryfit.UI.Adapters.ParticipantsAdapter;
+import fr.wildcodeschool.steeryfit.Utils.Utils;
+
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+import static fr.wildcodeschool.steeryfit.Models.Gender.FEMALE;
+import static fr.wildcodeschool.steeryfit.Models.Gender.MALE;
+import static fr.wildcodeschool.steeryfit.Models.Gender.MIXTE;
+import static fr.wildcodeschool.steeryfit.Utils.Constants.EVENTS_PREVIEW_ENTRY;
+
+/**
+ * Created by wilderjm on 19/12/17.
+ */
+
+public class SearchEventResultAdapter extends RecyclerView.Adapter<SearchEventResultAdapter.ViewHolder> {
+
+    enum State {
+        EXPANDED, COLLAPSE
+    }
+
+    enum Background {
+        DECLINE, ACCEPT
+    }
+
+    private List<EventModel> mEventsList;
+    private RecyclerView mRecyclerView;
+    private Context mContext;
+    private UserModel mUser;
+
+    private EventModel mExpandedEvent = null;
+
+
+    public SearchEventResultAdapter(List<EventModel> events, RecyclerView recyclerView, Context context) {
+        mEventsList = events;
+        mRecyclerView = recyclerView;
+        mContext = context;
+        mUser = UserController.getInstance().getUser();
+    }
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        View view = LayoutInflater.from(parent.getContext())
+                .inflate(R.layout.item_search_event_result,parent,false);
+        return new ViewHolder(view);
+    }
+
+
+
+    @Override
+    public void onBindViewHolder(final ViewHolder holder, final int position) {
+        final EventModel event = mEventsList.get(position);
+        if(event == mExpandedEvent) {
+            holder.setState(State.EXPANDED);
+        }
+        else {
+            holder.setState(State.COLLAPSE);
+        }
+
+
+        Gender gender = event.getGenderEnum();
+        switch (gender){
+            case MALE:
+                holder.imageViewEventGender.setImageDrawable(Utils.getGenderImageBw(MALE,mContext));
+                break;
+            case FEMALE:
+                holder.imageViewEventGender.setImageDrawable(Utils.getGenderImageBw(FEMALE,mContext));
+                break;
+            case MIXTE:
+                holder.imageViewEventGender.setImageDrawable(Utils.getGenderImageBw(MIXTE,mContext));
+                break;
+        }
+
+
+        holder.textViewPaticipantNumber.setText(String.valueOf(event.getConfirmParticipantsCount()) + "/" + (event.getUsersLimit() + 1));
+        holder.imageViewEventSport.setImageDrawable(Utils.getSportImage(event.getSport(), mContext));
+        holder.imageViewEventLevel.setImageDrawable(Utils.getLevelImage(event.getLevel(), mContext));
+        holder.textViewEventName.setText(event.getName());
+        //holder.textViewEventLevel.setText(Utils.getLevelName(event.getLevel(), mContext));
+        holder.textViewEventInfo.setText(event.getInfo());
+        holder.textViewEventDate.setText(Utils.formatDate(event.getDate()));
+        holder.textViewEventTime.setText(Utils.formatTime(event.getTime()));
+        holder.textViewEventDuration.setText(Utils.formatDuration(event.getDuration()));
+        holder.textViewEventLocation.setText(event.getAddress());
+
+        StorageReference storageRef = FirebaseStorage.getInstance().getReference();
+        StorageReference eventRef = storageRef.child(EVENTS_PREVIEW_ENTRY).child(event.getUid());
+        Glide.with(mContext)
+                .load(eventRef)
+                .into(holder.imageViewEventLocation);
+
+        holder.participantsAdapter.notifyDataSetChanged();
+        new EventsDetailsController().getParticipants(event).setOnCompleteListener(new EventsDetailsController.OnCompleteListener() {
+            @Override
+            public void onComplete(ArrayList<UserModel> results, @Nullable Exception e) {
+                holder.participantsList.clear();
+                holder.participantsList.addAll(results);
+                holder.participantsAdapter.notifyDataSetChanged();
+                // SmoothScrool to load datas in recyclerview
+                holder.recyclerViewParticipantsList.smoothScrollToPosition(0);
+            }
+        });
+
+        holder.view.setOnClickListener(v -> {
+            if(!event.equals(mExpandedEvent)) {
+                mExpandedEvent = event;
+                collapseItems();
+                holder.setState(State.EXPANDED);
+            }
+            else {
+                mExpandedEvent = null;
+                collapseItems();
+            }
+        });
+    }
+
+    @Override
+    public int getItemCount() {
+        return mEventsList.size();
+    }
+
+    private void collapseItems(){
+        for (int i = 0; i < mEventsList.size(); i++) {
+            ViewHolder holder = (ViewHolder) mRecyclerView.findViewHolderForAdapterPosition(i);
+            if(holder != null && !mEventsList.get(i).equals(mExpandedEvent)) {
+                holder.setState(State.COLLAPSE);
+            }
+        }
+    }
+
+    class ViewHolder extends RecyclerView.ViewHolder {
+        private State mState = State.COLLAPSE;
+        View view = null;
+        ImageView imageViewEventGender;
+        TextView textViewPaticipantNumber;
+        ImageView imageViewEventSport;
+        ImageView imageViewEventLevel;
+        TextView textViewEventName;
+        TextView textViewEventDate;
+        TextView textViewEventTime;
+        TextView textViewEventDuration;
+        TextView textViewEventInfo;
+        ImageView imageViewEventInfoLabel;
+        ImageView imageViewEventLocation;
+        ImageView imageViewEventLocationLabel;
+        TextView textViewEventLocation;
+        RecyclerView recyclerViewParticipantsList;
+        ImageButton imageButtonGoogleMapItinerary;
+        ParticipantsAdapter participantsAdapter;
+        LinearLayout linearLayoutHide;
+        ArrayList<UserModel> participantsList = new ArrayList<>();
+
+        public ViewHolder(View view) {
+            super(view);
+            this.view = view;
+            view.findViewById(R.id.imageViewLeftSwipe).setVisibility(GONE);
+            view.findViewById(R.id.imageViewRightSwipe).setVisibility(GONE);
+
+            linearLayoutHide = view.findViewById(R.id.layoutEventHide);
+
+            imageViewEventGender = view.findViewById(R.id.imageViewMessagesHeaderGender);
+            textViewPaticipantNumber = view.findViewById(R.id.textViewMessagesHeaderParticpantsNumber);
+            imageViewEventSport = view.findViewById(R.id.imageViewMessagesHeaderSportType);
+            imageViewEventLevel = view.findViewById(R.id.imageViewMessagesHeaderLevel);
+            textViewEventName = view.findViewById(R.id.textViewMessagesHeaderTitle);
+            textViewEventDate = view.findViewById(R.id.textViewMessagesHeaderDate);
+            textViewEventTime = view.findViewById(R.id.textViewMessagesHeaderTime);
+            textViewEventDuration = view.findViewById(R.id.textViewMessagesHeaderDuration);
+
+            imageButtonGoogleMapItinerary = view.findViewById(R.id.imageButtonGoogleMapsItinerary);
+            textViewEventInfo = view.findViewById(R.id.textViewEventInfo);
+            imageViewEventInfoLabel = view.findViewById(R.id.imageViewEventInf);
+            imageViewEventLocationLabel = view.findViewById(R.id.imageViewEventLocationLabel);
+            imageViewEventLocation = view.findViewById(R.id.imageViewEventLocation);
+            textViewEventLocation = view.findViewById(R.id.textViewEventLocation);
+
+            recyclerViewParticipantsList = view.findViewById(R.id.recyclerViewParticipantsList);
+            participantsAdapter = new ParticipantsAdapter(participantsList, mContext);
+            recyclerViewParticipantsList.setHasFixedSize(true);
+            recyclerViewParticipantsList.setLayoutManager(new LinearLayoutManager(mContext,
+                    LinearLayoutManager.HORIZONTAL, false));
+            recyclerViewParticipantsList.setAdapter(participantsAdapter);
+        }
+
+        public void setState(State state) {
+            mState = state;
+            switch (state) {
+                case EXPANDED:
+                    linearLayoutHide.setVisibility(VISIBLE);
+                    recyclerViewParticipantsList.setVisibility(VISIBLE);
+                    break;
+                case COLLAPSE:
+                    linearLayoutHide.setVisibility(GONE);
+                    recyclerViewParticipantsList.setVisibility(GONE);
+                    break;
+            }
+        }
+    }
+}

+ 119 - 17
app/src/main/java/fr/wildcodeschool/steeryfit/Services/NotificationsService.java

@@ -1,22 +1,38 @@
 package fr.wildcodeschool.steeryfit.Services;
 
+import android.annotation.SuppressLint;
 import android.app.Notification;
+import android.app.NotificationChannel;
 import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Intent;
 import android.graphics.Color;
 import android.media.RingtoneManager;
+import android.os.Build;
+import android.support.v4.app.NotificationCompat;
 import android.util.Log;
 
 import com.google.firebase.messaging.FirebaseMessagingService;
 import com.google.firebase.messaging.RemoteMessage;
 
 import java.util.Map;
+import java.util.UUID;
 
 import fr.wildcodeschool.steeryfit.Controllers.ConversationsController;
+import fr.wildcodeschool.steeryfit.Controllers.UserEventsController;
 import fr.wildcodeschool.steeryfit.Models.ConversationModel;
 import fr.wildcodeschool.steeryfit.R;
+import fr.wildcodeschool.steeryfit.UI.Activities.MainActivity;
+import fr.wildcodeschool.steeryfit.UI.Activities.MessagesActivity;
+import fr.wildcodeschool.steeryfit.UI.Activities.ModifyEventActivity;
+import fr.wildcodeschool.steeryfit.UI.Activities.Splashscreen;
 import fr.wildcodeschool.steeryfit.UI.Fragments.MessagesFragment;
 import fr.wildcodeschool.steeryfit.Utils.Utils;
 
+import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
+import static fr.wildcodeschool.steeryfit.Utils.Constants.CONVERSATIONS_ENTRY;
+import static fr.wildcodeschool.steeryfit.Utils.Constants.EVENTS_ENTRY;
+
 /**
  * Created by adphi on 12/12/17.
  */
@@ -30,7 +46,20 @@ public class NotificationsService extends FirebaseMessagingService {
     private final static String TITLE = "title";
     private final static String BODY = "body";
     private final static String TYPE = "type";
+    private final static String SUBTYPE = "subtype";
     private final static String UID = "uid";
+    private final static String TIME = "time";
+    private final static String AVATAR = "avatar";
+    private final static String NAME = "userName";
+    private final static String EVENT_TITLE = "eventTitle";
+
+    private final static String CANCEL = "CANCEL";
+    private final static String CONFIRM = "CONFIRM";
+    private final static String DELETE = "DELETE";
+    private final static String MATCH = "MATCH";
+    private final static String REJECT = "REJECT";
+    private final static String FULL = "FULL";
+
 
     public NotificationsService() {
         super();
@@ -47,50 +76,123 @@ public class NotificationsService extends FirebaseMessagingService {
 
         Map<String, String> data = remoteMessage.getData();
         Log.d(TAG, "onMessageReceived: " + data);
-        if(data.size() > 0) {
+        if (data.size() > 0) {
             String title = data.get(TITLE);
             String message = data.get(BODY);
             String type = data.get(TYPE);
             String uid = data.get(UID);
+            long time = Long.valueOf(data.get(TIME));
             // If New Message
             if (type.equals(MESSAGE)) {
                 Log.d(TAG, "onMessageReceived: " + uid);
                 // Don't show notification if conversation opened in chat.
-                if (MessagesFragment.isOpen()){
+                if (MessagesFragment.isOpen()) {
                     ConversationModel currentConversation = ConversationsController.getInstance().getSelectedConversation();
-                    if(currentConversation.getUid().equals(uid)){
+                    if (currentConversation.getUid().equals(uid)) {
                         return;
                     }
                 }
-                sendNotification(title, message, "", type);
+                sendNotification(title, message, getString(R.string.new_message), time, type, "", uid);
+            } else if (type.equals(EVENT)) {
+                String userName = data.get(NAME);
+                title = data.get(EVENT_TITLE);
+                String subtype = data.get(SUBTYPE);
+                switch (subtype) {
+                    case MATCH:
+                        message = String.format(getString(R.string.event_match_notification), userName);
+                        break;
+                    case CONFIRM:
+                        message = String.format(getString(R.string.event_confirm_notification), userName);
+                        break;
+                    case CANCEL:
+                        message = String.format(getString(R.string.event_cancel_notification), userName);
+                        break;
+                    case REJECT:
+                        message = String.format(getString(R.string.event_reject_notification), userName);
+                        break;
+                    case DELETE:
+                        message = String.format(getString(R.string.event_delete_notification), userName);
+                        break;
+                    case FULL:
+                        message = String.format(getString(R.string.event_complete));
+                        break;
+                }
+                sendNotification(title, message, "", time, type, subtype, uid);
             }
         }
     }
 
 
-    private void sendNotification(String title, String content, String subText, String type) {
+    @SuppressLint("NewApi")
+    private void sendNotification(String title, String content, String subText, long time, String type, String subtype, String uid) {
 
-        NotificationManager notificationManager =
-                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-        Notification.Builder builder = new Notification.Builder(NotificationsService.this);
+        NotificationCompat.Builder builder = new NotificationCompat.Builder(NotificationsService.this,
+                getResources().getString(R.string.app_name));
         builder.setContentTitle(title)
                 .setContentText(content)
-                .setSubText(title)
-                //.setContentIntent(PendingIntent.getActivity(getApplicationContext(), UUID.randomUUID().hashCode(), new Intent(NotificationsService.this, MainActivity.class), 0))
-                .setWhen(System.currentTimeMillis())
+                .setSubText(subText)
+                .setWhen(time)
+                .setShowWhen(true)
                 .setPriority(Notification.PRIORITY_DEFAULT)
                 .setAutoCancel(true)
-                //.setDefaults(Notification.DEFAULT_ALL)
                 .setVibrate(new long[]{0, 1000, 200, 1000})
                 .setLights(Color.RED, 500, 500)
                 .setSmallIcon(R.drawable.ic_stat_name)
                 .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
 
-        Notification ntf = builder.build();
-        /*ntf.flags = Notification.DEFAULT_ALL;
-        ntf.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
-        ntf.flags |= Notification.FLAG_AUTO_CANCEL;*/
+        if (type.equals(MESSAGE) || subtype.equals(MATCH)) {
+            // MESSAGE
+            Log.d(TAG, "sendNotification: Conversation Controller available: "
+                    + ConversationsController.isInstanciated());
+            if (ConversationsController.isInstanciated()) {
+                Intent intent = new Intent(NotificationsService.this, MessagesActivity.class);
+                intent.putExtra(CONVERSATIONS_ENTRY, uid);
+                if(MessagesFragment.isOpen()) intent.setFlags(FLAG_ACTIVITY_SINGLE_TOP);
+                builder.setContentIntent(PendingIntent.getActivity(this, UUID.randomUUID().hashCode(),
+                        intent, 0));
+            }
+            // TODO: ?? What if the notification is clicked after the application was closed ??
+            else {
+                Intent intent = new Intent(NotificationsService.this, Splashscreen.class);
+                intent.putExtra(CONVERSATIONS_ENTRY, uid);
+                builder.setContentIntent(PendingIntent.getActivity(this, UUID.randomUUID()
+                        .hashCode(), intent, 0));
+            }
+        } else {
+            // EVENT
+            Log.d(TAG, "sendNotification: UserEvents Controller available: "
+                    + UserEventsController.isInstantiated());
+
+            // CONFIRM or CANCEL: Open Event Details
+            if (UserEventsController.isInstantiated()) {
+                if (subtype.equals(CONFIRM) || subtype.equals(CANCEL)) {
+                    Intent intent = new Intent(NotificationsService.this, ModifyEventActivity.class);
+                    intent.putExtra(EVENTS_ENTRY, uid);
+                    builder.setContentIntent(PendingIntent.getActivity(this, UUID.randomUUID()
+                            .hashCode(), intent, 0));
+                } else {
+                    Intent intent = new Intent(NotificationsService.this, MainActivity.class);
+                    intent.putExtra(EVENTS_ENTRY, uid);
+                    builder.setContentIntent(PendingIntent.getActivity(this, UUID.randomUUID()
+                            .hashCode(), intent, 0));
+                }
+            }
+            else {
+                Intent intent = new Intent(NotificationsService.this, Splashscreen.class);
+                builder.setContentIntent(PendingIntent.getActivity(this, UUID.randomUUID()
+                        .hashCode(), intent, 0));
+            }
+        }
 
+        Notification ntf = builder.build();
+        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            /* Create or update. */
+            NotificationChannel channel = new NotificationChannel(getResources().getString(R.string.app_name),
+                    getResources().getString(R.string.app_name),
+                    NotificationManager.IMPORTANCE_DEFAULT);
+            notificationManager.createNotificationChannel(channel);
+        }
         notificationManager.notify(type.hashCode(), ntf);
     }
-}
+}

+ 0 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/Services/TokenService.java


+ 0 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/ConversationsActivity.java


+ 14 - 17
app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/EditoActivity.java

@@ -60,24 +60,21 @@ public class EditoActivity extends AppCompatActivity {
         mViewPager.setAdapter(myViewPagerAdapter);
         mViewPager.addOnPageChangeListener(viewPagerPageChangeListener);
 
-        mViewPager.setOnTouchListener(new View.OnTouchListener() {
-            @Override
-            public boolean onTouch(View view, MotionEvent motionEvent) {
-                switch (motionEvent.getAction()) {
-                    case MotionEvent.ACTION_UP:
-                        mSwipeHandler.removeCallbacks(mSwipeRunnable);
-                        mSwipeHandler.postDelayed(mSwipeRunnable, 4000);
-                        int nextItem = mViewPager.getCurrentItem() + 1;
-                        if (nextItem < mLayouts.length) {
-                            mViewPager.setCurrentItem(nextItem);
-                        } else {
-                            mHasSkipped = true;
-                            startActivity(new Intent(EditoActivity.this,
-                                    SignInActivity.class));
-                        }
-                }
-                return true;
+        mViewPager.setOnTouchListener((view, motionEvent) -> {
+            switch (motionEvent.getAction()) {
+                case MotionEvent.ACTION_UP:
+                    mSwipeHandler.removeCallbacks(mSwipeRunnable);
+                    mSwipeHandler.postDelayed(mSwipeRunnable, 4000);
+                    int nextItem = mViewPager.getCurrentItem() + 1;
+                    if (nextItem < mLayouts.length) {
+                        mViewPager.setCurrentItem(nextItem);
+                    } else {
+                        mHasSkipped = true;
+                        startActivity(new Intent(EditoActivity.this,
+                                SignInActivity.class));
+                    }
             }
+            return true;
         });
 
         mSwipeRunnable = new Runnable() {

+ 76 - 11
app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/MainActivity.java

@@ -16,19 +16,35 @@ import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
+import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.MultiTransformation;
+import com.bumptech.glide.request.RequestOptions;
+
+import de.hdodenhof.circleimageview.CircleImageView;
 import fr.wildcodeschool.steeryfit.Controllers.AuthController;
 import fr.wildcodeschool.steeryfit.Controllers.ConversationsController;
 import fr.wildcodeschool.steeryfit.Controllers.UserController;
 import fr.wildcodeschool.steeryfit.Controllers.UserEventsController;
+import fr.wildcodeschool.steeryfit.Models.UserModel;
 import fr.wildcodeschool.steeryfit.R;
 import fr.wildcodeschool.steeryfit.UI.CreateEvent.CreateEventFragment;
 import fr.wildcodeschool.steeryfit.UI.Fragments.MainFragment;
 import fr.wildcodeschool.steeryfit.UI.Fragments.PlanningFragment;
+import fr.wildcodeschool.steeryfit.UI.Fragments.ProfileFragment;
+import fr.wildcodeschool.steeryfit.UI.Fragments.SearchEventFragment;
 import fr.wildcodeschool.steeryfit.Utils.Utils;
+import jp.wasabeef.glide.transformations.BlurTransformation;
+import jp.wasabeef.glide.transformations.ColorFilterTransformation;
 
+import static com.bumptech.glide.request.RequestOptions.bitmapTransform;
+import static fr.wildcodeschool.steeryfit.Utils.Constants.BLUR_RADIUS;
+import static fr.wildcodeschool.steeryfit.Utils.Constants.CREATE_INDEX;
 import static fr.wildcodeschool.steeryfit.Utils.Constants.NAVIGATION_ITEM;
+import static fr.wildcodeschool.steeryfit.Utils.Constants.PROFILE_INDEX;
+import static fr.wildcodeschool.steeryfit.Utils.Constants.SEARCH_INDEX;
 
 public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
     private final String TAG = Utils.getTAG(this);
@@ -40,27 +56,34 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
     private ActionBarDrawerToggle mToggle;
     private DrawerLayout mDrawerLayout;
     private NavigationView mNavigationView;
-    private int currentFragmentId = -1;
+    private int mCurrentFragmentId = -1;
+
+    private CircleImageView mCircleImageViewUserAvatar;
+    private ImageView mImageViewHeaderBackGround;
+    private TextView mTextViewUserFirstname;
+    private Toolbar mToolbarMainActivity;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
 
-        Toolbar toolbarMainActivity = findViewById(R.id.toolbarMainActivity);
-        setSupportActionBar(toolbarMainActivity);
+        mToolbarMainActivity = findViewById(R.id.toolbarMainActivity);
+        setSupportActionBar(mToolbarMainActivity);
         getSupportActionBar().setDisplayShowTitleEnabled(false);
 
+
         // Drawer Menu
         mDrawerLayout = findViewById(R.id.drawerLayout);
         mToggle = new ActionBarDrawerToggle(
-                this, mDrawerLayout, toolbarMainActivity, R.string.navigation_drawer_open,
+                this, mDrawerLayout, mToolbarMainActivity, R.string.navigation_drawer_open,
                 R.string.navigation_drawer_close);
         mDrawerLayout.addDrawerListener(mToggle);
         mToggle.syncState();
         mNavigationView = findViewById(R.id.nav_view);
         mNavigationView.setNavigationItemSelectedListener(this);
-        mNavigationView.setItemIconTintList(null);
+        //mNavigationView.setItemIconTintList(null);
+
 
         mAuthController = AuthController.getInstance(this);
         mAuthController.setAuthListener(new AuthController.AuthListener() {
@@ -92,23 +115,33 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
         mConversationsController = ConversationsController.getInstance();
         mConversationsController.setOnUnreadCountChangedListener(count -> {
             if(mTextViewNotificationBadge != null) {
-                setupBadge();
+                runOnUiThread(this::setupBadge);
             }
         });
+        //Drawer Header Elements
+        View header = mNavigationView.getHeaderView(0);
+        mCircleImageViewUserAvatar = header.findViewById(R.id.circleImageUserAvatar);
+        mCircleImageViewUserAvatar.setOnClickListener(v -> {
+            onNavigationItemSelected(mNavigationView.getMenu().getItem(PROFILE_INDEX));
+        });
+        mImageViewHeaderBackGround = header.findViewById(R.id.imageViewHeaderBackGround);
+        mTextViewUserFirstname = header.findViewById(R.id.textViewUserName);
 
+        updateDrawer();
     }
 
     // Drawer Menu
     @Override
     public void onBackPressed() {
-        DrawerLayout drawer = findViewById(R.id.drawerLayout);
         Fragment currentFragment = mFragmentManager.findFragmentById(R.id.layoutMainContent);
-        if (drawer.isDrawerOpen(GravityCompat.START)) {
-            drawer.closeDrawer(GravityCompat.START);
+        if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
+            mDrawerLayout.closeDrawer(GravityCompat.START);
         }
         else if(! (currentFragment instanceof MainFragment)){
             mFragmentManager.beginTransaction().replace(R.id.layoutMainContent, new MainFragment()).commit();
             mNavigationView.getMenu().getItem(0).setChecked(true);
+            mCurrentFragmentId = R.id.drawer_home;
+            if(! getSupportActionBar().isShowing()) getSupportActionBar().show();
         }
         else {
             super.onBackPressed();
@@ -120,6 +153,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
         int id = item.getItemId();
         switch (id) {
             case R.id.action_messages:
+                if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
+                    mDrawerLayout.closeDrawer(GravityCompat.START);
+                }
                 startActivity(new Intent(MainActivity.this, ConversationsActivity.class));
                 return true;
 
@@ -132,8 +168,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
         Log.d(TAG, "onNavigationItemSelected: " + item.getItemId());
         // Handle navigation view item clicks here.
         int id = item.getItemId();
-        if(id != currentFragmentId) {
-            currentFragmentId = id;
+        if(id != mCurrentFragmentId) {
+            if(! getSupportActionBar().isShowing()) getSupportActionBar().show();
+            mCurrentFragmentId = id;
             FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
             Fragment fragment = null;
             Class fragmentClass = null;
@@ -143,6 +180,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
                     fragmentClass = MainFragment.class;
                     break;
                 case R.id.drawer_find_event:
+                    fragmentClass = SearchEventFragment.class;
                     break;
                 case R.id.drawer_create_event:
                     fragmentClass = CreateEventFragment.class;
@@ -151,6 +189,7 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
                     fragmentClass = PlanningFragment.class;
                     break;
                 case R.id.drawer_profile:
+                    fragmentClass = ProfileFragment.class;
                     break;
                 case R.id.drawer_sign_out:
                     signOut();
@@ -209,4 +248,30 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
             }
         }
     }
+
+    public void updateDrawer() {
+        UserModel user = UserController.getInstance().getUser();
+        Log.d(TAG, "updateDrawer() called " + user.getAvatar());
+        Glide.with(this)
+                .load(user.getAvatar())
+                .apply(new RequestOptions().placeholder(R.drawable.placeholder).error(R.drawable.placeholder))
+                .into(mCircleImageViewUserAvatar);
+
+        MultiTransformation multi = new MultiTransformation(
+                new ColorFilterTransformation(getResources().getColor(R.color.drawerAvatarBackgroundFilter)),
+                new BlurTransformation(BLUR_RADIUS));
+
+        Glide.with(this)
+                .load(user.getAvatar()).apply(bitmapTransform(multi))
+                .into(mImageViewHeaderBackGround);
+        mTextViewUserFirstname.setText(user.getName());
+    }
+
+    public void goToSearch() {
+        onNavigationItemSelected(mNavigationView.getMenu().getItem(SEARCH_INDEX));
+    }
+
+    public void goToCreate() {
+        onNavigationItemSelected(mNavigationView.getMenu().getItem(CREATE_INDEX));
+    }
 }

+ 14 - 0
app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/MessagesActivity.java

@@ -1,12 +1,16 @@
 package fr.wildcodeschool.steeryfit.UI.Activities;
 
+import android.content.Intent;
 import android.os.Bundle;
 import android.support.v7.app.AppCompatActivity;
+import android.util.Log;
 
 import fr.wildcodeschool.steeryfit.R;
 import fr.wildcodeschool.steeryfit.UI.Fragments.MessagesFragment;
+import fr.wildcodeschool.steeryfit.Utils.Utils;
 
 public class MessagesActivity extends AppCompatActivity {
+    private final String TAG = Utils.getTAG(this);
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -17,4 +21,14 @@ public class MessagesActivity extends AppCompatActivity {
                 .replace(R.id.layoutMessagesContent, MessagesFragment.newInstance())
                 .commit();
     }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        Log.d(TAG, "onNewIntent() called with: intent = [" + intent + "]");
+        setIntent(intent);
+        getSupportFragmentManager().beginTransaction()
+                .replace(R.id.layoutMessagesContent, MessagesFragment.newInstance())
+                .commit();
+        super.onNewIntent(intent);
+    }
 }

+ 307 - 131
app/src/main/java/fr/wildcodeschool/steeryfit/UI/Activities/ModifyEventActivity.java

@@ -3,15 +3,24 @@ package fr.wildcodeschool.steeryfit.UI.Activities;
 import android.app.DatePickerDialog;
 import android.app.ProgressDialog;
 import android.content.Intent;
+import android.graphics.Color;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
+import android.support.design.widget.BaseTransientBottomBar;
+import android.support.design.widget.Snackbar;
+import android.support.v7.app.ActionBar;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.Toolbar;
 import android.text.Editable;
+import android.text.Html;
 import android.text.TextWatcher;
 import android.text.format.DateUtils;
+import android.view.MenuItem;
 import android.view.View;
+import android.view.WindowManager;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
@@ -43,6 +52,7 @@ import fr.wildcodeschool.steeryfit.Controllers.EventsDetailsController;
 import fr.wildcodeschool.steeryfit.Controllers.UserController;
 import fr.wildcodeschool.steeryfit.Controllers.UserEventsController;
 import fr.wildcodeschool.steeryfit.Models.EventModel;
+import fr.wildcodeschool.steeryfit.Models.Gender;
 import fr.wildcodeschool.steeryfit.Models.Sports;
 import fr.wildcodeschool.steeryfit.Models.UserModel;
 import fr.wildcodeschool.steeryfit.R;
@@ -50,17 +60,25 @@ import fr.wildcodeschool.steeryfit.UI.Adapters.ParticipantsAdapter;
 import fr.wildcodeschool.steeryfit.UI.Fragments.LocationPickerFragment;
 import fr.wildcodeschool.steeryfit.Utils.Utils;
 
-import static fr.wildcodeschool.steeryfit.Utils.Constants.EVENTS_LIST_INDEX;
+import static fr.wildcodeschool.steeryfit.Models.Gender.FEMALE;
+import static fr.wildcodeschool.steeryfit.Models.Gender.MALE;
+import static fr.wildcodeschool.steeryfit.Models.Gender.MIXTE;
+import static fr.wildcodeschool.steeryfit.Utils.Constants.EVENTS_ENTRY;
 import static fr.wildcodeschool.steeryfit.Utils.Constants.EVENTS_PREVIEW_ENTRY;
-import static fr.wildcodeschool.steeryfit.Utils.Constants.NAVIGATION_ITEM;
+import static fr.wildcodeschool.steeryfit.Utils.Constants.NEW_EVENT_TAG;
 
 public class ModifyEventActivity extends AppCompatActivity {
 
     private final String TAG = Utils.getTAG(this);
     private UserEventsController mUserEventsController;
     private EventModel mEvent = null;
-    private EditText mEditTextEventDate, mEditTextEventTime, mEditTextEventEndTime;
+    private ImageView mImageViewCalendar, mImageViewClockStart, mImageViewClockEnd, mImageViewEventGenderModifyEvent2;
+    private EditText mEditTextEventName, mEditTextEventInfo, mEditTextEventDate, mEditTextEventTime,
+            mEditTextEventEndTime;
+    private TextView mTextViewEventInfoModifyEvent;
+    private Spinner mSpinnerEventLevel, mSpinnerEventGender;
     private Sports.Level mLevel;
+    private Gender mGender;
     private long mDuration, mStartTime;
     private NumberPicker mNumberPickerUsersLimitModifyEvent;
     private Calendar mStartCalendar, mEndCalendar;
@@ -70,8 +88,11 @@ public class ModifyEventActivity extends AppCompatActivity {
     private ScrollView mScrollView;
     private UserEventsController.UpdateEventBuilder mUpdateEventBuilder;
     private String mAddress;
+    private LocationPickerFragment mLocationPicker;
     private boolean mLocationChanged = false;
 
+    private final int SNAKBAR_TIME = 5000;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -79,6 +100,12 @@ public class ModifyEventActivity extends AppCompatActivity {
 
         // Controller instance & Update Listener
         mUserEventsController = UserEventsController.getInstance();
+        Intent intentFrom = getIntent();
+        String uid = intentFrom.getStringExtra(EVENTS_ENTRY);
+        if(uid != null) {
+            mEvent = mUserEventsController.getUserEvents().get(uid);
+            mUserEventsController.setSelectedEvent(mEvent);
+        }
         mEvent = mUserEventsController.getSelectedEvent();
         mUpdateListener = task -> {
             if(!task.isSuccessful()) {
@@ -89,44 +116,63 @@ public class ModifyEventActivity extends AppCompatActivity {
 
             Toast.makeText(ModifyEventActivity.this, R.string.event_creation_success_message, Toast.LENGTH_SHORT).show();
 
-            Intent intent = new Intent(ModifyEventActivity.this, MainActivity.class);
-            intent.putExtra(NAVIGATION_ITEM, EVENTS_LIST_INDEX);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-            startActivity(intent);
+            onBackPressed();
         };
         ;
         mUpdateEventBuilder = mUserEventsController.getUpdateEventBuilder(mEvent);
 
+        // Toolbar