diff --git a/.idea/compiler.xml b/.idea/compiler.xml index fb7f4a8..b589d56 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index b1f8730..0ad17cb 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + diff --git a/README.md b/README.md index 31d3e64..1a6eb5b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ For both types of tests, start by going into *Run* > *Edit Configurations* For unit tests, create a new JUnit4 test. For the module select `MrFit.app.unitTest`, and then select the class of the unit test you want to run. -To run behavioral tests, create a new Android Instrumented Test pointed at `MrFit.app.androidTest`, then run this new configuration. +To run behavioral tests, ![](../../AppData/Local/Temp/profilepicturev2.jpg)create a new Android Instrumented Test pointed at `MrFit.app.androidTest`, then run this new configuration. # Authors diff --git a/app/build.gradle b/app/build.gradle index 2854a2e..de91e1d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -40,39 +40,52 @@ android { } } + dependencies { - implementation 'androidx.core:core-ktx:1.9.0' + implementation 'androidx.core:core-ktx:1.10.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.8.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - implementation 'com.google.firebase:firebase-database-ktx:20.1.0' - implementation 'com.google.firebase:firebase-database:20.1.0' + implementation 'com.google.firebase:firebase-database-ktx:20.2.0' + implementation 'com.google.firebase:firebase-database:20.2.0' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4" - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.0" - implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.0" + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.1' implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3' implementation 'androidx.navigation:navigation-ui-ktx:2.5.3' // Testing dependencies + implementation 'androidx.arch.core:core-testing:2.2.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.junit.jupiter:junit-jupiter' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + androidTestImplementation('androidx.test.espresso:espresso-contrib:3.5.1') { + exclude group: 'com.android.support', module: 'appcompat' + exclude group: 'com.android.support', module: 'support-v4' + exclude module: 'recyclerview-v7' + exclude module: "protobuf-lite" + } + androidTestImplementation "org.hamcrest:hamcrest:2.2" androidTestImplementation 'androidx.test:runner:1.5.2' androidTestImplementation 'androidx.test:rules:1.5.0' androidTestImplementation 'androidx.test:core:1.5.0' androidTestImplementation 'androidx.test:core-ktx:1.5.0' androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.5' + // https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy + implementation 'net.bytebuddy:byte-buddy-android:1.14.4' + // Optional -- Mockito framework - testImplementation 'org.mockito:mockito-core:5.0.0' + testImplementation 'org.mockito:mockito-core:5.3.1' + androidTestImplementation 'org.mockito:mockito-android:5.3.1' testImplementation 'org.mockito.kotlin:mockito-kotlin:4.1.0' - testImplementation 'io.mockk:mockk:1.13.4' + testImplementation 'io.mockk:mockk:1.13.5' // Import the BoM for the Firebase platform - implementation platform('com.google.firebase:firebase-bom:31.1.0') + implementation platform('com.google.firebase:firebase-bom:31.5.0') // Add the dependency for the Firebase library // When using the BoM, you don't specify versions in Firebase library dependencies @@ -95,11 +108,11 @@ dependencies { implementation 'com.firebaseui:firebase-ui-storage:8.0.2' // Also add the dependency for the Google Play services library and specify its version - implementation 'com.google.android.gms:play-services-auth:20.4.1' + implementation 'com.google.android.gms:play-services-auth:20.5.0' // Add the dependency for Glide - implementation 'com.github.bumptech.glide:glide:4.15.0' - kapt 'com.github.bumptech.glide:compiler:4.15.0' + implementation 'com.github.bumptech.glide:glide:4.15.1' + kapt 'com.github.bumptech.glide:compiler:4.15.1' // Konfetti by https://github.com/DanielMartinus/Konfetti implementation 'nl.dionsegijn:konfetti-xml:2.0.2' diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/CalendarActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/CalendarActivityTest.kt new file mode 100644 index 0000000..5b87b9d --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/CalendarActivityTest.kt @@ -0,0 +1,18 @@ +package com.symphony.mrfit.ui + +import org.junit.Assert.* + +import org.junit.Test + +class CalendarActivityTest { + //behavioral + @Test + fun onCreate() { + } + @Test + fun onStart() { + } + @Test + fun onSupportNavigateUp() { + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/CoreFunctionalityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/CoreFunctionalityTest.kt new file mode 100644 index 0000000..6aa60e6 --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/CoreFunctionalityTest.kt @@ -0,0 +1,150 @@ +/* + * Created by Team Symphony on 4/22/23, 6:21 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/22/23, 6:05 AM + */ + +package com.symphony.mrfit.ui + +import androidx.recyclerview.widget.RecyclerView +import androidx.test.espresso.Espresso +import androidx.test.espresso.action.ViewActions.* +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition +import androidx.test.espresso.matcher.ViewMatchers.* +import androidx.test.ext.junit.rules.activityScenarioRule +import androidx.test.filters.LargeTest +import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner +import com.symphony.mrfit.R +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4ClassRunner::class) +@LargeTest +class CoreFunctionalityTest { + + @get:Rule + var activityScenarioRule = activityScenarioRule() + + /** + * Test a run through of the app's core functionality. It should: + * Log in with the credentials 'demo@email.com' and 'pass123' + * Start a new workout + * Make a new workout called "Automated Testing" + * Add 3 exercises to it, whichever 3 are at the top of the list + * Start the workout, wait 5 seconds, then finish the workout + * Return to the home screen after + * Navigate to and delete this new workout + * Navigate to the user's profile and log out + */ + @Test + fun coreFunctionality() { + // Wait to automatically move past welcome screen + Thread.sleep(100) + Espresso.onView(withId(R.id.layout_loginActivity)) + .check(matches(isDisplayed())) + + // Attempt to log in + Espresso.onView(withId(R.id.loginEmail)) + .perform(typeText(TEST_EMAIL), closeSoftKeyboard()) + Thread.sleep(500) + Espresso.onView(withId(R.id.loginPassword)) + .perform(typeText(TEST_PASS), closeSoftKeyboard()) + Thread.sleep(500) + Espresso.onView(withId(R.id.loginButton)) + .perform(click()) + Thread.sleep(1000) + Espresso.onView(withId(R.id.layout_homeActivity)) + .check(matches(isDisplayed())) + + // Navigate to the Template selection screen + Espresso.onView(withId(R.id.workoutButton)) + .perform(click()) + Thread.sleep(1000) + Espresso.onView(withId(R.id.layout_selectionActivity)) + .check(matches(isDisplayed())) + + // Make a new workout and name it + Espresso.onView(withId(R.id.newWorkoutButton)) + .perform(click()) + Thread.sleep(500) + Espresso.onView(withId(R.id.routineNameEditText)) + .perform(clearText()) + .perform(typeText(TEST_TEMPLATE), closeSoftKeyboard()) + + // Add 3 exercises + // 1st Exercise + Thread.sleep(1000) + Espresso.onView(withId(R.id.newExerciseButton)) + .perform(click()) + Thread.sleep(500) + Espresso.onView(withId(R.id.exerciseListView)) + .perform(actionOnItemAtPosition(0, click())) + Thread.sleep(500) + Espresso.onView(withId(R.id.saveTemplateButton)) + .perform(click()) + Thread.sleep(1000) + // 2nd Exercise + Espresso.onView(withId(R.id.newExerciseButton)) + .perform(click()) + Thread.sleep(500) + Espresso.onView(withId(R.id.exerciseListView)) + .perform(actionOnItemAtPosition(1, click())) + Thread.sleep(500) + Espresso.onView(withId(R.id.saveTemplateButton)) + .perform(click()) + Thread.sleep(1000) + // 3rd Exercise + Espresso.onView(withId(R.id.newExerciseButton)) + .perform(click()) + Thread.sleep(500) + Espresso.onView(withId(R.id.exerciseListView)) + .perform(actionOnItemAtPosition(2, click())) + Thread.sleep(500) + Espresso.onView(withId(R.id.saveTemplateButton)) + .perform(click()) + Thread.sleep(1000) + + // Start the workout and finish it after 10 seconds + Espresso.onView(withId(R.id.startWorkoutButton)) + .perform(click()) + Espresso.onView(withId(R.id.layout_currentActivity)) + .check(matches(isDisplayed())) + Thread.sleep(10000) + Espresso.onView(withId(R.id.finishWorkoutButton)) + .perform(click()) + Espresso.onView(withText("Good job!")).check(matches(isDisplayed())) + Espresso.onView(withText("Return Home")).perform(click()) + + // Navigate back and delete workout + Thread.sleep(1000) + Espresso.onView(withId(R.id.workoutButton)) + .perform(click()) + Thread.sleep(1000) + Espresso.onView(withId(R.id.layout_selectionActivity)) + .check(matches(isDisplayed())) + Espresso.onView(withText(TEST_TEMPLATE)) + .perform(click()) + Thread.sleep(1000) + Espresso.onView(withId(R.id.deleteWorkoutButton)) + .perform(click()) + Espresso.pressBack() + Thread.sleep(1000) + + // Navigate to user profile and log out + Espresso.onView(withId(R.id.userLayout)) + .perform(click()) + Thread.sleep(1000) + Espresso.onView(withId(R.id.layout_profileActivity)) + .check(matches(isDisplayed())) + Espresso.onView(withId(R.id.logoutButton)) + .perform(click()) + } + + companion object { + const val TEST_EMAIL = "demo@email.com" + const val TEST_PASS = "pass123" + const val TEST_TEMPLATE = "Automated Testing" + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/CurrentWorkoutActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/CurrentWorkoutActivityTest.kt new file mode 100644 index 0000000..7883615 --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/CurrentWorkoutActivityTest.kt @@ -0,0 +1,51 @@ +/* + * Created by Team Symphony on 4/23/23, 3:46 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/23/23, 3:46 AM + */ + +package com.symphony.mrfit.ui +import android.content.Context +import android.content.Intent +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Assert.* +import org.junit.Test +import org.junit.runner.RunWith + + +@RunWith(AndroidJUnit4::class) +class CurrentWorkoutActivityTest { + //behavioral + @Test + fun onCreate() { + + } + //behavioral + @Test + fun onStart() { + + } + @Test + fun gotoHome() { + // Start the activity + val context = ApplicationProvider.getApplicationContext() + val intent = Intent(context, HomeActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + + val expectedFlags = (Intent.FLAG_ACTIVITY_CLEAR_TOP or + Intent.FLAG_ACTIVITY_CLEAR_TASK or + Intent.FLAG_ACTIVITY_NEW_TASK) + + assertEquals(expectedFlags, intent.flags) + assertEquals(context.packageName, intent.component?.packageName) + assertEquals(HomeActivity::class.java.name, intent.component?.className) + } + //behavioral + @Test + fun onSupportNavigateUp() { + + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/CustomExercisesActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/CustomExercisesActivityTest.kt new file mode 100644 index 0000000..b4086ae --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/CustomExercisesActivityTest.kt @@ -0,0 +1,27 @@ +package com.symphony.mrfit.ui + +import androidx.test.core.app.ApplicationProvider +import com.symphony.mrfit.data.exercise.ExerciseViewModel +import com.symphony.mrfit.data.model.Exercise +import org.junit.Assert.* +import org.junit.Before + +import org.junit.Test + +class CustomExercisesActivityTest { + //behavioral + //TODO + @Test + fun onCreate() { + } + @Test + fun onStart() { + } + @Test + fun onSupportNavigateUp() { + } + @Test + fun deleteExercise(){ + } + +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/ExerciseTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/ExerciseTest.kt new file mode 100644 index 0000000..022efea --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/ExerciseTest.kt @@ -0,0 +1,61 @@ +/* + * Created by Team Symphony on 4/23/23, 3:46 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/23/23, 3:46 AM + */ + +package com.symphony.mrfit.ui + +import androidx.test.espresso.Espresso +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.rules.activityScenarioRule +import com.symphony.mrfit.R +import org.hamcrest.CoreMatchers.not +import org.junit.Rule +import org.junit.Test + +class ExerciseTest { + + + @get:Rule + var activityScenarioRule = activityScenarioRule() + + /** + * Test if the activity is displayed and visible to user + */ + @Test + fun checkActivityVisibility() { + Espresso.onView(withId(R.id.layout_exerciseSelectionActivity)) + .check(matches(isDisplayed())) + } + + /** + * Test if all the appropriate components are visible + */ + @Test + fun checkViewVisibility() { + Thread.sleep(500) + Espresso.onView(withId(R.id.exerciseScreenView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.exerciseListView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.exerciseSearchTextView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.exerciseSearchEditText)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.exerciseSearchButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.button2)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.loadingSpinner)) + .check(matches(not(isDisplayed()))) + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/GoalsActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/GoalsActivityTest.kt new file mode 100644 index 0000000..b78c811 --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/GoalsActivityTest.kt @@ -0,0 +1,41 @@ +/* + * Created by Team Symphony on 4/23/23, 3:46 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/23/23, 3:11 AM + */ + +package com.symphony.mrfit.ui + +import androidx.test.espresso.Espresso +import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.ext.junit.rules.activityScenarioRule +import com.symphony.mrfit.R +import org.junit.Rule +import org.junit.Test + +class GoalsActivityTest { + + @get:Rule + var activityScenarioRule = activityScenarioRule() + + //TODO: added simple tests, worked on mine but check if needs more + //tests if the activity is displayed and visible to user + @Test + fun checkActivityVisibility() { + Espresso.onView(ViewMatchers.withId(R.id.layout_goalsActivity)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + } + + //tests if components are visible + @Test + fun checkViewVisibility() { + Espresso.onView(ViewMatchers.withId(R.id.goalsTitleTextView)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + + Espresso.onView(ViewMatchers.withId(R.id.goalsList)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + + } +} + diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/HelperTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/HelperTest.kt new file mode 100644 index 0000000..380d7c6 --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/HelperTest.kt @@ -0,0 +1,30 @@ +/* + * Created by Team Symphony on 4/23/23, 3:02 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/22/23, 11:32 PM + */ + +package com.symphony.mrfit.ui + +import android.app.Activity +import androidx.test.espresso.matcher.ViewMatchers.assertThat +import org.hamcrest.CoreMatchers.`is` +import org.junit.Test +import java.util.* + + +class HelperTest{ + private lateinit var activity: Activity + + //test functionality of calendar method + @Test + fun toCalendarconvertsDatetoCalendar() { + val date = Date() + val cal = Helper.toCalendar(date) + assertThat(cal.get(Calendar.YEAR), `is`(Calendar.getInstance().get(Calendar.YEAR))) + assertThat(cal.get(Calendar.MONTH), `is`(Calendar.getInstance().get(Calendar.MONTH))) + assertThat(cal.get(Calendar.DAY_OF_MONTH), `is`(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)) + ) + } +} + diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/HomeActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/HomeActivityTest.kt new file mode 100644 index 0000000..27ca635 --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/HomeActivityTest.kt @@ -0,0 +1,74 @@ +/* + * Created by Team Symphony on 4/23/23, 3:46 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/23/23, 3:46 AM + */ + +package com.symphony.mrfit.ui + +import androidx.test.espresso.Espresso +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.rules.activityScenarioRule +import com.symphony.mrfit.R +import org.hamcrest.core.IsNot.not +import org.junit.Rule +import org.junit.Test + +class HomeActivityTest { + + @get:Rule + var activityScenarioRule = activityScenarioRule() + + /** + * Test if the activity is displayed and visible to user + */ + @Test + fun checkActivityVisibility() { + Espresso.onView(withId(R.id.layout_homeActivity)) + .check(matches(isDisplayed())) + } + + /** + * Test if all the appropriate components are visible + */ + @Test + fun checkViewVisibility() { + Thread.sleep(1000) + Espresso.onView(withId(R.id.homeScreenView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.userLayout)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.homeProfilePicture)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.homeWelcomeTextView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.homeNameTextView)) + .check(matches(isDisplayed())) + Espresso.onView(withId(R.id.homeScreenView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.settingsCog)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.scheduleButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.pastWorkout)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.workoutButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.historyList)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.loadingSpinner)) + .check(matches(not(isDisplayed()))) + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/LoginActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/LoginActivityTest.kt index 41094ea..696df75 100644 --- a/app/src/androidTest/java/com/symphony/mrfit/ui/LoginActivityTest.kt +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/LoginActivityTest.kt @@ -1,28 +1,23 @@ /* - * Created by Team Symphony on 2/24/23, 11:21 PM + * Created by Team Symphony on 4/23/23, 3:46 AM * Copyright (c) 2023 . All rights reserved. - * Last modified 2/24/23, 11:20 PM + * Last modified 4/23/23, 3:46 AM */ package com.symphony.mrfit.ui -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.Espresso import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.action.ViewActions.closeSoftKeyboard +import androidx.test.espresso.action.ViewActions.typeText import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.ext.junit.rules.activityScenarioRule -import androidx.test.filters.LargeTest -import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner import com.symphony.mrfit.R -import org.junit.Assert.* import org.junit.Rule import org.junit.Test -import org.junit.runner.RunWith -@RunWith(AndroidJUnit4ClassRunner::class) -@LargeTest class LoginActivityTest { @get:Rule @@ -33,7 +28,8 @@ class LoginActivityTest { */ @Test fun checkActivityVisibility() { - onView(withId(R.id.layout_loginActivity)).check(matches(isDisplayed())) + Espresso.onView(withId(R.id.layout_loginActivity)) + .check(matches(isDisplayed())) } /** @@ -41,19 +37,19 @@ class LoginActivityTest { */ @Test fun checkViewVisibility() { - onView(withId(R.id.loginEmail)) + Espresso.onView(withId(R.id.loginEmail)) .check(matches(isDisplayed())) - onView(withId(R.id.loginPassword)) + Espresso.onView(withId(R.id.loginPassword)) .check(matches(isDisplayed())) - onView(withId(R.id.loginButton)) + Espresso.onView(withId(R.id.loginButton)) .check(matches(isDisplayed())) - onView(withId(R.id.googleButton)) + Espresso.onView(withId(R.id.googleButton)) .check(matches(isDisplayed())) - onView(withId(R.id.toRegisterTextView)) + Espresso.onView(withId(R.id.toRegisterTextView)) .check(matches(isDisplayed())) } @@ -62,37 +58,36 @@ class LoginActivityTest { */ @Test fun checkFailedLogin() { - onView(withId(R.id.loginEmail)) - .perform(ViewActions.typeText(TEST_EMAIL), ViewActions.closeSoftKeyboard()) - onView(withId(R.id.loginPassword)) - .perform(ViewActions.typeText(TEST_PASS), ViewActions.closeSoftKeyboard()) - onView(withId(R.id.loginButton)) + Espresso.onView(withId(R.id.loginEmail)) + .perform(typeText(TEST_EMAIL), closeSoftKeyboard()) + Espresso.onView(withId(R.id.loginPassword)) + .perform(typeText(TEST_PASS), closeSoftKeyboard()) + Espresso.onView(withId(R.id.loginButton)) .perform(click()) - onView(withId(R.id.layout_loginActivity)).check(matches(isDisplayed())) + Espresso.onView(withId(R.id.layout_loginActivity)) + .check(matches(isDisplayed())) } /** * Test if login works */ - /* @Test fun checkValidLogin() { - onView(withId(R.id.loginEmail)) - .perform(ViewActions.typeText(REAL_EMAIL), ViewActions.closeSoftKeyboard()) - onView(withId(R.id.loginPassword)) - .perform(ViewActions.typeText(REAL_PASS), ViewActions.closeSoftKeyboard()) - onView(withId(R.id.loginButton)) + Espresso.onView(withId(R.id.loginEmail)) + .perform(typeText(REAL_EMAIL), closeSoftKeyboard()) + Espresso.onView(withId(R.id.loginPassword)) + .perform(typeText(REAL_PASS), closeSoftKeyboard()) + Espresso.onView(withId(R.id.loginButton)) .perform(click()) - onView(withId(R.id.layout_loginActivity)).check(matches(isDisplayed())) + Espresso.onView(withId(R.id.layout_loginActivity)) + .check(matches(isDisplayed())) } - */ - companion object { - const val REAL_EMAIL = "test@symphony.com" - const val REAL_PASS = "abcd1234" + const val REAL_EMAIL = "demo@symphony.com" + const val REAL_PASS = "pass123" const val TEST_EMAIL = "fake_email@symphony.com" const val TEST_PASS = "1234abcd" } diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/NotificationActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/NotificationActivityTest.kt new file mode 100644 index 0000000..f5eff35 --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/NotificationActivityTest.kt @@ -0,0 +1,45 @@ +package com.symphony.mrfit.ui + +import androidx.test.espresso.Espresso +import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.matcher.ViewMatchers +import com.symphony.mrfit.R +import org.junit.Assert.* + +import org.junit.Test +import org.mockito.Mockito; +import org.mockito.Mockito.`when` + + +class NotificationActivityTest { + + //TODO: cant figure out tests for notif activity + + /*@Test + fun getHasNotificationPermissionGranted() { + + } + + @Test + fun setHasNotificationPermissionGranted() { + + }*/ + + //tests if the activity is displayed and visible to user + /*@Test + fun checkActivityVisibility() { + Espresso.onView(ViewMatchers.withId(R.id.layout_notifActivity)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + } + + //tests if date picker and time picker are visible + @Test + fun checkViewVisibility() { + Espresso.onView(ViewMatchers.withId(R.id.datePicker)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + + Espresso.onView(ViewMatchers.withId(R.id.timePicker)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + + }*/ +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/PostWorkoutActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/PostWorkoutActivityTest.kt new file mode 100644 index 0000000..3e355c6 --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/PostWorkoutActivityTest.kt @@ -0,0 +1,41 @@ +package com.symphony.mrfit.ui + +import androidx.test.espresso.Espresso +import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.matcher.ViewMatchers +import androidx.test.ext.junit.rules.activityScenarioRule +import com.symphony.mrfit.R +import org.junit.Assert.* +import org.junit.Rule + +import org.junit.Test + +class PostWorkoutActivityTest { + + @get:Rule + var activityScenarioRule = activityScenarioRule() + + //tests if the activity is displayed and visible to user + @Test + fun checkActivityVisibility() { + Espresso.onView(ViewMatchers.withId(R.id.layout_postWorkoutActivity)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + } + + //tests if components are visible + @Test + fun checkViewVisibility() { + Espresso.onView(ViewMatchers.withId(R.id.postWorkoutTitle)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + + Espresso.onView(ViewMatchers.withId(R.id.postWorkoutTime)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + + /*Espresso.onView(ViewMatchers.withId(R.id.gotoGoalsButton)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) + + Espresso.onView(ViewMatchers.withId(R.id.returnHomeButton)) + .check(ViewAssertions.matches(ViewMatchers.isDisplayed()))*/ + + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/RegisterActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/RegisterActivityTest.kt new file mode 100644 index 0000000..7a0793b --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/RegisterActivityTest.kt @@ -0,0 +1,47 @@ +/* + * Created by Team Symphony on 4/23/23, 3:46 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/23/23, 3:46 AM + */ + +package com.symphony.mrfit.ui + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.rules.activityScenarioRule +import com.symphony.mrfit.R +import org.junit.Rule +import org.junit.Test + +class RegisterActivityTest { + + @get:Rule + var activityScenarioRule = activityScenarioRule() + + /*tests if register works*/ + @Test + fun checkValidRegister() { + onView(withId(R.id.registerEmail)) + .perform(ViewActions.typeText(REAL_EMAIL)) + onView(withId(R.id.registerPassword)) + .perform(ViewActions.typeText(LoginActivityTest.REAL_PASS), ViewActions.closeSoftKeyboard()) + onView(withId(R.id.registerButton)) + .perform(ViewActions.click()) + } + + /*tests if empty email/pass gives error*/ + @Test + fun checkInvalidRegister() { + onView(withId(R.id.registerEmail)) + .perform(ViewActions.typeText(TEST_EMAIL)) + } + + companion object { + + const val REAL_EMAIL = "testregister@symphony.com" + const val REAL_PASS = "abcd1234" + const val TEST_EMAIL = "" + const val TEST_PASS = "" + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/TemplateSelectionActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/TemplateSelectionActivityTest.kt new file mode 100644 index 0000000..c0d3a6b --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/TemplateSelectionActivityTest.kt @@ -0,0 +1,52 @@ +/* + * Created by Team Symphony on 4/23/23, 3:46 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/23/23, 3:46 AM + */ + +package com.symphony.mrfit.ui + +import androidx.test.espresso.Espresso +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.rules.activityScenarioRule +import com.symphony.mrfit.R +import org.hamcrest.CoreMatchers.not +import org.junit.Rule +import org.junit.Test + +class TemplateSelectionActivityTest { + + + @get:Rule + var activityScenarioRule = activityScenarioRule() + + /** + * Test if the activity is displayed and visible to user + */ + @Test + fun checkActivityVisibility() { + Espresso.onView(withId(R.id.layout_selectionActivity)) + .check(matches(isDisplayed())) + } + + /** + * Test if all the appropriate components are visible + */ + @Test + fun checkViewVisibility() { + Thread.sleep(500) + Espresso.onView(withId(R.id.selectionScreenView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.routineListView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.newWorkoutButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.loadingSpinner)) + .check(matches(not(isDisplayed()))) + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/UserProfileActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/UserProfileActivityTest.kt new file mode 100644 index 0000000..3f56c66 --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/UserProfileActivityTest.kt @@ -0,0 +1,154 @@ +/* + * Created by Team Symphony on 4/23/23, 3:46 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/23/23, 3:46 AM + */ + +package com.symphony.mrfit.ui + +import androidx.test.espresso.Espresso +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.rules.activityScenarioRule +import com.symphony.mrfit.R +import org.hamcrest.CoreMatchers.not +import org.junit.Rule +import org.junit.Test + +class UserProfileActivityTest { + + @get:Rule + var activityScenarioRule = activityScenarioRule() + + /** + * Test if the activity is displayed and visible to user + */ + @Test + fun checkActivityVisibility() { + Espresso.onView(withId(R.id.layout_profileActivity)) + .check(matches(isDisplayed())) + } + + /** + * Test if all the appropriate components are visible + */ + @Test + fun checkViewVisibility() { + Thread.sleep(500) + Espresso.onView(withId(R.id.profileScreenView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.profilePicture)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.profileNameTextView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.editProfileButton)) + .check(matches(not(isDisplayed()))) + + Espresso.onView(withId(R.id.heightLayout)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.weightLayout)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.ageLayout)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.stuffLayout)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.goalsButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.notificationsButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.historyButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.customExercisesButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.settingLayout)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.notificationToggle)) + .check(matches(not(isDisplayed()))) + + Espresso.onView(withId(R.id.logoutButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.deleteButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.loadingSpinner)) + .check(matches(not(isDisplayed()))) + } + + /** + * Test if the Notifications button navigates properly + */ + @Test + fun notificationsButtonTest() { + Espresso.onView(withId(R.id.notificationsButton)) + .perform(click()) + Espresso.onView(withId(R.id.layout_notificationLogActivity)) + .check(matches(isDisplayed())) + Espresso.pressBack() + Thread.sleep(500) + } + + /** + * Test if the Goals button navigates properly + */ + @Test + fun goalsButtonTest() { + Espresso.onView(withId(R.id.goalsButton)) + .perform(click()) + Espresso.onView(withId(R.id.layout_goalsActivity)) + .check(matches(isDisplayed())) + Espresso.pressBack() + Thread.sleep(500) + } + + /** + * Test if the History button navigates properly + */ + @Test + fun historyButtonTest() { + Espresso.onView(withId(R.id.historyButton)) + .perform(click()) + Espresso.onView(withId(R.id.layout_workoutHistoryActivity)) + .check(matches(isDisplayed())) + Espresso.pressBack() + Thread.sleep(500) + } + + /** + * Test if the Exercises button navigates properly + */ + @Test + fun exerciseButtonTest() { + Espresso.onView(withId(R.id.customExercisesButton)) + .perform(click()) + Espresso.onView(withId(R.id.layout_customExerciseActivity)) + .check(matches(isDisplayed())) + Espresso.pressBack() + Thread.sleep(500) + } + + /** + * Test if the Logout button navigates properly + */ + @Test + fun logoutButtonTest() { + Espresso.onView(withId(R.id.logoutButton)) + .perform(click()) + Espresso.onView(withId(R.id.layout_loginActivity)) + .check(matches(isDisplayed())) + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/WorkoutRoutineActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/WorkoutRoutineActivityTest.kt new file mode 100644 index 0000000..26b23b4 --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/WorkoutRoutineActivityTest.kt @@ -0,0 +1,83 @@ +/* + * Created by Team Symphony on 4/23/23, 3:46 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/23/23, 3:46 AM + */ + +package com.symphony.mrfit.ui + +import android.content.Intent +import androidx.test.core.app.ApplicationProvider +import androidx.test.espresso.Espresso +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.rules.activityScenarioRule +import com.symphony.mrfit.R +import org.hamcrest.CoreMatchers.not +import org.junit.Rule +import org.junit.Test + +class WorkoutRoutineActivityTest { + + @get:Rule + var activityScenarioRule = activityScenarioRule( + intent = Intent( + ApplicationProvider.getApplicationContext(), + WorkoutRoutineActivity::class.java + ) + .putExtra(WorkoutTemplateActivity.EXTRA_IDENTITY, "test") + ) + + /** + * Test if the activity is displayed and visible to user + */ + @Test + fun checkActivityVisibility() { + Espresso.onView(withId(R.id.layout_workoutBuilderActivity)) + .check(matches(isDisplayed())) + } + + /** + * Test if all the appropriate components are visible + */ + @Test + fun checkViewVisibility() { + Thread.sleep(1000) + Espresso.onView(withId(R.id.routineScreenView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.headerLayout)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.routineNameEditText)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.workoutPlaylistEditText)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.openPlaylistButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.workoutListView)) + .check(matches(not(isDisplayed()))) + + Espresso.onView(withId(R.id.routineScreenButtons)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.startWorkoutButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.newExerciseButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.saveWorkoutButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.deleteWorkoutButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.loadingSpinner)) + .check(matches(not(isDisplayed()))) + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/symphony/mrfit/ui/WorkoutTemplateActivityTest.kt b/app/src/androidTest/java/com/symphony/mrfit/ui/WorkoutTemplateActivityTest.kt new file mode 100644 index 0000000..dddb07c --- /dev/null +++ b/app/src/androidTest/java/com/symphony/mrfit/ui/WorkoutTemplateActivityTest.kt @@ -0,0 +1,76 @@ +/* + * Created by Team Symphony on 4/23/23, 3:46 AM + * Copyright (c) 2023 . All rights reserved. + * Last modified 4/23/23, 3:46 AM + */ + +package com.symphony.mrfit.ui + +import android.content.Intent +import androidx.test.core.app.ApplicationProvider +import androidx.test.espresso.Espresso +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.isDisplayed +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.rules.activityScenarioRule +import com.symphony.mrfit.R +import org.junit.Rule +import org.junit.Test + +class WorkoutTemplateActivityTest { + + @get:Rule + var activityScenarioRule = activityScenarioRule( + intent = Intent( + ApplicationProvider.getApplicationContext(), + WorkoutTemplateActivity::class.java + ) + .putExtra(WorkoutRoutineActivity.EXTRA_ROUTINE, "test") + .putExtra(WorkoutTemplateActivity.EXTRA_IDENTITY, "test") + .putExtra(WorkoutTemplateActivity.EXTRA_EXERCISE, "test") + .putExtra(WorkoutTemplateActivity.EXTRA_LIST, ArrayList()) + ) + + /** + * Test if the activity is displayed and visible to user + */ + @Test + fun checkActivityVisibility() { + Espresso.onView(withId(R.id.layout_exerciseBuilderActivity)) + .check(matches(isDisplayed())) + } + + /** + * Test if all the appropriate components are visible + */ + @Test + fun checkViewVisibility() { + Thread.sleep(500) + Espresso.onView(withId(R.id.templateScreenView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.exerciseCardView)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.editDuration)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.editDistance)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.repsAndSetsLayout)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.editReps)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.editSets)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.deleteTemplateButton)) + .check(matches(isDisplayed())) + + Espresso.onView(withId(R.id.saveTemplateButton)) + .check(matches(isDisplayed())) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1bf2511..2e192b1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,8 +1,8 @@ ): Recyc holder.historyTitle.text = data[i].name val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.US) holder.historyTimestamp.text = dateFormat.format(data[i].date!!.toDate()) - val seconds = (data[i].duration?.div(1000))?.mod(60) - val minutes = (data[i].duration?.div(1000))?.div(60) - holder.historyDuration.text = "Exercised for $minutes:$seconds" + val time = humanReadableDuration(data[i].duration!!) + holder.historyDuration.text = "Exercised for $time" } override fun getItemCount(): Int { diff --git a/app/src/main/java/com/symphony/mrfit/data/exercise/HistoryAdapter2.kt b/app/src/main/java/com/symphony/mrfit/data/adapters/HistoryAdapter2.kt similarity index 78% rename from app/src/main/java/com/symphony/mrfit/data/exercise/HistoryAdapter2.kt rename to app/src/main/java/com/symphony/mrfit/data/adapters/HistoryAdapter2.kt index 54f2b3e..7f15159 100644 --- a/app/src/main/java/com/symphony/mrfit/data/exercise/HistoryAdapter2.kt +++ b/app/src/main/java/com/symphony/mrfit/data/adapters/HistoryAdapter2.kt @@ -1,10 +1,10 @@ /* - * Created by Team Symphony on 4/1/23, 10:04 PM + * Created by Team Symphony on 4/22/23, 8:53 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/1/23, 10:04 PM + * Last modified 4/22/23, 8:53 PM */ -package com.symphony.mrfit.data.exercise +package com.symphony.mrfit.data.adapters import android.content.Context import android.view.LayoutInflater @@ -15,9 +15,8 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.symphony.mrfit.R import com.symphony.mrfit.data.model.History -import java.text.SimpleDateFormat -import java.util.* -import java.util.concurrent.TimeUnit +import com.symphony.mrfit.ui.Helper.humanReadableDate +import com.symphony.mrfit.ui.Helper.humanReadableDuration /** * Adapter for dynamically populating a card_history with a passed list of Histories @@ -74,14 +73,8 @@ class HistoryAdapter2( private fun buildString(i: Int): String { val milli = data[i].duration!! - val minutes = TimeUnit.MILLISECONDS.toMinutes(milli) - val seconds = TimeUnit.MILLISECONDS.toSeconds(milli) - val time = String.format("%02d:%02d", minutes, seconds) - val date = SimpleDateFormat( - "MMMM dd, yyyy", - Locale.getDefault() - ) - .format(data[i].date!!.toDate()) + val time = humanReadableDuration(milli) + val date = humanReadableDate(data[i].date!!.toDate()) return "Exercised for $time on $date" } } \ No newline at end of file diff --git a/app/src/main/java/com/symphony/mrfit/data/exercise/NotificationAdapter.kt b/app/src/main/java/com/symphony/mrfit/data/adapters/NotificationAdapter.kt similarity index 90% rename from app/src/main/java/com/symphony/mrfit/data/exercise/NotificationAdapter.kt rename to app/src/main/java/com/symphony/mrfit/data/adapters/NotificationAdapter.kt index 9fd32f4..2acbf2d 100644 --- a/app/src/main/java/com/symphony/mrfit/data/exercise/NotificationAdapter.kt +++ b/app/src/main/java/com/symphony/mrfit/data/adapters/NotificationAdapter.kt @@ -1,10 +1,10 @@ /* - * Created by Team Symphony on 4/1/23, 10:04 PM + * Created by Team Symphony on 4/22/23, 8:53 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/1/23, 9:50 PM + * Last modified 4/22/23, 8:53 PM */ -package com.symphony.mrfit.data.exercise +package com.symphony.mrfit.data.adapters import android.content.Context import android.os.Build @@ -19,7 +19,7 @@ import androidx.recyclerview.widget.RecyclerView import com.symphony.mrfit.R import com.symphony.mrfit.data.model.Notification import com.symphony.mrfit.data.profile.UserRepository -import java.text.SimpleDateFormat +import com.symphony.mrfit.ui.Helper.humanReadableDateTime import java.util.* /** @@ -47,11 +47,7 @@ class NotificationAdapter( override fun onBindViewHolder(holder: ViewHolder, i: Int) { holder.notificationMessage.text = data[i].message val date = data[i].date!!.toDate() - holder.notificationTimestamp.text = SimpleDateFormat( - "MMMM dd, yyyy 'at' hh:mm a", - Locale.getDefault() - ) - .format(date) + holder.notificationTimestamp.text = humanReadableDateTime(date) // If the Notification was from before the current date // allow user to delete it if (date.before(Date())) { diff --git a/app/src/main/java/com/symphony/mrfit/data/exercise/RoutineAdapter.kt b/app/src/main/java/com/symphony/mrfit/data/adapters/RoutineAdapter.kt similarity index 94% rename from app/src/main/java/com/symphony/mrfit/data/exercise/RoutineAdapter.kt rename to app/src/main/java/com/symphony/mrfit/data/adapters/RoutineAdapter.kt index 122c607..194a7d9 100644 --- a/app/src/main/java/com/symphony/mrfit/data/exercise/RoutineAdapter.kt +++ b/app/src/main/java/com/symphony/mrfit/data/adapters/RoutineAdapter.kt @@ -1,10 +1,10 @@ /* - * Created by Team Symphony on 2/24/23, 11:21 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 2/24/23, 11:20 PM + * Last modified 4/22/23, 4:43 PM */ -package com.symphony.mrfit.data.exercise +package com.symphony.mrfit.data.adapters import android.content.Context import android.content.Intent diff --git a/app/src/main/java/com/symphony/mrfit/data/exercise/RoutineAdapter2.kt b/app/src/main/java/com/symphony/mrfit/data/adapters/RoutineAdapter2.kt similarity index 95% rename from app/src/main/java/com/symphony/mrfit/data/exercise/RoutineAdapter2.kt rename to app/src/main/java/com/symphony/mrfit/data/adapters/RoutineAdapter2.kt index 42af742..e8a5289 100644 --- a/app/src/main/java/com/symphony/mrfit/data/exercise/RoutineAdapter2.kt +++ b/app/src/main/java/com/symphony/mrfit/data/adapters/RoutineAdapter2.kt @@ -1,10 +1,10 @@ /* - * Created by Team Symphony on 4/21/23, 3:22 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/21/23, 3:22 PM + * Last modified 4/22/23, 4:43 PM */ -package com.symphony.mrfit.data.exercise +package com.symphony.mrfit.data.adapters import android.content.Context import android.graphics.drawable.ColorDrawable diff --git a/app/src/main/java/com/symphony/mrfit/data/exercise/WorkoutAdapter.kt b/app/src/main/java/com/symphony/mrfit/data/adapters/WorkoutAdapter.kt similarity index 91% rename from app/src/main/java/com/symphony/mrfit/data/exercise/WorkoutAdapter.kt rename to app/src/main/java/com/symphony/mrfit/data/adapters/WorkoutAdapter.kt index e485500..bb8e6d5 100644 --- a/app/src/main/java/com/symphony/mrfit/data/exercise/WorkoutAdapter.kt +++ b/app/src/main/java/com/symphony/mrfit/data/adapters/WorkoutAdapter.kt @@ -1,10 +1,10 @@ /* - * Created by Team Symphony on 4/2/23, 10:27 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/2/23, 10:22 PM + * Last modified 4/22/23, 4:43 PM */ -package com.symphony.mrfit.data.exercise +package com.symphony.mrfit.data.adapters import android.content.Context import android.content.Intent @@ -19,6 +19,7 @@ import com.google.firebase.ktx.Firebase import com.google.firebase.storage.FirebaseStorage import com.google.firebase.storage.ktx.storage import com.symphony.mrfit.R +import com.symphony.mrfit.data.exercise.ExerciseRepository import com.symphony.mrfit.data.model.Workout import com.symphony.mrfit.ui.WorkoutRoutineActivity.Companion.EXTRA_ROUTINE import com.symphony.mrfit.ui.WorkoutTemplateActivity @@ -31,7 +32,12 @@ import com.symphony.mrfit.ui.WorkoutTemplateActivity.Companion.EXTRA_LIST * a passed list of Workouts, as well as the parent Routine's ID and workoutList */ -class WorkoutAdapter (val context: Context, val data: ArrayList, private val rID: String, private val rList: ArrayList): RecyclerView.Adapter() { +class WorkoutAdapter( + val context: Context, + val data: ArrayList, + private val rID: String, + private val rList: ArrayList +) : RecyclerView.Adapter() { private var storage: FirebaseStorage = Firebase.storage diff --git a/app/src/main/java/com/symphony/mrfit/data/exercise/WorkoutAdapter2.kt b/app/src/main/java/com/symphony/mrfit/data/adapters/WorkoutAdapter2.kt similarity index 94% rename from app/src/main/java/com/symphony/mrfit/data/exercise/WorkoutAdapter2.kt rename to app/src/main/java/com/symphony/mrfit/data/adapters/WorkoutAdapter2.kt index f1ae913..3333d7d 100644 --- a/app/src/main/java/com/symphony/mrfit/data/exercise/WorkoutAdapter2.kt +++ b/app/src/main/java/com/symphony/mrfit/data/adapters/WorkoutAdapter2.kt @@ -1,10 +1,10 @@ /* - * Created by Team Symphony on 4/2/23, 10:27 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/2/23, 10:22 PM + * Last modified 4/22/23, 4:43 PM */ -package com.symphony.mrfit.data.exercise +package com.symphony.mrfit.data.adapters import android.content.Context import android.view.LayoutInflater @@ -19,6 +19,7 @@ import com.google.firebase.ktx.Firebase import com.google.firebase.storage.FirebaseStorage import com.google.firebase.storage.ktx.storage import com.symphony.mrfit.R +import com.symphony.mrfit.data.exercise.ExerciseRepository import com.symphony.mrfit.data.model.Workout /** diff --git a/app/src/main/java/com/symphony/mrfit/data/exercise/ExerciseRepository.kt b/app/src/main/java/com/symphony/mrfit/data/exercise/ExerciseRepository.kt index 63ffcae..178542e 100644 --- a/app/src/main/java/com/symphony/mrfit/data/exercise/ExerciseRepository.kt +++ b/app/src/main/java/com/symphony/mrfit/data/exercise/ExerciseRepository.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/2/23, 2:50 PM + * Created by Team Symphony on 4/22/23, 7:14 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/2/23, 2:50 PM + * Last modified 4/22/23, 7:09 PM */ package com.symphony.mrfit.data.exercise @@ -82,10 +82,41 @@ class ExerciseRepository { /** * Remove a specific Exercise by it's ID + * Also remove any workouts using that Exercise + * Update any routines using those workouts to alert the user */ suspend fun deleteExercise(exeID: String) { Log.d(TAG, "Removing Exercise $exeID from Firestore") database.collection(EXERCISE_COLLECTION).document(exeID).delete().await() + val storageRef = storage.reference.child(EXERCISE_PICTURE).child(exeID) + storageRef.delete().await() + + Log.d(TAG, "Removing Exercise $exeID from all Routines") + try { + val workList = arrayListOf() + // Get and delete all workouts constructed from the deleted exercise + val result = database.collection(WORKOUT_COLLECTION) + .whereEqualTo("exercise", exeID) + .get() + .await() + for (document in result) { + workList.add(document.get("workoutID") as String) + document.reference.delete() + } + // Remove any deleted workouts from routines + for (workID in workList) { + val result2 = database.collection(ROUTINE_COLLECTION) + .whereArrayContains("workoutList", workID) + .get().await() + for (document2 in result2) { + val t = document2.toObject() + t.workoutList!!.remove(workID) + document2.reference.set(t) + } + } + } catch (e: java.lang.Exception) { + Log.d(TAG, "Error updating routines: $e") + } } /** diff --git a/app/src/main/java/com/symphony/mrfit/data/profile/UserRepository.kt b/app/src/main/java/com/symphony/mrfit/data/profile/UserRepository.kt index 5bdac84..4ab6e3c 100644 --- a/app/src/main/java/com/symphony/mrfit/data/profile/UserRepository.kt +++ b/app/src/main/java/com/symphony/mrfit/data/profile/UserRepository.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/19/23, 7:07 PM + * Created by Team Symphony on 4/22/23, 6:21 AM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/19/23, 7:07 PM + * Last modified 4/22/23, 6:05 AM */ package com.symphony.mrfit.data.profile @@ -50,21 +50,26 @@ class UserRepository { * Pull the currently logged in user's profile from Firestore */ suspend fun getCurrentUser() : User? { - Log.d(TAG, "Retrieving User ${auth.currentUser!!.uid} from Firestore") - val doc = auth.currentUser!!.uid - val docRef = database.collection(USER_COLLECTION).document(doc) - return try { - val snapshot = docRef.get().await() - // Something wrong happened when deleting this user, fix it - if (snapshot.get("userID") == null) { - LoginRepository().delete() - LoginRepository().logout() - User("delete") + val user = auth.currentUser + if (user != null) { + Log.d(TAG, "Retrieving User ${user.uid} from Firestore") + val doc = user.uid + val docRef = database.collection(USER_COLLECTION).document(doc) + return try { + val snapshot = docRef.get().await() + // Something wrong happened when deleting this user, fix it + if (snapshot.get("userID") == null) { + LoginRepository().delete() + LoginRepository().logout() + User("delete") + } + snapshot.toObject() + } catch (e: java.lang.Exception) { + Log.w(TAG, "Error getting document", e) + null } - snapshot.toObject() - } catch (e: java.lang.Exception) { - Log.w(TAG, "Error getting document", e) - null + } else { + return user } } @@ -97,15 +102,17 @@ class UserRepository { * Only called when a user is being deleted, remove their document from Firestore */ suspend fun removeUser() { - val user = auth.currentUser!! - Log.d(TAG, "Removing User ${user.uid} from Firestore") - try { - database.collection(USER_COLLECTION).document(user.uid) - .delete() - .await() - Log.d(TAG, "DocumentSnapshot successfully deleted!") - } catch (e: java.lang.Exception) { - Log.w(TAG, "Error deleting document", e) + val user = auth.currentUser + if (user != null) { + Log.d(TAG, "Removing User ${user.uid} from Firestore") + try { + database.collection(USER_COLLECTION).document(user.uid) + .delete() + .await() + Log.d(TAG, "DocumentSnapshot successfully deleted!") + } catch (e: java.lang.Exception) { + Log.w(TAG, "Error deleting document", e) + } } } @@ -113,14 +120,16 @@ class UserRepository { * Add a new Workout History to the user's subcollection */ suspend fun addWorkoutHistory(history: History) { - val user = auth.currentUser!! - Log.d(TAG, "Adding to the history of ${user.uid}") - try { - val docRef = database.collection(USER_COLLECTION).document(user.uid) - .collection(HISTORY_COLLECTION).add(history).await() - docRef.update("historyID", docRef.id).await() - } catch (e: java.lang.Exception) { - Log.d(TAG, "Error writing documents: ", e) + val user = auth.currentUser + if (user != null) { + Log.d(TAG, "Adding to the history of ${user.uid}") + try { + val docRef = database.collection(USER_COLLECTION).document(user.uid) + .collection(HISTORY_COLLECTION).add(history).await() + docRef.update("historyID", docRef.id).await() + } catch (e: java.lang.Exception) { + Log.d(TAG, "Error writing documents: ", e) + } } } @@ -128,37 +137,43 @@ class UserRepository { * Delete a given history via its ID */ suspend fun deleteWorkoutHistory(historyID: String) { - val user = auth.currentUser!! - Log.d(TAG, "Deleting history $historyID belonging to ${user.uid}") - database.collection(USER_COLLECTION) - .document(user.uid) - .collection(HISTORY_COLLECTION) - .document(historyID) - .delete() - .await() + val user = auth.currentUser + if (user != null) { + Log.d(TAG, "Deleting history $historyID belonging to ${user.uid}") + database.collection(USER_COLLECTION) + .document(user.uid) + .collection(HISTORY_COLLECTION) + .document(historyID) + .delete() + .await() + } } /** * Get a user's complete Workout History */ suspend fun getWorkoutHistory(): ArrayList { - val user = auth.currentUser!! + val user = auth.currentUser val historyList = arrayListOf() - Log.d(TAG, "Getting the history of ${user.uid}") - try { - val result = database.collection(USER_COLLECTION) - .document(user.uid) - .collection(HISTORY_COLLECTION) - .get() - .await() + if (user != null) { + Log.d(TAG, "Getting the history of ${user.uid}") + try { + val result = database.collection(USER_COLLECTION) + .document(user.uid) + .collection(HISTORY_COLLECTION) + .get() + .await() - for (document in result) { - historyList.add(document.toObject()) + for (document in result) { + historyList.add(document.toObject()) + } + } catch (e: java.lang.Exception) { + Log.d(TAG, "Error getting documents: ", e) } - } catch (e: java.lang.Exception) { - Log.d(TAG, "Error getting documents: ", e) + return historyList + } else { + return historyList } - return historyList } /** @@ -191,69 +206,78 @@ class UserRepository { * Add a new Notification to the user's notification subcollection */ suspend fun addNotification(notification: Notification) { - val user = auth.currentUser!! - Log.d(TAG, "Adding to the history of ${user.uid}") - database.collection(USER_COLLECTION) - .document(user.uid) - .collection(NOTIFICATION_COLLECTION) - .document(notification.date!!.toDate().time.toString()) - .set(notification) - .await() + val user = auth.currentUser + if (user != null) { + Log.d(TAG, "Adding to the history of ${user.uid}") + database.collection(USER_COLLECTION) + .document(user.uid) + .collection(NOTIFICATION_COLLECTION) + .document(notification.date!!.toDate().time.toString()) + .set(notification) + .await() + } } /** * Get a user's scheduled and past notifications */ suspend fun getNotifications(): ArrayList { - val user = auth.currentUser!! + val user = auth.currentUser val notificationList = arrayListOf() - Log.d(TAG, "Getting the notifications of ${user.uid}") - try { - val result = database.collection(USER_COLLECTION) - .document(user.uid) - .collection(NOTIFICATION_COLLECTION) - .get() - .await() + if (user == null) { + return notificationList + } else { + Log.d(TAG, "Getting the notifications of ${user.uid}") + try { + val result = database.collection(USER_COLLECTION) + .document(user.uid) + .collection(NOTIFICATION_COLLECTION) + .get() + .await() - for (document in result) { - notificationList.add(document.toObject()) + for (document in result) { + notificationList.add(document.toObject()) + } + } catch (e: java.lang.Exception) { + Log.d(TAG, "Error getting documents: ", e) } - } catch (e: java.lang.Exception) { - Log.d(TAG, "Error getting documents: ", e) + return notificationList } - return notificationList } /** * Remove a notification from the user's subcollection */ suspend fun deleteNotification(date: String) { - val user = auth.currentUser!! - Log.d(TAG, "Deleting notification with timestamp: $date") - database.collection(USER_COLLECTION) - .document(user.uid) - .collection(NOTIFICATION_COLLECTION) - .document(date) - .delete() - .await() - + val user = auth.currentUser + if (user != null) { + Log.d(TAG, "Deleting notification with timestamp: $date") + database.collection(USER_COLLECTION) + .document(user.uid) + .collection(NOTIFICATION_COLLECTION) + .document(date) + .delete() + .await() + } } /** * Add a new Goal to the user's goal subcollection */ suspend fun addGoal(goal: Goal) { - val user = auth.currentUser!! - Log.d(TAG, "Adding to the goals of ${user.uid}") - try { - val docRef = database.collection(USER_COLLECTION) - .document(user.uid) - .collection(GOAL_COLLECTION) - .add(goal) - .await() - docRef.update("goalID", docRef.id).await() - } catch (e: java.lang.Exception) { - Log.w(TAG, "Error writing document", e) + val user = auth.currentUser + if (user != null) { + Log.d(TAG, "Adding to the goals of ${user.uid}") + try { + val docRef = database.collection(USER_COLLECTION) + .document(user.uid) + .collection(GOAL_COLLECTION) + .add(goal) + .await() + docRef.update("goalID", docRef.id).await() + } catch (e: java.lang.Exception) { + Log.w(TAG, "Error writing document", e) + } } } @@ -261,16 +285,18 @@ class UserRepository { * Update an existing goal with its id */ suspend fun updateGoal(goal: Goal) { - val user = auth.currentUser!! - Log.d(TAG, "Updating goal ${goal.goalID} belonging to ${user.uid}") - try { - database.collection(USER_COLLECTION) - .document(user.uid) - .collection(GOAL_COLLECTION) - .document(goal.goalID!!) - .set(goal) - } catch (e: java.lang.Exception) { - Log.w(TAG, "Error writing document", e) + val user = auth.currentUser + if (user != null) { + Log.d(TAG, "Updating goal ${goal.goalID} belonging to ${user.uid}") + try { + database.collection(USER_COLLECTION) + .document(user.uid) + .collection(GOAL_COLLECTION) + .document(goal.goalID!!) + .set(goal) + } catch (e: java.lang.Exception) { + Log.w(TAG, "Error writing document", e) + } } } @@ -278,38 +304,43 @@ class UserRepository { * Get a user's scheduled and past goals */ suspend fun getGoals(): ArrayList { - val user = auth.currentUser!! + val user = auth.currentUser val goalList = arrayListOf() - Log.d(TAG, "Getting the goals of ${user.uid}") - try { - val result = database.collection(USER_COLLECTION) - .document(user.uid) - .collection(GOAL_COLLECTION) - .get() - .await() + if (user == null) { + return goalList + } else { + Log.d(TAG, "Getting the goals of ${user.uid}") + try { + val result = database.collection(USER_COLLECTION) + .document(user.uid) + .collection(GOAL_COLLECTION) + .get() + .await() - for (document in result) { - goalList.add(document.toObject()) + for (document in result) { + goalList.add(document.toObject()) + } + } catch (e: java.lang.Exception) { + Log.d(TAG, "Error getting documents: ", e) } - } catch (e: java.lang.Exception) { - Log.d(TAG, "Error getting documents: ", e) + return goalList } - return goalList } /** * Remove a goal from the user's subcollection */ suspend fun deleteGoal(goalID: String) { - val user = auth.currentUser!! - Log.d(TAG, "Deleting goal with ID: $goalID") - database.collection(USER_COLLECTION) - .document(user.uid) - .collection(GOAL_COLLECTION) - .document(goalID) - .delete() - .await() - + val user = auth.currentUser + if (user != null) { + Log.d(TAG, "Deleting goal with ID: $goalID") + database.collection(USER_COLLECTION) + .document(user.uid) + .collection(GOAL_COLLECTION) + .document(goalID) + .delete() + .await() + } } companion object { diff --git a/app/src/main/java/com/symphony/mrfit/ui/CalendarActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/CalendarActivity.kt index 377d797..6c3b06a 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/CalendarActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/CalendarActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/20/23, 2:11 AM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/20/23, 2:08 AM + * Last modified 4/22/23, 4:43 PM */ package com.symphony.mrfit.ui @@ -26,7 +26,7 @@ import com.applandeo.materialcalendarview.CalendarView import com.applandeo.materialcalendarview.EventDay import com.applandeo.materialcalendarview.listeners.OnDayClickListener import com.symphony.mrfit.R -import com.symphony.mrfit.data.exercise.NotificationAdapter +import com.symphony.mrfit.data.adapters.NotificationAdapter import com.symphony.mrfit.data.model.Notification import com.symphony.mrfit.data.profile.ProfileViewModel import com.symphony.mrfit.data.profile.ProfileViewModelFactory diff --git a/app/src/main/java/com/symphony/mrfit/ui/CurrentWorkoutActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/CurrentWorkoutActivity.kt index e81a7f1..fe8d34b 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/CurrentWorkoutActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/CurrentWorkoutActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/20/23, 2:11 AM + * Created by Team Symphony on 4/22/23, 8:53 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/20/23, 2:11 AM + * Last modified 4/22/23, 8:53 PM */ package com.symphony.mrfit.ui @@ -22,18 +22,18 @@ import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.firebase.Timestamp import com.symphony.mrfit.R +import com.symphony.mrfit.data.adapters.WorkoutAdapter2 import com.symphony.mrfit.data.exercise.ExerciseViewModel import com.symphony.mrfit.data.exercise.ExerciseViewModelFactory -import com.symphony.mrfit.data.exercise.WorkoutAdapter2 import com.symphony.mrfit.data.model.History import com.symphony.mrfit.data.profile.ProfileViewModel import com.symphony.mrfit.data.profile.ProfileViewModelFactory import com.symphony.mrfit.databinding.ActivityCurrentWorkoutBinding import com.symphony.mrfit.ui.Helper.ZERO +import com.symphony.mrfit.ui.Helper.humanReadableTime import com.symphony.mrfit.ui.RoutineSelectionActivity.Companion.EXTRA_LIST import com.symphony.mrfit.ui.RoutineSelectionActivity.Companion.EXTRA_STRING import com.symphony.mrfit.ui.WorkoutRoutineActivity.Companion.EXTRA_ROUTINE -import java.text.SimpleDateFormat import java.util.* /** @@ -134,20 +134,11 @@ class CurrentWorkoutActivity : AppCompatActivity() { .inflate(R.layout.activity_post_workout, null, false) materialDialog.setView(dialogView) - .setTitle("Post Exercise") val text = dialogView.findViewById(R.id.postWorkoutTime) - val startTime = SimpleDateFormat( - "'You started this workout at' hh:mm a", - Locale.getDefault() - ) - .format(Date().time - timeSpent) - val endTime = SimpleDateFormat( - "' and finished at ' hh:mm a", - Locale.getDefault() - ) - .format(Date()) - var totalTime = " for a total of " + val startTime = humanReadableTime(Date().time - timeSpent) + val endTime = humanReadableTime(Date()) + var totalTime = "" var hours: Long = 0 var minutes = timeSpent / 1000 / 60 val seconds = timeSpent / 1000 % 60 @@ -163,7 +154,7 @@ class CurrentWorkoutActivity : AppCompatActivity() { } totalTime += "$seconds seconds." - text.text = startTime + endTime + totalTime + text.text = getString(R.string.post_workout_message, startTime, endTime, totalTime) materialDialog.setOnCancelListener { gotoHome() diff --git a/app/src/main/java/com/symphony/mrfit/ui/CustomExercisesActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/CustomExercisesActivity.kt index 16cb5fb..0a0da80 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/CustomExercisesActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/CustomExercisesActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/20/23, 7:03 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/20/23, 7:03 PM + * Last modified 4/22/23, 4:43 PM */ package com.symphony.mrfit.ui @@ -32,7 +32,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.firebase.ktx.Firebase import com.google.firebase.storage.ktx.storage import com.symphony.mrfit.R -import com.symphony.mrfit.data.exercise.ExerciseAdapter2 +import com.symphony.mrfit.data.adapters.ExerciseAdapter2 import com.symphony.mrfit.data.exercise.ExerciseViewModel import com.symphony.mrfit.data.exercise.ExerciseViewModelFactory import com.symphony.mrfit.data.model.Exercise diff --git a/app/src/main/java/com/symphony/mrfit/ui/DateTimeActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/DateTimeActivity.kt index c397612..25edb4b 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/DateTimeActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/DateTimeActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/21/23, 3:22 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/21/23, 2:03 PM + * Last modified 4/22/23, 5:12 PM */ package com.symphony.mrfit.ui @@ -14,8 +14,8 @@ import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatActivity import com.applandeo.materialcalendarview.EventDay import com.applandeo.materialcalendarview.listeners.OnDayClickListener -import com.symphony.mrfit.ManualWorkoutActivity.Companion.EXTRA_TIME import com.symphony.mrfit.databinding.ActivityDateTimeBinding +import com.symphony.mrfit.ui.ManualWorkoutActivity.Companion.EXTRA_TIME import java.util.* class DateTimeActivity : AppCompatActivity() { diff --git a/app/src/main/java/com/symphony/mrfit/ui/ExerciseActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/ExerciseActivity.kt index 9f7e7e9..90e564a 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/ExerciseActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/ExerciseActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/21/23, 3:22 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/21/23, 1:31 PM + * Last modified 4/22/23, 4:43 PM */ package com.symphony.mrfit.ui @@ -31,7 +31,7 @@ import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.symphony.mrfit.R -import com.symphony.mrfit.data.exercise.ExerciseAdapter +import com.symphony.mrfit.data.adapters.ExerciseAdapter import com.symphony.mrfit.data.exercise.ExerciseViewModel import com.symphony.mrfit.data.exercise.ExerciseViewModelFactory import com.symphony.mrfit.data.model.Exercise diff --git a/app/src/main/java/com/symphony/mrfit/ui/GoalsActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/GoalsActivity.kt index ed5532c..c42eadf 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/GoalsActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/GoalsActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/20/23, 7:03 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/20/23, 5:47 PM + * Last modified 4/22/23, 4:43 PM */ package com.symphony.mrfit.ui @@ -22,7 +22,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.symphony.mrfit.R -import com.symphony.mrfit.data.exercise.GoalAdapter +import com.symphony.mrfit.data.adapters.GoalAdapter import com.symphony.mrfit.data.model.Goal import com.symphony.mrfit.data.profile.ProfileViewModel import com.symphony.mrfit.data.profile.ProfileViewModelFactory diff --git a/app/src/main/java/com/symphony/mrfit/ui/Helper.kt b/app/src/main/java/com/symphony/mrfit/ui/Helper.kt index ba29fcd..c837f4f 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/Helper.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/Helper.kt @@ -1,14 +1,16 @@ /* - * Created by Team Symphony on 4/2/23, 6:07 PM + * Created by Team Symphony on 4/23/23, 3:02 AM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/2/23, 5:25 PM + * Last modified 4/22/23, 11:42 PM */ package com.symphony.mrfit.ui import android.app.Activity import com.google.android.material.snackbar.Snackbar +import java.text.SimpleDateFormat import java.util.* +import java.util.concurrent.TimeUnit /** * Object for holding helper functions and consts @@ -19,6 +21,9 @@ object Helper { const val BLANK = "" const val ZERO = 0 const val EXTRA_DATE = "passed_date" + const val ONE_MINUTE: Long = 60000 + const val ONE_HOUR: Long = 3600000 + fun showSnackBar(message: String?, activity: Activity?) { if (null != activity && null != message) { Snackbar.make( @@ -33,4 +38,72 @@ object Helper { cal.time = date return cal } + + fun humanReadableDuration(time: Long): String { + return if (time >= ONE_HOUR) { + String.format( + "%02d:%02d:%02d", + TimeUnit.MILLISECONDS.toHours(time), + TimeUnit.MILLISECONDS.toMinutes(time) - + TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(time)), + TimeUnit.MILLISECONDS.toSeconds(time) - + TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time)) + ) + } else { + String.format( + "%02d:%02d", + TimeUnit.MILLISECONDS.toMinutes(time), + TimeUnit.MILLISECONDS.toSeconds(time) - + TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time)) + ) + } + } + + fun humanReadableTime(time: Long): String { + return SimpleDateFormat( + "hh:mm a", + Locale.getDefault() + ) + .format(time) + } + + fun humanReadableTime(time: Date): String { + return SimpleDateFormat( + "hh:mm a", + Locale.getDefault() + ) + .format(time) + } + + fun humanReadableDate(date: Date): String { + return SimpleDateFormat( + "MMMM dd, yyyy", + Locale.getDefault() + ) + .format(date) + } + + fun humanReadableDate(date: Long): String { + return SimpleDateFormat( + "MMMM dd, yyyy", + Locale.getDefault() + ) + .format(date) + } + + fun humanReadableDateTime(date: Date): String { + return SimpleDateFormat( + "MMMM dd, yyyy 'at' hh:mm a", + Locale.getDefault() + ) + .format(date) + } + + fun humanReadableDateTime(date: Long): String { + return SimpleDateFormat( + "MMMM dd, yyyy 'at' hh:mm a", + Locale.getDefault() + ) + .format(date) + } } \ No newline at end of file diff --git a/app/src/main/java/com/symphony/mrfit/ui/HomeActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/HomeActivity.kt index 45caee5..251e930 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/HomeActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/HomeActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/21/23, 3:22 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/21/23, 3:17 PM + * Last modified 4/22/23, 4:56 PM */ package com.symphony.mrfit.ui @@ -20,9 +20,8 @@ import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.bumptech.glide.signature.ObjectKey import com.google.firebase.auth.FirebaseAuth -import com.symphony.mrfit.ManualWorkoutActivity import com.symphony.mrfit.R -import com.symphony.mrfit.data.exercise.HistoryAdapter +import com.symphony.mrfit.data.adapters.HistoryAdapter import com.symphony.mrfit.data.profile.ProfileViewModel import com.symphony.mrfit.data.profile.ProfileViewModelFactory import com.symphony.mrfit.databinding.ActivityHomeBinding diff --git a/app/src/main/java/com/symphony/mrfit/ManualWorkoutActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/ManualWorkoutActivity.kt similarity index 96% rename from app/src/main/java/com/symphony/mrfit/ManualWorkoutActivity.kt rename to app/src/main/java/com/symphony/mrfit/ui/ManualWorkoutActivity.kt index d47d000..9ba32ee 100644 --- a/app/src/main/java/com/symphony/mrfit/ManualWorkoutActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/ManualWorkoutActivity.kt @@ -1,10 +1,10 @@ /* - * Created by Team Symphony on 4/21/23, 3:22 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/21/23, 3:22 PM + * Last modified 4/22/23, 5:12 PM */ -package com.symphony.mrfit +package com.symphony.mrfit.ui import android.app.Activity import android.content.ContentValues @@ -22,14 +22,13 @@ import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.firebase.Timestamp +import com.symphony.mrfit.data.adapters.RoutineAdapter2 import com.symphony.mrfit.data.exercise.ExerciseViewModel import com.symphony.mrfit.data.exercise.ExerciseViewModelFactory -import com.symphony.mrfit.data.exercise.RoutineAdapter2 import com.symphony.mrfit.data.model.History import com.symphony.mrfit.data.profile.ProfileViewModel import com.symphony.mrfit.data.profile.ProfileViewModelFactory import com.symphony.mrfit.databinding.ActivityManualWorkoutBinding -import com.symphony.mrfit.ui.DateTimeActivity import java.text.SimpleDateFormat import java.util.* @@ -126,12 +125,10 @@ class ManualWorkoutActivity : AppCompatActivity() { var selectedThing = intent.getIntExtra(SAVED_SELECTION, -999) var routineName = "" var routineID = "" - var selection = false fun update(name: String, id: String, num: Int) { routineName = name routineID = id - selection = true selectedThing = num } @@ -188,7 +185,7 @@ class ManualWorkoutActivity : AppCompatActivity() { * The end time must not be before the start time */ save.setOnClickListener { - if (selection) { + if (selectedThing >= 0) { if (startTime < endTime) { profileViewModel.addWorkoutToHistory( History( diff --git a/app/src/main/java/com/symphony/mrfit/ui/NotificationLogActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/NotificationLogActivity.kt index 0960988..21d7c9a 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/NotificationLogActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/NotificationLogActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/2/23, 9:44 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/2/23, 9:42 PM + * Last modified 4/22/23, 4:43 PM */ package com.symphony.mrfit.ui @@ -21,7 +21,7 @@ import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.symphony.mrfit.data.exercise.NotificationAdapter +import com.symphony.mrfit.data.adapters.NotificationAdapter import com.symphony.mrfit.data.profile.ProfileViewModel import com.symphony.mrfit.data.profile.ProfileViewModelFactory import com.symphony.mrfit.databinding.ActivityNotificationLogBinding diff --git a/app/src/main/java/com/symphony/mrfit/ui/RoutineSelectionActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/RoutineSelectionActivity.kt index 843b0dd..b2877e7 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/RoutineSelectionActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/RoutineSelectionActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/1/23, 7:44 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/1/23, 7:44 PM + * Last modified 4/22/23, 5:12 PM */ package com.symphony.mrfit.ui @@ -16,9 +16,9 @@ import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.symphony.mrfit.data.adapters.RoutineAdapter import com.symphony.mrfit.data.exercise.ExerciseViewModel import com.symphony.mrfit.data.exercise.ExerciseViewModelFactory -import com.symphony.mrfit.data.exercise.RoutineAdapter import com.symphony.mrfit.databinding.ActivityRoutineSelectionBinding import com.symphony.mrfit.ui.Helper.BLANK import com.symphony.mrfit.ui.WorkoutTemplateActivity.Companion.EXTRA_IDENTITY diff --git a/app/src/main/java/com/symphony/mrfit/ui/WorkoutHistoryActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/WorkoutHistoryActivity.kt index f64367e..0dac47a 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/WorkoutHistoryActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/WorkoutHistoryActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/20/23, 7:03 PM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/20/23, 4:59 PM + * Last modified 4/22/23, 4:56 PM */ package com.symphony.mrfit.ui @@ -19,9 +19,8 @@ import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.symphony.mrfit.ManualWorkoutActivity import com.symphony.mrfit.R -import com.symphony.mrfit.data.exercise.HistoryAdapter2 +import com.symphony.mrfit.data.adapters.HistoryAdapter2 import com.symphony.mrfit.data.model.History import com.symphony.mrfit.data.profile.ProfileViewModel import com.symphony.mrfit.data.profile.ProfileViewModelFactory diff --git a/app/src/main/java/com/symphony/mrfit/ui/WorkoutRoutineActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/WorkoutRoutineActivity.kt index 7fc296b..f3842e8 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/WorkoutRoutineActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/WorkoutRoutineActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/20/23, 2:11 AM + * Created by Team Symphony on 4/22/23, 5:12 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/20/23, 2:08 AM + * Last modified 4/22/23, 5:12 PM */ package com.symphony.mrfit.ui @@ -21,9 +21,9 @@ import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.symphony.mrfit.R +import com.symphony.mrfit.data.adapters.WorkoutAdapter import com.symphony.mrfit.data.exercise.ExerciseViewModel import com.symphony.mrfit.data.exercise.ExerciseViewModelFactory -import com.symphony.mrfit.data.exercise.WorkoutAdapter import com.symphony.mrfit.data.profile.ProfileViewModel import com.symphony.mrfit.data.profile.ProfileViewModelFactory import com.symphony.mrfit.databinding.ActivityWorkoutRoutineBinding @@ -43,9 +43,13 @@ class WorkoutRoutineActivity : AppCompatActivity() { private lateinit var profileViewModel: ProfileViewModel private lateinit var exerciseViewModel: ExerciseViewModel private lateinit var binding: ActivityWorkoutRoutineBinding - private lateinit var routineName: EditText + private lateinit var workoutList: RecyclerView + private lateinit var routineNameText: EditText private lateinit var routinePlaylist: EditText private lateinit var passedRoutineID: String + private var routineName: String? = null + private var playlist: String? = null + private var exercises: ArrayList? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -64,14 +68,13 @@ class WorkoutRoutineActivity : AppCompatActivity() { override fun onStart() { super.onStart() - Log.d(ContentValues.TAG, "Activity has (Re)Started") // Bind variables to View elements val spinner = binding.loadingSpinner - routineName = binding.routineNameEditText + routineNameText = binding.routineNameEditText routinePlaylist = binding.workoutPlaylistEditText - val workoutList = binding.workoutListView + workoutList = binding.workoutListView val startWorkout = binding.startWorkoutButton val newExercise = binding.newExerciseButton val saveWorkout = binding.saveWorkoutButton @@ -81,43 +84,54 @@ class WorkoutRoutineActivity : AppCompatActivity() { placeholderText.visibility = View.VISIBLE workoutList.visibility = View.GONE - spinner.visibility = View.VISIBLE /** * Retrieve the extras passed to this intent * passedID = The ID of the parent Routine * passedName = The Name of the parent Routine * passedList = The workoutList from the parent Routine + * savedName = The Name of the template if it was navigated away from + * savedMusic = The playlist for the template if it was navigated away from */ passedRoutineID = intent.getStringExtra(EXTRA_IDENTITY)!! - var passedList = ArrayList() - + routineName = intent.getStringExtra(SAVED_NAME) + playlist = intent.getStringExtra(SAVED_PLAYLIST) // Set the layout of the list of workouts presented to the user layoutManager = LinearLayoutManager(this) workoutList.layoutManager = layoutManager - - // Populate the list with the workouts associated with this routine exerciseViewModel.getRoutine(passedRoutineID) exerciseViewModel.routine.observe(this, Observer { val routine = it ?: return@Observer - routineName.setText(routine.name) - if (routine.playlist != null) { - routinePlaylist.setText(routine.playlist) + if (routineName != null) { + routineNameText.setText(routineName) + routinePlaylist.setText(playlist) + } else { + routineName = routine.name + } + routineNameText.setText(routineName) + if (playlist != null) { + routinePlaylist.setText(playlist) + } else if (routine.playlist != null) { + playlist = routine.playlist + routinePlaylist.setText(playlist) } else { routinePlaylist.setText(BLANK) } if (routine.workoutList != null) { - placeholderText.visibility = View.GONE - workoutList.visibility = View.VISIBLE - passedList = routine.workoutList - exerciseViewModel.getWorkouts(routine.workoutList) + if (routine.workoutList.isNotEmpty()) { + spinner.visibility = View.VISIBLE + exercises = routine.workoutList + exerciseViewModel.getWorkouts(exercises!!) + } } }) exerciseViewModel.workoutList.observe(this, Observer { val workList = it ?: return@Observer - workoutList.adapter = WorkoutAdapter(this, workList, passedRoutineID, passedList) + workoutList.adapter = WorkoutAdapter(this, workList, passedRoutineID, exercises!!) + placeholderText.visibility = View.GONE + workoutList.visibility = View.VISIBLE spinner.visibility = View.GONE }) @@ -134,32 +148,27 @@ class WorkoutRoutineActivity : AppCompatActivity() { // then return to their Home screen startWorkout.setOnClickListener { // Check if the routine name is empty - var newRoutineName = NEW_ROUTINE - if (routineName.text.isNotEmpty()) { - newRoutineName = routineName.text.toString() - } - save() + saveRoutine() val intent = Intent(this, CurrentWorkoutActivity::class.java) - intent.putExtra(EXTRA_STRING, newRoutineName) + intent.putExtra(EXTRA_STRING, routineName) intent.putExtra(EXTRA_ROUTINE, passedRoutineID) - intent.putExtra(EXTRA_LIST, passedList) + intent.putExtra(EXTRA_LIST, exercises) startActivity(intent) } // Navigate to a screen to make a new workout newExercise.setOnClickListener { - save() val intent = Intent(this, WorkoutTemplateActivity::class.java) intent.putExtra(EXTRA_ROUTINE, passedRoutineID) intent.putExtra(EXTRA_IDENTITY, NEW_ID) intent.putExtra(WorkoutTemplateActivity.EXTRA_STRING, getText(R.string.new_exercise)) - intent.putExtra(WorkoutTemplateActivity.EXTRA_LIST, passedList) + intent.putExtra(WorkoutTemplateActivity.EXTRA_LIST, exercises) startActivity(intent) } // Save the current Routine and go back to the user's Home screen saveWorkout.setOnClickListener { - save() + saveRoutine() finish() } @@ -168,7 +177,7 @@ class WorkoutRoutineActivity : AppCompatActivity() { exerciseViewModel.deleteRoutine(passedRoutineID) Toast.makeText( applicationContext, - "This workout has been removed from your list", + "This template has been removed from your list", Toast.LENGTH_SHORT ).show() finish() @@ -178,22 +187,35 @@ class WorkoutRoutineActivity : AppCompatActivity() { override fun onPause() { super.onPause() - save() + tempSave() + } + + private fun tempSave() { + val n: String? = if (routineNameText.text.isNotEmpty()) + routineNameText.text.toString() + else + routineName + val p: String? = if (routinePlaylist.text.isNotEmpty()) + routinePlaylist.text.toString() + else + playlist + intent.putExtra(SAVED_NAME, n) + intent.putExtra(SAVED_PLAYLIST, p) } /** * Save the current routine */ - private fun save() { - var newRoutineName = NEW_ROUTINE - if (routineName.text.isNotEmpty()) { - newRoutineName = routineName.text.toString() + private fun saveRoutine() { + routineName = NEW_ROUTINE + if (routineNameText.text.isNotEmpty()) { + routineName = routineNameText.text.toString() } var newRoutinePlaylist = BLANK if (routinePlaylist.text!!.isNotEmpty()) { newRoutinePlaylist = routinePlaylist.text.toString() } - exerciseViewModel.updateRoutine(newRoutineName, newRoutinePlaylist, passedRoutineID) + exerciseViewModel.updateRoutine(routineName!!, newRoutinePlaylist, passedRoutineID) } /** @@ -225,9 +247,10 @@ class WorkoutRoutineActivity : AppCompatActivity() { } companion object { - const val DEFAULT_DESC = "Workout Description" const val EXTRA_ROUTINE = "passed routine id" const val NEW_ID = "NEW" + const val SAVED_NAME = "saved template name" + const val SAVED_PLAYLIST = "saved playlist" } } \ No newline at end of file diff --git a/app/src/main/java/com/symphony/mrfit/ui/WorkoutTemplateActivity.kt b/app/src/main/java/com/symphony/mrfit/ui/WorkoutTemplateActivity.kt index 9e9fd2f..08e8108 100644 --- a/app/src/main/java/com/symphony/mrfit/ui/WorkoutTemplateActivity.kt +++ b/app/src/main/java/com/symphony/mrfit/ui/WorkoutTemplateActivity.kt @@ -1,7 +1,7 @@ /* - * Created by Team Symphony on 4/1/23, 7:44 PM + * Created by Team Symphony on 4/22/23, 7:14 PM * Copyright (c) 2023 . All rights reserved. - * Last modified 4/1/23, 7:41 PM + * Last modified 4/22/23, 7:14 PM */ package com.symphony.mrfit.ui @@ -12,6 +12,7 @@ import android.content.Intent import android.os.Bundle import android.util.Log import android.view.View +import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer @@ -187,6 +188,11 @@ class WorkoutTemplateActivity : AppCompatActivity() { deleteButton.setOnClickListener { passedList!!.remove(passedWorkoutID) exerciseViewModel.updateRoutineWorkoutList(passedRoutineID!!, passedList) + Toast.makeText( + applicationContext, + "This workout has been removed from your template", + Toast.LENGTH_SHORT + ).show() finish() } @@ -222,7 +228,7 @@ class WorkoutTemplateActivity : AppCompatActivity() { .child(ExerciseRepository.EXERCISE_PICTURE) .child(exercise.exerciseID!!) ) - .placeholder(R.drawable.cactuar) + .placeholder(R.drawable.glide_placeholder) .into(exeCard.exerciseImage) exeCard.exerciseNameTextView.text = exercise.name exeCard.exerciseTagsTextView.text = exercise.tags.toString() diff --git a/app/src/main/res/layout/activity_current_workout.xml b/app/src/main/res/layout/activity_current_workout.xml index 133ee4b..2f1537f 100644 --- a/app/src/main/res/layout/activity_current_workout.xml +++ b/app/src/main/res/layout/activity_current_workout.xml @@ -1,12 +1,13 @@ diff --git a/app/src/main/res/layout/activity_custom_exercises.xml b/app/src/main/res/layout/activity_custom_exercises.xml index 7b2bff5..9720ce2 100644 --- a/app/src/main/res/layout/activity_custom_exercises.xml +++ b/app/src/main/res/layout/activity_custom_exercises.xml @@ -1,12 +1,13 @@ diff --git a/app/src/main/res/layout/activity_exercise.xml b/app/src/main/res/layout/activity_exercise.xml index 5a040ec..290e077 100644 --- a/app/src/main/res/layout/activity_exercise.xml +++ b/app/src/main/res/layout/activity_exercise.xml @@ -1,19 +1,21 @@ diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index 6c6738f..28d33ee 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -1,8 +1,8 @@ - + + tools:context=".ui.ManualWorkoutActivity"> diff --git a/app/src/main/res/layout/activity_post_workout.xml b/app/src/main/res/layout/activity_post_workout.xml index d34401a..5f19ff1 100644 --- a/app/src/main/res/layout/activity_post_workout.xml +++ b/app/src/main/res/layout/activity_post_workout.xml @@ -1,13 +1,14 @@ @@ -39,7 +40,6 @@ android:gravity="center" android:maxLines="2" android:text="Good job!" - android:textColor="#000000" android:textSize="24sp" /> + android:layout_margin="10dp" /> diff --git a/app/src/main/res/layout/activity_register.xml b/app/src/main/res/layout/activity_register.xml index f09f774..1484b7c 100644 --- a/app/src/main/res/layout/activity_register.xml +++ b/app/src/main/res/layout/activity_register.xml @@ -1,13 +1,14 @@ diff --git a/app/src/main/res/layout/activity_routine_selection.xml b/app/src/main/res/layout/activity_routine_selection.xml index ec3be1f..b682128 100644 --- a/app/src/main/res/layout/activity_routine_selection.xml +++ b/app/src/main/res/layout/activity_routine_selection.xml @@ -1,13 +1,14 @@ diff --git a/app/src/main/res/layout/activity_user_profile.xml b/app/src/main/res/layout/activity_user_profile.xml index dd950a8..0adfb7d 100644 --- a/app/src/main/res/layout/activity_user_profile.xml +++ b/app/src/main/res/layout/activity_user_profile.xml @@ -1,13 +1,14 @@ @@ -15,7 +16,9 @@ + android:layout_height="match_parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> diff --git a/app/src/main/res/layout/activity_workout_routine.xml b/app/src/main/res/layout/activity_workout_routine.xml index 1a09085..54c7e7a 100644 --- a/app/src/main/res/layout/activity_workout_routine.xml +++ b/app/src/main/res/layout/activity_workout_routine.xml @@ -1,13 +1,14 @@ + android:textAlignment="center" + android:textColor="@color/black" + android:textColorHint="@color/black" /> + android:layout_weight="1" + android:textColorHint="@color/material_dynamic_neutral40"> + android:hint="@string/workout_playlist" + android:textColor="@color/black" + android:textColorHint="@color/black" />