Flutterando / triple_pattern

Segmented State Pattern for Reactive Property
MIT License
160 stars 36 forks source link

Triple 2.1.0 release introduced a new bug which cause onLoading is not triggered on following setLoading(false) calls #118

Open yubinz68 opened 9 months ago

yubinz68 commented 9 months ago

Describe the bug I have setup the store.observer to monitor loading state change and showing an overlay with circular progress indicator when isLoading=true and remove the overlay when isLoading=false. In side a store method, I have code call setLoading(true), update(),setLoading(false). Neither update() nor setLoading(false) triggered store.observer's onLading method. The behaviour results the overlay is always displaying and can not be removed.

Environment

To Reproduce import 'package:flutter/material.dart'; import 'package:flutter_triple/flutter_triple.dart';

void main() { runApp(MyApp()); }

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }

class MyHomePage extends StatefulWidget { MyHomePage({Key? key, required this.title}) : super(key: key); final String title;

@override _MyHomePageState createState() => _MyHomePageState(); }

class _MyHomePageState extends State { final counter = CounterStore(); late Disposer disposer;

@override void initState() { super.initState();

disposer = counter.observer(onState: print,onLoading: print);

}

@override void dispose() { super.dispose(); disposer(); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), actions: [ IconButton( onPressed: counter.undo, icon: Icon(Icons.arrow_back_ios), ), IconButton( onPressed: counter.redo, icon: Icon(Icons.arrow_forward_ios), ), ], ), body: Center( child: ScopedConsumer<CounterStore, int>( store: counter, onLoadingListener: (context, isLoading) {}, onErrorListener: (context, error) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(error.toString()), ), ); }, onLoadingBuilder: (context) => Text('Carregando...'), onStateBuilder: (context, state) { return Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('You have pushed the button 399 this many times:'), Text( '$state', style: Theme.of(context).textTheme.headlineMedium, ), ], ); }, ), ), floatingActionButton: TripleBuilder<CounterStore, int>( store: counter, builder: (context, triple) { return FloatingActionButton( onPressed: triple.isLoading ? null : counter.increment, tooltip: triple.isLoading ? 'no-active' : 'Increment', backgroundColor: triple.isLoading ? Colors.grey : Theme.of(context).primaryColor, child: Icon(Icons.add), ); }, ), ); } }

class CounterStore extends Store with MementoMixin { CounterStore() : super(0);

Future increment() async { setLoading(true); await Future.delayed(Duration(milliseconds: 1000)); update(state + 1); setLoading(false); } }

Expected behavior expect to see the console: true 1 false true 2 false

Screenshots but i see the console: true 1 true 2

Screen Shot 2024-01-25 at 4 57 43 PM
yubinz68 commented 9 months ago

after looking into the source code in base_store.dart,

Screen Shot 2024-01-25 at 5 08 37 PM Screen Shot 2024-01-25 at 5 08 56 PM

following changes can resolve the issue

Screen Shot 2024-01-25 at 5 07 59 PM Screen Shot 2024-01-25 at 5 08 20 PM