Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/health/health_export.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,12 @@ HealthWorkoutActivityType healthActivityForType(
case 'padel':
case 'badminton':
return HealthWorkoutActivityType.TENNIS;
case 'pickleball':
// iOS has its own type; Health Connect has none, so it files with the
// other racquet sports.
return ios
? HealthWorkoutActivityType.PICKLEBALL
: HealthWorkoutActivityType.TENNIS;
case 'basketball':
return HealthWorkoutActivityType.BASKETBALL;
case 'soccer':
Expand Down
2 changes: 1 addition & 1 deletion lib/l10n/app_ru.arb
Original file line number Diff line number Diff line change
Expand Up @@ -5800,7 +5800,7 @@
"tabNutrition": "Питание",
"tabWorkout": "Тренировка",
"tabWellness": "Самочувствие",
"activityCatalogueName": "{key, select, kcardio{Кардио} kstrength{Силовые} ksports{Спорт} kathletics{Лёгкая атлетика} koutdoor{На природе} kmindbody{Тело и внимание} keveryday{Повседневные дела} kother{Другое} krunning{Бег} ktrailrunning{Трейлраннинг} kwalking{Ходьба} khiking{Пеший поход} kcycling{Велоспорт} kindoorbike{Велотренажёр} krowing{Гребля} kswimming{Плавание} kelliptical{Эллиптический тренажёр} kstairclimber{Степпер} ktreadmill{Беговая дорожка} kjumprope{Прыжки со скакалкой} kweighttraining{Силовая тренировка} kpowerlifting{Пауэрлифтинг} kbodyweight{С собственным весом} kcalisthenics{Калистеника} kkettlebell{Гиря} kcrossfit{CrossFit} khiit{ВИИТ} kcircuittraining{Круговая тренировка} kfunctional{Функциональная тренировка} kfootball{Футбол} kbasketball{Баскетбол} kcricket{Крикет} ktennis{Теннис} kbadminton{Бадминтон} ktabletennis{Настольный теннис} ksquash{Сквош} kpadel{Падел} kvolleyball{Волейбол} khockey{Хоккей} kbaseball{Бейсбол} krugby{Регби} kgolf{Гольф} kbowling{Боулинг} kboxing{Бокс} kmartialarts{Боевые искусства} kwrestling{Борьба} kclimbing{Скалолазание} ksprinting{Спринт} ktrackintervals{Интервалы на стадионе} kcrosscountry{Кросс} khurdles{Бег с барьерами} klongjump{Прыжки в длину} kshotput{Толкание ядра} kjavelin{Метание копья} kpolevault{Прыжки с шестом} kmountainbiking{Горный велосипед} kkayaking{Каякинг} ksurfing{Сёрфинг} kpaddleboard{Сапбординг} kskiing{Лыжи} ksnowboarding{Сноуборд} kskating{Катание на коньках} kskateboarding{Скейтбординг} khorseriding{Верховая езда} kyoga{Йога} kpilates{Пилатес} kstretching{Растяжка} kmobility{Подвижность суставов} ktaichi{Тайцзи} kbreathwork{Дыхательная практика} kmeditation{Медитация} khousework{Домашние дела} kgardening{Садовые работы} kdogwalking{Прогулка с собакой} kchildcare{Уход за ребёнком} kdiy{Ремонт своими руками} kshopping{Покупки} kstairs{Подъём по лестнице} kgeneralworkout{Общая тренировка} kdancing{Танцы} kintimacy{Интимная близость} kphysiotherapy{Физиотерапия} ksauna{Сауна} kcoldplunge{Погружение в холодную воду} other{{name}}}",
"activityCatalogueName": "{key, select, kcardio{Кардио} kstrength{Силовые} ksports{Спорт} kathletics{Лёгкая атлетика} koutdoor{На природе} kmindbody{Тело и внимание} keveryday{Повседневные дела} kother{Другое} krunning{Бег} ktrailrunning{Трейлраннинг} kwalking{Ходьба} khiking{Пеший поход} kcycling{Велоспорт} kindoorbike{Велотренажёр} krowing{Гребля} kswimming{Плавание} kelliptical{Эллиптический тренажёр} kstairclimber{Степпер} ktreadmill{Беговая дорожка} kjumprope{Прыжки со скакалкой} kweighttraining{Силовая тренировка} kpowerlifting{Пауэрлифтинг} kbodyweight{С собственным весом} kcalisthenics{Калистеника} kkettlebell{Гиря} kcrossfit{CrossFit} khiit{ВИИТ} kcircuittraining{Круговая тренировка} kfunctional{Функциональная тренировка} kfootball{Футбол} kbasketball{Баскетбол} kcricket{Крикет} ktennis{Теннис} kbadminton{Бадминтон} ktabletennis{Настольный теннис} ksquash{Сквош} kpadel{Падел} kpickleball{Пиклбол} kvolleyball{Волейбол} khockey{Хоккей} kbaseball{Бейсбол} krugby{Регби} kgolf{Гольф} kbowling{Боулинг} kboxing{Бокс} kmartialarts{Боевые искусства} kwrestling{Борьба} kclimbing{Скалолазание} ksprinting{Спринт} ktrackintervals{Интервалы на стадионе} kcrosscountry{Кросс} khurdles{Бег с барьерами} klongjump{Прыжки в длину} kshotput{Толкание ядра} kjavelin{Метание копья} kpolevault{Прыжки с шестом} kmountainbiking{Горный велосипед} kkayaking{Каякинг} ksurfing{Сёрфинг} kpaddleboard{Сапбординг} kskiing{Лыжи} ksnowboarding{Сноуборд} kskating{Катание на коньках} kskateboarding{Скейтбординг} khorseriding{Верховая езда} kyoga{Йога} kpilates{Пилатес} kstretching{Растяжка} kmobility{Подвижность суставов} ktaichi{Тайцзи} kbreathwork{Дыхательная практика} kmeditation{Медитация} khousework{Домашние дела} kgardening{Садовые работы} kdogwalking{Прогулка с собакой} kchildcare{Уход за ребёнком} kdiy{Ремонт своими руками} kshopping{Покупки} kstairs{Подъём по лестнице} kgeneralworkout{Общая тренировка} kdancing{Танцы} kintimacy{Интимная близость} kphysiotherapy{Физиотерапия} ksauna{Сауна} kcoldplunge{Погружение в холодную воду} other{{name}}}",
"@activityCatalogueName": {
"placeholders": {
"key": {
Expand Down
4 changes: 4 additions & 0 deletions lib/ui2/activity/catalogue.dart
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ const activityLibrary = <ActGroup>[
// are different games, and borrowing either would be a stand-in. The
// post-session estimate still works from heart rate.
Activity('Padel', LucideIcons.volleyball, C.yellow, Track.duration, null),
// No MET for the same reason: the 2011 compendium predates pickleball as
// a listed activity, and paddleball or tennis doubles would be a guess.
Activity(
'Pickleball', LucideIcons.volleyball, C.green, Track.duration, null),
Activity('Volleyball', LucideIcons.volleyball, C.orange, Track.duration, 6.0),
Activity('Hockey', LucideIcons.target, C.blue, Track.duration, 8.0),
Activity('Baseball', LucideIcons.target, C.red, Track.duration, 5.0),
Expand Down
4 changes: 2 additions & 2 deletions lib/ui2/activity/summary.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ enum Arch { route, strength, interval, flow, laps, journey, match, basic }

const _sports = {
'Football', 'Basketball', 'Cricket', 'Tennis', 'Badminton', 'Table tennis',
'Squash', 'Padel', 'Volleyball', 'Hockey', 'Baseball', 'Rugby', 'Boxing',
'Martial arts', 'Wrestling',
'Squash', 'Padel', 'Pickleball', 'Volleyball', 'Hockey', 'Baseball',
'Rugby', 'Boxing', 'Martial arts', 'Wrestling',
};
const _laps = {'Swimming', 'Rowing'};
const _journey = {
Expand Down
3 changes: 2 additions & 1 deletion test/ui2_activity_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ void main() {
// saying it was told nothing, or a named sport the compendium has no
// row for. Pinned by name, or the exception quietly becomes a habit.
final unpriced = allActivities.where((a) => a.met == null).toList();
expect(unpriced.map((a) => a.name), ['Padel', 'General workout']);
expect(unpriced.map((a) => a.name),
['Padel', 'Pickleball', 'General workout']);
});

test('padel, skateboarding and push-ups resolve by their stored keys', () {
Expand Down
10 changes: 10 additions & 0 deletions test/whoop_activity_type_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ void main() {
}
});

test('an imported pickleball session is a catalogue sport', () {
final key = WhoopImporter.activityTypeKey('Pickleball');
expect(activityByName(key)?.name, 'Pickleball');
expect(healthActivityForType(key, ios: true),
HealthWorkoutActivityType.PICKLEBALL);
// Health Connect has no pickleball type.
expect(healthActivityForType(key, ios: false),
HealthWorkoutActivityType.TENNIS);
});

test('rows stored with the raw WHOOP name still map', () {
// The importer never rewrites a session it already holds, so rows from
// an earlier import keep the old spelling.
Expand Down
Loading