home_screen.dart 6.0 KB

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