refactor: remove domain folder

This commit is contained in:
appflowy 2022-03-01 16:05:45 +08:00
parent 156d38179a
commit 7a36fed778
56 changed files with 396 additions and 445 deletions

View File

@ -2,7 +2,7 @@ library flowy_plugin;
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flutter/widgets.dart';
@ -12,20 +12,24 @@ typedef PluginType = int;
typedef PluginDataType = ViewDataType;
typedef PluginId = String;
abstract class Plugin {
PluginId get pluginId;
PluginDisplay get pluginDisplay;
PluginType get pluginType;
String get pluginId;
ChangeNotifier? get displayNotifier => null;
void dispose();
PluginDisplay get display;
}
abstract class PluginBuilder {
Plugin build(dynamic data);
String get name;
String get menuName;
PluginType get pluginType;
@ -60,7 +64,6 @@ Plugin makePlugin({required PluginType pluginType, dynamic data}) {
List<PluginBuilder> pluginBuilders() {
final pluginBuilders = getIt<PluginSandbox>().builders;
final pluginConfigs = getIt<PluginSandbox>().pluginConfigs;
return pluginBuilders.where(
(builder) {
final config = pluginConfigs[builder.pluginType]?.creatable;

View File

@ -1,8 +1,8 @@
import 'package:app_flowy/plugin/plugin.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/trash/trash_page.dart';
import 'package:app_flowy/workspace/presentation/plugins/blank/blank.dart';
import 'package:app_flowy/workspace/presentation/plugins/doc/document.dart';
import 'package:app_flowy/workspace/presentation/plugins/trash/trash.dart';
enum DefaultPlugin {
quillEditor,

View File

@ -1,4 +1,4 @@
import 'package:app_flowy/workspace/domain/edit_context.dart';
import 'package:app_flowy/workspace/application/edit_pannel/edit_context.dart';
import 'package:dartz/dartz.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
// ignore: import_of_legacy_library_into_null_safe

View File

@ -1,4 +1,4 @@
import 'package:app_flowy/workspace/domain/edit_context.dart';
import 'package:app_flowy/workspace/application/edit_pannel/edit_context.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:dartz/dartz.dart';

View File

@ -1,29 +0,0 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.dart';
import 'package:flutter/material.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
enum AppDisclosureAction {
rename,
delete,
}
extension AppDisclosureExtension on AppDisclosureAction {
String get name {
switch (this) {
case AppDisclosureAction.rename:
return LocaleKeys.disclosureAction_rename.tr();
case AppDisclosureAction.delete:
return LocaleKeys.disclosureAction_delete.tr();
}
}
Widget get icon {
switch (this) {
case AppDisclosureAction.rename:
return svg('editor/edit', color: const Color(0xffe5e5e5));
case AppDisclosureAction.delete:
return svg('editor/delete', color: const Color(0xffe5e5e5));
}
}
}

View File

@ -1,34 +0,0 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.dart';
import 'package:flutter/material.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
enum ViewDisclosureAction {
rename,
delete,
duplicate,
}
extension ViewDisclosureExtension on ViewDisclosureAction {
String get name {
switch (this) {
case ViewDisclosureAction.rename:
return LocaleKeys.disclosureAction_rename.tr();
case ViewDisclosureAction.delete:
return LocaleKeys.disclosureAction_delete.tr();
case ViewDisclosureAction.duplicate:
return LocaleKeys.disclosureAction_duplicate.tr();
}
}
Widget get icon {
switch (this) {
case ViewDisclosureAction.rename:
return svg('editor/edit', color: const Color(0xff999999));
case ViewDisclosureAction.delete:
return svg('editor/delete', color: const Color(0xff999999));
case ViewDisclosureAction.duplicate:
return svg('editor/copy', color: const Color(0xff999999));
}
}
}

View File

@ -1,111 +0,0 @@
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/tasks/load_plugin.dart';
import 'package:flowy_infra/notifier.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/home_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
typedef NavigationCallback = void Function(String id);
abstract class NavigationItem {
Widget get leftBarItem;
Widget? get rightBarItem => null;
NavigationCallback get action => (id) {
getIt<HomeStackManager>().setStackWithId(id);
};
}
abstract class HomeStackContext<T> with NavigationItem {
List<NavigationItem> get navigationItems;
@override
Widget get leftBarItem;
@override
Widget? get rightBarItem;
ValueNotifier<T> get isUpdated;
Widget buildWidget();
void dispose();
}
class HomeStackNotifier extends ChangeNotifier {
Plugin _plugin;
PublishNotifier<bool> collapsedNotifier = PublishNotifier();
Widget get titleWidget => _plugin.display.leftBarItem;
HomeStackNotifier({Plugin? plugin}) : _plugin = plugin ?? makePlugin(pluginType: DefaultPlugin.blank.type());
set plugin(Plugin newPlugin) {
if (newPlugin.pluginId == _plugin.pluginId) {
return;
}
// stackContext.isUpdated.removeListener(notifyListeners);
_plugin.dispose();
_plugin = newPlugin;
// stackContext.isUpdated.addListener(notifyListeners);
notifyListeners();
}
Plugin get plugin => _plugin;
}
// HomeStack is initialized as singleton to controll the page stack.
class HomeStackManager {
final HomeStackNotifier _notifier = HomeStackNotifier();
HomeStackManager();
Widget title() {
return _notifier.plugin.display.leftBarItem;
}
PublishNotifier<bool> get collapsedNotifier => _notifier.collapsedNotifier;
void setPlugin(Plugin newPlugin) {
_notifier.plugin = newPlugin;
}
void setStackWithId(String id) {}
Widget stackTopBar() {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: _notifier),
],
child: Selector<HomeStackNotifier, Widget>(
selector: (context, notifier) => notifier.titleWidget,
builder: (context, widget, child) {
return const HomeTopBar();
},
),
);
}
Widget stackWidget() {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: _notifier),
],
child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
return FadingIndexedStack(
index: getIt<PluginSandbox>().indexOf(notifier.plugin.pluginType),
children: getIt<PluginSandbox>().supportPluginTypes.map((pluginType) {
if (pluginType == notifier.plugin.pluginType) {
return notifier.plugin.display.buildWidget();
} else {
return const BlankStackPage();
}
}).toList(),
);
}),
);
}
}

