srs/lib/widgets/auto_refresh.dart
Aswin Biju 749d18192a
All checks were successful
deploy / deploy (push) Successful in 4m58s
refactor: updated UI and other trivial fixes
2026-11-05 10:13:32 +05:30

86 lines
2.3 KiB
Dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../core/providers.dart';
class AutoRefresh extends ConsumerStatefulWidget {
const AutoRefresh({super.key, required this.location, required this.child});
final String location;
final Widget child;
static const pollEvery = Duration(seconds: 60);
static const gap = Duration(seconds: 30);
static const resumeGap = Duration(seconds: 30);
@override
ConsumerState<AutoRefresh> createState() => _AutoRefreshState();
}
class _AutoRefreshState extends ConsumerState<AutoRefresh>
with WidgetsBindingObserver {
Timer? _poll, _cool, _resumeCool;
static const _lists = ['/results', '/shops', '/orders', '/users'];
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
_poll = Timer.periodic(AutoRefresh.pollEvery, (_) => _onPoll());
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
_poll?.cancel();
_cool?.cancel();
_resumeCool?.cancel();
super.dispose();
}
bool get _onList => _lists.contains(widget.location);
bool get _visible {
final s = WidgetsBinding.instance.lifecycleState;
return s == null || s == AppLifecycleState.resumed;
}
// False while a sheet or dialog sits on top of the screen.
bool get _uncovered => ModalRoute.of(context)?.isCurrent ?? true;
bool get _signedIn => ref.read(sessionProvider) != null;
void _reload() => ref.read(dataVersionProvider.notifier).bump();
void _onPoll() {
if (_cool != null ||
!_visible ||
!_signedIn ||
!_uncovered ||
widget.location != '/orders') {
return;
}
_reload();
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state != AppLifecycleState.resumed) return;
if (_resumeCool != null || !_signedIn || !_onList || !_uncovered) return;
_reload();
_resumeCool = Timer(AutoRefresh.resumeGap, () => _resumeCool = null);
}
@override
Widget build(BuildContext context) {
// Every reload, whoever started it, restarts the quiet period.
ref.listen(dataVersionProvider, (_, _) {
_cool?.cancel();
_cool = Timer(AutoRefresh.gap, () => _cool = null);
});
return widget.child;
}
}