feat: Refine trail category model (#1059)

* feat: advanced trail categories

* rename remote_category

* fix merge issues

* subcategories for plugins mapping

* fix refresh

* remove vertical trail filter category scrolling

* cleanup

* add confirm modal for disabling a category

* Fix federation issues

* fix review findings

* redesign category settings page

* remove prio badge

* fix subcategory badge layout

* optimize subcategory settings layout

* further settings page layout optimization

* fix subcategory icon position

* fix

* update docs

---------

Co-authored-by: Christian Beutel <>
This commit is contained in:
slothful-vassal
2026-06-29 03:16:26 +02:00
committed by GitHub
parent 50cb6c7f5f
commit 3b8f00fd26
116 changed files with 9363 additions and 453 deletions

View File

@@ -0,0 +1,22 @@
package main
func activityTypeFromProvider(value string) string {
switch value {
case "AlpineSki", "BackcountrySki", "IceSkate", "NordicSki", "RollerSki", "Snowboard":
return "skiing"
case "Canoeing", "Kayaking", "Kitesurf", "Rowing", "Sail", "StandUpPaddling", "Surfing", "Windsurf":
return "canoeing"
case "Hike", "Snowshoe":
return "hiking"
case "Run", "TrailRun", "VirtualRun":
return "running"
case "Walk", "Golf", "Skateboard", "Wheelchair":
return "walking"
case "Ride", "EBikeRide", "Handcycle", "InlineSkate", "Velomobile", "VirtualRide":
return "biking"
case "RockClimbing":
return "climbing"
default:
return value
}
}

View File

@@ -208,21 +208,5 @@ func providerActivityType(activity *detailedActivity) string {
}
func activityType(activity *detailedActivity) string {
value := providerActivityType(activity)
switch value {
case "AlpineSki", "BackcountrySki", "IceSkate", "NordicSki", "RollerSki", "Snowboard":
return "skiing"
case "Canoeing", "Kayaking", "Kitesurf", "Rowing", "Sail", "StandUpPaddling", "Surfing", "Windsurf":
return "canoeing"
case "Hike", "Snowshoe":
return "hiking"
case "Run", "VirtualRun", "Walk", "Golf", "Skateboard", "Wheelchair":
return "walking"
case "Ride", "EBikeRide", "Handcycle", "InlineSkate", "Velomobile", "VirtualRide":
return "biking"
case "RockClimbing":
return "climbing"
default:
return value
}
return activityTypeFromProvider(providerActivityType(activity))
}

View File

@@ -0,0 +1,18 @@
package main
import "testing"
func TestActivityTypeMapsRunsToRunning(t *testing.T) {
cases := map[string]string{
"Run": "running",
"TrailRun": "running",
"VirtualRun": "running",
"Walk": "walking",
}
for providerType, want := range cases {
if got := activityTypeFromProvider(providerType); got != want {
t.Fatalf("activityTypeFromProvider(%q) = %q, want %q", providerType, got, want)
}
}
}

View File

@@ -145,15 +145,15 @@
"route:1": "Biking",
"route:2": "Walking",
"AlpineSki": "Skiing",
"BackcountrySki": "Skiing",
"BackcountrySki": { "category": "Skiing", "subcategory": "Backcountry" },
"Badminton": "Other",
"Canoeing": "Canoeing",
"Crossfit": "Workout",
"EBikeRide": "Biking",
"EMountainBikeRide": "Biking",
"Elliptical": "Workout",
"Crossfit": "Other",
"EBikeRide": { "category": "Biking", "subcategory": "E-Bike" },
"EMountainBikeRide": { "category": "Biking", "subcategory": "E-Bike" },
"Elliptical": "Other",
"Golf": "Other",
"GravelRide": "Biking",
"GravelRide": { "category": "Biking", "subcategory": "Gravel" },
"Handcycle": "Biking",
"HighIntensityIntervalTraining": "Other",
"Hike": "Hiking",
@@ -161,40 +161,40 @@
"InlineSkate": "Walking",
"Kayaking": "Canoeing",
"Kitesurf": "Canoeing",
"MountainBikeRide": "Biking",
"NordicSki": "Skiing",
"MountainBikeRide": { "category": "Biking", "subcategory": "MTB" },
"NordicSki": { "category": "Skiing", "subcategory": "Cross-country" },
"Pickleball": "Other",
"Pilates": "Other",
"Racquetball": "Other",
"Ride": "Biking",
"Ride": { "category": "Biking", "subcategory": "Road" },
"RockClimbing": "Climbing",
"RollerSki": "Skiing",
"RollerSki": { "category": "Skiing", "subcategory": "Cross-country" },
"Rowing": "Canoeing",
"Run": "Walking",
"Run": { "category": "Running", "subcategory": "Road" },
"Sail": "Canoeing",
"Skateboard": "Walking",
"Snowboard": "Skiing",
"Snowshoe": "Hiking",
"Snowshoe": { "category": "Hiking", "subcategory": "Snowshoeing" },
"Soccer": "Other",
"Squash": "Other",
"StairStepper": "Workout",
"StairStepper": "Other",
"StandUpPaddling": "Canoeing",
"Surfing": "Canoeing",
"Swim": "Other",
"TableTennis": "Other",
"Tennis": "Other",
"TrailRun": "Other",
"TrailRun": { "category": "Running", "subcategory": "Trail" },
"Training": "Other",
"Velomobile": "Biking",
"VirtualRide": "Biking",
"VirtualRow": "Other",
"VirtualRun": "Walking",
"VirtualRun": "Running",
"Walk": "Walking",
"WeightTraining": "Workout",
"WeightTraining": "Other",
"Wheelchair": "Walking",
"Windsurf": "Canoeing",
"Workout": "Workout",
"Yoga": "Workout"
"Workout": "Other",
"Yoga": "Other"
}
},
"metadata": {