mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[flutter]: config menu trash ui
This commit is contained in:
parent
50172e3fd4
commit
0d5a16e447
@ -1,18 +1,15 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
|
||||
|
||||
typedef NavigationCallback = void Function(String id);
|
||||
|
||||
abstract class NavigationItem {
|
||||
String get title;
|
||||
Widget get titleWidget;
|
||||
String get identifier;
|
||||
|
||||
NavigationCallback get action => (id) {
|
||||
@ -20,33 +17,28 @@ abstract class NavigationItem {
|
||||
};
|
||||
}
|
||||
|
||||
enum HomeStackType {
|
||||
blank,
|
||||
doc,
|
||||
trash,
|
||||
}
|
||||
|
||||
List<HomeStackType> pages = HomeStackType.values.toList();
|
||||
|
||||
abstract class HomeStackContext extends Equatable with NavigationItem {
|
||||
List<NavigationItem> get navigationItems;
|
||||
|
||||
@override
|
||||
String get title;
|
||||
Widget get titleWidget;
|
||||
|
||||
@override
|
||||
String get identifier;
|
||||
|
||||
ViewType get type;
|
||||
HomeStackType get type;
|
||||
|
||||
Widget render();
|
||||
}
|
||||
|
||||
extension ViewStackContext on View {
|
||||
HomeStackContext intoStackContext() {
|
||||
switch (viewType) {
|
||||
case ViewType.Blank:
|
||||
return BlankStackContext();
|
||||
case ViewType.Doc:
|
||||
return DocStackContext(view: this);
|
||||
default:
|
||||
return BlankStackContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HomeStackNotifier extends ChangeNotifier {
|
||||
HomeStackContext inner;
|
||||
HomeStackNotifier({HomeStackContext? context}) : inner = context ?? BlankStackContext();
|
||||
@ -64,8 +56,8 @@ class HomeStackManager {
|
||||
final HomeStackNotifier _notifier = HomeStackNotifier();
|
||||
HomeStackManager();
|
||||
|
||||
String title() {
|
||||
return _notifier.context.title;
|
||||
Widget title() {
|
||||
return _notifier.context.titleWidget;
|
||||
}
|
||||
|
||||
void setStack(HomeStackContext context) {
|
||||
@ -93,7 +85,7 @@ class HomeStackManager {
|
||||
child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
|
||||
return FadingIndexedStack(
|
||||
index: pages.indexOf(notifier.context.type),
|
||||
children: ViewType.values.map((viewType) {
|
||||
children: HomeStackType.values.map((viewType) {
|
||||
if (viewType == notifier.context.type) {
|
||||
return notifier.context.render();
|
||||
} else {
|
||||
@ -105,5 +97,3 @@ class HomeStackManager {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
List<ViewType> pages = ViewType.values.toList();
|
||||
|
30
app_flowy/lib/workspace/domain/view_ext.dart
Normal file
30
app_flowy/lib/workspace/domain/view_ext.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/blank/blank_page.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/doc/doc_stack_page.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||
|
||||
extension ToHomeStackContext on View {
|
||||
HomeStackContext stackContext() {
|
||||
switch (viewType) {
|
||||
case ViewType.Blank:
|
||||
return BlankStackContext();
|
||||
case ViewType.Doc:
|
||||
return DocStackContext(view: this);
|
||||
default:
|
||||
return BlankStackContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ToHomeStackType on View {
|
||||
HomeStackType stackType() {
|
||||
switch (viewType) {
|
||||
case ViewType.Blank:
|
||||
return HomeStackType.blank;
|
||||
case ViewType.Doc:
|
||||
return HomeStackType.doc;
|
||||
default:
|
||||
return HomeStackType.blank;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
@ -94,14 +95,12 @@ class IconNaviItemWidget extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 24,
|
||||
child: FlowyTextButton(
|
||||
item.title,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
fontSize: 12,
|
||||
onPressed: () {
|
||||
child: InkWell(
|
||||
child: item.titleWidget,
|
||||
onTap: () {
|
||||
debugPrint('show app document');
|
||||
},
|
||||
),
|
||||
).padding(horizontal: 8, vertical: 2),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -114,14 +113,12 @@ class NaviItemWidget extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 24,
|
||||
child: FlowyTextButton(
|
||||
item.title,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
|
||||
fontSize: 12,
|
||||
onPressed: () {
|
||||
child: InkWell(
|
||||
child: item.titleWidget,
|
||||
onTap: () {
|
||||
debugPrint('show app document');
|
||||
},
|
||||
),
|
||||
).padding(horizontal: 8, vertical: 2),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -145,7 +142,7 @@ class EllipsisNaviItem extends NavigationItem {
|
||||
});
|
||||
|
||||
@override
|
||||
String get title => "...";
|
||||
Widget get titleWidget => const FlowyText.medium('...');
|
||||
|
||||
@override
|
||||
NavigationCallback get action => (id) {};
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@ -10,10 +11,10 @@ class BlankStackContext extends HomeStackContext {
|
||||
List<Object?> get props => ["1"];
|
||||
|
||||
@override
|
||||
String get title => "Blank page";
|
||||
Widget get titleWidget => const FlowyText.medium('Blank page', fontSize: 12);
|
||||
|
||||
@override
|
||||
ViewType get type => ViewType.Blank;
|
||||
HomeStackType get type => HomeStackType.blank;
|
||||
|
||||
@override
|
||||
Widget render() {
|
||||
@ -28,10 +29,10 @@ class BlankStackPage extends StatefulWidget {
|
||||
const BlankStackPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<BlankStackPage> createState() => _AnnouncementPage();
|
||||
State<BlankStackPage> createState() => _BlankStackPageState();
|
||||
}
|
||||
|
||||
class _AnnouncementPage extends State<BlankStackPage> {
|
||||
class _BlankStackPageState extends State<BlankStackPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox.expand(
|
||||
|
@ -1,6 +1,8 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_log/flowy_log.dart';
|
||||
import 'package:flowy_infra_ui/widget/error_page.dart';
|
||||
import 'package:flowy_sdk/protobuf/flowy-workspace/view_create.pb.dart';
|
||||
@ -15,11 +17,11 @@ class DocStackContext extends HomeStackContext {
|
||||
DocStackContext({required View view, Key? key}) : _view = view;
|
||||
|
||||
@override
|
||||
String get title => _view.name;
|
||||
Widget get titleWidget => FlowyText.medium(_view.name, fontSize: 12);
|
||||
@override
|
||||
String get identifier => _view.id;
|
||||
@override
|
||||
ViewType get type => _view.viewType;
|
||||
HomeStackType get type => _view.stackType();
|
||||
|
||||
@override
|
||||
List<Object?> get props => [_view.id];
|
||||
|
@ -0,0 +1,47 @@
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TrashStackContext extends HomeStackContext {
|
||||
@override
|
||||
String get identifier => "TrashStackContext";
|
||||
|
||||
@override
|
||||
List<Object?> get props => ["TrashStackContext"];
|
||||
|
||||
@override
|
||||
Widget get titleWidget => const FlowyText.medium('Trash', fontSize: 12);
|
||||
|
||||
@override
|
||||
HomeStackType get type => HomeStackType.trash;
|
||||
|
||||
@override
|
||||
Widget render() {
|
||||
return const TrashStackPage();
|
||||
}
|
||||
|
||||
@override
|
||||
List<NavigationItem> get navigationItems => [this];
|
||||
}
|
||||
|
||||
class TrashStackPage extends StatefulWidget {
|
||||
const TrashStackPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<TrashStackPage> createState() => _TrashStackPageState();
|
||||
}
|
||||
|
||||
class _TrashStackPageState extends State<TrashStackPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox.expand(
|
||||
child: Container(
|
||||
color: Colors.white,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Container(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ import 'package:app_flowy/workspace/presentation/widgets/menu/widget/menu_user.d
|
||||
|
||||
import 'widget/app/menu_app.dart';
|
||||
import 'widget/app/create_button.dart';
|
||||
import 'widget/menu_trash.dart';
|
||||
|
||||
// [[diagram: HomeMenu's widget structure]]
|
||||
// get user profile or modify user
|
||||
@ -101,6 +102,9 @@ class HomeMenu extends StatelessWidget {
|
||||
],
|
||||
).padding(horizontal: Insets.l),
|
||||
),
|
||||
const VSpace(20),
|
||||
_renderTrash(context).padding(horizontal: Insets.l),
|
||||
const VSpace(20),
|
||||
_renderNewAppButton(context),
|
||||
],
|
||||
),
|
||||
@ -112,10 +116,10 @@ class HomeMenu extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
return state.map(
|
||||
initial: (_) => MenuList(
|
||||
menuItems: menuItemsWithApps(context.read<MenuBloc>().state.apps),
|
||||
menuItems: buildMenuItems(context.read<MenuBloc>().state.apps),
|
||||
),
|
||||
loadApps: (s) => MenuList(
|
||||
menuItems: menuItemsWithApps(some(s.apps)),
|
||||
menuItems: buildMenuItems(some(s.apps)),
|
||||
),
|
||||
loadFail: (s) => FlowyErrorPage(s.error.toString()),
|
||||
);
|
||||
@ -123,6 +127,10 @@ class HomeMenu extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _renderTrash(BuildContext context) {
|
||||
return const MenuTrash();
|
||||
}
|
||||
|
||||
Widget _renderNewAppButton(BuildContext context) {
|
||||
return NewAppButton(
|
||||
press: (appName) => context.read<MenuBloc>().add(MenuEvent.createApp(appName, desc: "")),
|
||||
@ -133,31 +141,14 @@ class HomeMenu extends StatelessWidget {
|
||||
return const MenuTopBar();
|
||||
}
|
||||
|
||||
List<MenuItem> menuItemsWithApps(Option<List<App>> someApps) {
|
||||
return MenuItemBuilder().withUser(user).withApps(someApps).build();
|
||||
}
|
||||
}
|
||||
|
||||
class MenuItemBuilder {
|
||||
List<MenuItem> items = [];
|
||||
|
||||
MenuItemBuilder();
|
||||
|
||||
MenuItemBuilder withUser(UserProfile user) {
|
||||
List<MenuItem> buildMenuItems(Option<List<App>> apps) {
|
||||
List<MenuItem> items = [];
|
||||
items.add(MenuUser(user));
|
||||
return this;
|
||||
}
|
||||
|
||||
MenuItemBuilder withApps(Option<List<App>> someApps) {
|
||||
List<MenuItem> appWidgets = someApps.foldRight(
|
||||
[],
|
||||
(apps, _) => apps.map((app) => MenuApp(MenuAppContext(app))).toList(),
|
||||
);
|
||||
List<MenuItem> appWidgets =
|
||||
apps.foldRight([], (apps, _) => apps.map((app) => MenuApp(MenuAppContext(app))).toList());
|
||||
|
||||
items.addAll(appWidgets);
|
||||
return this;
|
||||
}
|
||||
|
||||
List<MenuItem> build() {
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/domain/view_ext.dart';
|
||||
import 'package:dartz/dartz.dart' as dartz;
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
@ -44,7 +45,7 @@ class ViewSectionItem extends StatelessWidget {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
onSelected(context.read<ViewBloc>().state.view);
|
||||
getIt<HomeStackManager>().setStack(state.view.intoStackContext());
|
||||
getIt<HomeStackManager>().setStack(state.view.stackContext());
|
||||
},
|
||||
child: FlowyHover(
|
||||
config: HoverDisplayConfig(hoverColor: theme.bg3),
|
||||
|
@ -0,0 +1,33 @@
|
||||
import 'package:app_flowy/startup/startup.dart';
|
||||
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
|
||||
import 'package:app_flowy/workspace/presentation/stack_page/trash_page.dart';
|
||||
import 'package:flowy_infra/image.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class MenuTrash extends StatelessWidget {
|
||||
const MenuTrash({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 26,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
getIt<HomeStackManager>().setStack(TrashStackContext());
|
||||
},
|
||||
child: _render(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _render(BuildContext context) {
|
||||
return Row(children: [
|
||||
SizedBox(width: 16, height: 16, child: svg("home/trash")),
|
||||
const HSpace(6),
|
||||
const FlowyText.medium('Trash', fontSize: 12),
|
||||
]);
|
||||
}
|
||||
}
|
@ -11,6 +11,8 @@ import 'package:flowy_infra_ui/style_widget/icon_button.dart';
|
||||
class MenuUser extends MenuItem {
|
||||
final UserProfile user;
|
||||
MenuUser(this.user, {Key? key}) : super(key: ValueKey(user.id));
|
||||
@override
|
||||
MenuItemType get type => MenuItemType.userProfile;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -60,7 +62,4 @@ class MenuUser extends MenuItem {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
MenuItemType get type => MenuItemType.userProfile;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user