diff options
Diffstat (limited to 'web/ride-filters.go')
| -rw-r--r-- | web/ride-filters.go | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/web/ride-filters.go b/web/ride-filters.go index de8e242..2282b8d 100644 --- a/web/ride-filters.go +++ b/web/ride-filters.go @@ -43,7 +43,7 @@ type RideFilters struct { CotacolMinPoints *int CotacolMaxPoints *int BikeType *ride.BikeType - RideType *ride.RideType + RideTypes []ride.RideType } type RideFilterView struct { @@ -57,7 +57,7 @@ type RideFilterView struct { CotacolMinPoints int CotacolMaxPoints int BikeType string - RideType string + RideTypes []ride.RideType ResetURL string } @@ -140,7 +140,7 @@ func parseRideFilters(query url.Values) RideFilters { CotacolMinPoints: parseRideFilterInt(query.Get(rideFilterCotacolMinParam), rideFilterCotacolMinPoints, rideFilterCotacolMaxPoints, rideFilterCotacolStepPoints), CotacolMaxPoints: parseRideFilterInt(query.Get(rideFilterCotacolMaxParam), rideFilterCotacolMinPoints, rideFilterCotacolMaxPoints, rideFilterCotacolStepPoints), BikeType: parseRideBikeTypeFilter(query.Get(rideFilterBikeTypeParam)), - RideType: parseRideRideTypeFilter(query.Get(rideFilterRideTypeParam)), + RideTypes: parseRideRideTypesFilter(query[rideFilterRideTypeParam]), DateFrom: parseRideFilterDate(query.Get(rideFilterDateFromParam), false), DateToExclusive: parseRideFilterDate(query.Get(rideFilterDateToParam), true)} @@ -212,15 +212,60 @@ func parseRideBikeTypeFilter(value string) *ride.BikeType { return &bikeType } -func parseRideRideTypeFilter(value string) *ride.RideType { - if value == "" { - return nil +func parseRideRideTypesFilter(values []string) []ride.RideType { + set := make([]ride.RideType, 0, len(values)) + for _, value := range values { + if !ride.IsValidRideType(value) { + continue + } + rideType := ride.RideType(value) + if containsRideType(set, rideType) { + continue + } + set = append(set, rideType) } - if !ride.IsValidRideType(value) { - return nil + if len(set) == 0 { + return defaultRideTypes() + } + return set +} + +// defaultRideTypes is the ride type set represented by an absent ride_type +// filter: every ride type except transport. +func defaultRideTypes() []ride.RideType { + return []ride.RideType{ + ride.RideTypeTraining, + ride.RideTypeIndoor, + ride.RideTypeRace, + } +} + +func containsRideType(types []ride.RideType, target ride.RideType) bool { + for _, candidate := range types { + if candidate == target { + return true + } } - rideType := ride.RideType(value) - return &rideType + return false +} + +func rideTypesEqual(a, b []ride.RideType) bool { + if len(a) != len(b) { + return false + } + for _, candidate := range a { + if !containsRideType(b, candidate) { + return false + } + } + return true +} + +func rideTypeFilterActive(types []ride.RideType) bool { + if len(types) == 0 { + return false + } + return !rideTypesEqual(types, defaultRideTypes()) } func buildRideFilterView(filters RideFilters, sort RideSort) RideFilterView { @@ -236,10 +281,6 @@ func buildRideFilterView(filters RideFilters, sort RideSort) RideFilterView { if filters.BikeType != nil { bikeType = string(*filters.BikeType) } - rideType := "" - if filters.RideType != nil { - rideType = string(*filters.RideType) - } return RideFilterView{ Active: filters.Active(), DistanceMinKm: rideFilterValue(filters.DistanceMinKm, rideFilterDistanceMinKm), @@ -251,7 +292,7 @@ func buildRideFilterView(filters RideFilters, sort RideSort) RideFilterView { CotacolMinPoints: rideFilterValue(filters.CotacolMinPoints, rideFilterCotacolMinPoints), CotacolMaxPoints: rideFilterValue(filters.CotacolMaxPoints, rideFilterCotacolMaxPoints), BikeType: bikeType, - RideType: rideType, + RideTypes: filters.RideTypes, ResetURL: rideFiltersResetURL(sort), } } @@ -317,8 +358,10 @@ func rideFilterQuery(filters RideFilters) url.Values { if filters.BikeType != nil { query.Set(rideFilterBikeTypeParam, string(*filters.BikeType)) } - if filters.RideType != nil { - query.Set(rideFilterRideTypeParam, string(*filters.RideType)) + if len(filters.RideTypes) > 0 && !rideTypesEqual(filters.RideTypes, defaultRideTypes()) { + for _, rideType := range filters.RideTypes { + query.Add(rideFilterRideTypeParam, string(rideType)) + } } return query } @@ -343,7 +386,7 @@ func (filters RideFilters) Active() bool { filters.CotacolMinPoints != nil || filters.CotacolMaxPoints != nil || filters.BikeType != nil || - filters.RideType != nil + rideTypeFilterActive(filters.RideTypes) } func filterRides(items []ride.StoredRide, filters RideFilters) []ride.StoredRide { @@ -352,7 +395,7 @@ func filterRides(items []ride.StoredRide, filters RideFilters) []ride.StoredRide if !item.IsCategorised() { continue } - if filters.Active() && !rideMatchesFilters(item, filters) { + if !rideMatchesFilters(item, filters) { continue } filtered = append(filtered, item) @@ -395,7 +438,7 @@ func rideMatchesFilters(item ride.StoredRide, filters RideFilters) bool { if filters.BikeType != nil && item.BikeType != *filters.BikeType { return false } - if filters.RideType != nil && item.RideType != *filters.RideType { + if len(filters.RideTypes) > 0 && !containsRideType(filters.RideTypes, item.RideType) { return false } return true |
