buildBlocBuilder method
Implementation
@protected
Widget buildBlocBuilder(BuildParameters params) {
final children = params.widgets["states"] as List<Map>?;
if (children == null || children.isEmpty) {
return const SizedBox();
}
final log = Logger("BlocBuilder");
final stateActions = <String>[];
final stateWidgets = <String>[];
final actionMap = <String, Map?>{};
final widgetMap = <String, Map?>{};
for (var child in children) {
final childProps = child["properties"] as Map? ?? {};
final state = childProps["state"] as String? ?? "";
if (state.isNotEmpty) {
stateActions.add(state);
final childActions = child["actions"] as Map? ?? {};
actionMap[state] = childActions["listener"] as Map?;
if (child["_type"] != "StateListener") {
stateWidgets.add(state);
final childWidgets = child["widgets"] as Map? ?? {};
widgetMap[state] = childWidgets["child"] as Map?;
}
}
}
final parentContext = params.parentContext ?? {};
final type = params.props["type"] ?? "local";
final defaultWidgetSpec = params.widgets["child"] as Map?;
listenWhen(BaseState prev, BaseState next) =>
prev != next &&
next is ActionState &&
stateActions.contains(next.state);
buildWhen(BaseState prev, BaseState next) =>
prev != next &&
next is ActionState &&
stateWidgets.contains(next.state);
listener(BuildContext context, BaseState state) {
if (state is! ActionState) {
return;
}
final actionSpec = actionMap[state.state];
if (actionSpec == null) {
return;
}
final stateContext = parentContext.clone();
stateContext.addAll({"stateData": state.data});
final func = events.getFunction(
context, actionSpec.clone(), params.state, stateContext);
if (func != null) {
log.info(
"Executing '${actionSpec["name"] ?? actionSpec["_type"]}' from state '${state.state}'");
func();
}
}
stateBuilder(BuildContext context, BaseState state) {
Map? widgetSpec;
if (state is ActionState) {
widgetSpec = widgetMap[state.state];
}
widgetSpec ??= defaultWidgetSpec;
if (widgetSpec == null) return const SizedBox();
final stateContext = parentContext.clone();
if (state is ActionState) {
stateContext.addAll({"stateData": state.data});
log.info(
"Building '${widgetSpec["name"] ?? widgetSpec["_type"]}' from state '${state.state}'");
}
params.state.remove(widgetSpec["_id"]);
// Returning a dummy Builder with an unique key to force a repaint.
return Builder(
key: UniqueKey(),
builder: (context) => builder.buildWidget(
context, widgetSpec!.clone(), params.state, stateContext),
);
}
return type == "global"
? BlocConsumer<GlobalBloc, BaseState>(
listenWhen: listenWhen,
listener: listener,
buildWhen: buildWhen,
builder: stateBuilder)
: BlocConsumer<LocalBloc, BaseState>(
listenWhen: listenWhen,
listener: listener,
buildWhen: buildWhen,
builder: stateBuilder);
}