View File

@ -7,12 +7,12 @@ import 'package:app_flowy/workspace/application/menu/menu_user_bloc.dart';
import 'package:app_flowy/workspace/application/trash/trash_bloc.dart';
import 'package:app_flowy/workspace/application/view/view_bloc.dart';
import 'package:app_flowy/workspace/application/workspace/welcome_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/infrastructure/repos/app_repo.dart';
import 'package:app_flowy/workspace/infrastructure/repos/trash_repo.dart';
import 'package:app_flowy/workspace/infrastructure/repos/user_repo.dart';
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
import 'package:app_flowy/workspace/infrastructure/repos/workspace_repo.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-user-data-model/user_profile.pb.dart';

View File

@ -1,10 +1,8 @@
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/workspace/application/home/home_bloc.dart';
import 'package:app_flowy/workspace/application/home/home_listen_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/edit_pannel/pannel_animation.dart';
import 'package:app_flowy/workspace/presentation/widgets/float_bubble/question_bubble.dart';
import 'package:app_flowy/workspace/presentation/widgets/prelude.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flowy_infra_ui/style_widget/container.dart';
@ -14,7 +12,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:styled_widget/styled_widget.dart';
import '../widgets/edit_pannel/edit_pannel.dart';
import 'home_layout.dart';
import 'home_stack.dart';
import 'menu/menu.dart';
class HomeScreen extends StatefulWidget {
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();

View File

@ -0,0 +1,213 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:time/time.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/tasks/load_plugin.dart';
import 'package:app_flowy/workspace/presentation/plugins/blank/blank.dart';
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
import 'package:app_flowy/workspace/presentation/home/navigation.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_infra_ui/style_widget/extension.dart';
import 'package:flowy_infra/notifier.dart';
typedef NavigationCallback = void Function(String id);
late FToast fToast;
class HomeStack extends StatelessWidget {
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
// final Size size;
const HomeStack({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
Log.info('HomePage build');
final theme = context.watch<AppTheme>();
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIt<HomeStackManager>().stackTopBar(),
Expanded(
child: Container(
color: theme.surface,
child: FocusTraversalGroup(
child: getIt<HomeStackManager>().stackWidget(),
),
),
),
],
);
}
}
class FadingIndexedStack extends StatefulWidget {
final int index;
final List<Widget> children;
final Duration duration;
const FadingIndexedStack({
Key? key,
required this.index,
required this.children,
this.duration = const Duration(
milliseconds: 250,
),
}) : super(key: key);
@override
_FadingIndexedStackState createState() => _FadingIndexedStackState();
}
class _FadingIndexedStackState extends State<FadingIndexedStack> {
double _targetOpacity = 1;
@override
void initState() {
super.initState();
fToast = FToast();
fToast.init(HomeScreen.scaffoldKey.currentState!.context);
}
@override
void didUpdateWidget(FadingIndexedStack oldWidget) {
if (oldWidget.index == widget.index) return;
setState(() => _targetOpacity = 0);
Future.delayed(1.milliseconds, () => setState(() => _targetOpacity = 1));
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder<double>(
duration: _targetOpacity > 0 ? widget.duration : 0.milliseconds,
tween: Tween(begin: 0, end: _targetOpacity),
builder: (_, value, child) {
return Opacity(opacity: value, child: child);
},
child: IndexedStack(index: widget.index, children: widget.children),
);
}
}
abstract class NavigationItem {
Widget get leftBarItem;
Widget? get rightBarItem => null;
NavigationCallback get action => (id) {
getIt<HomeStackManager>().setStackWithId(id);
};
}
class HomeStackNotifier extends ChangeNotifier {
Plugin _plugin;
PublishNotifier<bool> collapsedNotifier = PublishNotifier();
Widget get titleWidget => _plugin.pluginDisplay.leftBarItem;
HomeStackNotifier({Plugin? plugin}) : _plugin = plugin ?? makePlugin(pluginType: DefaultPlugin.blank.type());
set plugin(Plugin newPlugin) {
if (newPlugin.pluginId == _plugin.pluginId) {
return;
}
_plugin.displayNotifier?.removeListener(notifyListeners);
_plugin.dispose();
_plugin = newPlugin;
_plugin.displayNotifier?.addListener(notifyListeners);
notifyListeners();
}
Plugin get plugin => _plugin;
}
// HomeStack is initialized as singleton to controll the page stack.
class HomeStackManager {
final HomeStackNotifier _notifier = HomeStackNotifier();
HomeStackManager();
Widget title() {
return _notifier.plugin.pluginDisplay.leftBarItem;
}
PublishNotifier<bool> get collapsedNotifier => _notifier.collapsedNotifier;
void setPlugin(Plugin newPlugin) {
_notifier.plugin = newPlugin;
}
void setStackWithId(String id) {}
Widget stackTopBar() {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: _notifier),
],
child: Selector<HomeStackNotifier, Widget>(
selector: (context, notifier) => notifier.titleWidget,
builder: (context, widget, child) {
return const HomeTopBar();
},
),
);
}
Widget stackWidget() {
return MultiProvider(
providers: [
ChangeNotifierProvider.value(value: _notifier),
],
child: Consumer(builder: (ctx, HomeStackNotifier notifier, child) {
return FadingIndexedStack(
index: getIt<PluginSandbox>().indexOf(notifier.plugin.pluginType),
children: getIt<PluginSandbox>().supportPluginTypes.map((pluginType) {
if (pluginType == notifier.plugin.pluginType) {
return notifier.plugin.pluginDisplay.buildWidget();
} else {
return const BlankStackPage();
}
}).toList(),
);
}),
);
}
}
class HomeTopBar extends StatelessWidget {
const HomeTopBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
return Container(
color: theme.surface,
height: HomeSizes.topBarHeight,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const FlowyNavigation(),
const HSpace(16),
ChangeNotifierProvider.value(
value: Provider.of<HomeStackNotifier>(context, listen: false),
child: Consumer(
builder: (BuildContext context, HomeStackNotifier notifier, Widget? child) {
return notifier.plugin.pluginDisplay.rightBarItem ?? const SizedBox();
},
),
) // _renderMoreButton(),
],
)
.padding(
horizontal: HomeInsets.topBarTitlePadding,
)
.bottomBorder(color: Colors.grey.shade300),
);
}
}

