mirror of
https://github.com/kuhyx/diet-guard.git
synced 2026-11-11 15:33:57 +01:00
`KuchniaQueueService` had no `init()` call in `main()`, so on a real device the whole feature would have done nothing: every entry point checks `isInitialized` first and returns quietly, which reads as "no delivery today" rather than as an error. All 694 tests passed throughout, because widget tests initialise the service directly. Caught by grepping main.dart before the phone deploy, not by the suite. So it is now a repo invariant: `repo_invariants_test.dart` asserts main() names both catering `init()` calls, and the assertion was checked against a main.dart with the line deleted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QQpCiPaSbyRpwsLkH3dgsX
69 lines
2.7 KiB
Dart
69 lines
2.7 KiB
Dart
/// App entry point: initializes local storage services, registers the
|
|
/// background due-slot check, then shows the primary meal-logging screen.
|
|
library;
|
|
|
|
import 'dart:async';
|
|
import 'package:diet_guard_app/screens/log_meal_screen.dart';
|
|
import 'package:diet_guard_app/services/app_settings_service.dart';
|
|
import 'package:diet_guard_app/services/background_tasks.dart';
|
|
import 'package:diet_guard_app/services/budget_history_service.dart';
|
|
import 'package:diet_guard_app/services/foodbank_service.dart';
|
|
import 'package:diet_guard_app/services/frame_stats.dart';
|
|
import 'package:diet_guard_app/services/kuchnia_credential_service.dart';
|
|
import 'package:diet_guard_app/services/kuchnia_queue.dart';
|
|
import 'package:diet_guard_app/services/log_storage_service.dart';
|
|
import 'package:diet_guard_app/services/meal_schedule_service.dart';
|
|
import 'package:diet_guard_app/services/notification_service.dart';
|
|
import 'package:diet_guard_app/services/sync_device_id.dart';
|
|
import 'package:diet_guard_app/ui/theme.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
// Before anything that stamps an Hlc or syncs: until this resolves, the
|
|
// device id falls back to the pre-migration role constant.
|
|
await initSyncDeviceId();
|
|
await LogStorageService.init();
|
|
await AppSettingsService.init();
|
|
await BudgetHistoryService.init();
|
|
await MealScheduleService.init();
|
|
await FoodBankService.init();
|
|
await KuchniaCredentialService.init();
|
|
await KuchniaQueueService.init();
|
|
final notifications = await NotificationService.init();
|
|
// Deliberately *not* awaited before the first frame: the browser's
|
|
// `Notification.requestPermission()` does not complete until the user
|
|
// answers the prompt, so awaiting it here left the desktop app as a blank
|
|
// white window behind the permission bubble. Scheduling is likewise
|
|
// platform-specific (WorkManager on Android, an in-page timer in the
|
|
// browser -- see background_tasks.dart) and equally not worth a delayed
|
|
// first frame.
|
|
// coverage:ignore-start
|
|
unawaited(
|
|
notifications.requestPermission().then((_) {
|
|
return initBackgroundTasks();
|
|
}),
|
|
);
|
|
// coverage:ignore-end
|
|
// Off unless armed with --dart-define=DIET_GUARD_FRAME_STATS=1.
|
|
// coverage:ignore-start
|
|
if (frameStatsEnabled) startFrameStats();
|
|
// coverage:ignore-end
|
|
runApp(const DietGuardApp());
|
|
}
|
|
|
|
/// Root widget for the Diet Guard companion app.
|
|
class DietGuardApp extends StatelessWidget {
|
|
/// Creates the [DietGuardApp] root widget.
|
|
const DietGuardApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
title: 'Diet Guard',
|
|
theme: buildAppTheme(),
|
|
home: const LogMealScreen(),
|
|
);
|
|
}
|
|
}
|