feat: Add refresh token mechanism and sync request handling in home screen
This commit is contained in:
@@ -70,6 +70,7 @@ class _NotesAppState extends State<NotesApp>
|
||||
_AppSection _currentSection = _AppSection.home;
|
||||
SyncStatus _syncStatus = SyncStatus.idle;
|
||||
String? _syncErrorMessage;
|
||||
int _homeRefreshToken = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -613,6 +614,10 @@ class _NotesAppState extends State<NotesApp>
|
||||
return;
|
||||
}
|
||||
|
||||
if (_syncStatus == SyncStatus.syncing) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_syncStatus = SyncStatus.syncing;
|
||||
_syncErrorMessage = null;
|
||||
@@ -634,6 +639,7 @@ class _NotesAppState extends State<NotesApp>
|
||||
setState(() {
|
||||
_syncStatus = SyncStatus.synced;
|
||||
_syncErrorMessage = null;
|
||||
_homeRefreshToken += 1;
|
||||
});
|
||||
|
||||
// Reset to idle after 3 seconds
|
||||
@@ -704,9 +710,11 @@ class _NotesAppState extends State<NotesApp>
|
||||
key: const ValueKey<String>('home-screen'),
|
||||
repository: repository,
|
||||
onOpenSettings: _openSettings,
|
||||
onRequestSync: _performSync,
|
||||
onVaultInvalid: _resetLocalVaultData,
|
||||
syncStatus: _syncStatus,
|
||||
syncErrorMessage: _syncErrorMessage,
|
||||
refreshToken: _homeRefreshToken,
|
||||
)
|
||||
: SettingsScreen(
|
||||
key: const ValueKey<String>('settings-screen'),
|
||||
|
||||
@@ -17,16 +17,20 @@ class HomeScreen extends StatefulWidget {
|
||||
super.key,
|
||||
required this.repository,
|
||||
required this.onOpenSettings,
|
||||
required this.onRequestSync,
|
||||
this.onVaultInvalid,
|
||||
this.syncStatus = SyncStatus.idle,
|
||||
this.syncErrorMessage,
|
||||
this.refreshToken = 0,
|
||||
});
|
||||
|
||||
final NoteRepository repository;
|
||||
final VoidCallback onOpenSettings;
|
||||
final Future<void> Function() onRequestSync;
|
||||
final Future<void> Function()? onVaultInvalid;
|
||||
final SyncStatus syncStatus;
|
||||
final String? syncErrorMessage;
|
||||
final int refreshToken;
|
||||
|
||||
@override
|
||||
State<HomeScreen> createState() => _HomeScreenState();
|
||||
@@ -52,6 +56,14 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
_loadNotes();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant HomeScreen oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.refreshToken != widget.refreshToken) {
|
||||
_loadNotes();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadNotes() async {
|
||||
try {
|
||||
final List<Note> storedNotes = await widget.repository.loadNotes();
|
||||
@@ -92,10 +104,9 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
_notes = updatedNotes;
|
||||
});
|
||||
|
||||
// Trigger sync after creating a note and refresh local list
|
||||
// Trigger sync after creating a note.
|
||||
try {
|
||||
await widget.repository.performSync();
|
||||
await _loadNotes();
|
||||
await widget.onRequestSync();
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
@@ -115,10 +126,9 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
_notes = updatedNotes;
|
||||
});
|
||||
|
||||
// Trigger sync after deleting a note and refresh local list
|
||||
// Trigger sync after deleting a note.
|
||||
try {
|
||||
await widget.repository.performSync();
|
||||
await _loadNotes();
|
||||
await widget.onRequestSync();
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
@@ -171,10 +181,9 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
setState(() {
|
||||
_notes = _normalizeNotes(updatedNotes);
|
||||
});
|
||||
// Trigger sync after editing a note and refresh local list
|
||||
// Trigger sync after editing a note.
|
||||
try {
|
||||
await widget.repository.performSync();
|
||||
await _loadNotes();
|
||||
await widget.onRequestSync();
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
@@ -212,10 +221,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
? const _EmptyState()
|
||||
: RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
try {
|
||||
await widget.repository.performSync();
|
||||
} catch (_) {}
|
||||
await _loadNotes();
|
||||
await widget.onRequestSync();
|
||||
},
|
||||
child: MouseRegion(
|
||||
cursor: _isDragging
|
||||
@@ -520,6 +526,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
trailingWidget: SyncStatusIndicator(
|
||||
status: widget.syncStatus,
|
||||
errorMessage: widget.syncErrorMessage,
|
||||
onTap: widget.onRequestSync,
|
||||
),
|
||||
onSearchChanged: (String query) {
|
||||
setState(() {
|
||||
|
||||
@@ -11,29 +11,49 @@ class SyncStatusIndicator extends StatelessWidget {
|
||||
const SyncStatusIndicator({
|
||||
required this.status,
|
||||
this.errorMessage,
|
||||
this.onTap,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final SyncStatus status;
|
||||
final String? errorMessage;
|
||||
final VoidCallback? onTap;
|
||||
|
||||
Widget _buildIndicator(Widget child) {
|
||||
if (onTap == null) {
|
||||
return child;
|
||||
}
|
||||
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: onTap,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
switch (status) {
|
||||
case SyncStatus.idle:
|
||||
return const Tooltip(
|
||||
return Tooltip(
|
||||
message: 'Sincronización en espera',
|
||||
child: Icon(
|
||||
child: _buildIndicator(
|
||||
const Icon(
|
||||
Icons.cloud_outlined,
|
||||
size: 16,
|
||||
color: Colors.white38,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
case SyncStatus.syncing:
|
||||
return const Tooltip(
|
||||
return Tooltip(
|
||||
message: 'Sincronizando...',
|
||||
child: SizedBox(
|
||||
child: _buildIndicator(
|
||||
const SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: CircularProgressIndicator(
|
||||
@@ -43,26 +63,31 @@ class SyncStatusIndicator extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
case SyncStatus.synced:
|
||||
return const Tooltip(
|
||||
return Tooltip(
|
||||
message: 'Sincronizado',
|
||||
child: Icon(
|
||||
child: _buildIndicator(
|
||||
const Icon(
|
||||
Icons.check_circle,
|
||||
size: 16,
|
||||
color: Colors.green,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
case SyncStatus.error:
|
||||
return Tooltip(
|
||||
message: errorMessage ?? 'Error al sincronizar',
|
||||
child: const Icon(
|
||||
child: _buildIndicator(
|
||||
const Icon(
|
||||
Icons.error,
|
||||
size: 16,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user