View File

@ -1,7 +1,4 @@
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/startup/tasks/load_plugin.dart';
import 'package:app_flowy/workspace/domain/view_ext.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@ -89,7 +86,7 @@ class CreateItem extends StatelessWidget {
return GestureDetector(
onTap: () => onSelected(pluginBuilder),
child: FlowyText.medium(
pluginBuilder.name,
pluginBuilder.menuName,
color: theme.textColor,
fontSize: 12,
).padding(horizontal: 10, vertical: 6),

View File

@ -1,4 +1,3 @@
import 'package:app_flowy/workspace/domain/edit_action/app_edit.dart';
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:expandable/expandable.dart';
@ -13,6 +12,8 @@ import 'package:app_flowy/workspace/application/app/app_bloc.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:dartz/dartz.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:flowy_infra/image.dart';
import '../menu_app.dart';
import 'add_button.dart';
import 'right_click_action.dart';
@ -134,3 +135,28 @@ class MenuAppHeader extends StatelessWidget {
});
}
}
enum AppDisclosureAction {
rename,
delete,
}
extension AppDisclosureExtension on AppDisclosureAction {
String get name {
switch (this) {
case AppDisclosureAction.rename:
return LocaleKeys.disclosureAction_rename.tr();
case AppDisclosureAction.delete:
return LocaleKeys.disclosureAction_delete.tr();
}
}
Widget get icon {
switch (this) {
case AppDisclosureAction.rename:
return svg('editor/edit', color: const Color(0xffe5e5e5));
case AppDisclosureAction.delete:
return svg('editor/delete', color: const Color(0xffe5e5e5));
}
}
}

