home_screen.dart 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import 'package:app_flowy/workspace/application/home/home_bloc.dart';
  2. import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
  3. import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
  4. import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
  5. import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
  6. import 'package:app_flowy/workspace/presentation/widgets/float_bubble/question_bubble.dart';
  7. import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
  8. import 'package:app_flowy/startup/startup.dart';
  9. import 'package:flowy_infra/notifier.dart';
  10. import 'package:flowy_log/flowy_log.dart';
  11. import 'package:flowy_infra_ui/style_widget/container.dart';
  12. import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart';
  13. import 'package:flowy_sdk/protobuf/flowy-workspace-infra/protobuf.dart';
  14. import 'package:flutter/material.dart';
  15. import 'package:flutter_bloc/flutter_bloc.dart';
  16. import 'package:styled_widget/styled_widget.dart';
  17. import 'package:app_flowy/workspace/domain/view_ext.dart';
  18. import 'home_layout.dart';
  19. class HomeScreen extends StatelessWidget {
  20. static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
  21. final UserProfile user;
  22. final CurrentWorkspaceSetting workspaceSetting;
  23. const HomeScreen(this.user, this.workspaceSetting, {Key? key}) : super(key: key);
  24. @override
  25. Widget build(BuildContext context) {
  26. return MultiBlocProvider(
  27. providers: [
  28. BlocProvider<HomeListenBloc>(
  29. create: (context) => getIt<HomeListenBloc>(param1: user)..add(const HomeListenEvent.started()),
  30. ),
  31. BlocProvider<HomeBloc>(create: (context) => getIt<HomeBloc>()),
  32. ],
  33. child: Scaffold(
  34. key: HomeScreen.scaffoldKey,
  35. body: BlocListener<HomeListenBloc, HomeListenState>(
  36. listener: (context, state) {
  37. state.map(
  38. loading: (_) {},
  39. unauthorized: (unauthorized) {
  40. // TODO: push to login screen when user token was invalid
  41. Log.error("Push to login screen when user token was invalid");
  42. },
  43. );
  44. },
  45. child: BlocBuilder<HomeBloc, HomeState>(
  46. buildWhen: (previous, current) => previous != current,
  47. builder: (context, state) {
  48. return FlowyContainer(
  49. Theme.of(context).colorScheme.surface,
  50. // Colors.white,
  51. child: _buildBody(state, context.read<HomeBloc>().state.forceCollapse),
  52. );
  53. },
  54. ),
  55. ),
  56. ),
  57. );
  58. }
  59. Widget _buildBody(HomeState state, bool forceCollapse) {
  60. return LayoutBuilder(
  61. builder: (BuildContext context, BoxConstraints constraints) {
  62. final layout = HomeLayout(context, constraints, forceCollapse);
  63. const homeStack = HomeStack();
  64. final menu = _buildHomeMenu(
  65. layout: layout,
  66. context: context,
  67. );
  68. final editPannel = _buildEditPannel(
  69. homeState: state,
  70. layout: layout,
  71. context: context,
  72. );
  73. const bubble = QuestionBubble();
  74. return _layoutWidgets(
  75. layout: layout,
  76. homeStack: homeStack,
  77. homeMenu: menu,
  78. editPannel: editPannel,
  79. bubble: bubble,
  80. );
  81. },
  82. );
  83. }
  84. Widget _buildHomeMenu({required HomeLayout layout, required BuildContext context}) {
  85. final homeBloc = context.read<HomeBloc>();
  86. final collapasedNotifier = getIt<HomeStackManager>().collapsedNotifier;
  87. collapasedNotifier.addPublishListener((isCollapsed) {
  88. homeBloc.add(HomeEvent.forceCollapse(isCollapsed));
  89. });
  90. final pageContext = PublishNotifier<HomeStackContext>();
  91. pageContext.addPublishListener((pageContext) {
  92. getIt<HomeStackManager>().switchStack(pageContext);
  93. });
  94. HomeStackContext? initialStackContext;
  95. if (workspaceSetting.hasLatestView()) {
  96. initialStackContext = workspaceSetting.latestView.stackContext();
  97. }
  98. HomeMenu homeMenu = HomeMenu(
  99. user: user,
  100. workspaceSetting: workspaceSetting,
  101. collapsedNotifier: collapasedNotifier,
  102. pageContext: pageContext,
  103. initialStackContext: initialStackContext,
  104. );
  105. return FocusTraversalGroup(child: RepaintBoundary(child: homeMenu));
  106. }
  107. Widget _buildEditPannel({required HomeState homeState, required BuildContext context, required HomeLayout layout}) {
  108. final homeBloc = context.read<HomeBloc>();
  109. Widget editPannel = EditPannel(
  110. context: homeState.editContext,
  111. onEndEdit: () => homeBloc.add(const HomeEvent.dismissEditPannel()),
  112. );
  113. // editPannel = RepaintBoundary(child: editPannel);
  114. // editPannel = FocusTraversalGroup(child: editPannel);
  115. return editPannel;
  116. }
  117. Widget _layoutWidgets({
  118. required HomeLayout layout,
  119. required Widget homeMenu,
  120. required Widget homeStack,
  121. required Widget editPannel,
  122. required Widget bubble,
  123. }) {
  124. return Stack(
  125. children: [
  126. homeMenu
  127. .animatedPanelX(
  128. closeX: -layout.menuWidth,
  129. isClosed: !layout.showMenu,
  130. )
  131. .positioned(left: 0, top: 0, width: layout.menuWidth, bottom: 0, animate: true)
  132. .animate(layout.animDuration, Curves.easeOut),
  133. homeStack
  134. .constrained(minWidth: 500)
  135. .positioned(left: layout.homePageLOffset, right: layout.homePageROffset, bottom: 0, top: 0, animate: true)
  136. .animate(layout.animDuration, Curves.easeOut),
  137. bubble
  138. .positioned(
  139. right: 20,
  140. bottom: 16,
  141. animate: true,
  142. )
  143. .animate(layout.animDuration, Curves.easeOut),
  144. editPannel
  145. .animatedPanelX(
  146. duration: layout.animDuration.inMilliseconds * 0.001,
  147. closeX: layout.editPannelWidth,
  148. isClosed: !layout.showEditPannel,
  149. )
  150. .positioned(right: 0, top: 0, bottom: 0, width: layout.editPannelWidth),
  151. ],
  152. );
  153. }
  154. }