home_screen.dart 6.3 KB

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