View File

@ -1,9 +1,10 @@
import 'package:app_flowy/workspace/domain/edit_action/app_edit.dart';
import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
import 'package:dartz/dartz.dart' as dartz;
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'header.dart';
class AppDisclosureActionSheet with ActionList<DisclosureActionWrapper> implements FlowyOverlayDelegate {
final Function(dartz.Option<AppDisclosureAction>) onSelected;
final _items = AppDisclosureAction.values.map((action) => DisclosureActionWrapper(action)).toList();

View File

@ -1,6 +1,5 @@
import 'package:app_flowy/workspace/application/appearance.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/menu.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/header/header.dart';
import 'package:app_flowy/workspace/presentation/home/menu/menu.dart';
import 'package:expandable/expandable.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/app.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';

View File

@ -1,4 +1,3 @@
import 'package:app_flowy/workspace/domain/edit_action/view_edit.dart';
import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
import 'package:dartz/dartz.dart' as dartz;
import 'package:flowy_infra/image.dart';
@ -8,6 +7,8 @@ import 'package:flutter/material.dart';
import 'package:flowy_infra/theme.dart';
import 'package:provider/provider.dart';
import 'item.dart';
// [[Widget: LifeCycle]]
// https://flutterbyexample.com/lesson/stateful-widget-lifecycle
class ViewDisclosureButton extends StatelessWidget

View File

@ -1,7 +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/edit_action/view_edit.dart';
import 'package:app_flowy/workspace/domain/view_ext.dart';
import 'package:app_flowy/workspace/application/view/view_ext.dart';
import 'package:app_flowy/workspace/presentation/home/menu/menu.dart';
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
import 'package:dartz/dartz.dart' as dartz;
import 'package:easy_localization/easy_localization.dart';
@ -13,8 +13,8 @@ import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/menu_app.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:flowy_infra/image.dart';
import 'disclosure_action.dart';
@ -104,3 +104,33 @@ class ViewSectionItem extends StatelessWidget {
});
}
}
enum ViewDisclosureAction {
rename,
delete,
duplicate,
}
extension ViewDisclosureExtension on ViewDisclosureAction {
String get name {
switch (this) {
case ViewDisclosureAction.rename:
return LocaleKeys.disclosureAction_rename.tr();
case ViewDisclosureAction.delete:
return LocaleKeys.disclosureAction_delete.tr();
case ViewDisclosureAction.duplicate:
return LocaleKeys.disclosureAction_duplicate.tr();
}
}
Widget get icon {
switch (this) {
case ViewDisclosureAction.rename:
return svg('editor/edit', color: const Color(0xff999999));
case ViewDisclosureAction.delete:
return svg('editor/delete', color: const Color(0xff999999));
case ViewDisclosureAction.duplicate:
return svg('editor/copy', color: const Color(0xff999999));
}
}
}

