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 extends State { final _subscriptions = List(); final _timers = List(); 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(void onEvent(T event)) { _subscriptions.add(EventsHelper.on(onEvent)); } /// Register to a new subscription /// /// Callback will we called inside of setState @protected void listenChangeState(void onEvent(T event)) { _subscriptions.add(EventsHelper.on((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); } }