feat: Refactor sync status handling and improve synchronization feedback in the app

This commit is contained in:
2026-05-19 09:23:38 +02:00
parent bb8caeef93
commit a5ab223e1f
6 changed files with 388 additions and 128 deletions
+127 -34
View File
@@ -1,21 +1,19 @@
import 'package:flutter/material.dart';
enum SyncStatus {
idle,
syncing,
synced,
error,
}
import 'package:notas/widgets/sync_status.dart';
class SyncStatusIndicator extends StatelessWidget {
const SyncStatusIndicator({
required this.status,
this.progress,
this.detailMessage,
this.errorMessage,
this.onTap,
super.key,
});
final SyncStatus status;
final double? progress;
final String? detailMessage;
final String? errorMessage;
final VoidCallback? onTap;
@@ -34,59 +32,154 @@ class SyncStatusIndicator extends StatelessWidget {
);
}
String _messageForStatus() {
switch (status) {
case SyncStatus.idle:
return 'Sincronización en espera';
case SyncStatus.preparing:
return detailMessage ?? 'Preparando sincronización...';
case SyncStatus.encrypting:
return detailMessage ?? 'Encriptando datos para subir...';
case SyncStatus.uploading:
return detailMessage ?? 'Subiendo datos al servidor...';
case SyncStatus.waitingResponse:
return detailMessage ?? 'Esperando respuesta del servidor...';
case SyncStatus.decrypting:
return detailMessage ?? 'Desencriptando datos recibidos...';
case SyncStatus.syncing:
return detailMessage ?? 'Sincronizando...';
case SyncStatus.synced:
return detailMessage ?? 'Sincronizado';
case SyncStatus.error:
return errorMessage ?? detailMessage ?? 'Error al sincronizar';
}
}
Widget _buildStatusBadge({
required IconData icon,
required Color color,
required bool determinate,
}) {
final double ringProgress = (progress ?? 0).clamp(0.0, 1.0);
return SizedBox(
width: 18,
height: 18,
child: Stack(
alignment: Alignment.center,
children: [
SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(
strokeWidth: 2,
value: determinate ? ringProgress : null,
backgroundColor: color.withValues(alpha: 0.16),
valueColor: AlwaysStoppedAnimation<Color>(color),
),
),
Icon(icon, size: 10, color: color),
],
),
);
}
@override
Widget build(BuildContext context) {
switch (status) {
case SyncStatus.idle:
return Tooltip(
message: 'Sincronización en espera',
message: _messageForStatus(),
child: _buildIndicator(
const Icon(
Icons.cloud_outlined,
size: 16,
color: Colors.white38,
const Icon(Icons.cloud_outlined, size: 16, color: Colors.white38),
),
);
case SyncStatus.preparing:
return Tooltip(
message: _messageForStatus(),
child: _buildIndicator(
_buildStatusBadge(
icon: Icons.sync,
color: const Color.fromARGB(255, 165, 165, 165),
determinate: false,
),
),
);
case SyncStatus.encrypting:
return Tooltip(
message: _messageForStatus(),
child: _buildIndicator(
_buildStatusBadge(
icon: Icons.cloud_upload_outlined,
color: const Color.fromARGB(255, 109, 191, 255),
determinate: true,
),
),
);
case SyncStatus.uploading:
return Tooltip(
message: _messageForStatus(),
child: _buildIndicator(
_buildStatusBadge(
icon: Icons.cloud_upload,
color: const Color.fromARGB(255, 98, 190, 255),
determinate: false,
),
),
);
case SyncStatus.waitingResponse:
return Tooltip(
message: _messageForStatus(),
child: _buildIndicator(
_buildStatusBadge(
icon: Icons.cloud_sync_outlined,
color: const Color.fromARGB(255, 150, 150, 150),
determinate: false,
),
),
);
case SyncStatus.decrypting:
return Tooltip(
message: _messageForStatus(),
child: _buildIndicator(
_buildStatusBadge(
icon: Icons.cloud_download_outlined,
color: const Color.fromARGB(255, 154, 194, 112),
determinate: false,
),
),
);
case SyncStatus.syncing:
return Tooltip(
message: 'Sincronizando...',
message: _messageForStatus(),
child: _buildIndicator(
const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(
Color.fromARGB(255, 150, 150, 150),
),
),
_buildStatusBadge(
icon: Icons.sync,
color: const Color.fromARGB(255, 150, 150, 150),
determinate: false,
),
),
);
case SyncStatus.synced:
return Tooltip(
message: 'Sincronizado',
message: _messageForStatus(),
child: _buildIndicator(
const Icon(
Icons.check_circle,
size: 16,
color: Colors.green,
),
const Icon(Icons.check_circle, size: 16, color: Colors.green),
),
);
case SyncStatus.error:
return Tooltip(
message: errorMessage ?? 'Error al sincronizar',
message: _messageForStatus(),
child: _buildIndicator(
const Icon(
Icons.error,
size: 16,
color: Colors.red,
),
const Icon(Icons.error, size: 16, color: Colors.red),
),
);
}