import 'dart:async'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../services/app_state.dart'; import 'backup_reminder.dart'; /// AppBar action flagging that this device's data isn't fully backed up — /// the same "shared widget dropped into every tab's AppBar" pattern /// [FaqActionButton] uses. Renders nothing once backup is configured *and* /// there's nothing unsynced (see [AppState.hasCloudBackupConfigured] / /// [AppState.hasUnsyncedChanges]); there's nothing left to flag at that /// point. Covers two different states behind one icon: /// - Backup was never set up — tapping opens the setup flow. /// - Backup *is* set up but something local hasn't been pushed up yet /// (most users, most of the time, since only a paid user auto-syncs on /// every change — see [AppState.hasUnsyncedChanges]) — tapping tries a /// sync right now, going through the normal ad gate. /// /// The small play-triangle badge marks this as potentially leading to an /// ad: syncing needs a rewarded ad to push local changes up on every sync /// but the first (see `AdService.showGateAd`) — unless the user has an /// active ad-free purchase, in which case syncing is silent and free. The /// badge only shows for someone who'd actually see an ad, so a paid user /// gets a plain icon instead. class CloudBackupActionButton extends StatelessWidget { const CloudBackupActionButton({super.key}); @override Widget build(BuildContext context) { final appState = context.watch(); final configured = appState.hasCloudBackupConfigured; if (configured && !appState.hasUnsyncedChanges) return const SizedBox.shrink(); final showAdBadge = !appState.adsCurrentlyDisabled; final colors = Theme.of(context).colorScheme; const icon = Icon(Icons.cloud_off_outlined); return IconButton( tooltip: configured ? 'Not synced yet — tap to sync now' : 'Not backed up — set up cloud backup', onPressed: () { if (configured) { unawaited(appState.syncNow()); } else { openCloudBackupSetup(context); } }, icon: showAdBadge ? Badge( backgroundColor: colors.tertiary, label: Icon(Icons.play_arrow, size: 8, color: colors.onTertiary), child: icon, ) : icon, ); } }