feat: support moveTo feature in more action menu (#6338)

* feat: support moveTo feature in more action menu

* fix: unable to switch to another workspace

* fix: integration test

* chore: update editor version

* fix: integration test
This commit is contained in:
Lucas 2024-09-18 14:45:25 +08:00 committed by GitHub
parent 522143cfd8
commit 630fdb8995
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 277 additions and 223 deletions

View File

@ -1,10 +1,5 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:appflowy/core/config/kv.dart';
import 'package:appflowy/core/config/kv_keys.dart';
import 'package:appflowy/generated/flowy_svgs.g.dart';
@ -35,6 +30,10 @@ import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/widget/buttons/primary_button.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'emoji.dart';
@ -572,8 +571,7 @@ extension CommonOperations on WidgetTester {
Future<void> openMoreViewActions() async {
final button = find.byType(MoreViewActions);
await tap(button);
await pumpAndSettle();
await tapButton(button);
}
/// Presses on the Duplicate ViewAction in the [MoreViewActions] popup.
@ -581,12 +579,9 @@ extension CommonOperations on WidgetTester {
/// [openMoreViewActions] must be called beforehand!
///
Future<void> duplicateByMoreViewActions() async {
final button = find.descendant(
of: find.byType(ListView),
matching: find.byWidgetPredicate(
(widget) =>
widget is ViewAction && widget.type == ViewActionType.duplicate,
),
final button = find.byWidgetPredicate(
(widget) =>
widget is ViewAction && widget.type == ViewMoreActionType.duplicate,
);
await tap(button);
await pump();
@ -601,7 +596,7 @@ extension CommonOperations on WidgetTester {
of: find.byType(ListView),
matching: find.byWidgetPredicate(
(widget) =>
widget is ViewAction && widget.type == ViewActionType.delete,
widget is ViewAction && widget.type == ViewMoreActionType.delete,
),
);
await tap(button);

View File

@ -225,11 +225,11 @@ class _HomePageState extends State<_HomePage> {
FavoriteBloc()..add(const FavoriteEvent.initial()),
),
BlocProvider(
create: (_) => SpaceBloc()
..add(
SpaceEvent.initial(
widget.userProfile,
workspaceId,
create: (_) => SpaceBloc(
userProfile: widget.userProfile,
workspaceId: workspaceId,
)..add(
const SpaceEvent.initial(
openFirstPage: false,
),
),

View File

@ -63,11 +63,14 @@ class SidebarSection {
/// The [SpaceBloc] is responsible for
/// managing the root views in different sections of the workspace.
class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
SpaceBloc() : super(SpaceState.initial()) {
SpaceBloc({
required this.userProfile,
required this.workspaceId,
}) : super(SpaceState.initial()) {
on<SpaceEvent>(
(event, emit) async {
await event.when(
initial: (userProfile, workspaceId, openFirstPage) async {
initial: (openFirstPage) async {
this.openFirstPage = openFirstPage;
_initial(userProfile, workspaceId);
@ -297,7 +300,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
);
},
reset: (userProfile, workspaceId, openFirstPage) async {
if (workspaceId == _workspaceId) {
if (this.workspaceId == workspaceId) {
return;
}
@ -305,8 +308,6 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
add(
SpaceEvent.initial(
userProfile,
workspaceId,
openFirstPage: openFirstPage,
),
);
@ -352,7 +353,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
}
late WorkspaceService _workspaceService;
String? _workspaceId;
late String workspaceId;
late UserProfilePB userProfile;
WorkspaceSectionsListener? _listener;
bool openFirstPage = false;
@ -442,9 +443,11 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
}
void _initial(UserProfilePB userProfile, String workspaceId) {
Log.info('initial(or reset) space bloc: $workspaceId, ${userProfile.id}');
_workspaceService = WorkspaceService(workspaceId: workspaceId);
_workspaceId = workspaceId;
this.userProfile = userProfile;
this.workspaceId = workspaceId;
_listener = WorkspaceSectionsListener(
user: userProfile,
@ -464,7 +467,8 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
_listener?.stop();
_listener = null;
_initial(userProfile, workspaceId);
this.userProfile = userProfile;
this.workspaceId = workspaceId;
}
Future<ViewPB?> _getLastOpenedSpace(List<ViewPB> spaces) async {
@ -522,16 +526,12 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
}
Future<bool> migrate({bool auto = true}) async {
if (_workspaceId == null) {
return false;
}
try {
final user =
await UserBackendService.getCurrentUserProfile().getOrThrow();
final service = UserBackendService(userId: user.id);
final members =
await service.getWorkspaceMembers(_workspaceId!).getOrThrow();
await service.getWorkspaceMembers(workspaceId).getOrThrow();
final isOwner = members.items
.any((e) => e.role == AFRolePB.Owner && e.email == user.email);
@ -563,7 +563,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
}
final viewId = fixedUuid(
user.id.toInt() + (_workspaceId?.hashCode ?? 0),
user.id.toInt() + workspaceId.hashCode,
UuidType.publicSpace,
);
final publicSpace = await _createSpace(
@ -702,9 +702,7 @@ class SpaceBloc extends Bloc<SpaceEvent, SpaceState> {
@freezed
class SpaceEvent with _$SpaceEvent {
const factory SpaceEvent.initial(
UserProfilePB userProfile,
String workspaceId, {
const factory SpaceEvent.initial({
required bool openFirstPage,
}) = _Initial;
const factory SpaceEvent.create({

View File

@ -7,7 +7,6 @@ import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/shared_w
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@ -20,14 +19,10 @@ class MovePageMenu extends StatefulWidget {
const MovePageMenu({
super.key,
required this.sourceView,
required this.userProfile,
required this.workspaceId,
required this.onSelected,
});
final ViewPB sourceView;
final UserProfilePB userProfile;
final String workspaceId;
final MovePageMenuOnSelected onSelected;
@override
@ -47,25 +42,11 @@ class _MovePageMenuState extends State<MovePageMenu> {
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => SpaceBloc()
..add(
SpaceEvent.initial(
widget.userProfile,
widget.workspaceId,
openFirstPage: false,
),
),
return BlocProvider(
create: (context) => SpaceSearchBloc()
..add(
const SpaceSearchEvent.initial(),
),
BlocProvider(
create: (context) => SpaceSearchBloc()
..add(
const SpaceSearchEvent.initial(),
),
),
],
child: BlocBuilder<SpaceBloc, SpaceState>(
builder: (context, state) {
final space = state.currentSpace;

View File

@ -116,11 +116,11 @@ class HomeSideBar extends StatelessWidget {
),
),
BlocProvider(
create: (_) => SpaceBloc()
..add(
SpaceEvent.initial(
userProfile,
workspaceId,
create: (_) => SpaceBloc(
userProfile: userProfile,
workspaceId: workspaceId,
)..add(
const SpaceEvent.initial(
openFirstPage: false,
),
),

View File

@ -5,7 +5,6 @@ import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart';
import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_menu.dart';
import 'package:appflowy/workspace/presentation/home/toast.dart';
import 'package:appflowy/workspace/presentation/notifications/widgets/notification_button.dart';
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:appflowy_backend/log.dart';
@ -16,6 +15,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:toastification/toastification.dart';
class SidebarWorkspace extends StatefulWidget {
const SidebarWorkspace({super.key, required this.userProfile});
@ -170,7 +170,14 @@ class _SidebarWorkspaceState extends State<SidebarWorkspace> {
}
if (message != null) {
showSnackBarMessage(context, message);
showToastNotification(
context,
message: message,
type: result.fold(
(_) => ToastificationType.success,
(_) => ToastificationType.error,
),
);
}
}
}

View File

@ -335,7 +335,7 @@ class _InnerViewItemState extends State<InnerViewItem> {
_isDragging = isDragging;
},
onMove: widget.isPlaceholder
? (from, to) => _moveViewCrossSection(
? (from, to) => moveViewCrossSpace(
context,
null,
widget.view,
@ -766,7 +766,7 @@ class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
}
final space = value.$1;
final target = value.$2;
_moveViewCrossSection(
moveViewCrossSpace(
context,
space,
widget.view,
@ -827,7 +827,7 @@ bool isReferencedDatabaseView(ViewPB view, ViewPB? parentView) {
return view.layout.isDatabaseView && parentView.layout.isDatabaseView;
}
void _moveViewCrossSection(
void moveViewCrossSpace(
BuildContext context,
ViewPB? toSpace,
ViewPB view,

View File

@ -122,13 +122,19 @@ class ViewMoreActionTypeWrapper extends CustomActionCell {
ViewMoreActionTypeWrapper(
this.inner,
this.sourceView,
this.onTap,
);
this.onTap, {
this.moveActionDirection,
this.moveActionOffset,
});
final ViewMoreActionType inner;
final ViewPB sourceView;
final void Function(PopoverController controller, dynamic data) onTap;
// custom the move to action button
final PopoverDirection? moveActionDirection;
final Offset? moveActionOffset;
@override
Widget buildWithContext(BuildContext context, PopoverController controller) {
if (inner == ViewMoreActionType.divider) {
@ -174,9 +180,12 @@ class ViewMoreActionTypeWrapper extends CustomActionCell {
BuildContext context,
PopoverController controller,
) {
// move to feature doesn't support in local mode
if (context.read<SpaceBloc>().state.spaces.isEmpty) {
return const SizedBox.shrink();
}
final child = _buildActionButton(context, null);
final userProfile = context.read<SpaceBloc>().userProfile;
final workspaceId = context.read<SpaceBloc>().state.currentSpace?.id;
return AppFlowyPopover(
constraints: const BoxConstraints(
@ -188,18 +197,17 @@ class ViewMoreActionTypeWrapper extends CustomActionCell {
vertical: 12.0,
),
clickHandler: PopoverClickHandler.gestureDetector,
direction: moveActionDirection ?? PopoverDirection.rightWithTopAligned,
offset: moveActionOffset,
popupBuilder: (_) {
if (workspaceId == null) {
return const SizedBox();
}
return MovePageMenu(
sourceView: sourceView,
userProfile: userProfile,
workspaceId: workspaceId,
onSelected: (space, view) {
onTap(controller, (space, view));
},
return BlocProvider.value(
value: context.read<SpaceBloc>(),
child: MovePageMenu(
sourceView: sourceView,
onSelected: (space, view) {
onTap(controller, (space, view));
},
),
);
},
child: child,

View File

@ -1,12 +1,16 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
import 'package:appflowy/workspace/application/view/view_bloc.dart';
import 'package:appflowy/workspace/application/view_info/view_info_bloc.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_action_type.dart';
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/common_view_action.dart';
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/font_size_action.dart';
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/view_meta_info.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
@ -42,74 +46,121 @@ class _MoreViewActionsState extends State<MoreViewActions> {
@override
Widget build(BuildContext context) {
final appearanceSettings = context.watch<AppearanceSettingsCubit>().state;
final dateFormat = appearanceSettings.dateFormat;
final timeFormat = appearanceSettings.timeFormat;
return BlocBuilder<ViewInfoBloc, ViewInfoState>(
builder: (context, state) {
return AppFlowyPopover(
mutex: popoverMutex,
constraints: BoxConstraints.loose(const Size(215, 400)),
offset: const Offset(0, 30),
popupBuilder: (_) {
final actions = [
if (widget.isDocument) ...[
const FontSizeAction(),
const Divider(height: 4),
],
...ViewActionType.values.map(
(type) => ViewAction(
type: type,
view: widget.view,
mutex: popoverMutex,
),
),
if (state.documentCounters != null ||
state.createdAt != null) ...[
const Divider(height: 4),
ViewMetaInfo(
dateFormat: dateFormat,
timeFormat: timeFormat,
documentCounters: state.documentCounters,
createdAt: state.createdAt,
),
],
];
return BlocProvider(
create: (_) =>
ViewBloc(view: widget.view)..add(const ViewEvent.initial()),
child: ListView.separated(
shrinkWrap: true,
padding: EdgeInsets.zero,
itemCount: actions.length,
separatorBuilder: (_, __) => const VSpace(4),
physics: StyledScrollPhysics(),
itemBuilder: (_, index) => actions[index],
),
);
},
child: FlowyTooltip(
message: LocaleKeys.moreAction_moreOptions.tr(),
child: FlowyHover(
style: HoverStyle(
foregroundColorOnHover: Theme.of(context).colorScheme.onPrimary,
),
builder: (context, isHovering) => Padding(
padding: const EdgeInsets.all(6),
child: FlowySvg(
FlowySvgs.three_dots_s,
size: const Size.square(18),
color: isHovering
? Theme.of(context).colorScheme.onSurface
: Theme.of(context).iconTheme.color,
),
),
),
),
constraints: const BoxConstraints(maxWidth: 220),
offset: const Offset(0, 42),
popupBuilder: (_) => _buildPopup(state),
child: const _ThreeDots(),
);
},
);
}
Widget _buildPopup(ViewInfoState state) {
final userWorkspaceBloc = context.read<UserWorkspaceBloc>();
final userProfile = userWorkspaceBloc.userProfile;
final workspaceId =
userWorkspaceBloc.state.currentWorkspace?.workspaceId ?? '';
final actions = _buildActions(state);
return MultiBlocProvider(
providers: [
BlocProvider(
create: (_) =>
ViewBloc(view: widget.view)..add(const ViewEvent.initial()),
),
BlocProvider(
create: (context) => SpaceBloc(
userProfile: userProfile,
workspaceId: workspaceId,
)..add(
const SpaceEvent.initial(openFirstPage: false),
),
),
],
child: BlocBuilder<SpaceBloc, SpaceState>(
builder: (context, state) {
if (state.spaces.isEmpty &&
userProfile.authenticator == AuthenticatorPB.AppFlowyCloud) {
return const SizedBox.shrink();
}
return ListView.builder(
key: ValueKey(state.spaces.hashCode),
shrinkWrap: true,
padding: EdgeInsets.zero,
itemCount: actions.length,
physics: StyledScrollPhysics(),
itemBuilder: (_, index) => actions[index],
);
},
),
);
}
List<Widget> _buildActions(ViewInfoState state) {
final appearanceSettings = context.watch<AppearanceSettingsCubit>().state;
final dateFormat = appearanceSettings.dateFormat;
final timeFormat = appearanceSettings.timeFormat;
final viewMoreActionTypes = [
if (widget.isDocument) ViewMoreActionType.divider,
ViewMoreActionType.duplicate,
ViewMoreActionType.moveTo,
ViewMoreActionType.delete,
ViewMoreActionType.divider,
];
final actions = [
if (widget.isDocument) ...[
const FontSizeAction(),
],
...viewMoreActionTypes.map(
(type) => ViewAction(
type: type,
view: widget.view,
mutex: popoverMutex,
),
),
if (state.documentCounters != null || state.createdAt != null) ...[
ViewMetaInfo(
dateFormat: dateFormat,
timeFormat: timeFormat,
documentCounters: state.documentCounters,
createdAt: state.createdAt,
),
const VSpace(4.0),
],
];
return actions;
}
}
class _ThreeDots extends StatelessWidget {
const _ThreeDots();
@override
Widget build(BuildContext context) {
return FlowyTooltip(
message: LocaleKeys.moreAction_moreOptions.tr(),
child: FlowyHover(
style: HoverStyle(
foregroundColorOnHover: Theme.of(context).colorScheme.onPrimary,
),
builder: (context, isHovering) => Padding(
padding: const EdgeInsets.all(6),
child: FlowySvg(
FlowySvgs.three_dots_s,
size: const Size.square(18),
color: isHovering
? Theme.of(context).colorScheme.onSurface
: Theme.of(context).iconTheme.color,
),
),
),
);
}
}

View File

@ -1,37 +1,18 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
import 'package:appflowy/workspace/application/view/view_bloc.dart';
import 'package:appflowy/workspace/application/view/view_service.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_action_type.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
import 'package:appflowy/workspace/presentation/home/menu/view/view_more_action_button.dart';
import 'package:appflowy/workspace/presentation/widgets/dialogs.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/style_widget/button.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
enum ViewActionType {
delete,
duplicate;
String get label => switch (this) {
ViewActionType.delete => LocaleKeys.moreAction_deleteView.tr(),
ViewActionType.duplicate => LocaleKeys.moreAction_duplicateView.tr(),
};
FlowySvgData get icon => switch (this) {
ViewActionType.delete => FlowySvgs.delete_s,
ViewActionType.duplicate => FlowySvgs.m_duplicate_s,
};
ViewEvent get actionEvent => switch (this) {
ViewActionType.delete => const ViewEvent.delete(),
ViewActionType.duplicate => const ViewEvent.duplicate(),
};
}
class ViewAction extends StatelessWidget {
const ViewAction({
super.key,
@ -40,49 +21,77 @@ class ViewAction extends StatelessWidget {
this.mutex,
});
final ViewActionType type;
final ViewMoreActionType type;
final ViewPB view;
final PopoverMutex? mutex;
@override
Widget build(BuildContext context) {
return FlowyButton(
onTap: () async {
await _onAction(context);
final wrapper = ViewMoreActionTypeWrapper(
type,
view,
(controller, data) async {
await _onAction(context, data);
mutex?.close();
},
text: FlowyText.regular(
type.label,
color: AFThemeExtension.of(context).textColor,
),
leftIcon: FlowySvg(
type.icon,
color: Theme.of(context).iconTheme.color,
size: const Size.square(18),
),
leftIconSize: const Size(18, 18),
hoverColor: AFThemeExtension.of(context).lightGreyHover,
moveActionDirection: PopoverDirection.leftWithTopAligned,
moveActionOffset: const Offset(-10, 0),
);
return wrapper.buildWithContext(
context,
// this is a dummy controller, we don't need to control the popover here.
PopoverController(),
);
}
Future<void> _onAction(BuildContext context) async {
if (type == ViewActionType.delete) {
final (containPublishedPage, _) =
await ViewBackendService.containPublishedPage(view);
if (containPublishedPage && context.mounted) {
await showConfirmDeletionDialog(
context: context,
name: view.name,
description: LocaleKeys.publish_containsPublishedPage.tr(),
onConfirm: () {
context.read<ViewBloc>().add(const ViewEvent.delete());
},
Future<void> _onAction(
BuildContext context,
dynamic data,
) async {
switch (type) {
case ViewMoreActionType.delete:
final (containPublishedPage, _) =
await ViewBackendService.containPublishedPage(view);
if (containPublishedPage && context.mounted) {
await showConfirmDeletionDialog(
context: context,
name: view.name,
description: LocaleKeys.publish_containsPublishedPage.tr(),
onConfirm: () {
context.read<ViewBloc>().add(const ViewEvent.delete());
},
);
} else if (context.mounted) {
context.read<ViewBloc>().add(const ViewEvent.delete());
}
case ViewMoreActionType.duplicate:
context.read<ViewBloc>().add(const ViewEvent.duplicate());
case ViewMoreActionType.moveTo:
final value = data;
if (value is! (ViewPB, ViewPB)) {
return;
}
final space = value.$1;
final target = value.$2;
final result = await ViewBackendService.getView(view.parentViewId);
result.fold(
(parentView) => moveViewCrossSpace(
context,
space,
view,
parentView,
FolderSpaceType.public,
view,
target.id,
),
(f) => Log.error(f),
);
} else if (context.mounted) {
context.read<ViewBloc>().add(const ViewEvent.delete());
}
} else {
context.read<ViewBloc>().add(type.actionEvent);
// the move action is handled in the button itself
break;
default:
throw UnimplementedError();
}
}
}

View File

@ -1,5 +1,3 @@
import 'package:flutter/material.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart';
import 'package:appflowy/workspace/presentation/widgets/more_view_actions/widgets/font_size_stepper.dart';
@ -7,6 +5,7 @@ import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class FontSizeAction extends StatelessWidget {
@ -31,18 +30,25 @@ class FontSizeAction extends StatelessWidget {
),
);
},
child: FlowyButton(
text: FlowyText.regular(
LocaleKeys.moreAction_fontSize.tr(),
color: AFThemeExtension.of(context).textColor,
child: Container(
height: 34,
padding: const EdgeInsets.symmetric(vertical: 2.0),
child: FlowyButton(
text: FlowyText.regular(
LocaleKeys.moreAction_fontSize.tr(),
fontSize: 14.0,
lineHeight: 1.0,
figmaLineHeight: 18.0,
color: AFThemeExtension.of(context).textColor,
),
leftIcon: Icon(
Icons.format_size_sharp,
color: Theme.of(context).iconTheme.color,
size: 18,
),
leftIconSize: const Size(18, 18),
hoverColor: AFThemeExtension.of(context).lightGreyHover,
),
leftIcon: Icon(
Icons.format_size_sharp,
color: Theme.of(context).iconTheme.color,
size: 18,
),
leftIconSize: const Size(18, 18),
hoverColor: AFThemeExtension.of(context).lightGreyHover,
),
);
}

View File

@ -1,5 +1,3 @@
import 'package:flutter/material.dart';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/workspace/application/settings/date_time/date_format_ext.dart';
import 'package:appflowy_backend/protobuf/flowy-user/date_time.pbenum.dart';
@ -7,6 +5,7 @@ import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra_ui/style_widget/text.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart';
class ViewMetaInfo extends StatelessWidget {
const ViewMetaInfo({
@ -39,7 +38,7 @@ class ViewMetaInfo extends StatelessWidget {
numberFormat.format(documentCounters!.wordCount).toString(),
],
),
fontSize: 11,
fontSize: 12,
color: Theme.of(context).hintColor,
),
const VSpace(2),
@ -49,7 +48,7 @@ class ViewMetaInfo extends StatelessWidget {
numberFormat.format(documentCounters!.charCount).toString(),
],
),
fontSize: 11,
fontSize: 12,
color: Theme.of(context).hintColor,
),
],
@ -59,7 +58,7 @@ class ViewMetaInfo extends StatelessWidget {
LocaleKeys.moreAction_createdAt.tr(
args: [dateFormat.formatDate(createdAt!, true, timeFormat)],
),
fontSize: 11,
fontSize: 12,
maxLines: 2,
color: Theme.of(context).hintColor,
),

View File

@ -53,8 +53,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: bb525e4
resolved-ref: bb525e41dfda40c891c2641d38bce29eb1a21769
ref: "0a0154ff7d10d13de755623e56527aa4bed26241"
resolved-ref: "0a0154ff7d10d13de755623e56527aa4bed26241"
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
source: git
version: "3.3.0"

View File

@ -175,7 +175,7 @@ dependency_overrides:
appflowy_editor:
git:
url: https://github.com/AppFlowy-IO/appflowy-editor.git
ref: "bb525e4"
ref: "0a0154ff7d10d13de755623e56527aa4bed26241"
appflowy_editor_plugins:
git: