123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- import 'package:app_flowy/startup/plugin/plugin.dart';
- import 'package:app_flowy/workspace/application/home/home_bloc.dart';
- import 'package:app_flowy/workspace/application/view/view_ext.dart';
- import 'package:app_flowy/workspace/presentation/widgets/edit_panel/panel_animation.dart';
- import 'package:app_flowy/workspace/presentation/widgets/float_bubble/question_bubble.dart';
- import 'package:app_flowy/startup/startup.dart';
- import 'package:flowy_sdk/log.dart';
- import 'package:flowy_infra_ui/style_widget/container.dart';
- import 'package:flowy_sdk/protobuf/flowy-user/protobuf.dart' show UserProfilePB;
- import 'package:flowy_sdk/protobuf/flowy-folder/protobuf.dart';
- import 'package:flutter/gestures.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_bloc/flutter_bloc.dart';
- import 'package:styled_widget/styled_widget.dart';
- import '../widgets/edit_panel/edit_panel.dart';
- import 'home_layout.dart';
- import 'home_stack.dart';
- import 'menu/menu.dart';
- class HomeScreen extends StatefulWidget {
- final UserProfilePB user;
- final CurrentWorkspaceSettingPB workspaceSetting;
- const HomeScreen(this.user, this.workspaceSetting, {Key? key})
- : super(key: key);
- @override
- State<HomeScreen> createState() => _HomeScreenState();
- }
- class _HomeScreenState extends State<HomeScreen> {
- ViewPB? initialView;
- @override
- void initState() {
- super.initState();
- }
- @override
- void didUpdateWidget(covariant HomeScreen oldWidget) {
- initialView = null;
- super.didUpdateWidget(oldWidget);
- }
- @override
- Widget build(BuildContext context) {
- return MultiBlocProvider(
- providers: [
- BlocProvider<HomeBloc>(
- create: (context) {
- return HomeBloc(widget.user, widget.workspaceSetting)
- ..add(const HomeEvent.initial());
- },
- ),
- ],
- child: Scaffold(
- body: BlocListener<HomeBloc, HomeState>(
- listenWhen: (p, c) => p.unauthorized != c.unauthorized,
- listener: (context, state) {
- if (state.unauthorized) {
- Log.error("Push to login screen when user token was invalid");
- }
- },
- child: BlocBuilder<HomeBloc, HomeState>(
- buildWhen: (previous, current) => previous != current,
- builder: (context, state) {
- final collapsedNotifier =
- getIt<HomeStackManager>().collapsedNotifier;
- collapsedNotifier.addPublishListener((isCollapsed) {
- context
- .read<HomeBloc>()
- .add(HomeEvent.forceCollapse(isCollapsed));
- });
- return FlowyContainer(
- Theme.of(context).colorScheme.surface,
- // Colors.white,
- child: _buildBody(state),
- );
- },
- ),
- ),
- ),
- );
- }
- Widget _buildBody(HomeState state) {
- return LayoutBuilder(
- builder: (BuildContext context, BoxConstraints constraints) {
- final layout = HomeLayout(context, constraints, state.forceCollapse);
- final homeStack = HomeStack(
- layout: layout,
- );
- final menu = _buildHomeMenu(
- layout: layout,
- context: context,
- state: state,
- );
- final homeMenuResizer = _buildHomeMenuResizer(context: context);
- final editPanel = _buildEditPanel(
- homeState: state,
- layout: layout,
- context: context,
- );
- const bubble = QuestionBubble();
- return _layoutWidgets(
- layout: layout,
- homeStack: homeStack,
- homeMenu: menu,
- editPanel: editPanel,
- bubble: bubble,
- homeMenuResizer: homeMenuResizer,
- );
- },
- );
- }
- Widget _buildHomeMenu(
- {required HomeLayout layout,
- required BuildContext context,
- required HomeState state}) {
- final workspaceSetting = state.workspaceSetting;
- if (initialView == null && workspaceSetting.hasLatestView()) {
- initialView = workspaceSetting.latestView;
- final plugin = makePlugin(
- pluginType: initialView!.pluginType,
- data: initialView,
- );
- getIt<HomeStackManager>().setPlugin(plugin);
- }
- HomeMenu homeMenu = HomeMenu(
- user: widget.user,
- workspaceSetting: workspaceSetting,
- collapsedNotifier: getIt<HomeStackManager>().collapsedNotifier,
- );
- final latestView =
- workspaceSetting.hasLatestView() ? workspaceSetting.latestView : null;
- if (getIt<MenuSharedState>().latestOpenView == null) {
- /// AppFlowy will open the view that the last time the user opened it. The _buildHomeMenu will get called when AppFlowy's screen resizes. So we only set the latestOpenView when it's null.
- getIt<MenuSharedState>().latestOpenView = latestView;
- }
- return FocusTraversalGroup(child: RepaintBoundary(child: homeMenu));
- }
- Widget _buildEditPanel(
- {required HomeState homeState,
- required BuildContext context,
- required HomeLayout layout}) {
- final homeBloc = context.read<HomeBloc>();
- return BlocBuilder<HomeBloc, HomeState>(
- buildWhen: (previous, current) =>
- previous.panelContext != current.panelContext,
- builder: (context, state) {
- return state.panelContext.fold(
- () => const SizedBox(),
- (panelContext) => FocusTraversalGroup(
- child: RepaintBoundary(
- child: EditPanel(
- panelContext: panelContext,
- onEndEdit: () =>
- homeBloc.add(const HomeEvent.dismissEditPanel()),
- ),
- ),
- ),
- );
- },
- );
- }
- Widget _buildHomeMenuResizer({
- required BuildContext context,
- }) {
- return MouseRegion(
- cursor: SystemMouseCursors.resizeLeftRight,
- child: GestureDetector(
- dragStartBehavior: DragStartBehavior.down,
- onPanUpdate: ((details) {
- context
- .read<HomeBloc>()
- .add(HomeEvent.editPanelResized(details.delta.dx));
- }),
- behavior: HitTestBehavior.translucent,
- child: SizedBox(
- width: 10,
- height: MediaQuery.of(context).size.height,
- )),
- );
- }
- Widget _layoutWidgets({
- required HomeLayout layout,
- required Widget homeMenu,
- required Widget homeStack,
- required Widget editPanel,
- required Widget bubble,
- required Widget homeMenuResizer,
- }) {
- return Stack(
- children: [
- homeMenu
- .animatedPanelX(
- closeX: -layout.menuWidth,
- isClosed: !layout.showMenu,
- )
- .positioned(
- left: 0,
- top: 0,
- width: layout.menuWidth,
- bottom: 0,
- animate: true)
- .animate(layout.animDuration, Curves.easeOut),
- homeStack
- .constrained(minWidth: 500)
- .positioned(
- left: layout.homePageLOffset,
- right: layout.homePageROffset,
- bottom: 0,
- top: 0,
- animate: true)
- .animate(layout.animDuration, Curves.easeOut),
- homeMenuResizer.positioned(left: layout.homePageLOffset - 5),
- bubble
- .positioned(
- right: 20,
- bottom: 16,
- animate: true,
- )
- .animate(layout.animDuration, Curves.easeOut),
- editPanel
- .animatedPanelX(
- duration: layout.animDuration.inMilliseconds * 0.001,
- closeX: layout.editPanelWidth,
- isClosed: !layout.showEditPanel,
- )
- .positioned(
- right: 0, top: 0, bottom: 0, width: layout.editPanelWidth),
- ],
- );
- }
- }
|