import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:logging/logging.dart'; import 'package:moneymgr_mobile/services/api/api_client.dart'; import 'package:moneymgr_mobile/services/api/files_api.dart'; import 'package:moneymgr_mobile/services/storage/expenses.dart'; import 'package:moneymgr_mobile/utils/extensions.dart'; import 'package:moneymgr_mobile/utils/hooks.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'synchronize_button.g.dart'; /// Synchronize expenses list with backend @riverpod Future _performSynchronization(Ref ref) async { final expenses = ref.watch(expensesProvider).requireValue; final apiService = ref.watch(apiServiceProvider)!; final list = await expenses.getList(); for (final exp in list) { // First, upload file final bytes = await expenses.loadFile(exp); final file = await apiService.uploadFile( filename: exp.localFileName, mimeType: exp.mimeType, bytes: bytes, ); // TODO continue break; } } class SynchronizeButton extends HookConsumerWidget { const SynchronizeButton({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final (:pending, :snapshot, :hasError) = useAsyncTask(); handleSynchronize() async { try { await ref.watch( _performSynchronizationProvider.selectAsync((it) => it), ); } catch (e, s) { Logger.root.warning("Failed to synchronize expenses! $e $s"); if (context.mounted) { context.showTextSnackBar("Failed to synchronize expenses! $e"); } } } return snapshot.connectionState == ConnectionState.waiting ? Padding( padding: const EdgeInsets.all(12.0), child: SizedBox( height: 20, width: 20, child: CircularProgressIndicator(strokeWidth: 2), ), ) : IconButton( onPressed: () => pending.value = handleSynchronize(), style: ButtonStyle( backgroundColor: hasError ? WidgetStatePropertyAll(Colors.red) : null, ), icon: Icon(Icons.sync_rounded), ); } }