[flutter]: customize home topbar action widget

This commit is contained in:
appflowy 2021-11-09 23:13:04 +08:00
parent 05f9f7b4a1
commit b1668bfe6c
13 changed files with 222 additions and 94 deletions

View File

@ -24,7 +24,7 @@ class _$MenuEventTearOff {
return const Collapse();
}
OpenPage openPage(HomeStackContext<dynamic> context) {
OpenPage openPage(HomeStackContext<dynamic, dynamic> context) {
return OpenPage(
context,
);
@ -53,7 +53,8 @@ mixin _$MenuEvent {
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic> context) openPage,
required TResult Function(HomeStackContext<dynamic, dynamic> context)
openPage,
required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
didReceiveApps,
@ -63,7 +64,7 @@ mixin _$MenuEvent {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic> context)? openPage,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
didReceiveApps,
@ -145,7 +146,8 @@ class _$_Initial implements _Initial {
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic> context) openPage,
required TResult Function(HomeStackContext<dynamic, dynamic> context)
openPage,
required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
didReceiveApps,
@ -158,7 +160,7 @@ class _$_Initial implements _Initial {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic> context)? openPage,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
didReceiveApps,
@ -242,7 +244,8 @@ class _$Collapse implements Collapse {
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic> context) openPage,
required TResult Function(HomeStackContext<dynamic, dynamic> context)
openPage,
required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
didReceiveApps,
@ -255,7 +258,7 @@ class _$Collapse implements Collapse {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic> context)? openPage,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
didReceiveApps,
@ -304,7 +307,7 @@ abstract class Collapse implements MenuEvent {
abstract class $OpenPageCopyWith<$Res> {
factory $OpenPageCopyWith(OpenPage value, $Res Function(OpenPage) then) =
_$OpenPageCopyWithImpl<$Res>;
$Res call({HomeStackContext<dynamic> context});
$Res call({HomeStackContext<dynamic, dynamic> context});
}
/// @nodoc
@ -324,7 +327,7 @@ class _$OpenPageCopyWithImpl<$Res> extends _$MenuEventCopyWithImpl<$Res>
context == freezed
? _value.context
: context // ignore: cast_nullable_to_non_nullable
as HomeStackContext<dynamic>,
as HomeStackContext<dynamic, dynamic>,
));
}
}
@ -335,7 +338,7 @@ class _$OpenPage implements OpenPage {
const _$OpenPage(this.context);
@override
final HomeStackContext<dynamic> context;
final HomeStackContext<dynamic, dynamic> context;
@override
String toString() {
@ -364,7 +367,8 @@ class _$OpenPage implements OpenPage {
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic> context) openPage,
required TResult Function(HomeStackContext<dynamic, dynamic> context)
openPage,
required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
didReceiveApps,
@ -377,7 +381,7 @@ class _$OpenPage implements OpenPage {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic> context)? openPage,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
didReceiveApps,
@ -419,9 +423,11 @@ class _$OpenPage implements OpenPage {
}
abstract class OpenPage implements MenuEvent {
const factory OpenPage(HomeStackContext<dynamic> context) = _$OpenPage;
const factory OpenPage(HomeStackContext<dynamic, dynamic> context) =
_$OpenPage;
HomeStackContext<dynamic> get context => throw _privateConstructorUsedError;
HomeStackContext<dynamic, dynamic> get context =>
throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$OpenPageCopyWith<OpenPage> get copyWith =>
throw _privateConstructorUsedError;
@ -502,7 +508,8 @@ class _$CreateApp implements CreateApp {
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic> context) openPage,
required TResult Function(HomeStackContext<dynamic, dynamic> context)
openPage,
required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
didReceiveApps,
@ -515,7 +522,7 @@ class _$CreateApp implements CreateApp {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic> context)? openPage,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
didReceiveApps,
@ -633,7 +640,8 @@ class _$ReceiveApps implements ReceiveApps {
TResult when<TResult extends Object?>({
required TResult Function() initial,
required TResult Function() collapse,
required TResult Function(HomeStackContext<dynamic> context) openPage,
required TResult Function(HomeStackContext<dynamic, dynamic> context)
openPage,
required TResult Function(String name, String? desc) createApp,
required TResult Function(Either<List<App>, WorkspaceError> appsOrFail)
didReceiveApps,
@ -646,7 +654,7 @@ class _$ReceiveApps implements ReceiveApps {
TResult maybeWhen<TResult extends Object?>({
TResult Function()? initial,
TResult Function()? collapse,
TResult Function(HomeStackContext<dynamic> context)? openPage,
TResult Function(HomeStackContext<dynamic, dynamic> context)? openPage,
TResult Function(String name, String? desc)? createApp,
TResult Function(Either<List<App>, WorkspaceError> appsOrFail)?
didReceiveApps,
@ -706,7 +714,7 @@ class _$MenuStateTearOff {
{required bool isCollapse,
required Option<List<App>> apps,
required Either<Unit, WorkspaceError> successOrFailure,
required HomeStackContext<dynamic> context}) {
required HomeStackContext<dynamic, dynamic> context}) {
return _MenuState(
isCollapse: isCollapse,
apps: apps,
@ -725,7 +733,8 @@ mixin _$MenuState {
Option<List<App>> get apps => throw _privateConstructorUsedError;
Either<Unit, WorkspaceError> get successOrFailure =>
throw _privateConstructorUsedError;
HomeStackContext<dynamic> get context => throw _privateConstructorUsedError;
HomeStackContext<dynamic, dynamic> get context =>
throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$MenuStateCopyWith<MenuState> get copyWith =>
@ -740,7 +749,7 @@ abstract class $MenuStateCopyWith<$Res> {
{bool isCollapse,
Option<List<App>> apps,
Either<Unit, WorkspaceError> successOrFailure,
HomeStackContext<dynamic> context});
HomeStackContext<dynamic, dynamic> context});
}
/// @nodoc
@ -774,7 +783,7 @@ class _$MenuStateCopyWithImpl<$Res> implements $MenuStateCopyWith<$Res> {
context: context == freezed
? _value.context
: context // ignore: cast_nullable_to_non_nullable
as HomeStackContext<dynamic>,
as HomeStackContext<dynamic, dynamic>,
));
}
}
@ -789,7 +798,7 @@ abstract class _$MenuStateCopyWith<$Res> implements $MenuStateCopyWith<$Res> {
{bool isCollapse,
Option<List<App>> apps,
Either<Unit, WorkspaceError> successOrFailure,
HomeStackContext<dynamic> context});
HomeStackContext<dynamic, dynamic> context});
}
/// @nodoc
@ -824,7 +833,7 @@ class __$MenuStateCopyWithImpl<$Res> extends _$MenuStateCopyWithImpl<$Res>
context: context == freezed
? _value.context
: context // ignore: cast_nullable_to_non_nullable
as HomeStackContext<dynamic>,
as HomeStackContext<dynamic, dynamic>,
));
}
}
@ -845,7 +854,7 @@ class _$_MenuState implements _MenuState {
@override
final Either<Unit, WorkspaceError> successOrFailure;
@override
final HomeStackContext<dynamic> context;
final HomeStackContext<dynamic, dynamic> context;
@override
String toString() {
@ -887,7 +896,7 @@ abstract class _MenuState implements MenuState {
{required bool isCollapse,
required Option<List<App>> apps,
required Either<Unit, WorkspaceError> successOrFailure,
required HomeStackContext<dynamic> context}) = _$_MenuState;
required HomeStackContext<dynamic, dynamic> context}) = _$_MenuState;
@override
bool get isCollapse => throw _privateConstructorUsedError;
@ -897,7 +906,8 @@ abstract class _MenuState implements MenuState {
Either<Unit, WorkspaceError> get successOrFailure =>
throw _privateConstructorUsedError;
@override
HomeStackContext<dynamic> get context => throw _privateConstructorUsedError;
HomeStackContext<dynamic, dynamic> get context =>
throw _privateConstructorUsedError;
@override
@JsonKey(ignore: true)
_$MenuStateCopyWith<_MenuState> get copyWith =>

View File

@ -25,12 +25,14 @@ enum HomeStackType {
List<HomeStackType> pages = HomeStackType.values.toList();
abstract class HomeStackContext<T> with NavigationItem {
abstract class HomeStackContext<T, S> with NavigationItem {
List<NavigationItem> get navigationItems;
@override
Widget get naviTitle;
Widget? Function(BuildContext context) get buildNavigationActions;
@override
String get identifier;

View File

@ -11,6 +11,9 @@ class BlankStackContext extends HomeStackContext {
@override
Widget get naviTitle => const FlowyText.medium('Blank page', fontSize: 12);
@override
Widget? Function(BuildContext context) get buildNavigationActions => (_) => null;
@override
HomeStackType get type => HomeStackType.blank;

View File

@ -2,13 +2,18 @@ import 'package:app_flowy/startup/startup.dart';
import 'package:app_flowy/workspace/domain/i_view.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/pop_up_action.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/rounded_button.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pb.dart';
import 'package:flutter/material.dart';
import 'package:dartz/dartz.dart' as dartz;
import 'doc_page.dart';
class DocStackContext extends HomeStackContext {
class DocStackContext extends HomeStackContext<String, ShareActionWrapper> {
View _view;
late IViewListener _listener;
final ValueNotifier<String> _isUpdated = ValueNotifier<String>("");
@ -29,15 +34,18 @@ class DocStackContext extends HomeStackContext {
@override
Widget get naviTitle => FlowyText.medium(_view.name, fontSize: 12);
@override
Widget? Function(BuildContext context) get buildNaviAction => _buildNaviAction;
@override
String get identifier => _view.id;
@override
HomeStackType get type => _view.stackType();
@override
Widget buildWidget() {
return DocStackPage(_view, key: ValueKey(_view.id));
}
Widget buildWidget() => DocStackPage(_view, key: ValueKey(_view.id));
@override
List<NavigationItem> get navigationItems => _makeNavigationItems();
@ -50,15 +58,52 @@ class DocStackContext extends HomeStackContext {
// }).toList();
List<NavigationItem> _makeNavigationItems() {
return [
this,
];
return [this];
}
@override
void dispose() {
_listener.stop();
}
Widget _buildNaviAction(BuildContext context) {
return const DocShareButton();
}
}
class DocShareButton extends StatelessWidget {
const DocShareButton({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
double buttonWidth = 60;
return RoundedTextButton(
title: 'Share',
height: 30,
width: buttonWidth,
fontSize: 12,
borderRadius: Corners.s6Border,
color: Colors.lightBlue,
onPressed: () {
final actionList = ShareActions(onSelected: (result) {
result.fold(() {}, (action) {
switch (action) {
case ShareAction.markdown:
break;
case ShareAction.copyLink:
break;
}
});
});
actionList.show(
context,
context,
anchorDirection: AnchorDirection.bottomWithCenterAligned,
anchorOffset: Offset(-(buttonWidth / 2), 10),
);
},
);
}
}
class DocStackPage extends StatefulWidget {
@ -90,3 +135,70 @@ class _DocStackPageState extends State<DocStackPage> {
super.didUpdateWidget(oldWidget);
}
}
class ShareActions with ActionList<ShareActionWrapper> implements FlowyOverlayDelegate {
final Function(dartz.Option<ShareAction>) onSelected;
final _items = ShareAction.values.map((action) => ShareActionWrapper(action)).toList();
ShareActions({
required this.onSelected,
});
@override
double get maxWidth => 130;
@override
double get itemHeight => 22;
@override
List<ShareActionWrapper> get items => _items;
@override
void Function(dartz.Option<ShareActionWrapper> p1) get selectCallback => (result) {
result.fold(
() => onSelected(dartz.none()),
(wrapper) => onSelected(
dartz.some(wrapper.inner),
),
);
};
@override
FlowyOverlayDelegate? get delegate => this;
@override
void didRemove() {
onSelected(dartz.none());
}
@override
ListOverlayFooter? get footer => null;
}
enum ShareAction {
markdown,
copyLink,
}
class ShareActionWrapper extends ActionItem {
final ShareAction inner;
ShareActionWrapper(this.inner);
@override
Widget? get icon => null;
@override
String get name => inner.name;
}
extension QuestionBubbleExtension on ShareAction {
String get name {
switch (this) {
case ShareAction.markdown:
return "Markdown";
case ShareAction.copyLink:
return "Copy Link";
}
}
}

View File

@ -3,6 +3,7 @@ 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/widgets/home_top_bar.dart';
import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
@ -27,6 +28,9 @@ class TrashStackContext extends HomeStackContext {
@override
Widget get naviTitle => const FlowyText.medium('Trash', fontSize: 12);
@override
Widget? Function(BuildContext context) get buildNavigationActions => (_) => null;
@override
HomeStackType get type => HomeStackType.trash;

View File

@ -22,21 +22,21 @@ class QuestionBubble extends StatelessWidget {
height: 30,
child: FlowyTextButton(
'?',
tooltip: QuestionBubbleAction.values.map((action) => action.name).toList().join(','),
tooltip: BubbleAction.values.map((action) => action.name).toList().join(','),
fontSize: 12,
fontWeight: FontWeight.w600,
fillColor: theme.selector,
mainAxisAlignment: MainAxisAlignment.center,
radius: BorderRadius.circular(10),
onPressed: () {
final actionList = QuestionBubbleActions(onSelected: (result) {
final actionList = QuestionBubbleActionSheet(onSelected: (result) {
result.fold(() {}, (action) {
switch (action) {
case QuestionBubbleAction.whatsNews:
case BubbleAction.whatsNews:
// TODO: annie replace the URL with real ones
_launchURL("https://www.appflowy.io/whatsnew");
break;
case QuestionBubbleAction.help:
case BubbleAction.help:
// TODO: annie replace the URL with real ones
_launchURL("https://discord.gg/9Q2xaN37tV");
break;
@ -63,11 +63,11 @@ class QuestionBubble extends StatelessWidget {
}
}
class QuestionBubbleActions with ActionList<QuestionBubbleActionWrapper> implements FlowyOverlayDelegate {
final Function(dartz.Option<QuestionBubbleAction>) onSelected;
final _items = QuestionBubbleAction.values.map((action) => QuestionBubbleActionWrapper(action)).toList();
class QuestionBubbleActionSheet with ActionList<BubbleActionWrapper> implements FlowyOverlayDelegate {
final Function(dartz.Option<BubbleAction>) onSelected;
final _items = BubbleAction.values.map((action) => BubbleActionWrapper(action)).toList();
QuestionBubbleActions({
QuestionBubbleActionSheet({
required this.onSelected,
});
@ -78,10 +78,10 @@ class QuestionBubbleActions with ActionList<QuestionBubbleActionWrapper> impleme
double get itemHeight => 22;
@override
List<QuestionBubbleActionWrapper> get items => _items;
List<BubbleActionWrapper> get items => _items;
@override
void Function(dartz.Option<QuestionBubbleActionWrapper> p1) get selectCallback => (result) {
void Function(dartz.Option<BubbleActionWrapper> p1) get selectCallback => (result) {
result.fold(
() => onSelected(dartz.none()),
(wrapper) => onSelected(
@ -145,15 +145,15 @@ class FlowyVersionDescription extends StatelessWidget {
}
}
enum QuestionBubbleAction {
enum BubbleAction {
whatsNews,
help,
}
class QuestionBubbleActionWrapper extends ActionItemData {
final QuestionBubbleAction inner;
class BubbleActionWrapper extends ActionItem {
final BubbleAction inner;
QuestionBubbleActionWrapper(this.inner);
BubbleActionWrapper(this.inner);
@override
Widget? get icon => inner.emoji;
@ -161,21 +161,21 @@ class QuestionBubbleActionWrapper extends ActionItemData {
String get name => inner.name;
}
extension QuestionBubbleExtension on QuestionBubbleAction {
extension QuestionBubbleExtension on BubbleAction {
String get name {
switch (this) {
case QuestionBubbleAction.whatsNews:
case BubbleAction.whatsNews:
return "What's new?";
case QuestionBubbleAction.help:
case BubbleAction.help:
return "Help & Support";
}
}
Widget get emoji {
switch (this) {
case QuestionBubbleAction.whatsNews:
case BubbleAction.whatsNews:
return const Text('⭐️', style: TextStyle(fontSize: 12));
case QuestionBubbleAction.help:
case BubbleAction.help:
return const Text('👥', style: TextStyle(fontSize: 12));
}
}

View File

@ -1,14 +1,14 @@
import 'package:app_flowy/workspace/domain/image.dart';
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/size.dart';
import 'package:flowy_infra_ui/widget/rounded_button.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pb.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/view_create.pbenum.dart';
import 'package:flutter/material.dart';
import 'package:flowy_infra_ui/style_widget/extension.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:provider/provider.dart';
class HomeTopBar extends StatelessWidget {
const HomeTopBar({Key? key}) : super(key: key);
@ -22,8 +22,14 @@ class HomeTopBar extends StatelessWidget {
children: [
const FlowyNavigation(),
const Spacer(),
_renderShareButton(),
// _renderMoreButton(),
ChangeNotifierProvider.value(
value: Provider.of<HomeStackNotifier>(context, listen: false),
child: Consumer(
builder: (BuildContext context, HomeStackNotifier notifier, Widget? child) {
return notifier.stackContext.buildNavigationActions(context) ?? const SizedBox();
},
),
) // _renderMoreButton(),
],
)
.padding(
@ -32,20 +38,6 @@ class HomeTopBar extends StatelessWidget {
.bottomBorder(color: Colors.grey.shade300),
);
}
Widget _renderShareButton() {
return RoundedTextButton(
title: 'Share',
height: 30,
width: 60,
fontSize: 12,
borderRadius: Corners.s6Border,
color: Colors.lightBlue,
onPressed: () {
debugPrint('share page');
},
);
}
}
class HomeTitle extends StatelessWidget {

View File

@ -5,7 +5,6 @@ import 'package:flowy_infra/flowy_icon_data_icons.dart';
import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flowy_sdk/protobuf/flowy-workspace-infra/app_create.pb.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -79,7 +78,7 @@ class MenuAppHeader extends StatelessWidget {
behavior: HitTestBehavior.opaque,
onTap: () => ExpandableController.of(context, rebuildOnChange: false, required: true)?.toggle(),
onSecondaryTap: () {
final actionList = AppDisclosureActions(onSelected: (action) => _handleAction(context, action));
final actionList = AppDisclosureActionSheet(onSelected: (action) => _handleAction(context, action));
actionList.show(
context,
context,

View File

@ -4,19 +4,19 @@ import 'package:dartz/dartz.dart' as dartz;
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
class AppDisclosureActions with ActionList<AppDisclosureActionWrapper> implements FlowyOverlayDelegate {
class AppDisclosureActionSheet with ActionList<DisclosureActionWrapper> implements FlowyOverlayDelegate {
final Function(dartz.Option<AppDisclosureAction>) onSelected;
final _items = AppDisclosureAction.values.map((action) => AppDisclosureActionWrapper(action)).toList();
final _items = AppDisclosureAction.values.map((action) => DisclosureActionWrapper(action)).toList();
AppDisclosureActions({
AppDisclosureActionSheet({
required this.onSelected,
});
@override
List<AppDisclosureActionWrapper> get items => _items;
List<DisclosureActionWrapper> get items => _items;
@override
void Function(dartz.Option<AppDisclosureActionWrapper> p1) get selectCallback => (result) {
void Function(dartz.Option<DisclosureActionWrapper> p1) get selectCallback => (result) {
result.fold(
() => onSelected(dartz.none()),
(wrapper) => onSelected(
@ -37,10 +37,10 @@ class AppDisclosureActions with ActionList<AppDisclosureActionWrapper> implement
ListOverlayFooter? get footer => null;
}
class AppDisclosureActionWrapper extends ActionItemData {
class DisclosureActionWrapper extends ActionItem {
final AppDisclosureAction inner;
AppDisclosureActionWrapper(this.inner);
DisclosureActionWrapper(this.inner);
@override
Widget? get icon => inner.icon;

View File

@ -57,7 +57,7 @@ class ViewDisclosureButton extends StatelessWidget
ListOverlayFooter? get footer => null;
}
class ViewDisclosureActionWrapper extends ActionItemData {
class ViewDisclosureActionWrapper extends ActionItem {
final ViewDisclosureAction inner;
ViewDisclosureActionWrapper(this.inner);

View File

@ -8,7 +8,7 @@ import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:dartz/dartz.dart' as dartz;
abstract class ActionList<T extends ActionItemData> {
abstract class ActionList<T extends ActionItem> {
List<T> get items;
String get identifier => toString();
@ -31,7 +31,7 @@ abstract class ActionList<T extends ActionItemData> {
}) {
final widgets = items
.map(
(action) => ActionItem<T>(
(action) => ActionCell<T>(
action: action,
itemHeight: itemHeight,
onSelected: (action) {
@ -58,7 +58,7 @@ abstract class ActionList<T extends ActionItemData> {
}
}
abstract class ActionItemData {
abstract class ActionItem {
Widget? get icon;
String get name;
}
@ -69,11 +69,11 @@ class ActionListSizes {
static double padding = 6;
}
class ActionItem<T extends ActionItemData> extends StatelessWidget {
class ActionCell<T extends ActionItem> extends StatelessWidget {
final T action;
final Function(T) onSelected;
final double itemHeight;
const ActionItem({
const ActionCell({
Key? key,
required this.action,
required this.onSelected,

View File

@ -17,7 +17,7 @@ use crate::{
};
use flowy_dispatch::prelude::{data_result, Data, DataResult, Unit};
use flowy_document::entities::doc::DocDelta;
use flowy_workspace_infra::entities::share::{ExportParams, ExportRequest};
use flowy_workspace_infra::entities::share::{ExportData, ExportParams, ExportRequest};
use std::{convert::TryInto, sync::Arc};
pub(crate) async fn create_view_handler(
@ -112,8 +112,8 @@ pub(crate) async fn duplicate_view_handler(
pub(crate) async fn export_handler(
data: Data<ExportRequest>,
controller: Unit<Arc<ViewController>>,
) -> Result<(), WorkspaceError> {
) -> DataResult<ExportData, WorkspaceError> {
let params: ExportParams = data.into_inner().try_into()?;
let _ = controller.export_doc(params.into()).await?;
Ok(())
let data = controller.export_doc(params.into()).await?;
data_result(data)
}

View File

@ -139,9 +139,15 @@ impl ViewController {
Ok(())
}
#[tracing::instrument(level = "debug", skip(self), err)]
pub(crate) async fn export_doc(&self, _params: ExportParams) -> Result<ExportData, WorkspaceError> {
unimplemented!()
#[tracing::instrument(level = "debug", skip(self, params), err)]
pub(crate) async fn export_doc(&self, params: ExportParams) -> Result<ExportData, WorkspaceError> {
let doc_identifier: DocIdentifier = params.doc_id.into();
let doc = self
.document
.read_document_data(doc_identifier, self.database.db_pool()?)
.await?;
Ok(ExportData { data: doc.data })
}
// belong_to_id will be the app_id or view_id.