Files
markettakers-flutter/lib/src/loader.dart

78 lines
2.1 KiB
Dart

import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:rive/rive.dart';
enum LoaderFlavour {
small(filepath: 'assets/animations/loaders/small_loader.riv'),
big(filepath: 'assets/animations/big_loaders/big_logo_splash.riv');
const LoaderFlavour({required this.filepath});
final String filepath;
}
class LoaderController extends Cubit<bool> {
LoaderController() : super(false);
void show() => emit(true);
void hide() => emit(false);
}
class Loader extends HookWidget {
final LoaderFlavour flavour;
final Fit fit;
final LoaderController controller;
const Loader(
this.controller, {
super.key,
required this.flavour,
this.fit = Fit.contain,
});
Loader.playing({required LoaderFlavour flavour, Fit fit = Fit.contain})
: this(LoaderController()..show(), flavour: flavour, fit: fit);
Loader.stopped({required LoaderFlavour flavour, Fit fit = Fit.contain})
: this(LoaderController()..hide(), flavour: flavour, fit: fit);
@override
Widget build(BuildContext context) {
final animFile = useMemoized(
() =>
FileLoader.fromAsset("packages/mtcore/${flavour.filepath}", riveFactory: Factory.flutter),
);
return RiveWidgetBuilder(
fileLoader: animFile,
builder: (context, state) {
switch (state) {
case RiveLoading():
return const Center(child: CircularProgressIndicator());
case RiveFailed():
final message = state.error.toString();
return ErrorWidget.withDetails(
message: message,
error: FlutterError(message),
);
case RiveLoaded(:final file):
final controller = RiveWidgetController(
file,
stateMachineSelector: StateMachineSelector.byIndex(0),
);
controller.active = this.controller.state;
this.controller.stream.listen((toggle) {
controller.active = toggle;
});
return RiveWidget(controller: controller, fit: fit);
}
},
);
}
}