home_screen.dart 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import 'package:app_flowy/plugin/plugin.dart';
  2. import 'package:app_flowy/workspace/application/home/home_bloc.dart';
  3. import 'package:app_flowy/workspace/presentation/widgets/edit_pannel/pannel_animation.dart';
  4. import 'package:app_flowy/workspace/presentation/widgets/float_bubble/question_bubble.dart';
  5. import 'package:app_flowy/startup/startup.dart';
  6. import 'package:flowy_sdk/log.dart';
  7. import 'package:flowy_infra_ui/style_widget/container.dart';
  8. import 'package:flowy_sdk/protobuf/flowy-user-data-model/protobuf.dart' show UserProfile;
  9. import 'package:flowy_sdk/protobuf/flowy-folder-data-model/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 '../widgets/edit_pannel/edit_pannel.dart';
  14. import 'home_layout.dart';
  15. import 'home_stack.dart';
  16. import 'menu/menu.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<HomeBloc>(
  41. create: (context) {
  42. return HomeBloc(widget.user, widget.workspaceSetting)..add(const HomeEvent.initial());
  43. },
  44. ),
  45. ],
  46. child: Scaffold(
  47. key: HomeScreen.scaffoldKey,
  48. body: BlocListener<HomeBloc, HomeState>(
  49. listenWhen: (p, c) => p.unauthorized != c.unauthorized,
  50. listener: (context, state) {
  51. if (state.unauthorized) {
  52. Log.error("Push to login screen when user token was invalid");
  53. }
  54. },
  55. child: BlocBuilder<HomeBloc, HomeState>(
  56. buildWhen: (previous, current) => previous != current,
  57. builder: (context, state) {
  58. final collapasedNotifier = getIt<HomeStackManager>().collapsedNotifier;
  59. collapasedNotifier.addPublishListener((isCollapsed) {
  60. context.read<HomeBloc>().add(HomeEvent.forceCollapse(isCollapsed));
  61. });
  62. return FlowyContainer(
  63. Theme.of(context).colorScheme.surface,
  64. // Colors.white,
  65. child: _buildBody(state),
  66. );
  67. },
  68. ),
  69. ),
  70. ),
  71. );
  72. }
  73. Widget _buildBody(HomeState state) {
  74. return LayoutBuilder(
  75. builder: (BuildContext context, BoxConstraints constraints) {
  76. final layout = HomeLayout(context, constraints, state.forceCollapse);
  77. const homeStack = HomeStack();
  78. final menu = _buildHomeMenu(
  79. layout: layout,
  80. context: context,
  81. state: state,
  82. );
  83. final editPannel = _buildEditPannel(
  84. homeState: state,
  85. layout: layout,
  86. context: context,
  87. );
  88. const bubble = QuestionBubble();
  89. return _layoutWidgets(
  90. layout: layout,
  91. homeStack: homeStack,
  92. homeMenu: menu,
  93. editPannel: editPannel,
  94. bubble: bubble,
  95. );
  96. },
  97. );
  98. }
  99. Widget _buildHomeMenu({required HomeLayout layout, required BuildContext context, required HomeState state}) {
  100. final workspaceSetting = state.workspaceSetting;
  101. if (initialView == null && workspaceSetting.hasLatestView()) {
  102. initialView = workspaceSetting.latestView;
  103. final plugin = makePlugin(pluginType: initialView!.pluginType, data: initialView);
  104. getIt<HomeStackManager>().setPlugin(plugin);
  105. }
  106. HomeMenu homeMenu = HomeMenu(
  107. user: widget.user,
  108. workspaceSetting: workspaceSetting,
  109. collapsedNotifier: getIt<HomeStackManager>().collapsedNotifier,
  110. );
  111. final latestView = workspaceSetting.hasLatestView() ? workspaceSetting.latestView : null;
  112. getIt<MenuSharedState>().latestOpenView = latestView;
  113. return FocusTraversalGroup(child: RepaintBoundary(child: homeMenu));
  114. }
  115. Widget _buildEditPannel({required HomeState homeState, required BuildContext context, required HomeLayout layout}) {
  116. final homeBloc = context.read<HomeBloc>();
  117. return BlocBuilder<HomeBloc, HomeState>(
  118. buildWhen: (previous, current) => previous.pannelContext != current.pannelContext,
  119. builder: (context, state) {
  120. return state.pannelContext.fold(
  121. () => const SizedBox(),
  122. (pannelContext) => FocusTraversalGroup(
  123. child: RepaintBoundary(
  124. child: EditPannel(
  125. pannelContext: pannelContext,
  126. onEndEdit: () => homeBloc.add(const HomeEvent.dismissEditPannel()),
  127. ),
  128. ),
  129. ),
  130. );
  131. },
  132. );
  133. }
  134. Widget _layoutWidgets({
  135. required HomeLayout layout,
  136. required Widget homeMenu,
  137. required Widget homeStack,
  138. required Widget editPannel,
  139. required Widget bubble,
  140. }) {
  141. return Stack(
  142. children: [
  143. homeMenu
  144. .animatedPanelX(
  145. closeX: -layout.menuWidth,
  146. isClosed: !layout.showMenu,
  147. )
  148. .positioned(left: 0, top: 0, width: layout.menuWidth, bottom: 0, animate: true)
  149. .animate(layout.animDuration, Curves.easeOut),
  150. homeStack
  151. .constrained(minWidth: 500)
  152. .positioned(left: layout.homePageLOffset, right: layout.homePageROffset, bottom: 0, top: 0, animate: true)
  153. .animate(layout.animDuration, Curves.easeOut),
  154. bubble
  155. .positioned(
  156. right: 20,
  157. bottom: 16,
  158. animate: true,
  159. )
  160. .animate(layout.animDuration, Curves.easeOut),
  161. editPannel
  162. .animatedPanelX(
  163. duration: layout.animDuration.inMilliseconds * 0.001,
  164. closeX: layout.editPannelWidth,
  165. isClosed: !layout.showEditPannel,
  166. )
  167. .positioned(right: 0, top: 0, bottom: 0, width: layout.editPannelWidth),
  168. ],
  169. );
  170. }
  171. }