adds syncing

This commit is contained in:
2025-08-27 16:17:21 +02:00
parent 1191d06e53
commit 709cf2cbd9
24 changed files with 3809 additions and 226 deletions

View File

@@ -1,8 +1,10 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/supplement_provider.dart';
import '../providers/settings_provider.dart';
import '../models/supplement.dart';
import '../providers/settings_provider.dart';
import '../providers/supplement_provider.dart';
import '../providers/sync_provider.dart';
import '../widgets/supplement_card.dart';
import 'add_supplement_screen.dart';
import 'archived_supplements_screen.dart';
@@ -17,6 +19,30 @@ class SupplementsListScreen extends StatelessWidget {
title: const Text('My Supplements'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
actions: [
Consumer<SyncProvider>(
builder: (context, syncProvider, child) {
if (!syncProvider.isConfigured) {
return const SizedBox.shrink();
}
return IconButton(
icon: syncProvider.isSyncing
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: syncProvider.status.name == 'success' &&
DateTime.now().difference(syncProvider.lastSyncTime ?? DateTime.now()).inSeconds < 5
? const Icon(Icons.check, color: Colors.green)
: const Icon(Icons.sync),
onPressed: syncProvider.isSyncing ? null : () {
syncProvider.performManualSync();
},
tooltip: syncProvider.isSyncing ? 'Syncing...' : 'Force Sync',
);
},
),
IconButton(
icon: const Icon(Icons.archive),
onPressed: () {
@@ -30,8 +56,8 @@ class SupplementsListScreen extends StatelessWidget {
),
],
),
body: Consumer2<SupplementProvider, SettingsProvider>(
builder: (context, provider, settingsProvider, child) {
body: Consumer3<SupplementProvider, SettingsProvider, SyncProvider>(
builder: (context, provider, settingsProvider, syncProvider, child) {
if (provider.isLoading) {
return const Center(child: CircularProgressIndicator());
}
@@ -80,13 +106,13 @@ class SupplementsListScreen extends StatelessWidget {
Widget _buildGroupedSupplementsList(BuildContext context, List<Supplement> supplements, SettingsProvider settingsProvider) {
final groupedSupplements = _groupSupplementsByTimeOfDay(supplements, settingsProvider);
return ListView(
padding: const EdgeInsets.all(16),
children: [
if (groupedSupplements['morning']!.isNotEmpty) ...[
_buildSectionHeader('Morning (${settingsProvider.morningRange})', Icons.wb_sunny, Colors.orange, groupedSupplements['morning']!.length),
...groupedSupplements['morning']!.map((supplement) =>
...groupedSupplements['morning']!.map((supplement) =>
SupplementCard(
supplement: supplement,
onTake: () => _showTakeDialog(context, supplement),
@@ -97,10 +123,10 @@ class SupplementsListScreen extends StatelessWidget {
),
const SizedBox(height: 16),
],
if (groupedSupplements['afternoon']!.isNotEmpty) ...[
_buildSectionHeader('Afternoon (${settingsProvider.afternoonRange})', Icons.light_mode, Colors.blue, groupedSupplements['afternoon']!.length),
...groupedSupplements['afternoon']!.map((supplement) =>
...groupedSupplements['afternoon']!.map((supplement) =>
SupplementCard(
supplement: supplement,
onTake: () => _showTakeDialog(context, supplement),
@@ -111,10 +137,10 @@ class SupplementsListScreen extends StatelessWidget {
),
const SizedBox(height: 16),
],
if (groupedSupplements['evening']!.isNotEmpty) ...[
_buildSectionHeader('Evening (${settingsProvider.eveningRange})', Icons.nightlight_round, Colors.indigo, groupedSupplements['evening']!.length),
...groupedSupplements['evening']!.map((supplement) =>
...groupedSupplements['evening']!.map((supplement) =>
SupplementCard(
supplement: supplement,
onTake: () => _showTakeDialog(context, supplement),
@@ -125,10 +151,10 @@ class SupplementsListScreen extends StatelessWidget {
),
const SizedBox(height: 16),
],
if (groupedSupplements['night']!.isNotEmpty) ...[
_buildSectionHeader('Night (${settingsProvider.nightRange})', Icons.bedtime, Colors.purple, groupedSupplements['night']!.length),
...groupedSupplements['night']!.map((supplement) =>
...groupedSupplements['night']!.map((supplement) =>
SupplementCard(
supplement: supplement,
onTake: () => _showTakeDialog(context, supplement),
@@ -139,10 +165,10 @@ class SupplementsListScreen extends StatelessWidget {
),
const SizedBox(height: 16),
],
if (groupedSupplements['anytime']!.isNotEmpty) ...[
_buildSectionHeader('Anytime', Icons.schedule, Colors.grey, groupedSupplements['anytime']!.length),
...groupedSupplements['anytime']!.map((supplement) =>
...groupedSupplements['anytime']!.map((supplement) =>
SupplementCard(
supplement: supplement,
onTake: () => _showTakeDialog(context, supplement),
@@ -305,7 +331,7 @@ class SupplementsListScreen extends StatelessWidget {
),
),
const SizedBox(height: 16),
// Time selection section
Container(
padding: const EdgeInsets.all(12),