menu_bloc.dart 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import 'dart:async';
  2. import 'package:app_flowy/workspace/domain/i_workspace.dart';
  3. import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
  4. import 'package:dartz/dartz.dart';
  5. import 'package:flowy_infra/flowy_logger.dart';
  6. import 'package:flowy_sdk/protobuf/flowy-workspace/app_create.pb.dart';
  7. import 'package:flowy_sdk/protobuf/flowy-workspace/errors.pb.dart';
  8. import 'package:flutter/material.dart';
  9. import 'package:freezed_annotation/freezed_annotation.dart';
  10. import 'package:flutter_bloc/flutter_bloc.dart';
  11. part 'menu_bloc.freezed.dart';
  12. class MenuBloc extends Bloc<MenuEvent, MenuState> {
  13. final IWorkspace workspace;
  14. MenuBloc(this.workspace) : super(MenuState.initial());
  15. @override
  16. Stream<MenuState> mapEventToState(
  17. MenuEvent event,
  18. ) async* {
  19. yield* event.map(
  20. initial: (value) async* {
  21. yield* _fetchApps();
  22. },
  23. collapse: (e) async* {
  24. final isCollapse = state.isCollapse;
  25. yield state.copyWith(isCollapse: !isCollapse);
  26. },
  27. openPage: (OpenPage e) async* {
  28. yield* _performActionOnOpenPage(e);
  29. },
  30. createApp: (CreateApp event) async* {
  31. yield* _performActionOnCreateApp(event);
  32. },
  33. );
  34. }
  35. Stream<MenuState> _performActionOnOpenPage(OpenPage e) async* {
  36. yield state.copyWith(stackView: e.stackView);
  37. }
  38. Stream<MenuState> _performActionOnCreateApp(CreateApp event) async* {
  39. final result =
  40. await workspace.createApp(name: event.name, desc: event.desc);
  41. yield result.fold(
  42. (app) => state.copyWith(apps: some([app])),
  43. (error) {
  44. Log.error(error);
  45. return state.copyWith(successOrFailure: right(error));
  46. },
  47. );
  48. }
  49. Stream<MenuState> _fetchApps() async* {
  50. final appsOrFail = await workspace.getApps();
  51. yield appsOrFail.fold(
  52. (apps) => state.copyWith(apps: some(apps)),
  53. (error) {
  54. Log.error(error);
  55. return state.copyWith(successOrFailure: right(error));
  56. },
  57. );
  58. }
  59. }
  60. @freezed
  61. abstract class MenuEvent with _$MenuEvent {
  62. const factory MenuEvent.initial() = _Initial;
  63. const factory MenuEvent.collapse() = Collapse;
  64. const factory MenuEvent.openPage(HomeStackView stackView) = OpenPage;
  65. const factory MenuEvent.createApp(String name, {String? desc}) = CreateApp;
  66. }
  67. @freezed
  68. abstract class MenuState implements _$MenuState {
  69. const factory MenuState({
  70. required bool isCollapse,
  71. required Option<List<App>> apps,
  72. required Either<Unit, WorkspaceError> successOrFailure,
  73. HomeStackView? stackView,
  74. }) = _MenuState;
  75. factory MenuState.initial() => MenuState(
  76. isCollapse: false,
  77. apps: none(),
  78. successOrFailure: left(unit),
  79. );
  80. }