app_bloc.dart 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import 'package:app_flowy/workspace/domain/i_app.dart';
  2. import 'package:flowy_log/flowy_log.dart';
  3. import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
  4. import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
  5. import 'package:freezed_annotation/freezed_annotation.dart';
  6. import 'package:flutter_bloc/flutter_bloc.dart';
  7. import 'package:dartz/dartz.dart';
  8. part 'app_bloc.freezed.dart';
  9. class AppBloc extends Bloc<AppEvent, AppState> {
  10. final IApp appManager;
  11. final IAppListenr listener;
  12. AppBloc({required this.appManager, required this.listener}) : super(AppState.initial());
  13. @override
  14. Stream<AppState> mapEventToState(
  15. AppEvent event,
  16. ) async* {
  17. yield* event.map(
  18. initial: (e) async* {
  19. listener.start(viewsChangeCallback: _handleViewsOrFail);
  20. yield* _fetchViews();
  21. },
  22. createView: (CreateView value) async* {
  23. final viewOrFailed = await appManager.createView(name: value.name, desc: value.desc, viewType: value.viewType);
  24. yield viewOrFailed.fold(
  25. (view) => state.copyWith(
  26. selectedView: view,
  27. successOrFailure: left(unit),
  28. ),
  29. (error) {
  30. Log.error(error);
  31. return state.copyWith(successOrFailure: right(error));
  32. },
  33. );
  34. },
  35. didReceiveViews: (e) async* {
  36. yield state.copyWith(views: e.views);
  37. },
  38. );
  39. }
  40. @override
  41. Future<void> close() async {
  42. await listener.stop();
  43. return super.close();
  44. }
  45. void _handleViewsOrFail(Either<List<View>, WorkspaceError> viewsOrFail) {
  46. viewsOrFail.fold(
  47. (views) => add(AppEvent.didReceiveViews(views)),
  48. (error) {
  49. Log.error(error);
  50. },
  51. );
  52. }
  53. Stream<AppState> _fetchViews() async* {
  54. final viewsOrFailed = await appManager.getViews();
  55. yield viewsOrFailed.fold(
  56. (apps) => state.copyWith(views: apps),
  57. (error) {
  58. Log.error(error);
  59. return state.copyWith(successOrFailure: right(error));
  60. },
  61. );
  62. }
  63. }
  64. @freezed
  65. class AppEvent with _$AppEvent {
  66. const factory AppEvent.initial() = Initial;
  67. const factory AppEvent.createView(String name, String desc, ViewType viewType) = CreateView;
  68. const factory AppEvent.didReceiveViews(List<View> views) = ReceiveViews;
  69. }
  70. @freezed
  71. class AppState with _$AppState {
  72. const factory AppState({
  73. required bool isLoading,
  74. required List<View>? views,
  75. View? selectedView,
  76. required Either<Unit, WorkspaceError> successOrFailure,
  77. }) = _AppState;
  78. factory AppState.initial() => AppState(
  79. isLoading: false,
  80. views: null,
  81. selectedView: null,
  82. successOrFailure: left(unit),
  83. );
  84. }