Skip to content

Commit

Permalink
Merge pull request #1892 from matthiasn/refactor/use_controller_in_he…
Browse files Browse the repository at this point in the history
…alth_charts

feat: use controller in health charts & chart improvements
  • Loading branch information
matthiasn authored Jan 2, 2025
2 parents e76c8ef + fda655f commit 3cbed1e
Show file tree
Hide file tree
Showing 20 changed files with 669 additions and 154 deletions.
5 changes: 5 additions & 0 deletions lib/classes/journal_entities.dart
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,11 @@ extension JournalEntityExtension on JournalEntity {
ids.add(checklistItem.data.dataTypeId);
}

if (this is QuantitativeEntry) {
final checklistItem = this as QuantitativeEntry;
ids.add(checklistItem.data.dataType);
}

return ids;
}
}
16 changes: 16 additions & 0 deletions lib/database/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,19 @@ class JournalDb extends _$JournalDb {
Future<int> updateJournalEntity(
JournalEntity updated, {
bool overrideComparison = false,
bool overwrite = true,
}) async {
var rowsAffected = 0;
final dbEntity = toDbEntity(updated).copyWith(
updatedAt: DateTime.now(),
);

final existingDbEntity = await entityById(dbEntity.id);

if (existingDbEntity != null && !overwrite) {
return rowsAffected;
}

if (existingDbEntity != null) {
final existing = fromDbEntity(existingDbEntity);
final status = await detectConflict(existing, updated);
Expand Down Expand Up @@ -696,6 +702,16 @@ class JournalDb extends _$JournalDb {
.map(entityStreamMapper);
}

Future<List<JournalEntity>> getQuantitativeByType({
required String type,
required DateTime rangeStart,
required DateTime rangeEnd,
}) async {
final res = await quantitativeByType(type, rangeStart, rangeEnd).get();

return res.map(fromDbEntity).toList();
}

Future<QuantitativeEntry?> latestQuantitativeByType(String type) async {
final dbEntities = await latestQuantByType(type).get();
if (dbEntities.isEmpty) {
Expand Down
2 changes: 1 addition & 1 deletion lib/features/calendar/ui/time_by_category_chart_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class TimeByCategoryChartCard extends ConsumerWidget {
),
hasTopBarLayer: true,
trailingNavBarWidget: IconButton(
padding: const EdgeInsets.all(WoltModalConfig.pagePadding),
padding: WoltModalConfig.pagePadding,
icon: const Icon(Icons.close),
onPressed: Navigator.of(modalSheetContext).pop,
),
Expand Down
93 changes: 93 additions & 0 deletions lib/features/dashboards/state/health_chart_controller.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import 'dart:async';
import 'dart:io';
import 'dart:math';

import 'package:lotti/classes/journal_entities.dart';
import 'package:lotti/database/database.dart';
import 'package:lotti/get_it.dart';
import 'package:lotti/logic/health_import.dart';
import 'package:lotti/services/db_notification.dart';
import 'package:lotti/utils/cache_extension.dart';
import 'package:lotti/widgets/charts/dashboard_health_data.dart';
import 'package:lotti/widgets/charts/utils.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'health_chart_controller.g.dart';

@riverpod
class HealthChartDataController extends _$HealthChartDataController {
final JournalDb _journalDb = getIt<JournalDb>();

StreamSubscription<Set<String>>? _updateSubscription;
final UpdateNotifications _updateNotifications = getIt<UpdateNotifications>();

void listen() {
_updateSubscription =
_updateNotifications.updateStream.listen((affectedIds) async {
if (affectedIds.contains(healthDataType)) {
final latest = await _fetch();
if (latest != state.value) {
state = AsyncData(latest);
}
}
});
}

@override
Future<List<JournalEntity>> build({
required String healthDataType,
required DateTime rangeStart,
required DateTime rangeEnd,
}) async {
ref
..onDispose(() {
_updateSubscription?.cancel();
})
..cacheFor(dashboardCacheDuration);

final data = await _fetch();
listen();
return data;
}

Future<List<JournalEntity>> _fetch() async {
return _journalDb.getQuantitativeByType(
type: healthDataType,
rangeStart: rangeStart,
rangeEnd: rangeEnd,
);
}
}

@riverpod
class HealthObservationsController extends _$HealthObservationsController {
HealthObservationsController() {
if (!Platform.environment.containsKey('FLUTTER_TEST')) {
Future.delayed(Duration(milliseconds: 500 + Random().nextInt(500)), () {
getIt<HealthImport>().fetchHealthDataDelta(healthDataType);
});
}
}

@override
Future<List<Observation>> build({
required String healthDataType,
required DateTime rangeStart,
required DateTime rangeEnd,
}) async {
ref.cacheFor(dashboardCacheDuration);

final items = ref
.watch(
healthChartDataControllerProvider(
healthDataType: healthDataType,
rangeStart: rangeStart,
rangeEnd: rangeEnd,
),
)
.valueOrNull ??
[];

return aggregateByType(items, healthDataType);
}
}
Loading

0 comments on commit 3cbed1e

Please sign in to comment.