refactor: Enhance sync status handling and improve UI feedback in NotesApp

This commit is contained in:
2026-07-02 20:59:22 +02:00
parent f662e59547
commit 9b6d92c372
2 changed files with 66 additions and 14 deletions
+2
View File
@@ -43,3 +43,5 @@ app.*.map.json
/android/app/debug /android/app/debug
/android/app/profile /android/app/profile
/android/app/release /android/app/release
problems-report.html
+56 -6
View File
@@ -87,10 +87,10 @@ class _NotesAppState extends State<NotesApp>
case SyncStatus.waitingResponse: case SyncStatus.waitingResponse:
case SyncStatus.decrypting: case SyncStatus.decrypting:
case SyncStatus.syncing: case SyncStatus.syncing:
return true;
case SyncStatus.idle:
case SyncStatus.synced: case SyncStatus.synced:
case SyncStatus.error: case SyncStatus.error:
return true;
case SyncStatus.idle:
return false; return false;
} }
} }
@@ -103,6 +103,32 @@ class _NotesAppState extends State<NotesApp>
final AppPalette palette = _activePalette(); final AppPalette palette = _activePalette();
final String message = _syncErrorMessage ?? _syncDetailMessage ?? 'Sincronizando...'; final String message = _syncErrorMessage ?? _syncDetailMessage ?? 'Sincronizando...';
final double? progress = _syncProgress; final double? progress = _syncProgress;
final IconData icon;
final Color accentColor;
switch (_syncStatus) {
case SyncStatus.preparing:
case SyncStatus.encrypting:
case SyncStatus.uploading:
case SyncStatus.waitingResponse:
case SyncStatus.decrypting:
case SyncStatus.syncing:
icon = Icons.cloud_sync_outlined;
accentColor = palette.textSecondary;
break;
case SyncStatus.synced:
icon = Icons.check_circle;
accentColor = palette.success;
break;
case SyncStatus.error:
icon = Icons.error;
accentColor = palette.destructiveAccent;
break;
case SyncStatus.idle:
icon = Icons.cloud_sync_outlined;
accentColor = palette.textSecondary;
break;
}
return Material( return Material(
color: palette.surfaceElevated, color: palette.surfaceElevated,
@@ -112,7 +138,7 @@ class _NotesAppState extends State<NotesApp>
child: Container( child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border(top: BorderSide(color: palette.border)), border: Border(top: BorderSide(color: accentColor.withValues(alpha: 0.45))),
), ),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@@ -120,7 +146,7 @@ class _NotesAppState extends State<NotesApp>
children: [ children: [
Row( Row(
children: [ children: [
Icon(Icons.cloud_sync_outlined, color: palette.textSecondary, size: 18), Icon(icon, color: accentColor, size: 18),
const SizedBox(width: 10), const SizedBox(width: 10),
Expanded( Expanded(
child: Text( child: Text(
@@ -136,6 +162,12 @@ class _NotesAppState extends State<NotesApp>
), ),
], ],
), ),
if (_syncStatus == SyncStatus.preparing ||
_syncStatus == SyncStatus.encrypting ||
_syncStatus == SyncStatus.uploading ||
_syncStatus == SyncStatus.waitingResponse ||
_syncStatus == SyncStatus.decrypting ||
_syncStatus == SyncStatus.syncing) ...[
const SizedBox(height: 8), const SizedBox(height: 8),
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular(999), borderRadius: BorderRadius.circular(999),
@@ -146,6 +178,7 @@ class _NotesAppState extends State<NotesApp>
), ),
), ),
], ],
],
), ),
), ),
), ),
@@ -914,8 +947,8 @@ class _NotesAppState extends State<NotesApp>
_homeRefreshToken += 1; _homeRefreshToken += 1;
}); });
// Reset to idle after 3 seconds // Keep the completion state visible briefly so it can be read.
Future<void>.delayed(const Duration(seconds: 3), () { Future<void>.delayed(const Duration(seconds: 1), () {
if (mounted && syncOperationId == _syncOperationId) { if (mounted && syncOperationId == _syncOperationId) {
setState(() { setState(() {
_syncStatus = SyncStatus.idle; _syncStatus = SyncStatus.idle;
@@ -1039,6 +1072,23 @@ class _NotesAppState extends State<NotesApp>
), ),
AnimatedSwitcher( AnimatedSwitcher(
duration: const Duration(milliseconds: 180), duration: const Duration(milliseconds: 180),
switchInCurve: Curves.easeOutCubic,
switchOutCurve: Curves.easeInCubic,
transitionBuilder:
(Widget child, Animation<double> animation) {
final Animation<Offset> slideAnimation = Tween<Offset>(
begin: const Offset(0.0, 0.35),
end: Offset.zero,
).animate(animation);
return FadeTransition(
opacity: animation,
child: SlideTransition(
position: slideAnimation,
child: child,
),
);
},
child: _buildSyncBanner(context), child: _buildSyncBanner(context),
), ),
], ],