home_bloc.dart 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import 'package:app_flowy/user/application/user_listener.dart';
  2. import 'package:app_flowy/workspace/application/edit_panel/edit_context.dart';
  3. import 'package:flowy_infra/time/duration.dart';
  4. import 'package:flowy_sdk/log.dart';
  5. import 'package:flowy_sdk/protobuf/flowy-error-code/code.pb.dart';
  6. import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
  7. import 'package:flowy_sdk/protobuf/flowy-folder/workspace.pb.dart'
  8. show CurrentWorkspaceSettingPB;
  9. import 'package:flowy_sdk/protobuf/flowy-user/user_profile.pb.dart';
  10. import 'package:flutter_bloc/flutter_bloc.dart';
  11. import 'package:freezed_annotation/freezed_annotation.dart';
  12. import 'package:dartz/dartz.dart';
  13. part 'home_bloc.freezed.dart';
  14. class HomeBloc extends Bloc<HomeEvent, HomeState> {
  15. final UserWorkspaceListener _listener;
  16. HomeBloc(UserProfilePB user, CurrentWorkspaceSettingPB workspaceSetting)
  17. : _listener = UserWorkspaceListener(userProfile: user),
  18. super(HomeState.initial(workspaceSetting)) {
  19. on<HomeEvent>(
  20. (event, emit) async {
  21. await event.map(
  22. initial: (_Initial value) {
  23. _listener.start(
  24. onAuthChanged: (result) => _authDidChanged(result),
  25. onSettingUpdated: (result) {
  26. result.fold(
  27. (setting) =>
  28. add(HomeEvent.didReceiveWorkspaceSetting(setting)),
  29. (r) => Log.error(r),
  30. );
  31. },
  32. );
  33. },
  34. showLoading: (e) async {
  35. emit(state.copyWith(isLoading: e.isLoading));
  36. },
  37. setEditPanel: (e) async {
  38. emit(state.copyWith(panelContext: some(e.editContext)));
  39. },
  40. dismissEditPanel: (value) async {
  41. emit(state.copyWith(panelContext: none()));
  42. },
  43. forceCollapse: (e) async {
  44. emit(state.copyWith(forceCollapse: e.forceCollapse));
  45. },
  46. didReceiveWorkspaceSetting: (_DidReceiveWorkspaceSetting value) {
  47. emit(state.copyWith(workspaceSetting: value.setting));
  48. },
  49. unauthorized: (_Unauthorized value) {
  50. emit(state.copyWith(unauthorized: true));
  51. },
  52. collapseMenu: (_CollapseMenu e) {
  53. emit(state.copyWith(isMenuCollapsed: !state.isMenuCollapsed));
  54. },
  55. editPanelResizeStart: (_EditPanelResizeStart e) {
  56. emit(state.copyWith(
  57. resizeType: MenuResizeType.drag,
  58. resizeStart: state.resizeOffset,
  59. ));
  60. },
  61. editPanelResized: (_EditPanelResized e) {
  62. final newPosition =
  63. (e.offset + state.resizeStart).clamp(-50, 200).toDouble();
  64. if (state.resizeOffset != newPosition) {
  65. emit(state.copyWith(resizeOffset: newPosition));
  66. }
  67. },
  68. editPanelResizeEnd: (_EditPanelResizeEnd e) {
  69. emit(state.copyWith(resizeType: MenuResizeType.slide));
  70. },
  71. );
  72. },
  73. );
  74. }
  75. @override
  76. Future<void> close() async {
  77. await _listener.stop();
  78. return super.close();
  79. }
  80. void _authDidChanged(Either<Unit, FlowyError> errorOrNothing) {
  81. errorOrNothing.fold((_) {}, (error) {
  82. if (error.code == ErrorCode.UserUnauthorized.value) {
  83. add(HomeEvent.unauthorized(error.msg));
  84. }
  85. });
  86. }
  87. }
  88. enum MenuResizeType {
  89. slide,
  90. drag,
  91. }
  92. extension MenuResizeTypeExtension on MenuResizeType {
  93. Duration duration() {
  94. switch (this) {
  95. case MenuResizeType.drag:
  96. return 30.milliseconds;
  97. case MenuResizeType.slide:
  98. return 350.milliseconds;
  99. }
  100. }
  101. }
  102. @freezed
  103. class HomeEvent with _$HomeEvent {
  104. const factory HomeEvent.initial() = _Initial;
  105. const factory HomeEvent.showLoading(bool isLoading) = _ShowLoading;
  106. const factory HomeEvent.forceCollapse(bool forceCollapse) = _ForceCollapse;
  107. const factory HomeEvent.setEditPanel(EditPanelContext editContext) =
  108. _ShowEditPanel;
  109. const factory HomeEvent.dismissEditPanel() = _DismissEditPanel;
  110. const factory HomeEvent.didReceiveWorkspaceSetting(
  111. CurrentWorkspaceSettingPB setting) = _DidReceiveWorkspaceSetting;
  112. const factory HomeEvent.unauthorized(String msg) = _Unauthorized;
  113. const factory HomeEvent.collapseMenu() = _CollapseMenu;
  114. const factory HomeEvent.editPanelResized(double offset) = _EditPanelResized;
  115. const factory HomeEvent.editPanelResizeStart() = _EditPanelResizeStart;
  116. const factory HomeEvent.editPanelResizeEnd() = _EditPanelResizeEnd;
  117. }
  118. @freezed
  119. class HomeState with _$HomeState {
  120. const factory HomeState({
  121. required bool isLoading,
  122. required bool forceCollapse,
  123. required Option<EditPanelContext> panelContext,
  124. required CurrentWorkspaceSettingPB workspaceSetting,
  125. required bool unauthorized,
  126. required bool isMenuCollapsed,
  127. required double resizeOffset,
  128. required double resizeStart,
  129. required MenuResizeType resizeType,
  130. }) = _HomeState;
  131. factory HomeState.initial(CurrentWorkspaceSettingPB workspaceSetting) =>
  132. HomeState(
  133. isLoading: false,
  134. forceCollapse: false,
  135. panelContext: none(),
  136. workspaceSetting: workspaceSetting,
  137. unauthorized: false,
  138. isMenuCollapsed: false,
  139. resizeOffset: 0,
  140. resizeStart: 0,
  141. resizeType: MenuResizeType.slide,
  142. );
  143. }