options) {
17 | super(options);
18 | }
19 |
20 | @Override
21 | protected void onBindViewHolder(@NonNull MembreHolder holder, int position, @NonNull Membre model) {
22 | holder.textViewFullName.setText(model.getFullName());
23 | holder.textViewUsername.setText("@" + model.getUsername());
24 | holder.textViewEmail.setText(String.valueOf(model.getEmail()));
25 | holder.textViewBirth.setText(String.valueOf(model.getBirth()));
26 | }
27 |
28 | @NonNull
29 | @Override
30 | public MembreHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
31 | View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.team_member_item, parent, false);
32 | return new MembreHolder(v);
33 | }
34 |
35 | static class MembreHolder extends RecyclerView.ViewHolder {
36 | TextView textViewFullName;
37 | TextView textViewUsername;
38 | TextView textViewEmail;
39 | TextView textViewBirth;
40 |
41 | MembreHolder(View itemView) {
42 | super(itemView);
43 | textViewFullName = itemView.findViewById(R.id.text_view_name);
44 | textViewUsername = itemView.findViewById(R.id.text_view_username);
45 | textViewEmail = itemView.findViewById(R.id.text_view_email);
46 | textViewBirth = itemView.findViewById(R.id.text_view_birth);
47 | }
48 | }
49 |
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/LockOrientation.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.Activity;
5 | import android.app.Application;
6 | import android.content.pm.ActivityInfo;
7 | import android.os.Bundle;
8 |
9 | public class LockOrientation extends Application {
10 | // le but de ce code est de assurer que tous les menus de l'application s'ouvrent en mode portrait et de vérouiller cette orientation
11 | @Override
12 | public void onCreate() {
13 | super.onCreate();
14 |
15 | // register to be informed of activities starting up
16 | registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
17 |
18 | @SuppressLint("SourceLockedOrientationActivity")
19 | @Override
20 | public void onActivityStarted(Activity activity) {
21 | activity.setRequestedOrientation(
22 | ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
23 | }
24 |
25 | @Override
26 | public void onActivityResumed(Activity activity) {
27 |
28 | }
29 |
30 | @Override
31 | public void onActivityPaused(Activity activity) {
32 |
33 | }
34 |
35 | @Override
36 | public void onActivityStopped(Activity activity) {
37 |
38 | }
39 |
40 | @Override
41 | public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
42 |
43 | }
44 |
45 | @Override
46 | public void onActivityDestroyed(Activity activity) {
47 |
48 | }
49 |
50 | @SuppressLint("SourceLockedOrientationActivity")
51 | @Override
52 | public void onActivityCreated(Activity activity,
53 | Bundle savedInstanceState) {
54 | activity.setRequestedOrientation(
55 | ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
56 | }
57 | });
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - Janvier
5 | - Fevrier
6 | - Mars
7 | - Avril
8 | - Mai
9 | - Juin
10 | - Juillet
11 | - Aout
12 | - Septembre
13 | - Octobre
14 | - Novembre
15 | - Decembre
16 |
17 | Training Tracker
18 | Sign in or register
19 | Register
20 | Sign in
21 | Sign up
22 | This email address is invalid
23 | Password too short or does not match
24 | This password is incorrect
25 |
26 |
27 | This field is required
28 |
29 |
30 |
31 | Equipes
32 |
33 | L
34 | M
35 | Me
36 | J
37 | V
38 | S
39 |
40 | D
41 |
42 | Aujourdhui
43 | OK
44 | Annuler
45 | Hello!
46 | Type a message
47 | Send
48 |
49 |
50 | ADD YOUR GOOGLE MAPS API HERE
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/LineCharItem.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.graphics.Typeface;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 |
9 | import com.github.mikephil.charting.charts.LineChart;
10 | import com.github.mikephil.charting.components.YAxis;
11 | import com.github.mikephil.charting.data.ChartData;
12 | import com.github.mikephil.charting.data.LineData;
13 |
14 | class LineChartItem extends ChartItem {
15 | private final Typeface mTf;
16 | LineChartItem(ChartData> cd, Context c) {
17 | super(cd);
18 | mTf = Typeface.createFromAsset(c.getAssets(), "OpenSans-Regular.ttf");
19 | }
20 |
21 | @Override
22 | public int getItemType() {
23 | return TYPE_LINECHART;
24 | }
25 |
26 | @SuppressLint("InflateParams")
27 | @Override
28 | public View getView(int position, View convertView, Context c) {
29 |
30 | ViewHolder holder;
31 | if (convertView == null) {
32 | holder = new ViewHolder();
33 | convertView = LayoutInflater.from(c).inflate(
34 | R.layout.list_item_linechart, null);
35 | holder.chart = convertView.findViewById(R.id.chart);
36 | convertView.setTag(holder);
37 |
38 | } else {
39 | holder = (ViewHolder) convertView.getTag();
40 | }
41 |
42 | holder.chart.getDescription().setEnabled(false);
43 | holder.chart.setDrawGridBackground(false);
44 |
45 | YAxis leftAxis = holder.chart.getAxisLeft();
46 | leftAxis.setTypeface(mTf);
47 | leftAxis.setLabelCount(5, false);
48 | leftAxis.setAxisMinimum(0f);
49 |
50 | YAxis rightAxis = holder.chart.getAxisRight();
51 | rightAxis.setTypeface(mTf);
52 | rightAxis.setLabelCount(5, false);
53 | rightAxis.setDrawGridLines(false);
54 | rightAxis.setAxisMinimum(0f);
55 |
56 | // set data
57 | holder.chart.setData((LineData) mChartData);
58 | holder.chart.animateX(750);
59 |
60 | return convertView;
61 | }
62 |
63 | private static class ViewHolder {
64 | LineChart chart;
65 | }
66 | }
--------------------------------------------------------------------------------
/app/src/main/res/layout/team_member_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
15 |
16 |
26 |
27 |
35 |
36 |
43 |
50 |
51 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 29
5 | defaultConfig {
6 | applicationId "com.choubapp.running"
7 | minSdkVersion 19
8 | targetSdkVersion 29
9 | versionCode 1
10 | versionName "1.0"
11 | multiDexEnabled true
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | compileOptions {
21 | sourceCompatibility = 1.8
22 | targetCompatibility = 1.8
23 | }
24 | }
25 |
26 | dependencies {
27 | implementation fileTree(dir: 'libs', include: ['*.jar'])
28 | //noinspection GradleCompatible
29 | implementation 'com.android.support:appcompat-v7:28.0.0'
30 | //noinspection GradleCompatible
31 | implementation 'com.android.support:cardview-v7:28.0.0'
32 | implementation 'com.android.support.constraint:constraint-layout:1.1.3'
33 | implementation 'androidx.appcompat:appcompat:1.1.0'
34 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
35 | implementation 'com.squareup.picasso:picasso:2.71828'
36 | testImplementation 'junit:junit:4.12'
37 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
38 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
39 |
40 | implementation 'com.applandeo:material-calendar-view:1.7.0'
41 | implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
42 |
43 | //noinspection GradleDependency
44 | implementation 'com.google.firebase:firebase-analytics:17.2.2'
45 | implementation 'com.firebaseui:firebase-ui-storage:6.2.0'
46 | implementation 'com.firebaseui:firebase-ui-firestore:6.2.1'
47 | implementation 'com.google.firebase:firebase-firestore:17.1.2'
48 | implementation 'com.google.firebase:firebase-storage:19.1.0'
49 |
50 | implementation 'com.google.android.material:material:1.0.0'
51 | implementation 'com.google.firebase:firebase-auth:19.3.0'
52 | implementation 'com.google.firebase:firebase-database:19.2.1'
53 | implementation "androidx.multidex:multidex:2.0.0"
54 | implementation 'com.google.android.gms:play-services-maps:17.0.0'
55 | implementation 'com.google.android.gms:play-services-location:17.0.0'
56 | implementation 'androidx.gridlayout:gridlayout:1.0.0'
57 |
58 | }
59 | apply plugin: 'com.android.application'
60 | apply plugin: 'com.google.gms.google-services'
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/BarChartItem.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.graphics.Typeface;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 |
9 | import com.github.mikephil.charting.charts.BarChart;
10 | import com.github.mikephil.charting.components.XAxis;
11 | import com.github.mikephil.charting.components.YAxis;
12 | import com.github.mikephil.charting.data.BarData;
13 | import com.github.mikephil.charting.data.ChartData;
14 |
15 | class BarChartItem extends ChartItem {
16 | private final Typeface mTf;
17 |
18 | BarChartItem(ChartData> cd, Context c) {
19 | super(cd);
20 | mTf = Typeface.createFromAsset(c.getAssets(), "OpenSans-Regular.ttf");
21 | }
22 |
23 | @Override
24 | public int getItemType() {
25 | return TYPE_BARCHART;
26 | }
27 |
28 | @SuppressLint("InflateParams")
29 | @Override
30 | public View getView(int position, View convertView, Context c) {
31 |
32 | ViewHolder holder;
33 |
34 | if (convertView == null) {
35 |
36 | holder = new ViewHolder();
37 |
38 | convertView = LayoutInflater.from(c).inflate(
39 | R.layout.list_item_barchart, null);
40 | holder.chart = convertView.findViewById(R.id.chart);
41 |
42 | convertView.setTag(holder);
43 |
44 | } else {
45 | holder = (ViewHolder) convertView.getTag();
46 | }
47 |
48 | // apply styling
49 | holder.chart.getDescription().setEnabled(false);
50 | holder.chart.setDrawGridBackground(false);
51 | holder.chart.setDrawBarShadow(false);
52 |
53 | YAxis leftAxis = holder.chart.getAxisLeft();
54 | leftAxis.setTypeface(mTf);
55 | leftAxis.setLabelCount(5, false);
56 | leftAxis.setSpaceTop(20f);
57 | leftAxis.setAxisMinimum(0f);
58 |
59 | YAxis rightAxis = holder.chart.getAxisRight();
60 | rightAxis.setTypeface(mTf);
61 | rightAxis.setLabelCount(5, false);
62 | rightAxis.setSpaceTop(20f);
63 | rightAxis.setAxisMinimum(0f);
64 |
65 | mChartData.setValueTypeface(mTf);
66 |
67 | // set data
68 | holder.chart.setData((BarData) mChartData);
69 | holder.chart.setFitBars(true);
70 | holder.chart.animateY(700);
71 |
72 | return convertView;
73 | }
74 |
75 | private static class ViewHolder {
76 | BarChart chart;
77 | }
78 | }
79 |
80 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/MessagesActivity.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.AbsListView;
7 | import android.widget.ListView;
8 | import android.widget.TextView;
9 |
10 | import androidx.appcompat.app.AppCompatActivity;
11 |
12 | import com.google.firebase.database.DatabaseReference;
13 | import com.google.firebase.database.FirebaseDatabase;
14 |
15 | import java.text.SimpleDateFormat;
16 | import java.util.Date;
17 | import java.util.Locale;
18 |
19 | public class MessagesActivity extends AppCompatActivity {
20 | String teamid;
21 | private ListView mChatListView;
22 |
23 | private DatabaseReference mDatabaseReference;
24 |
25 |
26 | private ChatListAdapter mAdapter;
27 |
28 | TextView date;
29 |
30 |
31 | @Override
32 | protected void onCreate(Bundle savedInstanceState) {
33 |
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_messages);
36 | Intent intent = getIntent();
37 | teamid = intent.getStringExtra(DashboardActivity.USER_TEAM);
38 | mDatabaseReference = FirebaseDatabase.getInstance().getReference();
39 |
40 | mChatListView = findViewById(R.id.chat_list_view1);
41 | date = findViewById(R.id.date1);
42 |
43 | }
44 |
45 | public void ChangeDate() {
46 | mChatListView.setOnScrollListener(new AbsListView.OnScrollListener() {
47 | @Override
48 | public void onScrollStateChanged(AbsListView view, int scrollState) {
49 |
50 | }
51 |
52 | @Override
53 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
54 | if (totalItemCount != 0) {
55 |
56 | if (mAdapter.getDateselected(firstVisibleItem + visibleItemCount - 1).equals(new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date()))) {
57 | date.setText("Today");
58 | } else {
59 | date.setText(mAdapter.getDateselected(firstVisibleItem + visibleItemCount - 1));
60 | }
61 | }
62 |
63 | }
64 | });
65 |
66 | }
67 | public void onStart(){
68 | super.onStart();
69 | mAdapter = new ChatListAdapter(this , mDatabaseReference,teamid);
70 | mChatListView.setAdapter(mAdapter);
71 | ChangeDate();
72 | }
73 |
74 | public void onStop() {
75 | super.onStop();
76 | mAdapter.cleaunup();
77 |
78 | }
79 |
80 |
81 |
82 | public void BacktoDashboard(View v) {
83 | Intent intent = new Intent(this, DashboardActivity.class);
84 | finish();
85 | startActivity(intent);
86 | }
87 |
88 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # :runner: TrainingTracker :running: | Unmaintained Project
2 | An android app to manage trainings between a coach and his team members. This is a school project for ENSIAS (National School of Applied Sciences in Rabat, Morocco) using Java and Firebase.
3 |
4 |
5 |
6 |
7 |
8 | ## :zap: Project Config
9 |
10 | ```
11 | applicationId "com.choubapp.running"
12 | compileSdkVersion 29
13 | minSdkVersion 19
14 | targetSdkVersion 29
15 | ```
16 |
17 | ## :key: Setup:
18 |
19 | * Create a Firebase Project : Firebase [Setup and Documentation](https://firebase.google.com/docs/android/setup) for Android
20 | * Get your own Google Maps [API Key](https://developers.google.com/maps/documentation/android-sdk/get-api-key) and add it to strings.xml
21 |
22 | We've used :
23 | * Firebase CloudFirestore to store users, teams and trainings data.
24 | * Realtime Database for sending and retreiving messages.
25 | * Firebase Storage to save profil pictures uploaded by the users.
26 |
27 |
28 | ## :iphone: Screenshots :
29 |
30 | **SignUp :**
31 |
32 |
33 |
34 |
35 | **:boy: Member Dashboard :**
36 |
37 |
38 |
39 |
40 |
41 | **Member Menus :**
42 |
43 |
44 |
45 |
46 | ##
47 |
48 | **:cop: Coach Dashboard :**
49 |
50 |
51 |
52 |
53 |
54 | **Coach Menus :**
55 |
56 |
57 |
58 |
59 | ##
60 |
61 | **:alarm_clock: Training Time :**
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | ## :bulb: External Libraries :
70 |
71 | [Picasso](https://github.com/square/picasso)
72 |
73 | [Material Calendar View](https://github.com/Applandeo/Material-Calendar-View)
74 |
75 | [MPAndroidChart](https://github.com/PhilJay/MPAndroidChart)
76 |
77 | [FirebaseUI](https://github.com/firebase/FirebaseUI-Android)
78 |
79 | ##
80 |
81 | ### :sparkles: Graphic Assets :
82 |
83 | Home Screen Illustration : [Freepik](https://freepik.com)
84 |
85 | Gradient Icons : [Roundicons](https://roundicons.com/gradient-icons-pack/)
86 |
87 | ##
88 |
89 | ### :paperclip: Somethings to fix or add :
90 |
91 | - [ ] Date picker Dialog isn't working for API 19-22
92 | - [ ] Refactor the code to MVC architecture and optimize call Firebase functions.
93 | - [ ] Push notifications to team members when the coach sends messages or the next training is near to start
94 | - [X] Show date and time of each message
95 |
96 | ## :sparkling_heart: Support :
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
24 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_create_team.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
18 |
27 |
35 |
36 |
50 |
51 |
59 |
60 |
69 |
70 |
81 |
82 |
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | xmlns:android
11 |
12 | ^$
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | xmlns:.*
22 |
23 | ^$
24 |
25 |
26 | BY_NAME
27 |
28 |
29 |
30 |
31 |
32 |
33 | .*:id
34 |
35 | http://schemas.android.com/apk/res/android
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | .*:name
45 |
46 | http://schemas.android.com/apk/res/android
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | name
56 |
57 | ^$
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | style
67 |
68 | ^$
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | .*
78 |
79 | ^$
80 |
81 |
82 | BY_NAME
83 |
84 |
85 |
86 |
87 |
88 |
89 | .*
90 |
91 | http://schemas.android.com/apk/res/android
92 |
93 |
94 | ANDROID_ATTRIBUTE_ORDER
95 |
96 |
97 |
98 |
99 |
100 |
101 | .*
102 |
103 | .*
104 |
105 |
106 | BY_NAME
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
31 |
32 |
33 |
34 |
35 |
36 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
52 |
59 |
60 |
63 |
66 |
67 |
70 |
71 |
72 |
73 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_calendar.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
18 |
22 |
27 |
38 |
44 |
45 |
49 |
50 |
51 |
60 |
68 |
69 |
70 |
76 |
83 |
84 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_tasks.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
18 |
23 |
28 |
39 |
45 |
46 |
50 |
51 |
52 |
61 |
69 |
70 |
75 |
76 |
80 |
81 |
82 |
87 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_messages.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
18 |
22 |
27 |
38 |
44 |
45 |
49 |
50 |
51 |
60 |
68 |
69 |
70 |
71 |
74 |
75 |
85 |
86 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/CreateTeam.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 | import androidx.annotation.NonNull;
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.content.ClipData;
6 | import android.content.ClipboardManager;
7 | import android.content.Context;
8 | import android.content.Intent;
9 | import android.os.Bundle;
10 | import android.util.Log;
11 | import android.view.View;
12 | import android.widget.TextView;
13 | import android.widget.Toast;
14 |
15 | import com.google.android.gms.tasks.OnFailureListener;
16 | import com.google.android.gms.tasks.OnSuccessListener;
17 | import com.google.firebase.firestore.DocumentReference;
18 | import com.google.firebase.firestore.FirebaseFirestore;
19 |
20 | import java.nio.charset.Charset;
21 | import java.util.HashMap;
22 | import java.util.Map;
23 | import java.util.Random;
24 |
25 | public class CreateTeam extends AppCompatActivity {
26 | String email;
27 | TextView TeamName, NewTeam,NewTeamId, CopyID;
28 | String teamId;
29 | FirebaseFirestore db = FirebaseFirestore.getInstance();
30 |
31 | @Override
32 | protected void onCreate(Bundle savedInstanceState) {
33 | Intent intent = getIntent();
34 | email = intent.getStringExtra(CoachDashboardActivity.USER_DATA);
35 | super.onCreate(savedInstanceState);
36 | setContentView(R.layout.activity_create_team);
37 | CopyID=findViewById(R.id.copyID);
38 | CopyID.setVisibility(View.INVISIBLE);
39 | }
40 |
41 | public void SaveTeam(View v) {
42 | NewTeam = findViewById(R.id.JustCreatedTeam);
43 | NewTeamId = findViewById(R.id.JustCreatedTeamId);
44 | TeamName = findViewById(R.id.teamname);
45 | String name = TeamName.getText().toString();
46 | // generer ID de l'equipe
47 | teamId= RandomString.getAlphaNumericString(6);
48 | Map team = new HashMap<>();
49 | team.put("Nom Equipe", name);
50 | team.put("Email Coach", email);
51 | team.put("ID", teamId);
52 | // enregistrer les donnees de l'equipe dans un nouveau document dans la collection Equipe
53 | db.collection("Equipe")
54 | .add(team)
55 | .addOnSuccessListener(documentReference -> {
56 | Log.d("TAG", "DocumentSnapshot added with ID: " + documentReference.getId());
57 | NewTeam.setText("Votre équipe a été enregistrée" );
58 | NewTeamId.setText("Son ID est :" +teamId );
59 | CopyID.setVisibility(View.VISIBLE);
60 |
61 | })
62 | .addOnFailureListener(e -> Log.w("TAG", "Error adding document", e));
63 | }
64 | // si on clique sur copier, l'ID de l'equipe créée sera copiée dans le presse-papier
65 | public void CopyID(View v){
66 | ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
67 | ClipData clip = ClipData.newPlainText("ID de l'équipe", teamId);
68 | clipboard.setPrimaryClip(clip);
69 | Toast.makeText(this, "Votre ID est copié dans le presse-papier", Toast.LENGTH_SHORT).show();
70 | }
71 |
72 | static class RandomString {
73 | static String getAlphaNumericString(int n) {
74 | // length is bounded by 256 Character
75 | byte[] array = new byte[256];
76 | new Random().nextBytes(array);
77 | String randomString = new String(array, Charset.forName("UTF-8"));
78 | // Create a StringBuffer to store the result
79 | StringBuilder r = new StringBuilder();
80 | // remove all spacial char
81 | String AlphaNumericString = randomString.replaceAll("[^A-Za-z0-9]", "");
82 | // Append first 20 alphanumeric characters
83 | // from the generated random String into the result
84 | for (int k = 0; k < AlphaNumericString.length(); k++) {
85 | if (Character.isLetter(AlphaNumericString.charAt(k))
86 | && (n > 0)
87 | || Character.isDigit(AlphaNumericString.charAt(k))
88 | && (n > 0)) {
89 | r.append(AlphaNumericString.charAt(k));
90 | n--;
91 | }
92 | }
93 | // return the resultant string
94 | return r.toString();
95 | }
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_member_training_time.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
21 |
27 |
34 |
42 |
43 |
49 |
53 |
54 |
61 |
68 |
75 |
76 |
77 |
78 |
83 |
84 |
88 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
22 |
24 |
26 |
28 |
30 |
32 |
34 |
36 |
38 |
40 |
42 |
44 |
46 |
48 |
50 |
52 |
54 |
56 |
58 |
60 |
62 |
64 |
66 |
68 |
70 |
72 |
74 |
75 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
21 |
22 |
29 |
30 |
39 |
40 |
47 |
55 |
56 |
57 |
65 |
73 |
74 |
75 |
76 |
82 |
83 |
96 |
107 |
117 |
118 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_coach_memberlist.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
18 |
22 |
27 |
38 |
44 |
45 |
49 |
50 |
51 |
60 |
68 |
69 |
70 |
74 |
75 |
83 |
84 |
98 |
110 |
111 |
115 |
116 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_training.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
18 |
23 |
28 |
39 |
45 |
46 |
50 |
51 |
52 |
61 |
69 |
70 |
71 |
76 |
82 |
91 |
101 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/ChatListAdapter.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.util.Log;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.BaseAdapter;
10 | import android.widget.LinearLayout;
11 | import android.widget.TextView;
12 |
13 | import androidx.annotation.NonNull;
14 | import androidx.annotation.Nullable;
15 |
16 | import com.google.firebase.database.ChildEventListener;
17 | import com.google.firebase.database.DataSnapshot;
18 | import com.google.firebase.database.DatabaseError;
19 | import com.google.firebase.database.DatabaseReference;
20 |
21 | import java.util.ArrayList;
22 |
23 | public class ChatListAdapter extends BaseAdapter {
24 | private Activity mActivity;
25 | private DatabaseReference mDatabaseReference;
26 | private ArrayList mSnapshotList;
27 |
28 | private String teamIdSelected;
29 |
30 | private ChildEventListener mListener = new ChildEventListener() {
31 | @Override
32 | public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
33 | Log.d("onChildadd","un child est ajouté");
34 | InstantMessage test =(InstantMessage) dataSnapshot.getValue(InstantMessage.class);
35 | if (test != null && test.getTeamId().equals(teamIdSelected)) {
36 | mSnapshotList.add(dataSnapshot);
37 | notifyDataSetChanged();
38 | }
39 | }
40 |
41 | @Override
42 | public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
43 | Log.d("onChanged","un child est modifié");
44 | }
45 |
46 | @Override
47 | public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
48 | Log.d("onChildRemoved","un child est supprimé");
49 |
50 | }
51 |
52 | @Override
53 | public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
54 | Log.d("onChildmoved","un child a été changé");
55 |
56 | }
57 |
58 | @Override
59 | public void onCancelled(@NonNull DatabaseError databaseError) {
60 | Log.d("onChildcancelled","un child a ete rejeter");
61 |
62 | }
63 | };
64 |
65 | ChatListAdapter(Activity activity, DatabaseReference ref, String id){
66 | Log.d("chatListAdapter","depuis adapter");
67 |
68 | mActivity = activity;
69 | teamIdSelected = id;
70 | mDatabaseReference = ref.child("messages");
71 | mDatabaseReference.addChildEventListener(mListener); // adding listener to database
72 |
73 | mSnapshotList = new ArrayList<>();
74 | }
75 | static class ViewHolder{
76 | TextView authorName;
77 | TextView body;
78 | TextView time;
79 | LinearLayout.LayoutParams params;
80 |
81 | }
82 |
83 | @Override
84 | public int getCount() {
85 | Log.d("getcont", "sizeof snapshot");
86 |
87 | return mSnapshotList.size();
88 | }
89 |
90 | @Override
91 | public InstantMessage getItem(int position) {
92 | Log.d("getItem", "J'ai pris l'item numéro "+position);
93 | DataSnapshot snapshot = mSnapshotList.get(position);
94 | return snapshot.getValue(InstantMessage.class);
95 | }
96 |
97 | @Override
98 | public long getItemId(int position) {
99 | Log.d("getItemId", "J'ai pris l'item id"+position);
100 | return 0;
101 | }
102 |
103 | @Override
104 | public View getView(int position, View convertView, ViewGroup parent) {
105 | Log.d("getView", "J'ai pris l item id"+position);
106 |
107 | if (convertView == null) {
108 | LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
109 | convertView = inflater.inflate(R.layout.chat_msg_row, parent, false);
110 |
111 | final ViewHolder holder = new ViewHolder();
112 | holder.authorName = convertView.findViewById(R.id.author);
113 | holder.body = convertView.findViewById(R.id.message);
114 | holder.params = (LinearLayout.LayoutParams) holder.authorName.getLayoutParams();
115 | holder.time = convertView.findViewById(R.id.Time);
116 |
117 | convertView.setTag(holder);
118 | }
119 |
120 | final InstantMessage message = getItem(position);
121 | final ViewHolder holder = (ViewHolder) convertView.getTag();
122 | // setting the view information
123 | String author = message.getCoachName();
124 | holder.authorName.setText(author);
125 |
126 | String msg = message.getMessage();
127 | holder.body.setText(msg);
128 |
129 | String time = message.getTime();
130 | holder.time.setText(time);
131 | return convertView;
132 |
133 | }
134 |
135 | String getDateselected(int position)
136 | {
137 | Log.d("getDateselected", "J'ai pris la date de "+position);
138 |
139 | InstantMessage message = getItem(position);
140 | Log.d("je retourne", message.getDate());
141 | return message.getDate();
142 | }
143 |
144 | void cleaunup(){
145 | Log.d("cleanup", "J'ai videe");
146 |
147 | mDatabaseReference.removeEventListener(mListener);
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/CoachDashboardActivity.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import androidx.annotation.NonNull;
4 | import androidx.appcompat.app.AppCompatActivity;
5 |
6 | import android.content.Intent;
7 | import android.net.Uri;
8 | import android.os.Bundle;
9 | import android.util.Log;
10 | import android.view.View;
11 | import android.widget.ImageView;
12 | import android.widget.TextView;
13 |
14 | import com.google.android.gms.tasks.OnCompleteListener;
15 | import com.google.android.gms.tasks.OnSuccessListener;
16 | import com.google.android.gms.tasks.Task;
17 | import com.google.firebase.auth.FirebaseAuth;
18 | import com.google.firebase.firestore.CollectionReference;
19 | import com.google.firebase.firestore.DocumentSnapshot;
20 | import com.google.firebase.firestore.FirebaseFirestore;
21 | import com.google.firebase.firestore.FirebaseFirestoreSettings;
22 | import com.google.firebase.firestore.QuerySnapshot;
23 | import com.google.firebase.storage.FirebaseStorage;
24 | import com.google.firebase.storage.StorageReference;
25 | import com.squareup.picasso.Picasso;
26 |
27 |
28 | public class CoachDashboardActivity extends AppCompatActivity {
29 | static final String USER_DATA = "com.choubapp.running.USER_DATA";
30 | FirebaseFirestore db = FirebaseFirestore.getInstance();
31 | FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder().setTimestampsInSnapshotsEnabled(true).build();
32 | String Email;
33 | String doc_id;
34 |
35 | @Override
36 | protected void onCreate(Bundle savedInstanceState) {
37 | Intent intent = getIntent();
38 | // récuperer email du login ou du menu paramètres
39 | Email = intent.getStringExtra(MainActivity.LOGIN_EMAIL);
40 | Email = intent.getStringExtra(CoachSettingsActivity.LOGIN_EMAIL);
41 | super.onCreate(savedInstanceState);
42 | setContentView(R.layout.activity_coach_dashboard);
43 |
44 | loadprofilepic();
45 | findViewById(R.id.header).setVisibility(View.GONE);
46 | findViewById(R.id.big_screen).setVisibility(View.GONE);
47 | final TextView DisplayName = findViewById(R.id.name);
48 | final TextView DisplayUsername = findViewById(R.id.username);
49 | db.setFirestoreSettings(settings);
50 | // afficher nom, username du caoch
51 | CollectionReference coach = db.collection("coach");
52 | coach.whereEqualTo("Email", Email)
53 | .get()
54 | .addOnCompleteListener(task -> {
55 | if (task.isSuccessful()) {
56 | for (DocumentSnapshot document : task.getResult()) {
57 | Log.d("TAG", document.getId() + " => " + document.getData());
58 | DisplayName.setText(document.get("FullName").toString());
59 | DisplayUsername.setText("@" + document.get("Username").toString());
60 | doc_id = document.getId();
61 | findViewById(R.id.loadingPanel).setVisibility(View.GONE);
62 | findViewById(R.id.header).setVisibility(View.VISIBLE);
63 | findViewById(R.id.big_screen).setVisibility(View.VISIBLE);
64 | }
65 | } else {
66 | Log.d("TAG", "Error getting documents: ", task.getException());
67 | }
68 | });
69 | }
70 | private void loadprofilepic(){
71 | // afficher image de profile si elle existe
72 | ImageView imageView =findViewById(R.id.person);
73 | FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
74 | FirebaseStorage firebaseStorage = FirebaseStorage.getInstance();
75 | StorageReference storageReference = firebaseStorage.getReference();
76 | // récuperer l'image enregistrée de Firebase Storage via "User id/ImageProfile/Profile Pic.jpg".
77 | storageReference.child(firebaseAuth.getUid()).child("ImageProfile").child("Profile Pic").getDownloadUrl().addOnSuccessListener(new OnSuccessListener() {
78 | @Override
79 | public void onSuccess(Uri uri) {
80 | Picasso.get().load(uri).fit().centerInside().into(imageView);
81 | }
82 | });
83 | }
84 |
85 |
86 | // si le boutton se déconnecter est cliqué
87 | public void Logout(View v) {
88 | // TODO: Logout
89 | Intent intent = new Intent(this, MainActivity.class);
90 | finish();
91 | startActivity(intent);
92 | }
93 |
94 | // si le menu calendrier est choisi
95 | public void CoachReports(View v) {
96 | Intent intent = new Intent(CoachDashboardActivity.this, CoachReportsActivity.class);
97 | intent.putExtra(USER_DATA, Email);
98 | startActivity(intent);
99 | }
100 |
101 | // si le menu entrainement est choisi
102 | public void CoachTraining(View v) {
103 | Intent intent = new Intent(this, CoachTrainingActivity.class);
104 | intent.putExtra(USER_DATA, Email);
105 | startActivity(intent);
106 | }
107 |
108 |
109 | // si le menu messages est choisi
110 | public void CoachMessages(View v) {
111 | Intent intent = new Intent(this, CoachMessagesActivity.class);
112 | intent.putExtra(USER_DATA, Email);
113 | startActivity(intent);
114 | }
115 |
116 |
117 | // si le menu membres est choisi
118 | public void CoachMemberlist(View v) {
119 | Intent intent = new Intent(this, CoachMemberlistActivity.class);
120 | intent.putExtra(USER_DATA, Email);
121 | startActivity(intent);
122 | }
123 |
124 | // si le menu parametres est choisi
125 | public void CoachSettings(View v) {
126 | Intent intent = new Intent(this, CoachSettingsActivity.class);
127 | intent.putExtra(USER_DATA, doc_id);
128 | startActivity(intent);
129 | }
130 | }
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_coach_training.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
18 |
22 |
27 |
38 |
44 |
45 |
49 |
50 |
51 |
60 |
68 |
69 |
70 |
74 |
75 |
89 |
102 |
103 |
104 |
109 |
115 |
124 |
134 |
135 |
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/DashboardActivity.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import androidx.annotation.NonNull;
4 | import androidx.appcompat.app.AppCompatActivity;
5 |
6 | import android.content.Intent;
7 | import android.net.Uri;
8 | import android.os.Bundle;
9 | import android.util.Log;
10 | import android.view.View;
11 | import android.widget.ImageView;
12 | import android.widget.TextView;
13 |
14 | import com.google.android.gms.tasks.OnCompleteListener;
15 | import com.google.android.gms.tasks.OnFailureListener;
16 | import com.google.android.gms.tasks.OnSuccessListener;
17 | import com.google.android.gms.tasks.Task;
18 | import com.google.firebase.auth.FirebaseAuth;
19 | import com.google.firebase.firestore.CollectionReference;
20 | import com.google.firebase.firestore.DocumentSnapshot;
21 | import com.google.firebase.firestore.FirebaseFirestore;
22 | import com.google.firebase.firestore.FirebaseFirestoreSettings;
23 | import com.google.firebase.firestore.QuerySnapshot;
24 | import com.google.firebase.storage.FirebaseStorage;
25 | import com.google.firebase.storage.StorageException;
26 | import com.google.firebase.storage.StorageReference;
27 | import com.squareup.picasso.Picasso;
28 |
29 |
30 | public class DashboardActivity extends AppCompatActivity {
31 | static final String USER_DATA = "com.choubapp.running.USER_DATA";
32 | static final String USER_TEAM = "com.choubapp.running.USER_TEAM";
33 | ImageView profilpic;
34 | FirebaseFirestore db = FirebaseFirestore.getInstance();
35 | FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder().setTimestampsInSnapshotsEnabled(true).build();
36 | String Email,Team;
37 | String doc_id ;
38 | TextView DisplayName ,DisplayUsername;
39 |
40 | @Override
41 | protected void onCreate(Bundle savedInstanceState) {
42 | Intent intent = getIntent();
43 | Email= intent.getStringExtra(MainActivity.LOGIN_EMAIL);
44 | Email= intent.getStringExtra(SettingsActivity.LOGIN_EMAIL);
45 | super.onCreate(savedInstanceState);
46 | setContentView(R.layout.activity_dashboard);
47 | loadprofilepic();
48 | findViewById(R.id.header).setVisibility(View.GONE);
49 | findViewById(R.id.big_screen).setVisibility(View.GONE);
50 | profilpic = findViewById(R.id.person);
51 | DisplayName = findViewById(R.id.name);
52 | DisplayUsername = findViewById(R.id.username);
53 | db.setFirestoreSettings(settings);
54 | // afficher nom et username du membre
55 | CollectionReference peopleRef = db.collection("member");
56 | peopleRef.whereEqualTo("Email", Email)
57 | .get()
58 | .addOnCompleteListener(task -> {
59 | if (task.isSuccessful()) {
60 | for (DocumentSnapshot document : task.getResult()) {
61 | Log.d("TAG", document.getId() + " => " + document.getData());
62 | DisplayName.setText(document.get("FullName").toString());
63 | DisplayUsername.setText("@" + document.get("Username").toString());
64 | doc_id = document.getId();
65 | Team=document.get("Team").toString();
66 | findViewById(R.id.loadingPanel).setVisibility(View.GONE);
67 | findViewById(R.id.header).setVisibility(View.VISIBLE);
68 | findViewById(R.id.big_screen).setVisibility(View.VISIBLE);
69 | }
70 | } else {
71 | Log.d("TAG", "Error getting documents: ", task.getException());
72 | }
73 | });
74 | }
75 | private void loadprofilepic(){
76 | ImageView imageView =findViewById(R.id.person);
77 | FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
78 | FirebaseStorage firebaseStorage = FirebaseStorage.getInstance();
79 | StorageReference storageReference = firebaseStorage.getReference();
80 | // récuperer l'image enregistrée de Firebase Storage via "User id/ImageProfile/Profile Pic.jpg".
81 | storageReference.child(firebaseAuth.getUid()).child("ImageProfile").child("Profile Pic").getDownloadUrl().addOnSuccessListener(uri -> Picasso.get().load(uri).fit().centerInside().into(imageView)).addOnFailureListener(exception -> {
82 | if (exception instanceof StorageException && ((StorageException) exception).getErrorCode() == StorageException.ERROR_OBJECT_NOT_FOUND) {
83 | Log.d("TAG", "File not exist");
84 | }
85 | });
86 | }
87 |
88 | // Se déconnecter
89 | public void Logout(View v) {
90 | // TODO: Logout
91 | Intent intent = new Intent(this, MainActivity.class);
92 | finish();
93 | startActivity(intent);
94 | }
95 |
96 | // menu calendrier
97 | public void Calendar(View v) {
98 | Intent intent = new Intent(this, CalendarActivity.class);
99 | intent.putExtra(USER_TEAM,Team);
100 | startActivity(intent);
101 | }
102 |
103 |
104 | // menu entraînement
105 | public void Training(View v) {
106 | DisplayName = findViewById(R.id.name);
107 | DisplayUsername = findViewById(R.id.username);
108 | Intent intent = new Intent(this, TrainingActivity.class);
109 | intent.putExtra(USER_TEAM,Team);
110 | intent.putExtra(USER_DATA, Email);
111 | intent.putExtra("userFullName", DisplayName.getText());
112 | intent.putExtra("username", DisplayUsername.getText());
113 | startActivity(intent);
114 | }
115 |
116 |
117 | // menu messages
118 | public void Messages(View v) {
119 | Intent intent = new Intent(this, MessagesActivity.class);
120 | intent.putExtra(USER_TEAM,Team);
121 |
122 | startActivity(intent);
123 | }
124 |
125 |
126 | // menu tâches accomplies
127 | public void Tasks(View v) {
128 | Intent intent = new Intent(this, TasksActivity.class);
129 | intent.putExtra(USER_DATA, Email);
130 | startActivity(intent);
131 | }
132 |
133 | // menu parametres
134 | public void Settings(View v) {
135 | Intent intent = new Intent(this, SettingsActivity.class);
136 | intent.putExtra(USER_DATA,doc_id);
137 | startActivity(intent);
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_coach_messages.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
22 |
26 |
31 |
42 |
48 |
49 |
53 |
54 |
55 |
64 |
72 |
73 |
74 |
78 |
91 |
100 |
101 |
102 |
103 |
104 |
107 |
108 |
109 |
116 |
117 |
118 |
119 |
120 |
130 |
131 |
132 |
137 |
143 |
149 |
150 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/CoachMemberlistActivity.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import androidx.annotation.NonNull;
4 | import androidx.appcompat.app.AppCompatActivity;
5 | import androidx.recyclerview.widget.LinearLayoutManager;
6 | import androidx.recyclerview.widget.RecyclerView;
7 |
8 | import android.content.ClipData;
9 | import android.content.ClipboardManager;
10 | import android.content.Context;
11 | import android.content.Intent;
12 | import android.os.Bundle;
13 | import android.util.Log;
14 | import android.view.View;
15 | import android.widget.AdapterView;
16 | import android.widget.ArrayAdapter;
17 | import android.widget.Spinner;
18 | import android.widget.TextView;
19 | import android.widget.Toast;
20 |
21 | import com.firebase.ui.firestore.FirestoreRecyclerOptions;
22 | import com.google.android.gms.tasks.OnCompleteListener;
23 | import com.google.android.gms.tasks.Task;
24 | import com.google.firebase.firestore.CollectionReference;
25 | import com.google.firebase.firestore.DocumentSnapshot;
26 | import com.google.firebase.firestore.FirebaseFirestore;
27 | import com.google.firebase.firestore.Query;
28 | import com.google.firebase.firestore.QueryDocumentSnapshot;
29 | import com.google.firebase.firestore.QuerySnapshot;
30 | import java.util.ArrayList;
31 | import java.util.List;
32 |
33 | import static com.choubapp.running.CoachDashboardActivity.USER_DATA;
34 |
35 | public class CoachMemberlistActivity extends AppCompatActivity {
36 | String email;
37 | FirebaseFirestore db = FirebaseFirestore.getInstance();
38 | CollectionReference Teams = db.collection("Equipe");
39 | private MembreAdapter adapter;
40 | TextView showID;
41 |
42 |
43 | @Override
44 | protected void onCreate(Bundle savedInstanceState) {
45 | Intent intent = getIntent();
46 | email= intent.getStringExtra(USER_DATA);
47 | super.onCreate(savedInstanceState);
48 | setContentView(R.layout.activity_coach_memberlist);
49 | LoadSpinnerData();
50 | }
51 |
52 |
53 | public void LoadSpinnerData(){
54 | // afficher les équipes du coach dans un spinner
55 | Spinner spinner = findViewById(R.id.spinner);
56 | List TeamsList = new ArrayList<>();
57 | ArrayAdapter adapter = new ArrayAdapter(getApplicationContext(), android.R.layout.simple_spinner_item, TeamsList);
58 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
59 | spinner.setAdapter(adapter);
60 | Teams.get().addOnCompleteListener(task -> {
61 | if (task.isSuccessful()) {
62 | for (QueryDocumentSnapshot document : task.getResult()) {
63 | String teamname = document.getString("Nom Equipe");
64 | String coachmail = document.getString("Email Coach");
65 | if (teamname!=null && coachmail.equals(email) ){
66 | TeamsList.add(teamname);
67 | }
68 | }
69 | adapter.notifyDataSetChanged();
70 | }
71 | });
72 | // si une équipe est séléctionnée, on affiche la liste de cette équipe
73 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
74 | @Override
75 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
76 | String team = parent.getSelectedItem().toString();
77 | SetRecyclerbyID(team);
78 | }
79 | @Override
80 | public void onNothingSelected(AdapterView> parent) {
81 | }
82 | });
83 | }
84 | // rechercher ID de l'équipe selectionnée et appeler la methode setUpRecyclerView
85 | private void SetRecyclerbyID(String team){
86 | showID=findViewById(R.id.ShowID);
87 | final String[] Id = new String[1];
88 | CollectionReference equipe = db.collection("Equipe");
89 | equipe.whereEqualTo("Nom Equipe", team)
90 | .get()
91 | .addOnCompleteListener(task -> {
92 | if (task.isSuccessful()) {
93 | for (DocumentSnapshot document : task.getResult()) {
94 | Log.d("TAG", document.getId() + " => " + document.getData());
95 | Id[0]=document.get("ID").toString();
96 | showID.setText(Id[0]);
97 | setUpRecyclerView(Id[0]);
98 | }
99 | } else {
100 | Log.d("TAG", "Error getting documents: ", task.getException());
101 | }
102 | });
103 | }
104 | // afficher la liste des membres de l'équipe sélectionnée dans un recyclerview
105 | private void setUpRecyclerView(String teamid) {
106 | CollectionReference Members = db.collection("member");
107 | Query query = Members.whereEqualTo("Team",teamid);
108 | FirestoreRecyclerOptions options = new FirestoreRecyclerOptions.Builder()
109 | .setQuery(query, Membre.class)
110 | .build();
111 | adapter = new MembreAdapter(options);
112 | adapter.startListening();
113 | RecyclerView recyclerView = findViewById(R.id.recycler_view);
114 | recyclerView.setHasFixedSize(true);
115 | recyclerView.setLayoutManager(new LinearLayoutManager(this));
116 | recyclerView.setAdapter(adapter);
117 | }
118 | public void BacktoDashboard(View v) {
119 | Intent intent = new Intent(this, CoachDashboardActivity.class);
120 | finish();
121 | startActivity(intent);
122 | }
123 | // si le coach clique sur le titre créer une équipe
124 | public void CreateTeam(View v){
125 | Intent intent = new Intent(this, CreateTeam.class);
126 | intent.putExtra(USER_DATA, email);
127 | finish();
128 | startActivity(intent);
129 | }
130 | // copier ID de l'équipe en cliquant sur l'ID affiché en gras
131 | public void copyID(View v){
132 | showID=findViewById(R.id.ShowID);
133 | ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
134 | ClipData clip = ClipData.newPlainText("ID de l'équipe", showID.getText());
135 | clipboard.setPrimaryClip(clip);
136 | Toast.makeText(this, "Votre ID est copié dans le presse-papier", Toast.LENGTH_SHORT).show();
137 |
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/CalendarActivity.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import androidx.annotation.NonNull;
4 | import androidx.appcompat.app.AppCompatActivity;
5 |
6 | import android.annotation.SuppressLint;
7 | import android.content.Intent;
8 | import android.os.Bundle;
9 | import android.util.Log;
10 | import android.view.View;
11 | import android.widget.TextView;
12 |
13 | import com.applandeo.materialcalendarview.CalendarView;
14 | import com.applandeo.materialcalendarview.EventDay;
15 | import com.applandeo.materialcalendarview.listeners.OnDayClickListener;
16 | import com.google.android.gms.tasks.OnCompleteListener;
17 | import com.google.android.gms.tasks.Task;
18 | import com.google.firebase.firestore.CollectionReference;
19 | import com.google.firebase.firestore.DocumentSnapshot;
20 | import com.google.firebase.firestore.FirebaseFirestore;
21 | import com.google.firebase.firestore.QuerySnapshot;
22 |
23 | import java.util.ArrayList;
24 | import java.util.Calendar;
25 | import java.util.List;
26 |
27 | public class CalendarActivity extends AppCompatActivity {
28 | //Menu Calendrier (Membre)
29 | String TeamID;
30 | FirebaseFirestore db = FirebaseFirestore.getInstance();
31 | CalendarView calendarView;
32 | List TrainingDates = new ArrayList<>();
33 | int b=0;
34 |
35 |
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState) {
38 | Intent intent = getIntent();
39 | TeamID= intent.getStringExtra(DashboardActivity.USER_TEAM);
40 | super.onCreate(savedInstanceState);
41 | setContentView(R.layout.activity_calendar);
42 | setEvent(TeamID);
43 | calendarView = findViewById(R.id.calendarView);
44 |
45 | //chercher si la date choisie correspond à une date d'entrainement
46 | calendarView.setOnDayClickListener(eventDay -> {
47 | Calendar clickedDayCalendar = eventDay.getCalendar();
48 | String day= String.format("%02d", clickedDayCalendar.get(Calendar.DAY_OF_MONTH));
49 | String month=String.format("%02d",clickedDayCalendar.get(Calendar.MONTH)+1);
50 | String year=String.valueOf(clickedDayCalendar.get(Calendar.YEAR));
51 | String selectedDate =day+"-"+month+"-"+year;
52 | if (TrainingDates.contains(selectedDate)){
53 | String title ="Entraînement(s) pour : " +selectedDate;
54 | final String[] message = {""};
55 | CollectionReference entr = db.collection("Entrainement");
56 | // on cherche dans la collection Entrainement les entrainements de la même équipe et durant la date séléctionnée
57 | entr.whereEqualTo("Date", selectedDate).whereEqualTo("TeamID", TeamID)
58 | .get()
59 | .addOnCompleteListener(task -> {
60 | if (task.isSuccessful()) {
61 | for (DocumentSnapshot document : task.getResult()) {
62 | // si il existe des entrainements, on crée ce message d'info et l'afficher dans training_info.xml
63 | Log.d("TAG", document.getId() + " => " + document.getData());
64 | message[0] = message[0] + "Entraînement: " + document.get("TrainingName") + "\n"
65 | + "Description: " +document.get("Description")+ "\n"
66 | + "Date: " + selectedDate + "\n"
67 | + "Heure: " + document.get("HeureDep") + " --> " + document.get("HeureArr") + "\n"
68 | + "Lieu: " + document.get("LieuDep") + " --> " + document.get("LieuArr") + "\n"+ "\n"+ "\n";
69 | }
70 | setContentView(R.layout.training_info);
71 | b=1;
72 | TextView tit=findViewById(R.id.info_title);
73 | TextView msg=findViewById(R.id.info_message);
74 | tit.setText(title);
75 | msg.setText(message[0]);
76 | } else {
77 | Log.d("TAG", "Error getting documents: ", task.getException());
78 | }
79 | });
80 | }
81 | });
82 | }
83 | public void setEvent(String id){
84 | //ajouter une icon sous la date de chaque entrainement dans le calendrier
85 | List events = new ArrayList<>();
86 | calendarView = findViewById(R.id.calendarView);
87 | CollectionReference entrainement = db.collection("Entrainement");
88 | entrainement.whereEqualTo("TeamID", id)
89 | .get()
90 | .addOnCompleteListener(task -> {
91 | if (task.isSuccessful()) {
92 | for (DocumentSnapshot document : task.getResult()) {
93 | Log.d("TAG", document.getId() + " => " + document.getData());
94 | String DateStr =document.get("Date").toString();
95 | TrainingDates.add(DateStr);
96 | String[] arrOfStr = DateStr.split("-");
97 | Calendar calendar = Calendar.getInstance();
98 | calendar.set(Integer.parseInt(arrOfStr[2]), Integer.parseInt(arrOfStr[1])-1, Integer.parseInt(arrOfStr[0]));
99 | events.add(new EventDay(calendar, R.drawable.emp));
100 |
101 | }
102 | calendarView.setEvents(events);
103 | } else {
104 | Log.d("TAG", "Error getting documents: ", task.getException());
105 | }
106 | });
107 | }
108 |
109 | public void BacktoDashboard(View v) {
110 | Intent intent = new Intent(this, DashboardActivity.class);
111 | finish();
112 | startActivity(intent);
113 | }
114 |
115 | @Override
116 | public void onBackPressed() {
117 | //si nous somme dans training_info.xml on revient au calendrier, sinon on revient au dashboard
118 | if (b == 1 ) {
119 | b = 0;
120 | finish();
121 | startActivity(getIntent());
122 | } else {
123 | super.onBackPressed();
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_coach_reports.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
18 |
23 |
28 |
39 |
45 |
46 |
50 |
51 |
52 |
61 |
69 |
70 |
71 |
74 |
87 |
96 |
97 |
102 |
106 |
107 |
114 |
120 |
127 |
134 |
135 |
140 |
147 |
154 |
155 |
156 |
160 |
161 |
162 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/CoachMessagesActivity.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.view.KeyEvent;
6 | import android.view.View;
7 | import android.widget.AbsListView;
8 | import android.widget.AdapterView;
9 | import android.widget.ArrayAdapter;
10 | import android.widget.EditText;
11 | import android.widget.ImageButton;
12 | import android.widget.ListView;
13 | import android.widget.Spinner;
14 | import android.widget.TextView;
15 |
16 | import androidx.annotation.NonNull;
17 | import androidx.appcompat.app.AppCompatActivity;
18 |
19 | import com.google.android.gms.tasks.OnCompleteListener;
20 | import com.google.android.gms.tasks.Task;
21 | import com.google.firebase.database.DatabaseReference;
22 | import com.google.firebase.database.FirebaseDatabase;
23 | import com.google.firebase.firestore.CollectionReference;
24 | import com.google.firebase.firestore.FirebaseFirestore;
25 | import com.google.firebase.firestore.QueryDocumentSnapshot;
26 | import com.google.firebase.firestore.QuerySnapshot;
27 |
28 | import java.text.SimpleDateFormat;
29 | import java.util.ArrayList;
30 | import java.util.Date;
31 | import java.util.List;
32 | import java.util.Locale;
33 |
34 | import static com.choubapp.running.CoachDashboardActivity.USER_DATA;
35 |
36 | public class CoachMessagesActivity extends AppCompatActivity {
37 | private String coachname;
38 | private ListView mChatListView;
39 | private EditText mInputText;
40 | private ImageButton mSendButton;
41 | String email;
42 | String teamidselected;
43 |
44 | private DatabaseReference mDatabaseReference;
45 | FirebaseFirestore db = FirebaseFirestore.getInstance();
46 | CollectionReference Teams = db.collection("Equipe");
47 | CollectionReference Coach = db.collection("coach");
48 |
49 | TextView date;
50 |
51 | private ChatListAdapter mAdapter;
52 | @Override
53 | protected void onCreate(Bundle savedInstanceState) {
54 | Intent intent = getIntent();
55 | email= intent.getStringExtra(USER_DATA);
56 | super.onCreate(savedInstanceState);
57 | setContentView(R.layout.activity_coach_messages);
58 |
59 | setupDisplayName();
60 | mDatabaseReference = FirebaseDatabase.getInstance().getReference();
61 |
62 | mInputText = findViewById(R.id.messageInput);
63 | mSendButton = findViewById(R.id.sendButton);
64 | mChatListView = findViewById(R.id.chat_list_view);
65 |
66 | date = findViewById(R.id.date);
67 | // envoyer message si la touche "enter" du clavier est cliquée
68 | mInputText.setOnEditorActionListener((v, actionId, event) -> {
69 | sendMessage();
70 | return false;
71 | });
72 |
73 | // envoyer un message si le boutton d'envoi est cliqué
74 | mSendButton.setOnClickListener(v -> sendMessage());
75 | LoadSpinnerData();
76 | }
77 |
78 | public void LoadSpinnerData(){
79 | // spinner des équipes
80 | Spinner spinner = findViewById(R.id.spinnerMessagesCoach);
81 | List TeamsList = new ArrayList<>();
82 | List TeamsIds = new ArrayList<>();
83 | ArrayAdapter adapter = new ArrayAdapter(getApplicationContext(), android.R.layout.simple_spinner_item, TeamsList);
84 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
85 | spinner.setAdapter(adapter);
86 | Teams.get().addOnCompleteListener(task -> {
87 | if (task.isSuccessful()) {
88 | for (QueryDocumentSnapshot document : task.getResult()) {
89 | String teamname = document.getString("Nom Equipe");
90 | String coachmail = document.getString("Email Coach");
91 | String teamid = document.getString("ID");
92 | if (teamname!=null && coachmail.equals(email) ){
93 | TeamsList.add(teamname);
94 | TeamsIds.add(teamid);
95 | }
96 | }
97 | adapter.notifyDataSetChanged();
98 | }
99 | });
100 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
101 | @Override
102 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
103 | int select = parent.getSelectedItemPosition();
104 | teamidselected = TeamsIds.get(select);
105 | date.setText("");
106 | onStop();
107 | onStart();
108 | }
109 | @Override
110 | public void onNothingSelected(AdapterView> parent) {
111 | }
112 | });
113 | }
114 | // Récupérer le nom du coach (l'emmetteur du message)
115 | private void setupDisplayName(){
116 | Coach.get().addOnCompleteListener(task -> {
117 | if (task.isSuccessful()) {
118 | for (QueryDocumentSnapshot document : task.getResult()) {
119 | if(document.getString("Email").equals(email)) coachname = document.getString("FullName") ;
120 | }
121 | }
122 | });
123 |
124 | }
125 |
126 | private void sendMessage() {
127 | //envoyer le message à Firebase
128 | String input = mInputText.getText().toString();
129 | if(!input.equals("")){
130 | InstantMessage chat = new InstantMessage(input, coachname, teamidselected, new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date()), new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date()));
131 | mDatabaseReference.child("messages").push().setValue(chat);
132 | mInputText.setText("");
133 | }
134 | }
135 |
136 | // Setup adapter au début.
137 | public void onStart(){
138 | super.onStart();
139 | mAdapter = new ChatListAdapter(this , mDatabaseReference,teamidselected);
140 | mChatListView.setAdapter(mAdapter);
141 | ChangeDate();
142 | }
143 |
144 | public void ChangeDate() {
145 | mChatListView.setOnScrollListener(new AbsListView.OnScrollListener() {
146 | @Override
147 | public void onScrollStateChanged(AbsListView view, int scrollState) {
148 | }
149 |
150 | @Override
151 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
152 | if (totalItemCount != 0) {
153 |
154 | if (mAdapter.getDateselected(firstVisibleItem + visibleItemCount - 1).equals(new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date()))) {
155 | date.setText("Today");
156 | } else {
157 | //changer le text de la Date
158 | date.setText(mAdapter.getDateselected(firstVisibleItem + visibleItemCount - 1));
159 | }
160 | }
161 |
162 | }
163 | });
164 |
165 | }
166 |
167 | @Override
168 | public void onStop() {
169 | super.onStop();
170 | //supprimer Firebase event listener de l'adapter.
171 | mAdapter.cleaunup();
172 |
173 | }
174 |
175 | public void BacktoDashboard(View v) {
176 | Intent intent = new Intent(this, CoachDashboardActivity.class);
177 | finish();
178 | startActivity(intent);
179 | }
180 | }
--------------------------------------------------------------------------------
/.idea/assetWizardSettings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
149 |
150 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/CreateTraining.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import androidx.annotation.NonNull;
4 | import androidx.appcompat.app.AlertDialog;
5 | import androidx.appcompat.app.AppCompatActivity;
6 |
7 | import android.app.DatePickerDialog;
8 | import android.app.TimePickerDialog;
9 | import android.content.DialogInterface;
10 | import android.content.Intent;
11 | import android.os.Bundle;
12 | import android.util.Log;
13 | import android.view.View;
14 | import android.widget.AdapterView;
15 | import android.widget.ArrayAdapter;
16 | import android.widget.DatePicker;
17 | import android.widget.Spinner;
18 | import android.widget.TextView;
19 | import android.widget.TimePicker;
20 |
21 | import com.google.android.gms.tasks.OnCompleteListener;
22 | import com.google.android.gms.tasks.OnFailureListener;
23 | import com.google.android.gms.tasks.OnSuccessListener;
24 | import com.google.android.gms.tasks.Task;
25 | import com.google.android.material.textfield.TextInputEditText;
26 | import com.google.firebase.firestore.CollectionReference;
27 | import com.google.firebase.firestore.DocumentReference;
28 | import com.google.firebase.firestore.FirebaseFirestore;
29 | import com.google.firebase.firestore.QueryDocumentSnapshot;
30 | import com.google.firebase.firestore.QuerySnapshot;
31 |
32 | import java.text.ParseException;
33 | import java.util.ArrayList;
34 | import java.util.Calendar;
35 | import java.util.Date;
36 | import java.util.HashMap;
37 | import java.util.List;
38 | import java.util.Map;
39 |
40 | import static com.choubapp.running.CoachDashboardActivity.USER_DATA;
41 |
42 | public class CreateTraining extends AppCompatActivity {
43 | private TextView LieuDep,LieuArr,TrainingName, Description;
44 | private TextInputEditText eDate,eTimeDep, eTimeArr;
45 | String team,teamID;
46 | FirebaseFirestore db = FirebaseFirestore.getInstance();
47 | CollectionReference Teams = db.collection("Equipe");
48 | String email;
49 | List TeamsList = new ArrayList<>();
50 | List TeamIDsList = new ArrayList<>();
51 |
52 | @Override
53 | protected void onCreate(Bundle savedInstanceState) {
54 | Intent intent = getIntent();
55 | email= intent.getStringExtra(USER_DATA);
56 | super.onCreate(savedInstanceState);
57 | setContentView(R.layout.activity_create_training);
58 | LoadSpinnerTeams();
59 | }
60 | public void LoadSpinnerTeams(){
61 | // charger les noms des équipe dans le spinner
62 | Spinner spinner = findViewById(R.id.pickteam);
63 | ArrayAdapter adapter = new ArrayAdapter(getApplicationContext(), android.R.layout.simple_spinner_item, TeamsList);
64 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
65 | spinner.setAdapter(adapter);
66 | Teams.get().addOnCompleteListener(task -> {
67 | if (task.isSuccessful()) {
68 | for (QueryDocumentSnapshot document : task.getResult()) {
69 | String teamname = document.getString("Nom Equipe");
70 | String team_id = document.getString("ID");
71 | String coachmail = document.getString("Email Coach");
72 | if (teamname!=null && coachmail.equals(email) ){
73 | TeamIDsList.add(team_id);
74 | TeamsList.add(teamname);
75 | }
76 | }
77 | adapter.notifyDataSetChanged();
78 | }
79 | });
80 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
81 | @Override
82 | public void onItemSelected(AdapterView> parent, View view, int position, long id) {
83 | team= parent.getSelectedItem().toString();
84 | teamID= TeamIDsList.get(TeamsList.indexOf(team));
85 | }
86 | @Override
87 | public void onNothingSelected(AdapterView> parent) {
88 | }
89 | });
90 | }
91 | // fenetre pour choisir la date de l'entrainement
92 | public void DatePicker(View v) throws ParseException {
93 | final DatePickerDialog[] picker = new DatePickerDialog[1];
94 | eDate= findViewById(R.id.trainingdate);
95 | final Calendar cldr = Calendar.getInstance();
96 | int day = cldr.get(Calendar.DAY_OF_MONTH);
97 | int month = cldr.get(Calendar.MONTH);
98 | int year = cldr.get(Calendar.YEAR);
99 | picker[0] = new DatePickerDialog(this, (view, year1, monthOfYear, dayOfMonth) -> eDate.setText(String.format("%02d", dayOfMonth) + "-" + String.format("%02d", (monthOfYear + 1)) + "-" + year1), year, month, day);
100 | picker[0].getDatePicker().setMinDate(new Date().getTime());
101 | picker[0].show();
102 | }
103 | // fenetre pour choisir heure de depart
104 | public void TimePickerDep(View v){
105 | eTimeDep= findViewById(R.id.heuredep);
106 | Calendar mcurrentTime = Calendar.getInstance();
107 | int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
108 | int minute = mcurrentTime.get(Calendar.MINUTE);
109 | TimePickerDialog mTimePicker;
110 | mTimePicker = new TimePickerDialog(this, (timePicker, selectedHour, selectedMinute) -> eTimeDep.setText(String.format("%02d", selectedHour )+ ":" + String.format("%02d", selectedMinute)), hour, minute, true);//Yes 24 hour time
111 | mTimePicker.setTitle("Select Time");
112 | mTimePicker.show();
113 | }
114 | // fenetre pour choisir heure d'arrivée
115 | public void TimePickerArr(View v){
116 | eTimeArr= findViewById(R.id.heurearr);
117 | Calendar mcurrentTime = Calendar.getInstance();
118 | int hour = mcurrentTime.get(Calendar.HOUR_OF_DAY);
119 | int minute = mcurrentTime.get(Calendar.MINUTE);
120 | TimePickerDialog mTimePicker;
121 | mTimePicker = new TimePickerDialog(this, (timePicker, selectedHour, selectedMinute) -> eTimeArr.setText( String.format("%02d", selectedHour )+ ":" + String.format("%02d", selectedMinute)), hour, minute, true);//Yes 24 hour time
122 | mTimePicker.setTitle("Select Time");
123 | mTimePicker.show();
124 | }
125 | // enregistrer l'entrainement
126 | public void SaveTraining(View v){
127 | LieuDep =findViewById(R.id.depart);
128 | LieuArr=findViewById(R.id.arrive);
129 | TrainingName=findViewById(R.id.trainingname);
130 | Description=findViewById(R.id.trainingdesc);
131 | Map training = new HashMap<>();
132 | training.put("TrainingName", TrainingName.getText().toString());
133 | training.put("Description", Description.getText().toString());
134 | training.put("Team", team);
135 | training.put("TeamID", teamID);
136 | training.put("Email Coach", email);
137 | training.put("Date", eDate.getText().toString());
138 | training.put("HeureDep", eTimeDep.getText().toString());
139 | training.put("HeureArr", eTimeArr.getText().toString());
140 | training.put("LieuDep", LieuDep.getText().toString());
141 | training.put("LieuArr", LieuArr.getText().toString());
142 | db.collection("Entrainement")
143 | .add(training)
144 | .addOnSuccessListener(documentReference -> {
145 | Log.d("TAG", "DocumentSnapshot added with ID: " + documentReference.getId());
146 | new AlertDialog.Builder(CreateTraining.this)
147 | .setTitle("Succes !")
148 | .setMessage("Votre entraînement a été créé")
149 | .setPositiveButton("Ok", (dialog, which) -> onBackPressed())
150 | .show();
151 | })
152 | .addOnFailureListener(e -> Log.w("TAG", "Error adding document", e));
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_create_training.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
27 |
35 |
36 |
44 |
52 |
53 |
54 |
62 |
69 |
70 |
78 |
84 |
85 |
93 |
99 |
100 |
108 |
116 |
117 |
125 |
133 |
134 |
140 |
145 |
149 |
150 |
164 |
165 |
--------------------------------------------------------------------------------
/app/src/main/java/com/choubapp/running/LocationService.java:
--------------------------------------------------------------------------------
1 | package com.choubapp.running;
2 |
3 | import android.Manifest;
4 | import android.app.Notification;
5 | import android.app.NotificationChannel;
6 | import android.app.NotificationManager;
7 | import android.app.Service;
8 | import android.content.Context;
9 | import android.content.Intent;
10 | import android.content.pm.PackageManager;
11 | import android.location.Location;
12 |
13 | import android.os.Build;
14 | import android.os.IBinder;
15 | import android.os.Looper;
16 | import android.util.Log;
17 |
18 | import com.google.android.gms.location.FusedLocationProviderClient;
19 | import com.google.android.gms.location.LocationCallback;
20 | import com.google.android.gms.location.LocationRequest;
21 | import com.google.android.gms.location.LocationResult;
22 | import com.google.android.gms.location.LocationServices;
23 | import com.google.android.gms.tasks.OnCompleteListener;
24 | import com.google.android.gms.tasks.Task;
25 | import com.google.firebase.auth.FirebaseAuth;
26 | import com.google.firebase.firestore.DocumentReference;
27 | import com.google.firebase.firestore.DocumentSnapshot;
28 | import com.google.firebase.firestore.FirebaseFirestore;
29 | import com.google.firebase.firestore.GeoPoint;
30 |
31 | import androidx.annotation.NonNull;
32 | import androidx.annotation.Nullable;
33 | import androidx.core.app.ActivityCompat;
34 | import androidx.core.app.NotificationCompat;
35 |
36 | public class LocationService extends Service {
37 | private String trainingID;
38 | FirebaseFirestore db = FirebaseFirestore.getInstance();
39 | DocumentReference trackingTraining ;
40 | DocumentReference userInfoDoc;
41 | private GeoPoint previous=null;
42 | private static final String TAG = "LocationService";
43 | private FusedLocationProviderClient mFusedLocationClient;
44 | private final static long UPDATE_INTERVAL = 10 * 1000; /* 10 secs */
45 | private final static long FASTEST_INTERVAL = 5000; /* 5 sec */
46 |
47 | @Nullable
48 | @Override
49 | public IBinder onBind(Intent intent) {
50 | return null;
51 | }
52 |
53 | @Override
54 | public void onCreate() {
55 | super.onCreate();
56 |
57 | mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
58 |
59 | if (Build.VERSION.SDK_INT >= 26) {
60 | String CHANNEL_ID = "my_channel_01";
61 | NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
62 | "My Channel",
63 | NotificationManager.IMPORTANCE_DEFAULT);
64 |
65 | ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
66 |
67 | Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
68 | .setContentTitle("")
69 | .setContentText("").build();
70 |
71 | startForeground(1, notification);
72 | }
73 | }
74 |
75 | @Override
76 | public int onStartCommand(Intent intent, int flags, int startId) {
77 | trainingID = intent.getStringExtra("trainingID");
78 | System.out.println("from service "+trainingID);
79 | trackingTraining =db.collection("tracking").document(trainingID);
80 | userInfoDoc =trackingTraining.collection("Participants").document(FirebaseAuth.getInstance().getCurrentUser().getEmail());
81 | Log.d(TAG, "onStartCommand: called.");
82 | getLocation();
83 | return START_NOT_STICKY;
84 | }
85 |
86 | private void getLocation() {
87 |
88 | // ---------------------------------- LocationRequest ------------------------------------
89 | // Create the location request to start receiving updates
90 | LocationRequest mLocationRequestHighAccuracy = new LocationRequest();
91 | mLocationRequestHighAccuracy.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
92 | mLocationRequestHighAccuracy.setInterval(UPDATE_INTERVAL);
93 | mLocationRequestHighAccuracy.setFastestInterval(FASTEST_INTERVAL);
94 |
95 |
96 | // new Google API SDK v11 uses getFusedLocationProviderClient(this)
97 | if (ActivityCompat.checkSelfPermission(this,
98 | Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
99 | Log.d(TAG, "getLocation: stopping the location service.");
100 | stopSelf();
101 | return;
102 | }
103 | Log.d(TAG, "getLocation: getting location information.");
104 | mFusedLocationClient.requestLocationUpdates(mLocationRequestHighAccuracy, new LocationCallback() {
105 | @Override
106 | public void onLocationResult(LocationResult locationResult) {
107 | Log.d(TAG, "onLocationResult: got location result.");
108 | Location location = locationResult.getLastLocation();
109 | if (location != null) {
110 | GeoPoint geoPoint = new GeoPoint(location.getLatitude(), location.getLongitude());
111 | userInfoDoc.get().addOnCompleteListener(task -> {
112 | Boolean av = (Boolean) task.getResult().get("Availability");
113 | saveUserLocation(geoPoint , av);
114 | });
115 | saveDistance(geoPoint);
116 |
117 | }
118 | }
119 | },
120 | Looper.myLooper()); // Looper.myLooper tells this to repeat forever until thread is destroyed
121 | }
122 |
123 | private void saveUserLocation(final GeoPoint geo , Boolean av){
124 | // enregistrer la localisation du membre lorsqu'il est encore participant dans l'entrainement
125 | try{
126 | if (av) {
127 | userInfoDoc.update("Location", geo).addOnCompleteListener(task -> {
128 | if (task.isSuccessful()) {
129 | Log.d(TAG, "onComplete: \ninserted user location into database." +
130 | "\n latitude: " + geo.getLatitude() +
131 | "\n longitude: " + geo.getLongitude());
132 | }
133 | });
134 | } else stopSelf();
135 | }catch (NullPointerException e){
136 | Log.e(TAG, "saveUserLocation: User instance is null, stopping location service.");
137 | Log.e(TAG, "saveUserLocation: NullPointerException: " + e.getMessage() );
138 | stopSelf();
139 | }
140 | }
141 | private void saveDistance(GeoPoint geo){
142 | if (previous!=null) {
143 | long distance = calculateDistance(previous, geo);
144 | if (distance != 0) {
145 | System.out.println("distance in meters :" + distance);
146 | userInfoDoc.get().addOnCompleteListener(task -> {
147 | if (task.isSuccessful()) {
148 | DocumentSnapshot document = task.getResult();
149 | if (document.exists()) {
150 | if (document.get("Distance") != null) {
151 | long previousDistance = (long) document.get("Distance");
152 | // mise a jour du distance
153 | userInfoDoc.update("Distance", distance + previousDistance);
154 | } else {
155 | // enregistrer la distance
156 | userInfoDoc.update("Distance", distance);
157 | Log.d(TAG, "previous distance does not exist");
158 | }
159 | }
160 | }
161 | });
162 | }
163 | }
164 | previous = geo;
165 | }
166 | private long calculateDistance(GeoPoint prv , GeoPoint nxt) {
167 | // callculer distance entre deux points geographiques
168 | double lat1 = prv.getLatitude();
169 | double lng1 = prv.getLatitude();
170 | double lat2 = nxt.getLatitude();
171 | double lng2 = nxt.getLatitude();
172 |
173 | double dLat = Math.toRadians(lat2 - lat1);
174 | double dLon = Math.toRadians(lng2 - lng1);
175 | double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
176 | + Math.cos(Math.toRadians(lat1))
177 | * Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
178 | * Math.sin(dLon / 2);
179 | double c = 2 * Math.asin(Math.sqrt(a));
180 | return Math.round(6371000 * c);
181 | }
182 |
183 |
184 |
185 | }
--------------------------------------------------------------------------------