verbindings_banner.dart.txt 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Automatic FlutterFlow imports
  2. import '/backend/schema/structs/index.dart';
  3. import '/flutter_flow/flutter_flow_theme.dart';
  4. import '/flutter_flow/flutter_flow_util.dart';
  5. import 'index.dart'; // Imports other custom widgets
  6. import '/custom_code/actions/index.dart'; // Imports custom actions
  7. import '/flutter_flow/custom_functions.dart'; // Imports custom functions
  8. import 'package:flutter/material.dart';
  9. // Begin custom widget code
  10. // DO NOT REMOVE OR MODIFY THE CODE ABOVE!
  11. // ⬇⬇⬇ PLAK VANAF HIER ⬇⬇⬇
  12. // (deze import mag, maar is niet strikt nodig: go_router komt hier ook
  13. // via de FlutterFlow-imports binnen — getest 2026-09-13)
  14. import 'package:go_router/go_router.dart';
  15. /// Balkje dat zichzelf toont zodra de server onbereikbaar is.
  16. ///
  17. /// Waarom een custom widget en geen Text met een Visibility-conditie: de
  18. /// widgets in dit project lezen App State via de singleton `FFAppState()`,
  19. /// niet via `context.watch`. Een gewone conditie zou dus pas opnieuw
  20. /// evalueren als er toevallig iets anders een rebuild veroorzaakt. Dit
  21. /// widget luistert zelf naar FFAppState en verschijnt daardoor direct.
  22. class VerbindingsBanner extends StatefulWidget {
  23. const VerbindingsBanner({
  24. super.key,
  25. this.width,
  26. this.height,
  27. this.tekst,
  28. });
  29. final double? width;
  30. final double? height;
  31. final String? tekst;
  32. @override
  33. State<VerbindingsBanner> createState() => _VerbindingsBannerState();
  34. }
  35. class _VerbindingsBannerState extends State<VerbindingsBanner> {
  36. // Gedeeld over alle instanties: bij het doorklikken tussen pagina's wordt
  37. // niet bij elke opbouw opnieuw een verzoek gedaan.
  38. static DateTime? _laatsteCheck;
  39. static const Duration _minimaalTussenChecks = Duration(seconds: 20);
  40. bool _bezig = false;
  41. @override
  42. void initState() {
  43. super.initState();
  44. WidgetsBinding.instance.addPostFrameCallback((_) => _checkIndienNodig());
  45. }
  46. Future<void> _checkIndienNodig() async {
  47. final vorige = _laatsteCheck;
  48. if (vorige != null &&
  49. DateTime.now().difference(vorige) < _minimaalTussenChecks) {
  50. return;
  51. }
  52. await _check(herlaadBijHerstel: false);
  53. }
  54. /// [herlaadBijHerstel] staat alleen aan bij een tik van de gebruiker.
  55. /// Automatisch herladen zou een lus opleveren: de pagina bouwt het widget
  56. /// opnieuw op, dat checkt weer, enzovoort.
  57. Future<void> _check({bool herlaadBijHerstel = true}) async {
  58. if (_bezig) return;
  59. if (mounted) setState(() => _bezig = true);
  60. _laatsteCheck = DateTime.now();
  61. bool bereikbaar = false;
  62. try {
  63. bereikbaar = await checkVerbinding();
  64. } finally {
  65. if (mounted) setState(() => _bezig = false);
  66. }
  67. if (bereikbaar && herlaadBijHerstel && mounted) {
  68. // De FutureBuilders op deze pagina zijn al klaar met een mislukte
  69. // respons; alleen de balk weghalen laat een leeg scherm achter.
  70. // Daarom de huidige route opnieuw opbouwen, zodat de data alsnog laadt.
  71. final huidigePad = GoRouterState.of(context).uri.toString();
  72. context.pushReplacement(huidigePad);
  73. }
  74. }
  75. @override
  76. Widget build(BuildContext context) {
  77. return AnimatedBuilder(
  78. animation: FFAppState(),
  79. builder: (context, _) {
  80. if (!FFAppState().geenVerbinding) {
  81. // Neemt geen ruimte in zolang alles in orde is.
  82. return const SizedBox.shrink();
  83. }
  84. return Material(
  85. color: Colors.transparent,
  86. child: InkWell(
  87. onTap: () => _check(),
  88. child: Container(
  89. width: widget.width ?? double.infinity,
  90. height: widget.height,
  91. color: FlutterFlowTheme.of(context).primary,
  92. padding:
  93. const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
  94. child: Row(
  95. mainAxisSize: MainAxisSize.max,
  96. children: [
  97. const Icon(Icons.cloud_off, color: Colors.white, size: 18.0),
  98. const SizedBox(width: 8.0),
  99. Expanded(
  100. child: Text(
  101. widget.tekst ??
  102. 'Geen verbinding — tik om het opnieuw te proberen',
  103. style: const TextStyle(
  104. color: Colors.white,
  105. fontSize: 13.0,
  106. ),
  107. ),
  108. ),
  109. if (_bezig)
  110. const SizedBox(
  111. width: 14.0,
  112. height: 14.0,
  113. child: CircularProgressIndicator(
  114. strokeWidth: 2.0,
  115. color: Colors.white,
  116. ),
  117. ),
  118. ],
  119. ),
  120. ),
  121. ),
  122. );
  123. },
  124. );
  125. }
  126. }