home_screen.dart 5.3 KB

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