menu_bloc.dart 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
  5. import 'package:dartz/dartz.dart';
  6. import 'package:flowy_log/flowy_log.dart';
  7. import 'package:flowy_sdk/protobuf/flowy-core-infra/app_create.pb.dart';
  8. import 'package:flowy_sdk/protobuf/flowy-core/errors.pb.dart';
  9. import 'package:flutter/material.dart';
  10. import 'package:freezed_annotation/freezed_annotation.dart';
  11. import 'package:flutter_bloc/flutter_bloc.dart';
  12. part 'menu_bloc.freezed.dart';
  13. class MenuBloc extends Bloc<MenuEvent, MenuState> {
  14. final IWorkspace workspaceManager;
  15. final IWorkspaceListener listener;
  16. MenuBloc({required this.workspaceManager, required this.listener}) : super(MenuState.initial());
  17. @override
  18. Stream<MenuState> mapEventToState(
  19. MenuEvent event,
  20. ) async* {
  21. yield* event.map(
  22. initial: (e) async* {
  23. listener.start(addAppCallback: _handleAppsOrFail);
  24. yield* _fetchApps();
  25. },
  26. collapse: (e) async* {
  27. final isCollapse = state.isCollapse;
  28. yield state.copyWith(isCollapse: !isCollapse);
  29. },
  30. openPage: (e) async* {
  31. yield* _performActionOnOpenPage(e);
  32. },
  33. createApp: (CreateApp event) async* {
  34. yield* _performActionOnCreateApp(event);
  35. },
  36. didReceiveApps: (e) async* {
  37. yield e.appsOrFail.fold(
  38. (apps) => state.copyWith(apps: some(apps), successOrFailure: left(unit)),
  39. (err) => state.copyWith(successOrFailure: right(err)),
  40. );
  41. },
  42. );
  43. }
  44. @override
  45. Future<void> close() async {
  46. await listener.stop();
  47. return super.close();
  48. }
  49. Stream<MenuState> _performActionOnOpenPage(OpenPage e) async* {
  50. yield state.copyWith(stackContext: e.context);
  51. }
  52. Stream<MenuState> _performActionOnCreateApp(CreateApp event) async* {
  53. final result = await workspaceManager.createApp(name: event.name, desc: event.desc);
  54. yield result.fold(
  55. (app) => state.copyWith(apps: some([app])),
  56. (error) {
  57. Log.error(error);
  58. return state.copyWith(successOrFailure: right(error));
  59. },
  60. );
  61. }
  62. // ignore: unused_element
  63. Stream<MenuState> _fetchApps() async* {
  64. final appsOrFail = await workspaceManager.getApps();
  65. yield appsOrFail.fold(
  66. (apps) => state.copyWith(apps: some(apps)),
  67. (error) {
  68. Log.error(error);
  69. return state.copyWith(successOrFailure: right(error));
  70. },
  71. );
  72. }
  73. void _handleAppsOrFail(Either<List<App>, WorkspaceError> appsOrFail) {
  74. appsOrFail.fold(
  75. (apps) => add(MenuEvent.didReceiveApps(left(apps))),
  76. (error) => add(MenuEvent.didReceiveApps(right(error))),
  77. );
  78. }
  79. }
  80. @freezed
  81. class MenuEvent with _$MenuEvent {
  82. const factory MenuEvent.initial() = _Initial;
  83. const factory MenuEvent.collapse() = Collapse;
  84. const factory MenuEvent.openPage(HomeStackContext context) = OpenPage;
  85. const factory MenuEvent.createApp(String name, {String? desc}) = CreateApp;
  86. const factory MenuEvent.didReceiveApps(Either<List<App>, WorkspaceError> appsOrFail) = ReceiveApps;
  87. }
  88. @freezed
  89. class MenuState with _$MenuState {
  90. const factory MenuState({
  91. required bool isCollapse,
  92. required Option<List<App>> apps,
  93. required Either<Unit, WorkspaceError> successOrFailure,
  94. required HomeStackContext stackContext,
  95. }) = _MenuState;
  96. factory MenuState.initial() => MenuState(
  97. isCollapse: false,
  98. apps: none(),
  99. successOrFailure: left(unit),
  100. stackContext: BlankStackContext(),
  101. );
  102. }