feat(app): add version check system and enhance internationalization support

Add comprehensive app update checking functionality with:
- New VersionCheckContext for managing update detection and notifications
- VersionUpdateModal UI component for presenting update information
- Version service API integration with platform-specific update URLs
- Version check menu item in personal settings with manual/automatic checking

Enhance internationalization across workout features:
- Complete workout type translations for English and Chinese
- Localized workout detail modal with proper date/time formatting
- Locale-aware date formatting in fitness rings detail
- Workout notification improvements with deep linking to specific workout details

Improve UI/UX with better chart rendering, sizing fixes, and enhanced navigation flow. Update app version to 1.1.3 and include app version in API headers for better tracking.
This commit is contained in:
2025-11-29 20:47:16 +08:00
parent 83b77615cf
commit a309123b35
19 changed files with 1132 additions and 159 deletions

View File

@@ -338,6 +338,9 @@ export const fitnessRingsDetail = {
saturday: 'Sat',
sunday: 'Sun',
},
dateFormats: {
header: 'MMM D, YYYY',
},
cards: {
activeCalories: {
title: 'Active Calories',
@@ -474,6 +477,159 @@ export const basalMetabolismDetail = {
},
};
export const workoutTypes = {
americanfootball: 'American Football',
archery: 'Archery',
australianfootball: 'Australian Football',
badminton: 'Badminton',
baseball: 'Baseball',
basketball: 'Basketball',
bowling: 'Bowling',
boxing: 'Boxing',
climbing: 'Climbing',
cricket: 'Cricket',
crosstraining: 'Cross Training',
curling: 'Curling',
cycling: 'Cycling',
dance: 'Dance',
danceinspiredtraining: 'Dance Inspired Training',
elliptical: 'Elliptical',
equestriansports: 'Equestrian Sports',
fencing: 'Fencing',
fishing: 'Fishing',
functionalstrengthtraining: 'Functional Strength Training',
golf: 'Golf',
gymnastics: 'Gymnastics',
handball: 'Handball',
hiking: 'Hiking',
hockey: 'Hockey',
hunting: 'Hunting',
lacrosse: 'Lacrosse',
martialarts: 'Martial Arts',
mindandbody: 'Mind and Body',
mixedmetaboliccardiotraining: 'Mixed Metabolic Cardio Training',
paddlesports: 'Paddle Sports',
play: 'Play',
preparationandrecovery: 'Preparation & Recovery',
racquetball: 'Racquetball',
rowing: 'Rowing',
rugby: 'Rugby',
running: 'Running',
sailing: 'Sailing',
skatingsports: 'Skating Sports',
snowsports: 'Snow Sports',
soccer: 'Soccer',
softball: 'Softball',
squash: 'Squash',
stairclimbing: 'Stair Climbing',
surfingsports: 'Surfing Sports',
swimming: 'Swimming',
tabletennis: 'Table Tennis',
tennis: 'Tennis',
trackandfield: 'Track and Field',
traditionalstrengthtraining: 'Traditional Strength Training',
volleyball: 'Volleyball',
walking: 'Walking',
waterfitness: 'Water Fitness',
waterpolo: 'Water Polo',
watersports: 'Water Sports',
wrestling: 'Wrestling',
yoga: 'Yoga',
barre: 'Barre',
coretraining: 'Core Training',
crosscountryskiing: 'Cross-Country Skiing',
downhillskiing: 'Downhill Skiing',
flexibility: 'Flexibility',
highintensityintervaltraining: 'High-Intensity Interval Training',
jumprope: 'Jump Rope',
kickboxing: 'Kickboxing',
pilates: 'Pilates',
snowboarding: 'Snowboarding',
stairs: 'Stairs',
steptraining: 'Step Training',
wheelchairwalkpace: 'Wheelchair Walk Pace',
wheelchairrunpace: 'Wheelchair Run Pace',
taichi: 'Tai Chi',
mixedcardio: 'Mixed Cardio',
handcycling: 'Hand Cycling',
discsports: 'Disc Sports',
fitnessgaming: 'Fitness Gaming',
cardiodance: 'Cardio Dance',
socialdance: 'Social Dance',
pickleball: 'Pickleball',
cooldown: 'Cooldown',
swimbikerun: 'Swim Bike Run',
transition: 'Transition',
underwaterdiving: 'Underwater Diving',
other: 'Other',
};
export const workoutDetail = {
loading: 'Loading workout details...',
retry: 'Retry',
errors: {
loadFailed: 'Failed to load workout details',
noHeartRateData: 'No heart rate data available',
noZoneStats: 'No heart rate zone data',
},
metrics: {
duration: 'Duration',
calories: 'Calories',
caloriesUnit: 'kcal',
intensity: 'Intensity',
averageHeartRate: 'Average Heart Rate',
heartRateUnit: 'bpm',
},
sections: {
heartRateRange: 'Heart Rate Range',
averageHeartRate: 'Average',
maximumHeartRate: 'Maximum',
minimumHeartRate: 'Minimum',
heartRateUnit: 'bpm',
heartRateZones: 'Heart Rate Zones',
},
chart: {
unavailable: 'Chart unavailable',
noData: 'No heart rate chart data yet',
},
intensityInfo: {
title: 'About workout intensity (METs)',
description1: 'METs (metabolic equivalent) reflect energy cost; resting equals 1 MET.',
description2: '3-6 METs is moderate intensity, above 6 METs is high intensity.',
description3: 'Higher values mean more energy burned per minute—adjust to your fitness level.',
description4: 'Warm up and cool down before and after sustained high-intensity sessions.',
formula: {
title: 'Formula',
value: 'METs = Exercise VO₂ ÷ Resting VO₂',
},
legend: {
low: '2-3 METs',
lowLabel: 'Low intensity',
medium: '3-6 METs',
mediumLabel: 'Moderate',
high: '>6 METs',
highLabel: 'High intensity',
},
},
zones: {
summary: '{{minutes}} min · {{range}}',
labels: {
warmup: 'Warm-up',
fatburn: 'Fat burn',
aerobic: 'Aerobic',
anaerobic: 'Anaerobic',
max: 'Max effort',
},
ranges: {
warmup: '<100 bpm',
fatburn: '100-119 bpm',
aerobic: '120-149 bpm',
anaerobic: '150-169 bpm',
max: '≥170 bpm',
},
},
};
export const workoutHistory = {
title: 'Workout Summary',
loading: 'Loading workout records...',
@@ -504,4 +660,4 @@ export const workoutHistory = {
subtitle: 'Complete a workout to view detailed history here',
},
monthOccurrence: 'This is your {{index}} {{activity}} in {{month}}.',
};
};

View File

@@ -37,6 +37,25 @@ export const personal = {
medicalSources: 'Medical Advice Sources',
customization: 'Customization',
},
versionCheck: {
sectionTitle: 'Updates',
menuTitle: 'Check for updates',
checking: 'Checking for updates...',
upToDate: 'You are on the latest version',
updateBadge: 'v{{version}} available',
failed: 'Update check failed, please try again later',
updateFound: 'New version v{{version}}',
modalTitle: 'Update available',
modalTag: 'New',
currentVersion: 'Current',
latestVersion: 'Latest',
releaseNotesTitle: "What's new",
fallbackNotes: 'Performance improvements and fixes to keep things smooth.',
later: 'Remind me later',
updateNow: 'Update now',
missingUrl: 'Store link is not ready yet',
openStoreFailed: 'Could not open the store, please try again',
},
menu: {
notificationSettings: 'Notification settings',
developerOptions: 'Developer options',
@@ -405,4 +424,4 @@ export const notificationSettings = {
body: 'You will receive mood record reminders in the evening',
},
},
};
};