View File

@ -1,8 +1,7 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/domain/view_ext.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/menu.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/app/menu_app.dart';
import 'package:app_flowy/workspace/application/view/view_ext.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:app_flowy/workspace/presentation/home/menu/menu.dart';
import 'package:flowy_sdk/protobuf/flowy-folder-data-model/view.pb.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

View File

@ -1,4 +1,8 @@
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/top_bar.dart';
export './app/header/header.dart';
export './app/menu_app.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:app_flowy/workspace/presentation/plugins/trash/menu.dart';
import 'package:flowy_infra/notifier.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra/theme.dart';
@ -15,32 +19,13 @@ import 'package:expandable/expandable.dart';
import 'package:flowy_infra/time/duration.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/menu/menu_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/widget/menu_user.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 '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
//
// IUser
// MenuTopBar
// MenuUserMenuUserBloc
//
// HomeMenu IUserListener
//
// listen workspace changes or user
// impl profile changes
//
// MenuList MenuItem
//
// AppBloc fetch app's views or modify view
//
//
// MenuApp
//
import 'app/menu_app.dart';
import 'app/create_button.dart';
import 'menu_user.dart';
class HomeMenu extends StatelessWidget {
final PublishNotifier<bool> _collapsedNotifier;
@ -181,3 +166,32 @@ class MenuSharedState extends ChangeNotifier {
});
}
}
class MenuTopBar extends StatelessWidget {
const MenuTopBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
return BlocBuilder<MenuBloc, MenuState>(
builder: (context, state) {
return SizedBox(
height: HomeSizes.topBarHeight,
child: Row(
children: [
(theme.isDark
? svgWithSize("flowy_logo_dark_mode", const Size(92, 17))
: svgWithSize("flowy_logo_with_text", const Size(92, 17))),
const Spacer(),
FlowyIconButton(
width: 28,
onPressed: () => context.read<MenuBloc>().add(const MenuEvent.collapse()),
iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4),
icon: svg("home/hide_menu", color: theme.iconColor),
)
],
),
);
},
);
}
}

View File

