roughike/streaming_shared_preferences

Extending PreferenceBuilder to multiple values

degloff opened this issue · 2 comments

I like the PreferenceBuilder a lot. It would be even better if there would be a MultiPreferenceBuilder that allows to listen on multiple changing values, probably with Rx.combineLatest. It is a bit tedious to implement, as we would need to have it for 2, 3, 4, etc. Would it be possible to add such a feature?

Great idea! I'm working on it.

I'll likely have support for listening to 3 preferences. If you need more than that, you should maybe rethink your code. That said, I'll make it easy to extend to more than 3 preferences.

@TheBestMoshe & @degloff this is the current plan.

Let's say we have these three preferences:

PreferenceBuilder3<String, int, bool>(
  preferences.getString('name'),
  preferences.getInt('age'),
  preferences.getBool('isAwesome'),
  builder: (BuildContext context, String name, int age, bool isAwesome) {
    // Do something with "name", "age", and "isAwesome" typed values.
  },
)

It works a bit like combineLatest() from rxdart/rxjava/rx*, but without the rxdart dependency.

The order of the arguments in the builder method is the same order as they were passed as arguments for the PreferenceBuilder3.
The generic type arguments (=<String, int, bool>), which can be inferred, must also be in the same order.

There's also a PreferenceBuilder2 for watching changes and rebuilding a widget based on two preference values.

I'm not making PreferenceBuilder4, PreferenceBuilder5, etc - I think at that point you probably want to rethink your code.
If you're sure about it, it's possible to make your own PreferenceBuilder4 (or 5, 6, 7, etc.) by extending PreferenceBuilderBase:

typedef PreferenceWidgetBuilder4<A, B, C, D> = Widget Function(
  BuildContext context,
  A a,
  B b,
  C c,
  D d,
);

class PreferenceBuilder4<A, B, C, D> extends PreferenceBuilderBase<dynamic> {
  PreferenceBuilder4(
    this.a,
    this.b,
    this.c, 
    this.d, {
    Key key,
    @required this.builder,
  }) : super(preferences: [a, b, c, d], key: key);

  final Preference<A> a;
  final Preference<B> b;
  final Preference<C> c;
  final Preference<D> d;
  final PreferenceWidgetBuilder4<A, B, C, D> builder;

  @override
  Widget build(BuildContext context, List<dynamic> values) {
    return builder(
      context,
      values[0] as A,
      values[1] as B,
      values[2] as C,
      values[3] as D,
    );
  }
}

I should have this on the master branch this week, then I'll do some testing and make a new release.

Let me know what you think!