mirror of
https://github.com/vleeuwenmenno/supplements.git
synced 2025-09-11 18:29:12 +02:00
feat: Add daily status refresh on supplements list screen pull-to-refresh
This commit is contained in:
@@ -1,12 +1,13 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import '../models/supplement.dart';
|
import '../models/supplement.dart';
|
||||||
import '../models/supplement_intake.dart';
|
import '../models/supplement_intake.dart';
|
||||||
import '../services/database_helper.dart';
|
import '../services/database_helper.dart';
|
||||||
import '../services/notification_service.dart';
|
import '../services/notification_service.dart';
|
||||||
|
|
||||||
class SupplementProvider with ChangeNotifier {
|
class SupplementProvider with ChangeNotifier, WidgetsBindingObserver {
|
||||||
final DatabaseHelper _databaseHelper = DatabaseHelper.instance;
|
final DatabaseHelper _databaseHelper = DatabaseHelper.instance;
|
||||||
final NotificationService _notificationService = NotificationService();
|
final NotificationService _notificationService = NotificationService();
|
||||||
|
|
||||||
@@ -15,6 +16,8 @@ class SupplementProvider with ChangeNotifier {
|
|||||||
List<Map<String, dynamic>> _monthlyIntakes = [];
|
List<Map<String, dynamic>> _monthlyIntakes = [];
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
Timer? _persistentReminderTimer;
|
Timer? _persistentReminderTimer;
|
||||||
|
Timer? _dateChangeTimer;
|
||||||
|
DateTime _lastDateCheck = DateTime.now();
|
||||||
|
|
||||||
List<Supplement> get supplements => _supplements;
|
List<Supplement> get supplements => _supplements;
|
||||||
List<Map<String, dynamic>> get todayIntakes => _todayIntakes;
|
List<Map<String, dynamic>> get todayIntakes => _todayIntakes;
|
||||||
@@ -22,6 +25,9 @@ class SupplementProvider with ChangeNotifier {
|
|||||||
bool get isLoading => _isLoading;
|
bool get isLoading => _isLoading;
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
|
// Add this provider as an observer for app lifecycle changes
|
||||||
|
WidgetsBinding.instance.addObserver(this);
|
||||||
|
|
||||||
await _notificationService.initialize();
|
await _notificationService.initialize();
|
||||||
|
|
||||||
// Set up the callback for handling supplement intake from notifications
|
// Set up the callback for handling supplement intake from notifications
|
||||||
@@ -62,6 +68,9 @@ class SupplementProvider with ChangeNotifier {
|
|||||||
|
|
||||||
// Start periodic checking for persistent reminders (every 5 minutes)
|
// Start periodic checking for persistent reminders (every 5 minutes)
|
||||||
_startPersistentReminderCheck();
|
_startPersistentReminderCheck();
|
||||||
|
|
||||||
|
// Start date change monitoring to reset daily intake status
|
||||||
|
_startDateChangeMonitoring();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _startPersistentReminderCheck() {
|
void _startPersistentReminderCheck() {
|
||||||
@@ -84,6 +93,33 @@ class SupplementProvider with ChangeNotifier {
|
|||||||
_checkPersistentReminders();
|
_checkPersistentReminders();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _startDateChangeMonitoring() {
|
||||||
|
// Cancel any existing timer
|
||||||
|
_dateChangeTimer?.cancel();
|
||||||
|
|
||||||
|
// Check every minute if the date has changed
|
||||||
|
_dateChangeTimer = Timer.periodic(const Duration(minutes: 1), (timer) async {
|
||||||
|
final now = DateTime.now();
|
||||||
|
final currentDate = DateTime(now.year, now.month, now.day);
|
||||||
|
final lastCheckDate = DateTime(_lastDateCheck.year, _lastDateCheck.month, _lastDateCheck.day);
|
||||||
|
|
||||||
|
if (currentDate != lastCheckDate) {
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('Date changed detected: ${lastCheckDate} -> ${currentDate}');
|
||||||
|
print('Refreshing today\'s intakes for new day...');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Date has changed, refresh today's intakes
|
||||||
|
_lastDateCheck = now;
|
||||||
|
await loadTodayIntakes();
|
||||||
|
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('Today\'s intakes refreshed for new day');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _checkPersistentReminders() async {
|
Future<void> _checkPersistentReminders() async {
|
||||||
// This method will be enhanced to accept settings from the UI layer
|
// This method will be enhanced to accept settings from the UI layer
|
||||||
// For now, we'll check with default settings
|
// For now, we'll check with default settings
|
||||||
@@ -119,10 +155,25 @@ class SupplementProvider with ChangeNotifier {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
WidgetsBinding.instance.removeObserver(this);
|
||||||
_persistentReminderTimer?.cancel();
|
_persistentReminderTimer?.cancel();
|
||||||
|
_dateChangeTimer?.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
|
super.didChangeAppLifecycleState(state);
|
||||||
|
|
||||||
|
if (state == AppLifecycleState.resumed) {
|
||||||
|
// App came back to foreground, check if date changed
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('App resumed, checking for date change...');
|
||||||
|
}
|
||||||
|
forceCheckDateChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _rescheduleAllNotifications() async {
|
Future<void> _rescheduleAllNotifications() async {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('📱 Rescheduling notifications for all active supplements...');
|
print('📱 Rescheduling notifications for all active supplements...');
|
||||||
@@ -252,7 +303,20 @@ class SupplementProvider with ChangeNotifier {
|
|||||||
|
|
||||||
Future<void> loadTodayIntakes() async {
|
Future<void> loadTodayIntakes() async {
|
||||||
try {
|
try {
|
||||||
_todayIntakes = await _databaseHelper.getIntakesWithSupplementsForDate(DateTime.now());
|
final today = DateTime.now();
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('Loading intakes for date: ${today.year}-${today.month}-${today.day}');
|
||||||
|
}
|
||||||
|
|
||||||
|
_todayIntakes = await _databaseHelper.getIntakesWithSupplementsForDate(today);
|
||||||
|
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('Loaded ${_todayIntakes.length} intakes for today');
|
||||||
|
for (var intake in _todayIntakes) {
|
||||||
|
print(' - Supplement ID: ${intake['supplement_id']}, taken at: ${intake['takenAt']}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
@@ -307,6 +371,40 @@ class SupplementProvider with ChangeNotifier {
|
|||||||
return _todayIntakes.where((intake) => intake['supplement_id'] == supplementId).length;
|
return _todayIntakes.where((intake) => intake['supplement_id'] == supplementId).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method to manually refresh daily status (useful for testing or manual refresh)
|
||||||
|
Future<void> refreshDailyStatus() async {
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('Manually refreshing daily status...');
|
||||||
|
}
|
||||||
|
_lastDateCheck = DateTime.now();
|
||||||
|
await loadTodayIntakes();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to force check for date change (useful for testing)
|
||||||
|
Future<void> forceCheckDateChange() async {
|
||||||
|
final now = DateTime.now();
|
||||||
|
final currentDate = DateTime(now.year, now.month, now.day);
|
||||||
|
final lastCheckDate = DateTime(_lastDateCheck.year, _lastDateCheck.month, _lastDateCheck.day);
|
||||||
|
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('Force checking date change...');
|
||||||
|
print('Current date: $currentDate');
|
||||||
|
print('Last check date: $lastCheckDate');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentDate != lastCheckDate) {
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('Date change detected, refreshing intakes...');
|
||||||
|
}
|
||||||
|
_lastDateCheck = now;
|
||||||
|
await loadTodayIntakes();
|
||||||
|
} else {
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('No date change detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Archive functionality
|
// Archive functionality
|
||||||
List<Supplement> _archivedSupplements = [];
|
List<Supplement> _archivedSupplements = [];
|
||||||
List<Supplement> get archivedSupplements => _archivedSupplements;
|
List<Supplement> get archivedSupplements => _archivedSupplements;
|
||||||
|
@@ -69,6 +69,7 @@ class SupplementsListScreen extends StatelessWidget {
|
|||||||
return RefreshIndicator(
|
return RefreshIndicator(
|
||||||
onRefresh: () async {
|
onRefresh: () async {
|
||||||
await provider.loadSupplements();
|
await provider.loadSupplements();
|
||||||
|
await provider.refreshDailyStatus();
|
||||||
},
|
},
|
||||||
child: _buildGroupedSupplementsList(context, provider.supplements, settingsProvider),
|
child: _buildGroupedSupplementsList(context, provider.supplements, settingsProvider),
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user