@ -1,4 +1,4 @@
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/notifier.dart';
import 'package:flowy_infra/theme.dart';
@ -17,8 +17,8 @@ class NavigationNotifier with ChangeNotifier {
void update(HomeStackNotifier notifier) {
bool shouldNotify = false;
if (navigationItems != notifier.plugin.display.navigationItems) {
navigationItems = notifier.plugin.display.navigationItems;
if (navigationItems != notifier.plugin.pluginDisplay.navigationItems) {
navigationItems = notifier.plugin.pluginDisplay.navigationItems;
shouldNotify = true;
}
@ -59,7 +59,7 @@ class FlowyNavigation extends StatelessWidget {
create: (_) {
final notifier = Provider.of<HomeStackNotifier>(context, listen: false);
return NavigationNotifier(
navigationItems: notifier.plugin.display.navigationItems,
navigationItems: notifier.plugin.pluginDisplay.navigationItems,
collapasedNotifier: notifier.collapsedNotifier,
);
},
@ -179,7 +179,4 @@ class EllipsisNaviItem extends NavigationItem {
@override
NavigationCallback get action => (id) {};
@override
String get identifier => "Ellipsis";
}

View File

@ -1,11 +1,11 @@
import 'package:app_flowy/startup/tasks/load_plugin.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/material.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
class BlankPluginBuilder extends PluginBuilder {
@override
@ -14,7 +14,7 @@ class BlankPluginBuilder extends PluginBuilder {
}
@override
String get name => "Blank";
String get menuName => "Blank";
@override
PluginType get pluginType => DefaultPlugin.blank.type();
@ -25,7 +25,7 @@ class BlankPluginConfig implements PluginConfig {
bool get creatable => false;
}
class BlankPagePlugin implements Plugin {
class BlankPagePlugin extends Plugin {
final PluginType _pluginType;
BlankPagePlugin({
required PluginType pluginType,
@ -35,10 +35,10 @@ class BlankPagePlugin implements Plugin {
void dispose() {}
@override
PluginDisplay get display => BlankPagePluginDisplay();
PluginDisplay get pluginDisplay => BlankPagePluginDisplay();
@override
String get pluginId => "BlankStack";
PluginId get pluginId => "BlankStack";
@override
PluginType get pluginType => _pluginType;
@ -49,12 +49,7 @@ class BlankPagePluginDisplay extends PluginDisplay {
Widget get leftBarItem => FlowyText.medium(LocaleKeys.blankPageTitle.tr(), fontSize: 12);
@override
Widget? get rightBarItem => null;
@override
Widget buildWidget() {
return const BlankStackPage();
}
Widget buildWidget() => const BlankStackPage();
@override
List<NavigationItem> get navigationItems => [this];

View File

@ -1,10 +1,17 @@
library docuemnt_plugin;
export './src/document_page.dart';
export './src/widget/toolbar/history_button.dart';
export './src/widget/toolbar/toolbar_icon_button.dart';
export './src/widget/toolbar/tool_bar.dart';
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/startup/tasks/load_plugin.dart';
import 'package:app_flowy/workspace/application/appearance.dart';
import 'package:app_flowy/workspace/application/doc/share_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/infrastructure/repos/view_repo.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/dialogs.dart';
import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
import 'package:easy_localization/easy_localization.dart';
@ -23,7 +30,7 @@ import 'package:clipboard/clipboard.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:provider/provider.dart';
import 'document_page.dart';
import 'src/document_page.dart';
class DocumentPluginBuilder extends PluginBuilder {
@override
@ -36,7 +43,7 @@ class DocumentPluginBuilder extends PluginBuilder {
}
@override
String get name => "Doc";
String get menuName => "Doc";
@override
PluginType get pluginType => DefaultPlugin.quillEditor.type();
@ -47,38 +54,42 @@ class DocumentPluginBuilder extends PluginBuilder {
class DocumentPlugin implements Plugin {
late View _view;
late ViewListener _listener;
final ValueNotifier<int> _isUpdated = ValueNotifier<int>(0);
ViewListener? _listener;
final ValueNotifier<int> _displayNotifier = ValueNotifier<int>(0);
late PluginType _pluginType;
DocumentPlugin({required PluginType pluginType, required View view, Key? key}) : _view = view {
_pluginType = pluginType;
_listener = getIt<ViewListener>(param1: view);
_listener.updatedNotifier.addPublishListener((result) {
_listener?.updatedNotifier.addPublishListener((result) {
result.fold(
(newView) {
_view = newView;
_isUpdated.value = _view.hashCode;
_displayNotifier.value = _view.hashCode;
},
(error) {},
);
});
_listener.start();
_listener?.start();
}
@override
void dispose() {
_listener.close();
_listener?.close();
_listener = null;
}
@override
PluginDisplay get display => DocumentPluginDisplay(view: _view);
PluginDisplay get pluginDisplay => DocumentPluginDisplay(view: _view);
@override
PluginType get pluginType => _pluginType;
@override
String get pluginId => _view.id;
PluginId get pluginId => _view.id;
@override
ChangeNotifier? get displayNotifier => _displayNotifier;
}
class DocumentPluginDisplay extends PluginDisplay {

View File

@ -1,6 +1,7 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/application/appearance.dart';
import 'package:app_flowy/workspace/application/doc/doc_bloc.dart';
import 'package:app_flowy/workspace/presentation/plugins/doc/document.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_scroll_bar.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter_quill/flutter_quill.dart' as quill;
@ -12,7 +13,6 @@ import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart';
import 'styles.dart';
import 'widget/banner.dart';
import 'widget/toolbar/tool_bar.dart';
class DocumentPage extends StatefulWidget {
final View view;

View File

@ -4,7 +4,7 @@ import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:flowy_infra/theme.dart';
import 'widget/style_widgets/style_widgets.dart';
import 'widget/style_widgets.dart';
DefaultStyles customStyles(BuildContext context) {
const baseSpacing = Tuple2<double, double>(6, 0);

View File

@ -1,7 +1,6 @@
import 'dart:async';
import 'dart:math';
import 'package:app_flowy/workspace/presentation/stack_page/doc/widget/toolbar/history_button.dart';
import 'package:app_flowy/workspace/presentation/widgets/emoji_picker/emoji_picker.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter_quill/flutter_quill.dart';
@ -10,6 +9,7 @@ import 'package:styled_widget/styled_widget.dart';
import 'check_button.dart';
import 'color_picker.dart';
import 'header_button.dart';
import 'history_button.dart';
import 'link_button.dart';
import 'toggle_button.dart';
import 'toolbar_icon_button.dart';

View File

@ -2,8 +2,8 @@ import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/startup/tasks/load_plugin.dart';
import 'package:app_flowy/workspace/application/appearance.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/menu/menu.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:app_flowy/workspace/presentation/home/menu/menu.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';

View File

@ -1,10 +1,12 @@
export "./src/sizes.dart";
export "./src/trash_cell.dart";
export "./src/trash_header.dart";
import 'package:app_flowy/plugin/plugin.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/startup/tasks/load_plugin.dart';
import 'package:app_flowy/workspace/application/trash/trash_bloc.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/stack_page/trash/widget/sizes.dart';
import 'package:app_flowy/workspace/presentation/stack_page/trash/widget/trash_cell.dart';
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart';
@ -19,7 +21,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
import 'widget/trash_header.dart';
import 'src/sizes.dart';
import 'src/trash_cell.dart';
import 'src/trash_header.dart';
class TrashPluginBuilder extends PluginBuilder {
@override
@ -28,7 +32,7 @@ class TrashPluginBuilder extends PluginBuilder {
}
@override
String get name => "Trash";
String get menuName => "Trash";
@override
PluginType get pluginType => DefaultPlugin.trash.type();
@ -39,7 +43,7 @@ class TrashPluginConfig implements PluginConfig {
bool get creatable => false;
}
class TrashPlugin implements Plugin {
class TrashPlugin extends Plugin {
final PluginType _pluginType;
TrashPlugin({required PluginType pluginType}) : _pluginType = pluginType;
@ -48,10 +52,10 @@ class TrashPlugin implements Plugin {
void dispose() {}
@override
PluginDisplay get display => TrashPluginDisplay();
PluginDisplay get pluginDisplay => TrashPluginDisplay();
@override
String get pluginId => "TrashStack";
PluginId get pluginId => "TrashStack";
@override
PluginType get pluginType => _pluginType;

View File

@ -1,86 +0,0 @@
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/home/home_screen.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_sdk/log.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:time/time.dart';
import 'package:fluttertoast/fluttertoast.dart';
late FToast fToast;
class HomeStack extends StatelessWidget {
static GlobalKey<ScaffoldState> scaffoldKey = GlobalKey();
// final Size size;
const HomeStack({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
Log.info('HomePage build');
final theme = context.watch<AppTheme>();
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIt<HomeStackManager>().stackTopBar(),
Expanded(
child: Container(
color: theme.surface,
child: FocusTraversalGroup(
child: getIt<HomeStackManager>().stackWidget(),
),
),
),
],
);
}
}
class FadingIndexedStack extends StatefulWidget {
final int index;
final List<Widget> children;
final Duration duration;
const FadingIndexedStack({
Key? key,
required this.index,
required this.children,
this.duration = const Duration(
milliseconds: 250,
),
}) : super(key: key);
@override
_FadingIndexedStackState createState() => _FadingIndexedStackState();
}
class _FadingIndexedStackState extends State<FadingIndexedStack> {
double _targetOpacity = 1;
@override
void initState() {
super.initState();
fToast = FToast();
fToast.init(HomeScreen.scaffoldKey.currentState!.context);
}
@override
void didUpdateWidget(FadingIndexedStack oldWidget) {
if (oldWidget.index == widget.index) return;
setState(() => _targetOpacity = 0);
Future.delayed(1.milliseconds, () => setState(() => _targetOpacity = 1));
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder<double>(
duration: _targetOpacity > 0 ? widget.duration : 0.milliseconds,
tween: Tween(begin: 0, end: _targetOpacity),
builder: (_, value, child) {
return Opacity(opacity: value, child: child);
},
child: IndexedStack(index: widget.index, children: widget.children),
);
}
}

View File

@ -1,5 +1,5 @@
import 'package:app_flowy/workspace/application/edit_pannel/edit_pannel_bloc.dart';
import 'package:app_flowy/workspace/domain/edit_context.dart';
import 'package:app_flowy/workspace/application/edit_pannel/edit_context.dart';
import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
import 'package:dartz/dartz.dart';

View File

@ -1,7 +1,6 @@
import 'package:app_flowy/workspace/presentation/plugins/doc/document.dart';
import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart';
import 'package:app_flowy/workspace/presentation/stack_page/doc/widget/toolbar/toolbar_icon_button.dart';
import 'package:app_flowy/workspace/presentation/widgets/emoji_picker/emoji_picker.dart';
class FlowyEmojiStyleButton extends StatefulWidget {

View File

@ -1,3 +1,4 @@
import 'package:app_flowy/workspace/presentation/home/home_stack.dart';
import 'package:app_flowy/workspace/presentation/widgets/pop_up_action.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme.dart';
@ -16,7 +17,6 @@ import 'package:url_launcher/url_launcher.dart';
import 'package:app_flowy/generated/locale_keys.g.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:app_flowy/workspace/presentation/stack_page/home_stack.dart';
class QuestionBubble extends StatelessWidget {
const QuestionBubble({Key? key}) : super(key: key);

View File

@ -1,40 +0,0 @@
import 'package:app_flowy/workspace/domain/page_stack/page_stack.dart';
import 'package:app_flowy/workspace/presentation/home/home_sizes.dart';
import 'package:app_flowy/workspace/presentation/home/navigation.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart';
import 'package:flowy_infra_ui/style_widget/extension.dart';
import 'package:provider/provider.dart';
class HomeTopBar extends StatelessWidget {
const HomeTopBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
return Container(
color: theme.surface,
height: HomeSizes.topBarHeight,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const FlowyNavigation(),
const HSpace(16),
ChangeNotifierProvider.value(
value: Provider.of<HomeStackNotifier>(context, listen: false),
child: Consumer(
builder: (BuildContext context, HomeStackNotifier notifier, Widget? child) {
return notifier.plugin.display.rightBarItem ?? const SizedBox();
},
),
) // _renderMoreButton(),
],
)
.padding(
horizontal: HomeInsets.topBarTitlePadding,
)
.bottomBorder(color: Colors.grey.shade300),
);
}
}

View File

@ -1 +0,0 @@
export 'menu.dart';

View File

@ -1,36 +0,0 @@
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';
import 'package:flowy_infra/theme.dart';
class MenuTopBar extends StatelessWidget {
const MenuTopBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final theme = context.watch<AppTheme>();
return BlocBuilder<MenuBloc, MenuState>(
builder: (context, state) {
return SizedBox(
height: HomeSizes.topBarHeight,
child: Row(
children: [
(theme.isDark
? svgWithSize("flowy_logo_dark_mode", const Size(92, 17))
: svgWithSize("flowy_logo_with_text", const Size(92, 17))),
const Spacer(),
FlowyIconButton(
width: 28,
onPressed: () => context.read<MenuBloc>().add(const MenuEvent.collapse()),
iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4),
icon: svg("home/hide_menu", color: theme.iconColor),
)
],
),
);
},
);
}
}

View File

@ -1,5 +0,0 @@
export '../stack_page/blank/blank_page.dart';
export './edit_pannel/edit_pannel.dart';
export './edit_pannel/pannel_animation.dart';
export './home_top_bar.dart';
export 'menu/menu.dart';

View File

@ -117,6 +117,7 @@ pub async fn create_view(sdk: &FlowySDKTest, app_id: &str, name: &str, desc: &st
thumbnail: None,
data_type: view_type,
ext_data: "".to_string(),
plugin_type: 0,
};
let view = FolderEventBuilder::new(sdk.clone())
.event(CreateView)

View File

@ -90,6 +90,7 @@ async fn create_view(sdk: &FlowySDKTest, app_id: &str) -> View {
thumbnail: Some("http://1.png".to_string()),
data_type: ViewDataType::RichText,
ext_data: "".to_string(),
plugin_type: 0,
};
let view = FolderEventBuilder::new(sdk.clone())