diff --git a/lib/app.dart b/lib/app.dart index 294aec3..aa41f9f 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -193,7 +193,7 @@ class _ShellState extends ConsumerState<_Shell> with WidgetsBindingObserver { ]; // Minimum gap between app-resume refreshes to avoid hammering the server. - static const _resumeCooldown = Duration(minutes: 5); + static const _resumeCooldown = Duration(seconds: 30); DateTime? _lastResumeRefresh; int? _prevTabIndex; diff --git a/lib/screens/calendar/calendar_screen.dart b/lib/screens/calendar/calendar_screen.dart index 68751a5..0d0394e 100644 --- a/lib/screens/calendar/calendar_screen.dart +++ b/lib/screens/calendar/calendar_screen.dart @@ -67,10 +67,13 @@ class CalendarScreen extends ConsumerWidget { ), const Divider(height: 1), Expanded( - child: _AgendaList( - events: - cal.eventsByDay[dateOnly(cal.selectedDay)] ?? [], - notifier: notifier, + child: RefreshIndicator( + onRefresh: () async => ref.invalidate(calendarProvider), + child: _AgendaList( + events: + cal.eventsByDay[dateOnly(cal.selectedDay)] ?? [], + notifier: notifier, + ), ), ), ], @@ -106,7 +109,12 @@ class _AgendaList extends StatelessWidget { @override Widget build(BuildContext context) { if (events.isEmpty) { - return const Center(child: Text('No events')); + return ListView( + children: const [ + SizedBox(height: 80), + Center(child: Text('No events')), + ], + ); } return ListView.builder( padding: const EdgeInsets.symmetric(vertical: 8), diff --git a/lib/screens/chat/chat_screen.dart b/lib/screens/chat/chat_screen.dart index 0dbb479..7520aea 100644 --- a/lib/screens/chat/chat_screen.dart +++ b/lib/screens/chat/chat_screen.dart @@ -16,12 +16,27 @@ class ChatScreen extends ConsumerStatefulWidget { ConsumerState createState() => _ChatScreenState(); } -class _ChatScreenState extends ConsumerState { +class _ChatScreenState extends ConsumerState + with WidgetsBindingObserver { final _controller = TextEditingController(); final _scrollController = ScrollController(); + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addObserver(this); + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + if (state == AppLifecycleState.resumed) { + ref.invalidate(messagesProvider(widget.conversationId)); + } + } + @override void dispose() { + WidgetsBinding.instance.removeObserver(this); _controller.dispose(); _scrollController.dispose(); // Exit voice mode if the user navigates away mid-session. diff --git a/lib/screens/news/news_screen.dart b/lib/screens/news/news_screen.dart index 3094581..be3d16c 100644 --- a/lib/screens/news/news_screen.dart +++ b/lib/screens/news/news_screen.dart @@ -96,7 +96,9 @@ class _NewsScreenState extends ConsumerState { ), const Divider(height: 1), Expanded( - child: ListView.builder( + child: RefreshIndicator( + onRefresh: () async => ref.invalidate(newsProvider), + child: ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8), itemCount: news.items.length + 1, @@ -128,6 +130,7 @@ class _NewsScreenState extends ConsumerState { ); }, ), + ), ), ], ),