// Generic Interface for all BLoCs
import 'package:flutter/material.dart';

// 用法参考 https://www.dazhuanlan.com/2019/10/05/5d9835e2149ec/?__cf_chl_jschl_tk__=c887a5bbcade5b1c4e512e339d6456adc0a9e1e8-1589771890-0-AaeNBGzxeReSfKWxA7TZlNbvVfXjv759gU0mNNvmcB14JVlRVGLhl1cVJAVapb4Nc6W_mcSvPtAJQQ8okAWy4d9SdnrUcUJmZQJq2XP59oNFEEAg5oP9GhCHMvR2bqpWQzZXIKgIn3m_GvRMZ1B5lpGP-HPtkjjpb4vO4NHzRgnwwRJtm3-HEeknIa53PShS5wY4EEPXI4i8UdtJRc8oXlzYdNFzVJ_QteCKS6v2jsmP4LzGFo3zFspPF63dj5px-6nMLQlz2sKFSimTI7DQD4baHMDDSZr_4G_vohZjy7Ye1Qy_JHWTT_2TkW60f99AwA
abstract class BlocBase {
  void dispose();
}

// Generic BLoC provider
class BlocProvider<T extends BlocBase> extends StatefulWidget {
  BlocProvider({
    Key key,
    @required this.child,
    @required this.bloc,
  }) : super(key: key);

  final T bloc;
  final Widget child;

  @override
  _BlocProviderState<T> createState() => _BlocProviderState<T>();

  static T of<T extends BlocBase>(BuildContext context) {
    final type = _typeOf<BlocProvider<T>>();
    BlocProvider<T> provider = context.ancestorWidgetOfExactType(type);
    return provider.bloc;
  }

  static Type _typeOf<T>() => T;
}

class _BlocProviderState<T> extends State<BlocProvider<BlocBase>> {
  @override
  void dispose() {
    widget.bloc.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}