home_bloc.dart 5.2 KB

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