part of '../async_action_button.dart'; class _AsyncMixin extends StatefulWidget { final AsyncActionCallback? onPressed; final AsyncActionController? controller; final AsyncErrorBuilder? errorBuilder; final void Function(String message)? onError; final VoidCallback? onSuccess; final Widget Function(BuildContext context, bool busy, VoidCallback? handler) builder; const _AsyncMixin({ required this.onPressed, required this.builder, this.controller, this.errorBuilder, this.onError, this.onSuccess, }); @override State<_AsyncMixin> createState() => _AsyncMixinState(); } class _AsyncMixinState extends State<_AsyncMixin> { late final AsyncActionController _internal; AsyncActionController get _controller => widget.controller ?? _internal; @override void initState() { super.initState(); if (widget.controller == null) { _internal = AsyncActionController(); } _controller.addListener(_onControllerChange); } @override void didUpdateWidget(covariant _AsyncMixin oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.controller != widget.controller) { (oldWidget.controller ?? _internal).removeListener(_onControllerChange); _controller.addListener(_onControllerChange); } } @override void dispose() { _controller.removeListener(_onControllerChange); if (widget.controller == null) { _internal.dispose(); } super.dispose(); } void _onControllerChange() { if (mounted) setState(() {}); } Future _trigger() async { final action = widget.onPressed; if (action == null) return; final success = await _controller.run( action, errorBuilder: widget.errorBuilder, ); if (!mounted) return; if (success) { widget.onSuccess?.call(); } else if (widget.onError != null && _controller.error != null) { widget.onError!(_controller.error!); } } @override Widget build(BuildContext context) { final handler = widget.onPressed == null ? null : _trigger; return widget.builder( context, _controller.busy, _controller.busy ? null : handler, ); } } class _InlineErrorWrapper extends StatelessWidget { final AsyncActionController? controller; final Widget child; const _InlineErrorWrapper({required this.controller, required this.child}); @override Widget build(BuildContext context) { final c = controller; if (c == null) return child; return AnimatedBuilder( animation: c, builder: (context, _) { final err = c.error; return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ child, if (err != null) ...[ const SizedBox(height: 8), Text( err, textAlign: TextAlign.center, style: TextStyle( color: Theme.of(context).colorScheme.error, fontSize: 13, ), ), ], ], ); }, ); } }