import 'dart:async'; import 'package:comunic/helpers/events_helper.dart'; import 'package:flutter/material.dart'; /// Little State hack to avoid issues /// /// @author Pierre HUBERT abstract class SafeState<T extends StatefulWidget> extends State<T> { final _subscriptions = List<StreamSubscription>(); final _timers = List<Timer>(); bool _unmounted = false; @override void dispose() { _unmounted = true; // Close subscriptions _subscriptions.forEach((f) => f.cancel()); // Stop intervals _timers.forEach((f) => f.cancel()); super.dispose(); } @override void setState(fn) { if (mounted && !_unmounted) super.setState(fn); } /// Register to a new subscription @protected void listen<T>(void onEvent(T event)) { _subscriptions.add(EventsHelper.on<T>(onEvent)); } /// Register to a new subscription /// /// Callback will we called inside of setState @protected void listenChangeState<T>(void onEvent(T event)) { _subscriptions.add(EventsHelper.on<T>((d) { setState(() => onEvent(d)); })); } /// Safely mimic the setTimeout javascript function /// /// If the widget is unmounted before the end of the timeout, /// the callback function is not called void setTimeout(int secs, void Function() cb) { Timer(Duration(seconds: secs), () { if (!_unmounted) cb(); }); } /// Safely mimic the setInterval javascript function void setInterval(int secs, void Function(Timer) cb) { final timer = Timer.periodic(Duration(seconds: secs), cb); _timers.add(timer); } }