Skip to content

WIP: health sync#1260

Open
rolandgeider wants to merge 29 commits into
masterfrom
feature/health-sync
Open

WIP: health sync#1260
rolandgeider wants to merge 29 commits into
masterfrom
feature/health-sync

Conversation

@rolandgeider

Copy link
Copy Markdown
Member

Adds google and apple health sync, plus all the necessary changes to the categories. See the umbrella issue wger-project/wger#2417

Closes #618

JohnWeidner and others added 23 commits March 27, 2026 14:12
…onnect

Import body weight data from Apple Health (iOS) and Google Health Connect
(Android) into wger when the app is opened. Uses the Flutter `health` package
for cross-platform access. Feature is opt-in via a settings toggle.

Key changes:
- Add HealthSyncNotifier (Riverpod) for sync orchestration
- Add HealthSyncSettingsTile in settings page
- Add health package dependency and platform permissions
- Fix WeightEntry.copyWith parameter type (int? -> num?)
- Fix BodyWeightProvider.findByDate() to use calendar-date comparison
- Raise Android minSdkVersion to 26 (Health Connect requirement)
- Change MainActivity to extend FlutterFragmentActivity

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Show "Weight (kg)" or "Weight (lb)" on the weight entry form based on
  the user's profile preference
- Convert health sync values from kg to lb before POSTing when the user's
  profile is set to lb
- Check/request health permissions on sync to handle app restart
- Fix weight form tests to provide UserProvider mock

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Pass isMetric to enableSync() so the initial sync from the settings
  toggle converts kg to lb when the user's profile is set to lb
- Refresh BodyWeightProvider after sync from settings tile so the
  dashboard and weight screen update immediately
- Fix DashboardWeightWidget to compute sensibleRange() inside the
  Consumer builder so it rebuilds when weight data changes
- Add permission check in syncOnAppOpen() for app restart scenarios
- Add unit tests for weight conversion logic and HealthSyncState

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use existing isSameDayAs() extension in findByDate() instead of
  manual year/month/day comparison
- Build a Set of existing timestamps for O(1) dedup lookups instead
  of O(n*m) .any() scan per data point
- Simplify nullable bool check (_isAvailable != true)
- Remove comments that restate the code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add healthSync, healthSyncDescription, healthSyncSuccess, and health
keys to app_en.arb and use AppLocalizations instead of hardcoded
English strings in the settings tile and settings page.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the 30-day lookback limit on initial sync. Pull all available
weight data from Health Connect on first enable. Add
READ_HEALTH_DATA_HISTORY permission to AndroidManifest to allow
reading data older than 30 days.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Call requestHealthDataHistoryAuthorization() on Android after initial
permission grant. Without this runtime request, Health Connect limits
data access to the last 30 days regardless of the manifest permission.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
We don't just want to sync the weight entries
This follows the convention in the rest of the application and allows us to
easily mock it for tests.
- Add MetricType enum supporting Django API field mapping
- Provide localized en string descriptors for health categories

- implement daily aggregation logic and bar chart widget
- Implement MeasurementBarChartWidgetFl using fl_chart

- Update getOverviewWidgets signatures to dynamically handle MetricType
- Add buildChartForMetricType conditional rendering interceptor
- Bind step, distance, sleep, and energy categories to the bar chart pipeline
- Replace hardcoded line charts with buildChartForMetricType

- add metric type selection and detail view support
- Add DropdownButtonFormField to MeasurementCategory form for user assignment
- Pass metricType to detail view rendering pipeline in EntriesList
- Update form state management to handle manual metric type assignment
- Add metricType property to MeasurementCategory model and DB table.

- Include local-only persistence for metric categorization.

- Update UI form and localization strings.
- Implement centered moving average trendline in charts.dart.
- Update MeasurementChartWidgetFl to render trendline bar data.
- Integrate smoothedTreadline logic into metric chart builder.

refactor(db): implement MetricType Drift converter
- Add MeasurementMetricTypeConverter to map enum to SQLite text.
- Update MeasurementCategoryTable to use the new converter.
# Conflicts:
#	lib/database/powersync/tables/measurements.dart
#	lib/features/measurements/models/measurement_category.dart
#	lib/features/measurements/widgets/helpers.dart
feat(measurements): measurement charts and metric type selection #1247
Measurement categories can optionally point to another category, In practice, this
will just be something like blood pressure since these values only make sense in a
pair. Others can be interesting while combined (heart rate and steps), but are valid
on their own.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Android Health Connect and Apple Health sync

3 participants