import 'package:flutter/material.dart'; import '../infrastructure/controller.dart'; import '../infrastructure/loadable_state.dart'; import '../infrastructure/state_extensions.dart'; class LoadableControllerConsumer, TState extends LoadableState> extends StatelessWidget { final Widget child; const LoadableControllerConsumer({required this.child, super.key}); final Duration animationDuration = const Duration(milliseconds: 200); @override Widget build(BuildContext context) { var state = context.readController().state; var loadableContent = Stack( children: [ AnimatedOpacity( opacity: !state.hasStateData() ? 1.0 : 0.0, duration: animationDuration, curve: Curves.easeInOut, child: const Center(child: CircularProgressIndicator()), ), AnimatedSwitcher( duration: animationDuration, transitionBuilder: (Widget child, Animation animation) => SlideTransition( position: Tween( begin: const Offset(0.0, -1.0), end: Offset.zero, ).animate(animation), child: child, ), child: state.isBackgroundLoading() && !state.errorBarVisible() ? const LinearProgressIndicator() : const SizedBox.shrink(), ), AnimatedOpacity( opacity: state.hasStateData() ? 1.0 : 0.0, duration: animationDuration, curve: Curves.easeInOut, child: state.hasStateData() ? child : const SizedBox.shrink() ), ], ); var errorBar = AnimatedSwitcher( duration: animationDuration, transitionBuilder: (Widget child, Animation animation) => SlideTransition( position: Tween( begin: const Offset(0.0, -1.0), end: Offset.zero, ).animate(animation), child: child, ), child: !state.errorBarVisible() ? const SizedBox.shrink() : Container( height: 20, decoration: const BoxDecoration( color: Colors.red, ), child: const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.wifi_find_outlined, size: 12), SizedBox(width: 10), Text('Keine Verbindung', style: TextStyle(fontSize: 12)) ], ), ), ); return Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [errorBar, loadableContent], ); } }