Files
moxxy/lib/ui/bloc/crop_bloc.dart
Alexander "PapaTutuWawa f094a326ac feat(ui): Switch cropping libraries
This makes the avatar cropper much more consistent
with the background cropper. Fixes #168.
2022-11-26 18:40:46 +01:00

103 lines
2.7 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:bloc/bloc.dart';
import 'package:cropperx/cropperx.dart';
import 'package:flutter/widgets.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:get_it/get_it.dart';
import 'package:moxxyv2/ui/bloc/navigation_bloc.dart';
import 'package:moxxyv2/ui/constants.dart';
part 'crop_bloc.freezed.dart';
part 'crop_event.dart';
part 'crop_state.dart';
class CropBloc extends Bloc<CropEvent, CropState> {
CropBloc() : super(CropState()) {
on<ImageCroppedEvent>(_onImageCropped);
on<ResetImageEvent>(_onImageReset);
on<SetImageEvent>(_onImageSet);
}
late Completer<Uint8List?> _completer;
final GlobalKey cropKey = GlobalKey();
Future<void> _onImageCropped(ImageCroppedEvent event, Emitter<CropState> emit) async {
emit(
state.copyWith(
isWorking: true,
),
);
final bytes = await Cropper.crop(
cropperKey: cropKey,
);
_completer.complete(bytes);
GetIt.I.get<NavigationBloc>().add(PoppedRouteEvent());
await _onImageReset(ResetImageEvent(), emit);
}
Future<void> _onImageReset(ResetImageEvent event, Emitter<CropState> emit) async {
emit(
state.copyWith(
image: null,
isWorking: false,
),
);
}
Future<void> _onImageSet(SetImageEvent event, Emitter<CropState> emit) async {
emit(
state.copyWith(
image: event.image,
),
);
}
Future<void> _performCropping(String path) async {
final file = File(path);
if (!file.existsSync()) _completer.complete(null);
final bytes = await file.readAsBytes();
add(SetImageEvent(bytes));
}
/// User-callable function. Loads the image, navigates to the page
/// and allows the user to crop the image. The future resolves when
/// either an error occures or the image has been cropped.
/// [path] is the path to the file to load.
Future<Uint8List?> cropImage(String path) {
_completer = Completer();
add(ResetImageEvent());
GetIt.I.get<NavigationBloc>().add(
PushedNamedEvent(
const NavigationDestination(cropRoute),
),
);
_performCropping(path);
return _completer.future;
}
/// User-callable function. Loads the image, navigates to the page
/// and allows the user to crop the image. The future resolves when
/// either an error occures or the image has been cropped.
Future<Uint8List?> cropImageWithData(Uint8List data) {
_completer = Completer();
GetIt.I.get<NavigationBloc>().add(
PushedNamedEvent(
const NavigationDestination(cropRoute),
),
);
add(SetImageEvent(data));
return _completer.future;
}
}