refactor: Enhance sync status handling and improve UI feedback in NotesApp
This commit is contained in:
@@ -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
|
||||||
+64
-14
@@ -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,15 +162,22 @@ class _NotesAppState extends State<NotesApp>
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
if (_syncStatus == SyncStatus.preparing ||
|
||||||
ClipRRect(
|
_syncStatus == SyncStatus.encrypting ||
|
||||||
borderRadius: BorderRadius.circular(999),
|
_syncStatus == SyncStatus.uploading ||
|
||||||
child: LinearProgressIndicator(
|
_syncStatus == SyncStatus.waitingResponse ||
|
||||||
minHeight: 4,
|
_syncStatus == SyncStatus.decrypting ||
|
||||||
value: progress,
|
_syncStatus == SyncStatus.syncing) ...[
|
||||||
backgroundColor: palette.borderMuted,
|
const SizedBox(height: 8),
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(999),
|
||||||
|
child: LinearProgressIndicator(
|
||||||
|
minHeight: 4,
|
||||||
|
value: progress,
|
||||||
|
backgroundColor: palette.borderMuted,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -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),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user