From bed7fbb88d68283b6d20c1f91c8af180d37cd5c6 Mon Sep 17 00:00:00 2001 From: Tyler Lopez <77797048+Tyler-Lopez@users.noreply.github.com> Date: Wed, 15 Feb 2023 20:11:01 -0500 Subject: [PATCH] Update usage of Strava API to use "sport_type" instead of "type" (#25) * This commit updates usage of Strava API to use "sport_type" instead of "type" * To translate complicated new sport types, an enum class SportType is used instead of storing a String for the type which was used previously. --- app/build.gradle | 4 +- .../data/database/AthleteDatabase.kt | 2 +- .../data/entities/ActivityEntity.kt | 3 +- .../data/remote/responses/ActivityResponse.kt | 46 ++----- .../activityartapp/domain/models/Activity.kt | 5 +- .../GetActivitiesByYearFromRemote.kt | 1 + .../activities/InsertActivitiesIntoDisk.kt | 2 +- .../presentation/MainActivity.kt | 3 +- .../activityartapp/presentation/MainModels.kt | 7 +- .../editArtScreen/EditArtModels.kt | 9 +- .../editArtScreen/EditArtViewModel.kt | 4 +- .../filters/EditArtFiltersScreen.kt | 3 +- .../composables/FilterSectionActivityType.kt | 5 +- .../saveArtScreen/SaveArtViewModel.kt | 15 +-- .../util/ActivitiesParcelizerUtils.kt | 2 +- .../util/ActivityFilterUtils.kt | 22 ++-- .../activityartapp/util/ActivitySortUtils.kt | 2 +- .../activityartapp/util/ParcelableActivity.kt | 3 +- .../activityartapp/util/enums/SportType.kt | 118 ++++++++++++++++++ app/src/main/res/values/strings.xml | 53 ++++++++ .../util/ActivityFilterUtilsTest.kt | 27 ++-- .../util/ActivitySortUtilsTest.kt | 17 +-- 22 files changed, 251 insertions(+), 102 deletions(-) create mode 100644 app/src/main/java/com/activityartapp/util/enums/SportType.kt diff --git a/app/build.gradle b/app/build.gradle index 2baa0b74..424849fc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,8 +18,8 @@ android { applicationId "com.activityartapp" minSdk 26 targetSdk 33 - versionCode 9 - versionName "1.2.1" + versionCode 10 + versionName "1.3.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/java/com/activityartapp/data/database/AthleteDatabase.kt b/app/src/main/java/com/activityartapp/data/database/AthleteDatabase.kt index 75337967..f6204a5e 100644 --- a/app/src/main/java/com/activityartapp/data/database/AthleteDatabase.kt +++ b/app/src/main/java/com/activityartapp/data/database/AthleteDatabase.kt @@ -18,7 +18,7 @@ import com.activityartapp.data.entities.OAuth2Entity @Database( entities = [ActivityEntity::class, AthleteCacheDictionaryEntity::class, OAuth2Entity::class], - version = 2 + version = 3 ) @TypeConverters(Converters::class) abstract class AthleteDatabase : RoomDatabase() { diff --git a/app/src/main/java/com/activityartapp/data/entities/ActivityEntity.kt b/app/src/main/java/com/activityartapp/data/entities/ActivityEntity.kt index 73c8f452..e6740331 100644 --- a/app/src/main/java/com/activityartapp/data/entities/ActivityEntity.kt +++ b/app/src/main/java/com/activityartapp/data/entities/ActivityEntity.kt @@ -3,6 +3,7 @@ package com.activityartapp.data.entities import androidx.room.Entity import androidx.room.PrimaryKey import com.activityartapp.domain.models.Activity +import com.activityartapp.util.enums.SportType @Entity data class ActivityEntity( @@ -22,5 +23,5 @@ data class ActivityEntity( override val sufferScore: Int?, override val iso8601LocalDate: String, override val summaryPolyline: String?, - override val type: String, // "Ride" + override val sportType: SportType, ) : Activity \ No newline at end of file diff --git a/app/src/main/java/com/activityartapp/data/remote/responses/ActivityResponse.kt b/app/src/main/java/com/activityartapp/data/remote/responses/ActivityResponse.kt index 6c4ae237..23751ee4 100644 --- a/app/src/main/java/com/activityartapp/data/remote/responses/ActivityResponse.kt +++ b/app/src/main/java/com/activityartapp/data/remote/responses/ActivityResponse.kt @@ -1,6 +1,7 @@ package com.activityartapp.data.remote.responses import com.activityartapp.domain.models.Activity +import com.activityartapp.util.enums.SportType import com.google.gson.annotations.SerializedName data class ActivityResponse( @@ -26,54 +27,21 @@ data class ActivityResponse( override val movingTime: Int, @SerializedName("name") override val name: String, - @SerializedName("type") - override val type: String, + @SerializedName("sport_type") + val sportTypeRaw: String, @SerializedName("start_date_local") override val iso8601LocalDate: String, @SerializedName("suffer_score") override val sufferScore: Int?, - - val achievement_count: Int, val athlete: AthleteWithResourceState, - val athlete_count: Int, - val average_cadence: Double, - val comment_count: Int, - val commute: Boolean, - val display_hide_heartrate_option: Boolean, - val elapsed_time: Int, - val elev_high: Double, - val elev_low: Double, - val end_latlng: List, - val external_id: String, - val flagged: Boolean, - val from_accepted_tag: Boolean, - val has_heartrate: Boolean, - val has_kudoed: Boolean, - val heartrate_opt_out: Boolean, - val manual: Boolean, - val map: Map?, - val photo_count: Int, - val pr_count: Int, - val `private`: Boolean, - val resource_state: Int, - val start_date: String, - val start_latitude: Double, - val start_latlng: List, - val start_longitude: Double, - val timezone: String, - val total_elevation_gain: Double, - val total_photo_count: Int, - val trainer: Boolean, - val upload_id: Long, - val upload_id_str: String, - val utc_offset: Double, - val visibility: String, - val workout_type: Int + val map: Map? ) : Activity { - override val athleteId: Long get() = athlete.id override val summaryPolyline: String? get() = map?.summary_polyline + + override val sportType: SportType + get() = SportType.fromSportTypeString(sportTypeRaw) } \ No newline at end of file diff --git a/app/src/main/java/com/activityartapp/domain/models/Activity.kt b/app/src/main/java/com/activityartapp/domain/models/Activity.kt index 1c6cacd1..6b40f738 100644 --- a/app/src/main/java/com/activityartapp/domain/models/Activity.kt +++ b/app/src/main/java/com/activityartapp/domain/models/Activity.kt @@ -1,5 +1,7 @@ package com.activityartapp.domain.models +import com.activityartapp.util.enums.SportType + interface Activity { val athleteId: Long val averageSpeed: Double @@ -16,5 +18,6 @@ interface Activity { val name: String // "Happy Friday" val sufferScore: Int? val summaryPolyline: String? - val type: String // "Ride" + val sportType: SportType + } \ No newline at end of file diff --git a/app/src/main/java/com/activityartapp/domain/useCase/activities/GetActivitiesByYearFromRemote.kt b/app/src/main/java/com/activityartapp/domain/useCase/activities/GetActivitiesByYearFromRemote.kt index 63a90c90..7dc2971f 100644 --- a/app/src/main/java/com/activityartapp/domain/useCase/activities/GetActivitiesByYearFromRemote.kt +++ b/app/src/main/java/com/activityartapp/domain/useCase/activities/GetActivitiesByYearFromRemote.kt @@ -74,6 +74,7 @@ class GetActivitiesByYearFromRemote @Inject constructor( activities.addAll(data) } .doOnError { + println("Here, an error occurred, that error was ${this.exception}") return Response.Error(data = activities, exception = this.exception) } } diff --git a/app/src/main/java/com/activityartapp/domain/useCase/activities/InsertActivitiesIntoDisk.kt b/app/src/main/java/com/activityartapp/domain/useCase/activities/InsertActivitiesIntoDisk.kt index 7cbccd9f..c913af46 100644 --- a/app/src/main/java/com/activityartapp/domain/useCase/activities/InsertActivitiesIntoDisk.kt +++ b/app/src/main/java/com/activityartapp/domain/useCase/activities/InsertActivitiesIntoDisk.kt @@ -42,7 +42,7 @@ class InsertActivitiesIntoDisk @Inject constructor( sufferScore, iso8601LocalDate, summaryPolyline, - type + sportType ) } } diff --git a/app/src/main/java/com/activityartapp/presentation/MainActivity.kt b/app/src/main/java/com/activityartapp/presentation/MainActivity.kt index 7837826f..805c4886 100644 --- a/app/src/main/java/com/activityartapp/presentation/MainActivity.kt +++ b/app/src/main/java/com/activityartapp/presentation/MainActivity.kt @@ -162,10 +162,11 @@ class MainActivity : ComponentActivity(), Router { private fun navigateSaveArt(destination: NavigateSaveArt) { destination.apply { + println("yo here, the json is ${gson.toJson(activityTypes)}") navController.navigate( route = SaveArt.withArgs( args = arrayOf( - ActivityTypes to gson.toJson(activityTypes), + ActivityTypes to gson.toJson(activityTypes.map { it.toString() }), BackgroundType to backgroundType.toString(), ColorActivitiesArgb to colorActivitiesArgb.toString(), ColorsBackgroundArgb to gson.toJson(backgroundColorsArgb), diff --git a/app/src/main/java/com/activityartapp/presentation/MainModels.kt b/app/src/main/java/com/activityartapp/presentation/MainModels.kt index 377ecbc4..8822143e 100644 --- a/app/src/main/java/com/activityartapp/presentation/MainModels.kt +++ b/app/src/main/java/com/activityartapp/presentation/MainModels.kt @@ -6,10 +6,7 @@ import com.activityartapp.architecture.ViewEvent import com.activityartapp.architecture.ViewState import com.activityartapp.presentation.editArtScreen.StrokeWidthType import com.activityartapp.presentation.errorScreen.ErrorScreenType -import com.activityartapp.util.enums.BackgroundType -import com.activityartapp.util.enums.EditArtSortDirectionType -import com.activityartapp.util.enums.EditArtSortType -import com.activityartapp.util.enums.FontSizeType +import com.activityartapp.util.enums.* sealed interface MainViewState : ViewState { object Unauthenticated : MainViewState @@ -34,7 +31,7 @@ sealed interface MainDestination : Destination { ) : MainDestination data class NavigateSaveArt( - val activityTypes: List, + val activityTypes: List, val backgroundType: BackgroundType, val backgroundColorsArgb: List, val colorActivitiesArgb: Int, diff --git a/app/src/main/java/com/activityartapp/presentation/editArtScreen/EditArtModels.kt b/app/src/main/java/com/activityartapp/presentation/editArtScreen/EditArtModels.kt index 78acc6c0..757f03a8 100644 --- a/app/src/main/java/com/activityartapp/presentation/editArtScreen/EditArtModels.kt +++ b/app/src/main/java/com/activityartapp/presentation/editArtScreen/EditArtModels.kt @@ -87,7 +87,7 @@ sealed interface EditArtViewEvent : ViewEvent { } } - data class FilterTypeToggled(val type: String) : FilterChanged { + data class FilterTypeToggled(val type: SportType) : FilterChanged { override val filterType: EditArtFilterType get() = EditArtFilterType.TYPE } @@ -179,7 +179,7 @@ sealed interface EditArtViewState : ViewState { val filterDistanceTotalEnd: Double? = null, @IgnoredOnParcel val filterDistancePendingChangeStart: String? = null, @IgnoredOnParcel val filterDistancePendingChangeEnd: String? = null, - val filterTypes: Map? = null, + val filterTypes: Map? = null, @IgnoredOnParcel override val pagerStateWrapper: PagerStateWrapper = PagerStateWrapper( pagerHeaders = EditArtHeaderType.values().toList(), pagerState = PagerState(EditArtHeaderType.values().toList().size), @@ -274,10 +274,7 @@ sealed interface EditArtViewState : ViewState { ) != NO_ACTIVITIES_COUNT @IgnoredOnParcel - val filterDateSelectionUnset = filterDateSelectionIndex == INIT_SELECTION_INDEX - - @IgnoredOnParcel - val filteredTypes: List + val filteredTypes: List get() = filterTypes?.entries?.filter { it.value }?.map { it.key } ?: emptyList() val filteredDistanceRangeMeters: IntRange diff --git a/app/src/main/java/com/activityartapp/presentation/editArtScreen/EditArtViewModel.kt b/app/src/main/java/com/activityartapp/presentation/editArtScreen/EditArtViewModel.kt index 7b524aa7..531ca2a7 100644 --- a/app/src/main/java/com/activityartapp/presentation/editArtScreen/EditArtViewModel.kt +++ b/app/src/main/java/com/activityartapp/presentation/editArtScreen/EditArtViewModel.kt @@ -87,7 +87,7 @@ class EditArtViewModel @Inject constructor( private val activitiesSummedDistance: Double get() = activitiesFiltered.sumOf { it.distance } /** Updates [activitiesFilteredByFilterType] for a given [EditArtFilterType]. - * Designates which activities this particular filter type is in-charge of filtering. **/ + * Designates which activities this particular filter sportType is in-charge of filtering. **/ private fun EditArtFilterType.updateFilteredActivities() { withLastState { val prevActivities = activitiesFilteredByFilterType[lastFilter] ?: activities @@ -203,7 +203,7 @@ class EditArtViewModel @Inject constructor( * the various saved filters. **/ it.updateFilteredActivities() } else { - /** Otherwise, simply initialize filtered activities for each type as all activities and + /** Otherwise, simply initialize filtered activities for each sportType as all activities and * initialize filters. **/ activitiesFilteredByFilterType[it] = activities it.pushUpdatedFilteredActivityCountToView() diff --git a/app/src/main/java/com/activityartapp/presentation/editArtScreen/subscreens/filters/EditArtFiltersScreen.kt b/app/src/main/java/com/activityartapp/presentation/editArtScreen/subscreens/filters/EditArtFiltersScreen.kt index a1b479f2..c1e1026a 100644 --- a/app/src/main/java/com/activityartapp/presentation/editArtScreen/subscreens/filters/EditArtFiltersScreen.kt +++ b/app/src/main/java/com/activityartapp/presentation/editArtScreen/subscreens/filters/EditArtFiltersScreen.kt @@ -10,6 +10,7 @@ import com.activityartapp.presentation.editArtScreen.EditArtFilterType.* import com.activityartapp.presentation.editArtScreen.EditArtViewEvent import com.activityartapp.presentation.editArtScreen.subscreens.filters.composables.FilterSectionDate import com.activityartapp.presentation.editArtScreen.subscreens.filters.composables.FilterSectionDistances +import com.activityartapp.util.enums.SportType @Composable fun ColumnScope.EditArtFiltersScreen( @@ -22,7 +23,7 @@ fun ColumnScope.EditArtFiltersScreen( distanceTotal: ClosedFloatingPointRange?, distancePendingChangeStart: String?, distancePendingChangeEnd: String?, - typesWithSelectedFlag: List>?, + typesWithSelectedFlag: List>?, eventReceiver: EventReceiver ) { EditArtFilterType.values().onEach { diff --git a/app/src/main/java/com/activityartapp/presentation/editArtScreen/subscreens/filters/composables/FilterSectionActivityType.kt b/app/src/main/java/com/activityartapp/presentation/editArtScreen/subscreens/filters/composables/FilterSectionActivityType.kt index 7e492662..160431c1 100644 --- a/app/src/main/java/com/activityartapp/presentation/editArtScreen/subscreens/filters/composables/FilterSectionActivityType.kt +++ b/app/src/main/java/com/activityartapp/presentation/editArtScreen/subscreens/filters/composables/FilterSectionActivityType.kt @@ -14,11 +14,12 @@ import com.activityartapp.architecture.EventReceiver import com.activityartapp.presentation.editArtScreen.EditArtViewEvent import com.activityartapp.presentation.ui.theme.spacing import com.activityartapp.presentation.editArtScreen.subscreens.filters.composables.FilterSection +import com.activityartapp.util.enums.SportType @Composable fun ColumnScope.FilterSectionActivityType( count: Int, - typesWithSelectedFlag: List>, + typesWithSelectedFlag: List>, eventReceiver: EventReceiver ) { FilterSection( @@ -41,7 +42,7 @@ fun ColumnScope.FilterSectionActivityType( ) }) Text( - text = typeMap.first, + text = stringResource(typeMap.first.stringRes), style = MaterialTheme.typography.body1 ) } diff --git a/app/src/main/java/com/activityartapp/presentation/saveArtScreen/SaveArtViewModel.kt b/app/src/main/java/com/activityartapp/presentation/saveArtScreen/SaveArtViewModel.kt index 4a5d2059..3d638a3c 100644 --- a/app/src/main/java/com/activityartapp/presentation/saveArtScreen/SaveArtViewModel.kt +++ b/app/src/main/java/com/activityartapp/presentation/saveArtScreen/SaveArtViewModel.kt @@ -17,10 +17,8 @@ import com.activityartapp.presentation.saveArtScreen.SaveArtViewState.Standby.Do import com.activityartapp.presentation.saveArtScreen.SaveArtViewEvent.* import com.activityartapp.util.* import com.activityartapp.util.NavArgSpecification.* +import com.activityartapp.util.enums.* import com.activityartapp.util.enums.BackgroundType -import com.activityartapp.util.enums.EditArtSortDirectionType -import com.activityartapp.util.enums.EditArtSortType -import com.activityartapp.util.enums.FontSizeType import com.google.gson.Gson import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers @@ -40,10 +38,12 @@ class SaveArtViewModel @Inject constructor( ssh: SavedStateHandle, ) : BaseRoutingViewModel() { - private val activityTypes = gson.fromJson>( - ActivityTypes.rawArg(ssh), - List::class.java - ) + private val activityTypes = gson + .fromJson>( + ActivityTypes.rawArg(ssh), + List::class.java + ) + .map { SportType.valueOf(it) } private val activities = getActivitiesFromMemory() private val backgroundType = BackgroundType.valueOf(NavArgSpecification.BackgroundType.rawArg(ssh)) @@ -163,6 +163,7 @@ class SaveArtViewModel @Inject constructor( } private fun createArtBitmapOfSize(isPreview: Boolean, size: Size): Bitmap { + println("here, activity types are $activityTypes") return visualizationUtils.createBitmap( activities = activityFilterUtils.filterActivities( activities = activities, diff --git a/app/src/main/java/com/activityartapp/util/ActivitiesParcelizerUtils.kt b/app/src/main/java/com/activityartapp/util/ActivitiesParcelizerUtils.kt index 68705ecb..4f43eddd 100644 --- a/app/src/main/java/com/activityartapp/util/ActivitiesParcelizerUtils.kt +++ b/app/src/main/java/com/activityartapp/util/ActivitiesParcelizerUtils.kt @@ -20,7 +20,7 @@ fun List.parcelize(): List { it.name, it.sufferScore, it.summaryPolyline, - it.type + it.sportType ) } } \ No newline at end of file diff --git a/app/src/main/java/com/activityartapp/util/ActivityFilterUtils.kt b/app/src/main/java/com/activityartapp/util/ActivityFilterUtils.kt index 3abffd2d..1aa6191f 100644 --- a/app/src/main/java/com/activityartapp/util/ActivityFilterUtils.kt +++ b/app/src/main/java/com/activityartapp/util/ActivityFilterUtils.kt @@ -1,9 +1,8 @@ package com.activityartapp.util -import android.util.Range import com.activityartapp.domain.models.Activity import com.activityartapp.presentation.editArtScreen.DateSelection -import com.activityartapp.presentation.editArtScreen.EditArtViewModel +import com.activityartapp.util.enums.SportType import java.util.concurrent.TimeUnit import javax.inject.Inject import kotlin.math.roundToInt @@ -18,12 +17,13 @@ class ActivityFilterUtils @Inject constructor( fun filterActivities( activities: List, - includeActivityTypes: Collection, + includeActivityTypes: Collection, unixMsRange: LongProgression, distanceRange: IntRange ): List { println(unixMsRange) return activities.filter { + println("checking to see if ${it.sportType} is in $includeActivityTypes") activityWithinDistanceRange(it, distanceRange) && activityWithinUnixMs(it, unixMsRange) && activityTypeContainedWithinTypes(it, includeActivityTypes) @@ -46,8 +46,12 @@ class ActivityFilterUtils @Inject constructor( fun activityTypeContainedWithinTypes( activity: Activity, - types: Collection - ): Boolean = types.contains(activity.type) + types: Collection + ): Boolean = types.contains(activity.sportType).also { + println("result $it types was $types") + println("activity sport type ${activity.sportType}") + println("sport type in types: ${types.contains(activity.sportType)}") + } /** * Provided a [List] of [Activity], returns all possible [DateSelection]. Returns null @@ -96,12 +100,12 @@ class ActivityFilterUtils @Inject constructor( fun getPossibleActivityTypes( activities: List, - filterTypesPrevious: Map? - ): Map? { + filterTypesPrevious: Map? + ): Map? { return activities .takeIf { it.isNotEmpty() } - ?.distinctBy(Activity::type) - ?.map(Activity::type) + ?.distinctBy(Activity::sportType) + ?.map(Activity::sportType) ?.sorted() ?.associateWith { filterTypesPrevious?.get(it) ?: DEFAULT_ACTIVITY_TYPE_SELECTION diff --git a/app/src/main/java/com/activityartapp/util/ActivitySortUtils.kt b/app/src/main/java/com/activityartapp/util/ActivitySortUtils.kt index a15df2f2..479fa3b1 100644 --- a/app/src/main/java/com/activityartapp/util/ActivitySortUtils.kt +++ b/app/src/main/java/com/activityartapp/util/ActivitySortUtils.kt @@ -18,7 +18,7 @@ class ActivitySortUtils @Inject constructor( when (sortType) { EditArtSortType.DATE -> timeUtils.iso8601StringToUnixSecond(it.iso8601LocalDate) EditArtSortType.DISTANCE -> it.distance - EditArtSortType.TYPE -> it.type + EditArtSortType.TYPE -> it.sportType } }) .run { diff --git a/app/src/main/java/com/activityartapp/util/ParcelableActivity.kt b/app/src/main/java/com/activityartapp/util/ParcelableActivity.kt index e43cc062..6dd1ffe9 100644 --- a/app/src/main/java/com/activityartapp/util/ParcelableActivity.kt +++ b/app/src/main/java/com/activityartapp/util/ParcelableActivity.kt @@ -2,6 +2,7 @@ package com.activityartapp.util import android.os.Parcelable import com.activityartapp.domain.models.Activity +import com.activityartapp.util.enums.SportType import kotlinx.parcelize.Parcelize @Parcelize @@ -21,5 +22,5 @@ data class ParcelableActivity( override val name: String, override val sufferScore: Int?, override val summaryPolyline: String?, - override val type: String + override val sportType: SportType ) : Activity, Parcelable diff --git a/app/src/main/java/com/activityartapp/util/enums/SportType.kt b/app/src/main/java/com/activityartapp/util/enums/SportType.kt new file mode 100644 index 00000000..51a17d24 --- /dev/null +++ b/app/src/main/java/com/activityartapp/util/enums/SportType.kt @@ -0,0 +1,118 @@ +package com.activityartapp.util.enums + +import androidx.annotation.StringRes +import com.activityartapp.R + +/** + * Last updated 2/15/2023 + * https://developers.strava.com/docs/reference/#api-models-SportType + */ +enum class SportType(@StringRes val stringRes: Int) { + ALPINE_SKI(R.string.sport_type_alpine_ski), + BACKCOUNTRY_SKI(R.string.sport_type_backcountry_ski), + BADMINTON(R.string.sport_type_badminton), + CANOEING(R.string.sport_type_canoeing), + CROSSFIT(R.string.sport_type_crossfit), + EBIKE_RIDE(R.string.sport_type_ebike_ride), + ELLIPTICAL(R.string.sport_type_elliptical), + EMOUNTAINBIKE_RIDE(R.string.sport_type_emountainbike_ride), + GOLF(R.string.sport_type_golf), + GRAVEL_RIDE(R.string.sport_type_gravel_ride), + HAND_CYCLE(R.string.sport_type_hand_cycle), + HIGH_INTENSITY_INTERVAL_TRAINING(R.string.sport_type_high_intensity_interval_training), + HIKE(R.string.sport_type_hike), + ICE_SKATE(R.string.sport_type_ice_skate), + INLINE_SKATE(R.string.sport_type_inline_skate), + KAYAKING(R.string.sport_type_kayaking), + KITE_SURF(R.string.sport_type_kite_surf), + MOUNTAIN_BIKE_RIDE(R.string.sport_type_mountainbike_ride), + NORDIC_SKI(R.string.sport_type_nordic_ski), + PICKLE_BALL(R.string.sport_type_pickle_ball), + PILATES(R.string.sport_type_pilates), + RACQUETBALL(R.string.sport_type_racquetball), + RIDE(R.string.sport_type_ride), + ROCK_CLIMBING(R.string.sport_type_rock_climbing), + ROLLER_SKI(R.string.sport_type_roller_ski), + ROWING(R.string.sport_type_rowing), + RUN(R.string.sport_type_run), + SAIL(R.string.sport_type_sail), + SKATEBOARD(R.string.sport_type_skateboard), + SNOWBOARD(R.string.sport_type_snowboard), + SNOWSHOE(R.string.sport_type_snowshoe), + SOCCER(R.string.sport_type_soccer), + SQUASH(R.string.sport_type_squash), + STAIR_STEPPER(R.string.sport_type_stair_stepper), + STAND_UP_PADDLING(R.string.sport_type_stand_up_paddling), + SURFING(R.string.sport_type_surfing), + SWIM(R.string.sport_type_swim), + TABLE_TENNIS(R.string.sport_type_table_tennis), + TENNIS(R.string.sport_type_tennis), + TRAIL_RUN(R.string.sport_type_trail_run), + VELO_MOBILE(R.string.sport_type_velo_mobile), + VIRTUAL_RIDE(R.string.sport_type_virtual_ride), + VIRTUAL_ROW(R.string.sport_type_virtual_row), + VIRTUAL_RUN(R.string.sport_type_virtual_run), + WALK(R.string.sport_type_walk), + WEIGHT_TRAINING(R.string.sport_type_weight_training), + WHEEL_CHAIR(R.string.sport_type_wheel_chair), + WIND_SURF(R.string.sport_type_wind_surf), + WORKOUT(R.string.sport_type_workout), + YOGA(R.string.sport_type_yoga); + + companion object { + fun fromSportTypeString(value: String): SportType { + return when (value) { + "AlpineSki" -> ALPINE_SKI + "BackcountrySki" -> BACKCOUNTRY_SKI + "Badminton" -> BADMINTON + "Canoeing" -> CANOEING + "Crossfit" -> CROSSFIT + "EBikeRide" -> EBIKE_RIDE + "Elliptical" -> ELLIPTICAL + "EMountainBikeRide" -> EMOUNTAINBIKE_RIDE + "Golf" -> GOLF + "GravelRide" -> GRAVEL_RIDE + "Handcycle" -> HAND_CYCLE + "HighIntensityIntervalTraining" -> HIGH_INTENSITY_INTERVAL_TRAINING + "Hike" -> HIKE + "IceSkate" -> ICE_SKATE + "InlineSkate" -> INLINE_SKATE + "Kayaking" -> KAYAKING + "Kitesurf" -> KITE_SURF + "MountainBikeRide" -> MOUNTAIN_BIKE_RIDE + "NordicSki" -> NORDIC_SKI + "Pickleball" -> PICKLE_BALL + "Pilates" -> PILATES + "Racquetball" -> RACQUETBALL + "Ride" -> RIDE + "RockClimbing" -> ROCK_CLIMBING + "RollerSki" -> ROLLER_SKI + "Rowing" -> ROWING + "Run" -> RUN + "Sail" -> SAIL + "Skateboard" -> SKATEBOARD + "Snowboard" -> SNOWBOARD + "Snowshoe" -> SNOWSHOE + "Soccer" -> SOCCER + "Squash" -> SQUASH + "StairStepper" -> STAIR_STEPPER + "StandUpPaddling" -> STAND_UP_PADDLING + "Surfing" -> SURFING + "Swim" -> SWIM + "TableTennis" -> TABLE_TENNIS + "Tennis" -> TENNIS + "TrailRun" -> TRAIL_RUN + "Velomobile" -> VELO_MOBILE + "VirtualRide" -> VIRTUAL_RIDE + "VirtualRow" -> VIRTUAL_ROW + "VirtualRun" -> VIRTUAL_RUN + "Walk" -> WALK + "WeightTraining" -> WEIGHT_TRAINING + "Wheelchair" -> WHEEL_CHAIR + "Windsurf" -> WIND_SURF + "Yoga" -> YOGA + else -> WORKOUT + } + } + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9bd356ba..69477aa1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -312,6 +312,58 @@ Large XL + + Alpine Ski + Backcountry Ski + Badminton + Canoe + CrossFit + Electric Bike Ride + Elliptical + Electric Mountain Bike Ride + Golf + Gravel Ride + Handcycle + High-Intensity Interval Training + Hike + Ice Skate + Inline Skate + Kayak + Kite Surf + Mountain Bike Ride + Nordic Ski + Pickleball + Pilates + Racquetball + Ride + Rock Climb + Roller Ski + Row + Run + Sail + Skateboard + Snowboard + Snowshoe + Soccer + Squash + Stair Stepper + Stand Up Paddle Board + Surf + Swim + Table Tennis + Tennis + Trail Run + Velomobile + Virtual Ride + Virtual Row + Virtual Run + Walk + Weight Train + Wheelchair + Wind Surf + Workout + Yoga + Reconnect with Strava Make Art @@ -324,4 +376,5 @@ Unable to Download We need permission to download your art. When we asked for this permission earlier, you denied it. We aren\'t able to request it again. To grant this permission, open your device\'s settings, find Activity Art, and enable the storage permission. + diff --git a/app/src/test/java/com/activityartapp/util/ActivityFilterUtilsTest.kt b/app/src/test/java/com/activityartapp/util/ActivityFilterUtilsTest.kt index b8665fa6..3443887a 100644 --- a/app/src/test/java/com/activityartapp/util/ActivityFilterUtilsTest.kt +++ b/app/src/test/java/com/activityartapp/util/ActivityFilterUtilsTest.kt @@ -2,6 +2,7 @@ package com.activityartapp.util import com.activityartapp.domain.models.Activity import com.activityartapp.presentation.editArtScreen.DateSelection +import com.activityartapp.util.enums.SportType import org.junit.Assert.* import org.junit.Before import org.junit.Test @@ -26,16 +27,16 @@ class ActivityFilterUtilsTest { private const val ACTIVITY_ONE_DISTANCE = 5.0 private const val ACTIVITY_ONE_ISO8601_LOCAL_DATE = "2018-05-02T05:15:09Z" - private const val ACTIVITY_ONE_TYPE = "Walk" + private val ACTIVITY_ONE_TYPE = SportType.WALK private const val ACTIVITY_TWO_DISTANCE = 5.0 private const val ACTIVITY_TWO_ISO8601_LOCAL_DATE = "2019-05-02T05:15:09Z" - private const val ACTIVITY_TWO_TYPE = "Ride" + private val ACTIVITY_TWO_TYPE = SportType.RIDE private const val ACTIVITY_THREE_DISTANCE = 5.0 private const val ACTIVITY_THREE_ISO8601_LOCAL_DATE = "2020-05-02T05:15:09Z" - private const val ACTIVITY_THREE_TYPE = "Ride" + private val ACTIVITY_THREE_TYPE = SportType.RIDE private const val ACTIVITY_FOUR_DISTANCE = 5.0 private const val ACTIVITY_FOUR_ISO8601_LOCAL_DATE = "2022-05-02T05:15:09Z" - private const val ACTIVITY_FOUR_TYPE = "Ride" + private val ACTIVITY_FOUR_TYPE = SportType.RIDE } private lateinit var activityFilterUtils: ActivityFilterUtils @@ -65,7 +66,7 @@ class ActivityFilterUtilsTest { override val name: String = CONSTANT_NAME override val sufferScore: Int = CONSTANT_SUFFER_SCORE override val summaryPolyline: String = CONSTANT_SUMMARY_POLYLINE - override val type: String = ACTIVITY_ONE_TYPE + override val sportType: SportType = ACTIVITY_ONE_TYPE } activityTwo = object : Activity { override val athleteId: Long = CONSTANT_ATHLETE_ID @@ -83,7 +84,7 @@ class ActivityFilterUtilsTest { override val name: String = CONSTANT_NAME override val sufferScore: Int = CONSTANT_SUFFER_SCORE override val summaryPolyline: String = CONSTANT_SUMMARY_POLYLINE - override val type: String = ACTIVITY_TWO_TYPE + override val sportType: SportType = ACTIVITY_TWO_TYPE } activityThree = object : Activity { override val athleteId: Long = CONSTANT_ATHLETE_ID @@ -101,7 +102,7 @@ class ActivityFilterUtilsTest { override val name: String = CONSTANT_NAME override val sufferScore: Int = CONSTANT_SUFFER_SCORE override val summaryPolyline: String = CONSTANT_SUMMARY_POLYLINE - override val type: String = ACTIVITY_THREE_TYPE + override val sportType: SportType = ACTIVITY_THREE_TYPE } activityFour = object : Activity { override val athleteId: Long = CONSTANT_ATHLETE_ID @@ -119,7 +120,7 @@ class ActivityFilterUtilsTest { override val name: String = CONSTANT_NAME override val sufferScore: Int = CONSTANT_SUFFER_SCORE override val summaryPolyline: String = CONSTANT_SUMMARY_POLYLINE - override val type: String = ACTIVITY_FOUR_TYPE + override val sportType: SportType = ACTIVITY_FOUR_TYPE } activitiesIncludingOnlyActivityOne = listOf(activityOne) activities = listOf(activityOne, activityTwo, activityThree, activityFour) @@ -128,7 +129,7 @@ class ActivityFilterUtilsTest { /** Test [ActivityFilterUtils.filterActivities] **/ @Test fun `Filtering activities when all activities satisfy all criteria is equal to original size`() { - val includeActivityTypes = listOf("Walk") + val includeActivityTypes = listOf(SportType.WALK) val unixRangeMs = Long.MIN_VALUE..Long.MAX_VALUE val distanceRange = Int.MIN_VALUE..Int.MAX_VALUE val filteredActivities = activityFilterUtils.filterActivities( @@ -311,7 +312,7 @@ class ActivityFilterUtilsTest { /** Test [ActivityFilterUtils.activityTypeContainedWithinTypes] **/ @Test fun `Activity type contained within an empty list of types is false`() { - val types: List = listOf() + val types: List = listOf() assertFalse( activityFilterUtils.activityTypeContainedWithinTypes( activityOne, @@ -322,7 +323,7 @@ class ActivityFilterUtilsTest { @Test fun `Activity type contained within a list of other types is false`() { - val types: List = listOf("Ride", "Hike") + val types: List = listOf(SportType.RIDE, SportType.HIKE) assertFalse( activityFilterUtils.activityTypeContainedWithinTypes( activityOne, @@ -333,7 +334,7 @@ class ActivityFilterUtilsTest { @Test fun `Activity type contained within a list of types which include the type is true`() { - val types: List = listOf("Ride", "Walk", "Hike") + val types: List = listOf(SportType.RIDE, SportType.WALK, SportType.HIKE) assertTrue( activityFilterUtils.activityTypeContainedWithinTypes( activityOne, @@ -344,7 +345,7 @@ class ActivityFilterUtilsTest { @Test fun `Activity type contained within a list of types that only contains the type is true`() { - val types: List = listOf("Walk") + val types: List = listOf(SportType.WALK) assertTrue( activityFilterUtils.activityTypeContainedWithinTypes( activityOne, diff --git a/app/src/test/java/com/activityartapp/util/ActivitySortUtilsTest.kt b/app/src/test/java/com/activityartapp/util/ActivitySortUtilsTest.kt index afe32163..1ae7232a 100644 --- a/app/src/test/java/com/activityartapp/util/ActivitySortUtilsTest.kt +++ b/app/src/test/java/com/activityartapp/util/ActivitySortUtilsTest.kt @@ -3,6 +3,7 @@ package com.activityartapp.util import com.activityartapp.domain.models.Activity import com.activityartapp.util.enums.EditArtSortDirectionType import com.activityartapp.util.enums.EditArtSortType +import com.activityartapp.util.enums.SportType import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test @@ -26,16 +27,16 @@ class ActivitySortUtilsTest { private const val ACTIVITY_ONE_DISTANCE = 5.0 private const val ACTIVITY_ONE_ISO8601_LOCAL_DATE = "2018-05-02T05:15:09Z" - private const val ACTIVITY_ONE_TYPE = "Walk" + private val ACTIVITY_ONE_TYPE = SportType.WALK private const val ACTIVITY_TWO_DISTANCE = 10.0 private const val ACTIVITY_TWO_ISO8601_LOCAL_DATE = "2019-05-02T05:15:09Z" - private const val ACTIVITY_TWO_TYPE = "Ride" + private val ACTIVITY_TWO_TYPE = SportType.RIDE private const val ACTIVITY_THREE_DISTANCE = 15.0 private const val ACTIVITY_THREE_ISO8601_LOCAL_DATE = "2020-05-02T05:15:09Z" - private const val ACTIVITY_THREE_TYPE = "Kayaking" + private val ACTIVITY_THREE_TYPE = SportType.KAYAKING private const val ACTIVITY_FOUR_DISTANCE = 5.0 private const val ACTIVITY_FOUR_ISO8601_LOCAL_DATE = "2022-05-02T05:15:09Z" - private const val ACTIVITY_FOUR_TYPE = "Ride" + private val ACTIVITY_FOUR_TYPE = SportType.RIDE } private lateinit var activitySortUtils: ActivitySortUtils @@ -65,7 +66,7 @@ class ActivitySortUtilsTest { override val name: String = CONSTANT_NAME override val sufferScore: Int = CONSTANT_SUFFER_SCORE override val summaryPolyline: String = CONSTANT_SUMMARY_POLYLINE - override val type: String = ACTIVITY_ONE_TYPE + override val sportType: SportType = ACTIVITY_ONE_TYPE } activityTwo = object : Activity { override val athleteId: Long = CONSTANT_ATHLETE_ID @@ -83,7 +84,7 @@ class ActivitySortUtilsTest { override val name: String = CONSTANT_NAME override val sufferScore: Int = CONSTANT_SUFFER_SCORE override val summaryPolyline: String = CONSTANT_SUMMARY_POLYLINE - override val type: String = ACTIVITY_TWO_TYPE + override val sportType: SportType = ACTIVITY_TWO_TYPE } activityThree = object : Activity { override val athleteId: Long = CONSTANT_ATHLETE_ID @@ -101,7 +102,7 @@ class ActivitySortUtilsTest { override val name: String = CONSTANT_NAME override val sufferScore: Int = CONSTANT_SUFFER_SCORE override val summaryPolyline: String = CONSTANT_SUMMARY_POLYLINE - override val type: String = ACTIVITY_THREE_TYPE + override val sportType: SportType = ACTIVITY_THREE_TYPE } activityFour = object : Activity { override val athleteId: Long = CONSTANT_ATHLETE_ID @@ -119,7 +120,7 @@ class ActivitySortUtilsTest { override val name: String = CONSTANT_NAME override val sufferScore: Int = CONSTANT_SUFFER_SCORE override val summaryPolyline: String = CONSTANT_SUMMARY_POLYLINE - override val type: String = ACTIVITY_FOUR_TYPE + override val sportType: SportType = ACTIVITY_FOUR_TYPE } activitiesIncludingOnlyActivityOne = listOf(activityOne) activities = listOf(activityOne, activityThree, activityTwo, activityFour)