ui backbone

This commit is contained in:
Mehul Ahal 2022-12-20 21:52:24 +01:00
parent 3e374d24f6
commit b7045fc242
24 changed files with 918 additions and 73 deletions

View file

@ -1,5 +1,4 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
@ -9,7 +8,7 @@ import '../services/connection_service.dart';
class McgScaffold extends StatelessWidget {
const McgScaffold({
this.appBar,
this.bodyBuilderCompleter,
this.bodyBuilderWaiter,
this.body,
this.waitingWidget,
this.forceInternetCheck = false,
@ -19,10 +18,10 @@ class McgScaffold extends StatelessWidget {
final AppBar? appBar;
/// Awaits an external signal (complete) before building the body.
final Completer? bodyBuilderCompleter;
final ValueListenable<bool>? bodyBuilderWaiter;
final Widget? body;
/// Custom widget to be used while awaiting [bodyBuilderCompleter].
/// Custom widget to be used while awaiting [bodyBuilderWaiter].
///
/// Defaults to using [PlatformCircularProgressIndicator].
final Widget? waitingWidget;
@ -32,19 +31,12 @@ class McgScaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
final Widget loginOptionsBody = bodyBuilderCompleter != null
? FutureBuilder(
future: bodyBuilderCompleter!.future,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
return Center(child: waitingWidget ?? const CircularProgressIndicator());
case ConnectionState.done:
return body ?? const SizedBox.shrink();
}
},
final Widget loginOptionsBody = bodyBuilderWaiter != null
? ValueListenableBuilder<bool>(
valueListenable: bodyBuilderWaiter!,
builder: (context, final isReady, child) => !isReady
? Center(child: waitingWidget ?? const CircularProgressIndicator())
: body ?? const SizedBox.shrink(),
)
: body ?? const SizedBox.shrink();

View file

@ -0,0 +1,47 @@
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
import '../abstracts/base_view_model.dart';
class ViewModelBuilder<T extends BaseViewModel> extends StatefulWidget {
const ViewModelBuilder({
required Widget Function(BuildContext context, T model) builder,
required T Function() viewModelBuilder,
dynamic Function()? argumentBuilder,
super.key,
}) : _builder = builder,
_viewModelBuilder = viewModelBuilder,
_argumentBuilder = argumentBuilder;
final Widget Function(BuildContext context, T model) _builder;
final T Function() _viewModelBuilder;
final dynamic Function()? _argumentBuilder;
@override
_ViewModelBuilderState<T> createState() => _ViewModelBuilderState<T>();
}
class _ViewModelBuilderState<T extends BaseViewModel> extends State<ViewModelBuilder<T>> {
late final T _viewModel;
@override
void initState() {
_viewModel = widget._viewModelBuilder();
_viewModel.initialise(() => mounted, widget._argumentBuilder?.call());
super.initState();
}
@override
void dispose() {
_viewModel.dispose();
super.dispose();
}
@override
Widget build(BuildContext _) => ChangeNotifierProvider.value(
value: _viewModel,
child: Consumer<T>(
builder: (context, model, _) => widget._builder(context, model),
),
);
}