mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[flutter]: collpase menu
This commit is contained in:
parent
31edb66508
commit
2f4f440097
@ -1,3 +1,4 @@
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
@ -44,20 +45,18 @@ abstract class HomeStackContext<T> with NavigationItem {
|
||||
|
||||
class HomeStackNotifier extends ChangeNotifier {
|
||||
HomeStackContext stackContext;
|
||||
PublishNotifier<bool> collapsedNotifier = PublishNotifier();
|
||||
|
||||
Widget get titleWidget => stackContext.naviTitle;
|
||||
|
||||
HomeStackNotifier({HomeStackContext? context}) : stackContext = context ?? BlankStackContext();
|
||||
|
||||
set context(HomeStackContext context) {
|
||||
notifyChange() {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
stackContext.isUpdated.removeListener(notifyChange);
|
||||
stackContext.isUpdated.removeListener(notifyListeners);
|
||||
stackContext.dispose();
|
||||
|
||||
stackContext = context;
|
||||
stackContext.isUpdated.addListener(notifyChange);
|
||||
stackContext.isUpdated.addListener(notifyListeners);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@ -73,7 +72,9 @@ class HomeStackManager {
|
||||
return _notifier.context.naviTitle;
|
||||
}
|
||||
|
||||
void setStack(HomeStackContext context) {
|
||||
PublishNotifier<bool> get collapsedNotifier => _notifier.collapsedNotifier;
|
||||
|
||||
void switchStack(HomeStackContext context) {
|
||||
_notifier.context = context;
|
||||
}
|
||||
|
||||
|
@ -99,19 +99,18 @@ class HomeScreen extends StatelessWidget {
|
||||
|
||||
Widget _buildHomeMenu({required HomeLayout layout, required BuildContext context}) {
|
||||
final homeBloc = context.read<HomeBloc>();
|
||||
Widget homeMenu = HomeMenu(
|
||||
pageContextChanged: (pageContext) {
|
||||
getIt<HomeStackManager>().setStack(pageContext);
|
||||
},
|
||||
isCollapseChanged: (isCollapse) {
|
||||
homeBloc.add(HomeEvent.forceCollapse(isCollapse));
|
||||
},
|
||||
user: user,
|
||||
workspaceId: workspaceId,
|
||||
);
|
||||
homeMenu = RepaintBoundary(child: homeMenu);
|
||||
homeMenu = FocusTraversalGroup(child: homeMenu);
|
||||
return homeMenu;
|
||||
final collapasedNotifier = getIt<HomeStackManager>().collapsedNotifier;
|
||||
|
||||
HomeMenu homeMenu = HomeMenu(user: user, workspaceId: workspaceId, collapsedNotifier: collapasedNotifier);
|
||||
collapasedNotifier.addPublishListener((isCollapsed) {
|
||||
homeBloc.add(HomeEvent.forceCollapse(isCollapsed));
|
||||
});
|
||||
|
||||
homeMenu.pageContext.addPublishListener((pageContext) {
|
||||
getIt<HomeStackManager>().switchStack(pageContext);
|
||||
});
|
||||
|
||||
return FocusTraversalGroup(child: RepaintBoundary(child: homeMenu));
|
||||
}
|
||||
|
||||
Widget _buildEditPannel({required HomeState homeState, required BuildContext context, required HomeLayout layout}) {
|
||||
|
@ -1,5 +1,4 @@
|
||||
class HomeSizes {
|
||||
static double get menuTopBarHeight => 48;
|
||||
static double get menuAddButtonHeight => 60;
|
||||
static double get topBarHeight => 60;
|
||||
static double get editPannelTopBarHeight => 60;
|
||||
|
@ -1,6 +1,9 @@
|
||||
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
@ -9,11 +12,19 @@ typedef NaviAction = void Function();
|
||||
|
||||
class NavigationNotifier with ChangeNotifier {
|
||||
List<NavigationItem> navigationItems;
|
||||
NavigationNotifier({required this.navigationItems});
|
||||
PublishNotifier<bool> collapasedNotifier;
|
||||
NavigationNotifier({required this.navigationItems, required this.collapasedNotifier});
|
||||
|
||||
void update(HomeStackNotifier notifier) {
|
||||
navigationItems = notifier.context.navigationItems;
|
||||
notifyListeners();
|
||||
bool shouldNotify = false;
|
||||
if (navigationItems != notifier.context.navigationItems) {
|
||||
navigationItems = notifier.context.navigationItems;
|
||||
shouldNotify = true;
|
||||
}
|
||||
|
||||
if (shouldNotify) {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,16 +58,47 @@ class FlowyNavigation extends StatelessWidget {
|
||||
final notifier = Provider.of<HomeStackNotifier>(context, listen: false);
|
||||
return NavigationNotifier(
|
||||
navigationItems: notifier.context.navigationItems,
|
||||
collapasedNotifier: notifier.collapsedNotifier,
|
||||
);
|
||||
},
|
||||
update: (_, notifier, controller) => controller!..update(notifier),
|
||||
child: Consumer(builder: (ctx, NavigationNotifier notifier, child) {
|
||||
return Row(children: _renderChildren(notifier.navigationItems));
|
||||
}),
|
||||
child: Row(children: [
|
||||
Selector<NavigationNotifier, PublishNotifier<bool>>(
|
||||
selector: (context, notifier) => notifier.collapasedNotifier,
|
||||
builder: (ctx, collapsedNotifier, child) => _renderCollapse(ctx, collapsedNotifier)),
|
||||
Selector<NavigationNotifier, List<NavigationItem>>(
|
||||
selector: (context, notifier) => notifier.navigationItems,
|
||||
builder: (ctx, items, child) => Row(children: _renderNavigationItems(items))),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _renderChildren(List<NavigationItem> items) {
|
||||
Widget _renderCollapse(BuildContext context, PublishNotifier<bool> collapsedNotifier) {
|
||||
return ChangeNotifierProvider.value(
|
||||
value: collapsedNotifier,
|
||||
child: Consumer(
|
||||
builder: (ctx, PublishNotifier<bool> notifier, child) {
|
||||
if (notifier.currentValue ?? false) {
|
||||
return RotationTransition(
|
||||
turns: const AlwaysStoppedAnimation(180 / 360),
|
||||
child: FlowyIconButton(
|
||||
width: 24,
|
||||
onPressed: () {
|
||||
notifier.value = false;
|
||||
},
|
||||
iconPadding: const EdgeInsets.fromLTRB(2, 2, 2, 2),
|
||||
icon: svg("home/hide_menu"),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _renderNavigationItems(List<NavigationItem> items) {
|
||||
if (items.isEmpty) {
|
||||
return [];
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/top_bar.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:flowy_infra/notifier.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
@ -41,17 +42,16 @@ import 'widget/menu_trash.dart';
|
||||
// └────────┘
|
||||
|
||||
class HomeMenu extends StatelessWidget {
|
||||
final Function(HomeStackContext) pageContextChanged;
|
||||
final Function(bool) isCollapseChanged;
|
||||
final PublishNotifier<HomeStackContext> pageContext = PublishNotifier();
|
||||
final PublishNotifier<bool> collapsedNotifier;
|
||||
final UserProfile user;
|
||||
final String workspaceId;
|
||||
|
||||
const HomeMenu({
|
||||
HomeMenu({
|
||||
Key? key,
|
||||
required this.pageContextChanged,
|
||||
required this.isCollapseChanged,
|
||||
required this.user,
|
||||
required this.workspaceId,
|
||||
required this.collapsedNotifier,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
@ -59,18 +59,22 @@ class HomeMenu extends StatelessWidget {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<MenuBloc>(
|
||||
create: (context) => getIt<MenuBloc>(param1: user, param2: workspaceId)..add(const MenuEvent.initial()),
|
||||
create: (context) {
|
||||
final menuBloc = getIt<MenuBloc>(param1: user, param2: workspaceId);
|
||||
menuBloc.add(const MenuEvent.initial());
|
||||
return menuBloc;
|
||||
},
|
||||
),
|
||||
],
|
||||
child: MultiBlocListener(
|
||||
listeners: [
|
||||
BlocListener<MenuBloc, MenuState>(
|
||||
listenWhen: (p, c) => p.context != c.context,
|
||||
listener: (context, state) => pageContextChanged(state.context),
|
||||
listener: (context, state) => pageContext.value = state.context,
|
||||
),
|
||||
BlocListener<MenuBloc, MenuState>(
|
||||
listenWhen: (p, c) => p.isCollapse != c.isCollapse,
|
||||
listener: (context, state) => isCollapseChanged(state.isCollapse),
|
||||
listener: (context, state) => collapsedNotifier.value = state.isCollapse,
|
||||
)
|
||||
],
|
||||
child: BlocBuilder<MenuBloc, MenuState>(
|
||||
@ -94,7 +98,7 @@ class HomeMenu extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
_renderTopBar(context),
|
||||
const VSpace(32),
|
||||
const VSpace(16),
|
||||
_renderApps(context),
|
||||
],
|
||||
).padding(horizontal: Insets.l),
|
||||
|
@ -90,7 +90,7 @@ class ViewSectionNotifier with ChangeNotifier {
|
||||
|
||||
if (view != null) {
|
||||
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||
getIt<HomeStackManager>().setStack(view.stackContext());
|
||||
getIt<HomeStackManager>().switchStack(view.stackContext());
|
||||
});
|
||||
} else {
|
||||
// do nothing
|
||||
|
@ -19,7 +19,7 @@ class MenuTrash extends StatelessWidget {
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Provider.of<MenuSharedState>(context, listen: false).selectedView = null;
|
||||
getIt<HomeStackManager>().setStack(TrashStackContext());
|
||||
getIt<HomeStackManager>().switchStack(TrashStackContext());
|
||||
},
|
||||
child: _render(context),
|
||||
),
|
||||
|
@ -1,5 +1,7 @@
|
||||
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
|
||||
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
@ -10,18 +12,17 @@ class MenuTopBar extends StatelessWidget {
|
||||
return BlocBuilder<MenuBloc, MenuState>(
|
||||
builder: (context, state) {
|
||||
return SizedBox(
|
||||
height: 48,
|
||||
height: HomeSizes.topBarHeight,
|
||||
child: Row(
|
||||
children: [
|
||||
svgWithSize("flowy_logo_with_text", const Size(92, 17)),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
iconSize: 16,
|
||||
icon: svg("home/hide_menu"),
|
||||
alignment: Alignment.centerRight,
|
||||
padding: EdgeInsets.zero,
|
||||
FlowyIconButton(
|
||||
width: 28,
|
||||
onPressed: () => context.read<MenuBloc>().add(const MenuEvent.collapse()),
|
||||
),
|
||||
iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4),
|
||||
icon: svg("home/hide_menu"),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user