home_screen.dart 6.8 KB

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