fix: rtl related issues

This commit is contained in:
Lucas.Xu
2023-09-18 14:33:51 +08:00
committed by GitHub
parent f3148640eb
commit 0ea5b3c483
11 changed files with 108 additions and 48 deletions

View File

@ -75,7 +75,8 @@ class _AppFlowyEditorPageState extends State<AppFlowyEditorPage> {
alignToolbarItem, alignToolbarItem,
buildTextColorItem(), buildTextColorItem(),
buildHighlightColorItem(), buildHighlightColorItem(),
...textDirectionItems // TODO: enable it in version 0.3.3
// ...textDirectionItems,
]; ];
late final List<SelectionMenuItem> slashMenuItems; late final List<SelectionMenuItem> slashMenuItems;

View File

@ -2,11 +2,13 @@ import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_button.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_button.dart';
import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/option_action.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/option_action.dart';
import 'package:appflowy/workspace/application/appearance.dart';
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart'; import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class BlockOptionButton extends StatelessWidget { class BlockOptionButton extends StatelessWidget {
const BlockOptionButton({ const BlockOptionButton({
@ -38,7 +40,11 @@ class BlockOptionButton extends StatelessWidget {
}).toList(); }).toList();
return PopoverActionList<PopoverAction>( return PopoverActionList<PopoverAction>(
direction: PopoverDirection.leftWithCenterAligned, direction:
context.read<AppearanceSettingsCubit>().state.layoutDirection ==
LayoutDirection.rtlLayout
? PopoverDirection.rightWithCenterAligned
: PopoverDirection.leftWithCenterAligned,
actions: popoverActions, actions: popoverActions,
onPopupBuilder: () { onPopupBuilder: () {
keepEditorFocusNotifier.value += 1; keepEditorFocusNotifier.value += 1;

View File

@ -115,7 +115,12 @@ class CalloutBlockComponentWidget extends BlockComponentStatefulWidget {
class _CalloutBlockComponentWidgetState class _CalloutBlockComponentWidgetState
extends State<CalloutBlockComponentWidget> extends State<CalloutBlockComponentWidget>
with SelectableMixin, DefaultSelectableMixin, BlockComponentConfigurable { with
SelectableMixin,
DefaultSelectableMixin,
BlockComponentConfigurable,
BlockComponentTextDirectionMixin,
BlockComponentAlignMixin {
// the key used to forward focus to the richtext child // the key used to forward focus to the richtext child
@override @override
final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text'); final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text');
@ -146,19 +151,28 @@ class _CalloutBlockComponentWidgetState
String get emoji => node.attributes[CalloutBlockKeys.icon] ?? '📌'; String get emoji => node.attributes[CalloutBlockKeys.icon] ?? '📌';
// get access to the editor state via provider // get access to the editor state via provider
@override
late final editorState = Provider.of<EditorState>(context, listen: false); late final editorState = Provider.of<EditorState>(context, listen: false);
// build the callout block widget // build the callout block widget
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final textDirection = calculateTextDirection(
layoutDirection: Directionality.maybeOf(context),
);
Widget child = Container( Widget child = Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(8.0)), borderRadius: const BorderRadius.all(Radius.circular(8.0)),
color: backgroundColor, color: backgroundColor,
), ),
width: double.infinity, width: double.infinity,
alignment: alignment,
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
textDirection: textDirection,
children: [ children: [
// the emoji picker button for the note // the emoji picker button for the note
Padding( Padding(
@ -178,10 +192,10 @@ class _CalloutBlockComponentWidgetState
}, },
), ),
), ),
Expanded( Flexible(
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0), padding: const EdgeInsets.symmetric(vertical: 8.0),
child: buildCalloutBlockComponent(context), child: buildCalloutBlockComponent(context, textDirection),
), ),
), ),
const HSpace(8.0), const HSpace(8.0),
@ -218,7 +232,10 @@ class _CalloutBlockComponentWidgetState
} }
// build the richtext child // build the richtext child
Widget buildCalloutBlockComponent(BuildContext context) { Widget buildCalloutBlockComponent(
BuildContext context,
TextDirection textDirection,
) {
return Padding( return Padding(
padding: padding, padding: padding,
child: AppFlowyRichText( child: AppFlowyRichText(
@ -233,6 +250,7 @@ class _CalloutBlockComponentWidgetState
placeholderTextSpanDecorator: (textSpan) => textSpan.updateTextStyle( placeholderTextSpanDecorator: (textSpan) => textSpan.updateTextStyle(
placeholderTextStyle, placeholderTextStyle,
), ),
textDirection: textDirection,
cursorColor: editorState.editorStyle.cursorColor, cursorColor: editorState.editorStyle.cursorColor,
selectionColor: editorState.editorStyle.selectionColor, selectionColor: editorState.editorStyle.selectionColor,
), ),

View File

@ -3,7 +3,7 @@ import 'package:appflowy/plugins/document/presentation/editor_plugins/base/selec
import 'package:appflowy/plugins/document/presentation/editor_plugins/base/string_extension.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/base/string_extension.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart' hide TextDirection;
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:highlight/highlight.dart' as highlight; import 'package:highlight/highlight.dart' as highlight;
@ -98,7 +98,11 @@ class CodeBlockComponentWidget extends BlockComponentStatefulWidget {
} }
class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget> class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget>
with SelectableMixin, DefaultSelectableMixin, BlockComponentConfigurable { with
SelectableMixin,
DefaultSelectableMixin,
BlockComponentConfigurable,
BlockComponentTextDirectionMixin {
// the key used to forward focus to the richtext child // the key used to forward focus to the richtext child
@override @override
final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text'); final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text');
@ -175,6 +179,7 @@ class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget>
..add('c') ..add('c')
..sort(); ..sort();
@override
late final editorState = context.read<EditorState>(); late final editorState = context.read<EditorState>();
String? get language => node.attributes[CodeBlockKeys.language] as String?; String? get language => node.attributes[CodeBlockKeys.language] as String?;
@ -182,6 +187,9 @@ class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final textDirection = calculateTextDirection(
layoutDirection: Directionality.maybeOf(context),
);
Widget child = Container( Widget child = Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(8.0)), borderRadius: const BorderRadius.all(Radius.circular(8.0)),
@ -191,9 +199,10 @@ class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget>
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
textDirection: textDirection,
children: [ children: [
_buildSwitchLanguageButton(context), _buildSwitchLanguageButton(context),
_buildCodeBlock(context), _buildCodeBlock(context, textDirection),
], ],
), ),
); );
@ -226,7 +235,7 @@ class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget>
return child; return child;
} }
Widget _buildCodeBlock(BuildContext context) { Widget _buildCodeBlock(BuildContext context, TextDirection textDirection) {
final delta = node.delta ?? Delta(); final delta = node.delta ?? Delta();
final content = delta.toPlainText(); final content = delta.toPlainText();
@ -258,6 +267,7 @@ class _CodeBlockComponentWidgetState extends State<CodeBlockComponentWidget>
placeholderTextSpanDecorator: (textSpan) => TextSpan( placeholderTextSpanDecorator: (textSpan) => TextSpan(
style: textStyle, style: textStyle,
), ),
textDirection: textDirection,
cursorColor: editorState.editorStyle.cursorColor, cursorColor: editorState.editorStyle.cursorColor,
selectionColor: editorState.editorStyle.selectionColor, selectionColor: editorState.editorStyle.selectionColor,
), ),

View File

@ -2,7 +2,8 @@ import 'dart:async';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart' hide TextDirection;
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -70,7 +71,7 @@ class OutlineBlockWidget extends BlockComponentStatefulWidget {
} }
class _OutlineBlockWidgetState extends State<OutlineBlockWidget> class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
with BlockComponentConfigurable { with BlockComponentConfigurable, BlockComponentTextDirectionMixin {
@override @override
BlockComponentConfiguration get configuration => widget.configuration; BlockComponentConfiguration get configuration => widget.configuration;
@ -87,6 +88,7 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
return colorString.tryToColor() ?? Colors.transparent; return colorString.tryToColor() ?? Colors.transparent;
} }
@override
late EditorState editorState = context.read<EditorState>(); late EditorState editorState = context.read<EditorState>();
late Stream<(TransactionTime, Transaction)> stream = late Stream<(TransactionTime, Transaction)> stream =
editorState.transactionStream; editorState.transactionStream;
@ -109,6 +111,10 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
} }
Widget _buildOutlineBlock() { Widget _buildOutlineBlock() {
final textDirection = calculateTextDirection(
layoutDirection: Directionality.maybeOf(context),
);
final children = getHeadingNodes() final children = getHeadingNodes()
.map( .map(
(e) => Container( (e) => Container(
@ -116,7 +122,10 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
bottom: 4.0, bottom: 4.0,
), ),
width: double.infinity, width: double.infinity,
child: OutlineItemWidget(node: e), child: OutlineItemWidget(
node: e,
textDirection: textDirection,
),
), ),
) )
.toList(); .toList();
@ -136,7 +145,9 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
textDirection: textDirection,
children: children, children: children,
), ),
); );
@ -152,11 +163,13 @@ class OutlineItemWidget extends StatelessWidget {
OutlineItemWidget({ OutlineItemWidget({
super.key, super.key,
required this.node, required this.node,
required this.textDirection,
}) { }) {
assert(node.type == HeadingBlockKeys.type); assert(node.type == HeadingBlockKeys.type);
} }
final Node node; final Node node;
final TextDirection textDirection;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -170,15 +183,20 @@ class OutlineItemWidget extends StatelessWidget {
builder: (context, onHover) { builder: (context, onHover) {
return GestureDetector( return GestureDetector(
onTap: () => scrollToBlock(context), onTap: () => scrollToBlock(context),
child: Container( child: Row(
padding: EdgeInsets.only(left: node.leftIndent), textDirection: textDirection,
child: Text( children: [
node.outlineItemText, HSpace(node.leftIndent),
style: style.copyWith( Text(
color: node.outlineItemText,
onHover ? Theme.of(context).colorScheme.onSecondary : null, textDirection: textDirection,
style: style.copyWith(
color: onHover
? Theme.of(context).colorScheme.onSecondary
: null,
),
), ),
), ],
), ),
); );
}, },

View File

@ -109,7 +109,8 @@ class _ToggleListBlockComponentWidgetState
BlockComponentConfigurable, BlockComponentConfigurable,
BlockComponentBackgroundColorMixin, BlockComponentBackgroundColorMixin,
NestedBlockComponentStatefulWidgetMixin, NestedBlockComponentStatefulWidgetMixin,
BlockComponentTextDirectionMixin { BlockComponentTextDirectionMixin,
BlockComponentAlignMixin {
// the key used to forward focus to the richtext child // the key used to forward focus to the richtext child
@override @override
final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text'); final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text');
@ -157,8 +158,12 @@ class _ToggleListBlockComponentWidgetState
Widget child = Container( Widget child = Container(
color: backgroundColor, color: backgroundColor,
width: double.infinity, width: double.infinity,
alignment: alignment,
child: Row( child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
textDirection: textDirection,
children: [ children: [
// the emoji picker button for the note // the emoji picker button for the note
FlowyIconButton( FlowyIconButton(
@ -171,7 +176,7 @@ class _ToggleListBlockComponentWidgetState
const SizedBox( const SizedBox(
width: 4.0, width: 4.0,
), ),
Expanded( Flexible(
child: AppFlowyRichText( child: AppFlowyRichText(
key: forwardKey, key: forwardKey,
delegate: this, delegate: this,
@ -187,6 +192,7 @@ class _ToggleListBlockComponentWidgetState
placeholderTextStyle, placeholderTextStyle,
), ),
textDirection: textDirection, textDirection: textDirection,
textAlign: alignment?.toTextAlign,
cursorColor: editorState.editorStyle.cursorColor, cursorColor: editorState.editorStyle.cursorColor,
selectionColor: editorState.editorStyle.selectionColor, selectionColor: editorState.editorStyle.selectionColor,
), ),

View File

@ -300,6 +300,10 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
ThemeData get lightTheme => _getThemeData(Brightness.light); ThemeData get lightTheme => _getThemeData(Brightness.light);
ThemeData get darkTheme => _getThemeData(Brightness.dark); ThemeData get darkTheme => _getThemeData(Brightness.dark);
// only support LTR layout in version 0.3.2, enable it in version 0.3.3
LayoutDirectionPB get layoutDirectionPB => LayoutDirectionPB.LTRLayout;
TextDirectionPB get textDirectionPB => TextDirectionPB.LTR;
ThemeData _getThemeData(Brightness brightness) { ThemeData _getThemeData(Brightness brightness) {
// Poppins and SF Mono are not well supported in some languages, so use the // Poppins and SF Mono are not well supported in some languages, so use the
// built-in font for the following languages. // built-in font for the following languages.
@ -450,7 +454,7 @@ class AppearanceSettingsState with _$AppearanceSettingsState {
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
fontColor: theme.hint, fontColor: theme.hint,
), ),
) ),
], ],
); );
return desktopThemeData; return desktopThemeData;

View File

@ -29,12 +29,13 @@ class SettingsAppearanceView extends StatelessWidget {
ThemeFontFamilySetting( ThemeFontFamilySetting(
currentFontFamily: state.font, currentFontFamily: state.font,
), ),
LayoutDirectionSetting( // TODO: enablt them in version 0.3.3
currentLayoutDirection: state.layoutDirection, // LayoutDirectionSetting(
), // currentLayoutDirection: state.layoutDirection,
TextDirectionSetting( // ),
currentTextDirection: state.textDirection, // TextDirectionSetting(
), // currentTextDirection: state.textDirection,
// ),
CreateFileSettings(), CreateFileSettings(),
], ],
); );

View File

@ -54,8 +54,8 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: a97c816 ref: "4a87ec4"
resolved-ref: a97c816c1d8cfbc5644a8be49deae334c47261e3 resolved-ref: "4a87ec4bd440344b8f51dd61ab84e2c68d4196d2"
url: "https://github.com/AppFlowy-IO/appflowy-editor.git" url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
source: git source: git
version: "1.3.0" version: "1.3.0"

View File

@ -47,7 +47,7 @@ dependencies:
appflowy_editor: appflowy_editor:
git: git:
url: https://github.com/AppFlowy-IO/appflowy-editor.git url: https://github.com/AppFlowy-IO/appflowy-editor.git
ref: a97c816 ref: 4a87ec4
appflowy_popover: appflowy_popover:
path: packages/appflowy_popover path: packages/appflowy_popover

24
shared-lib/Cargo.lock generated
View File

@ -20,6 +20,12 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]] [[package]]
name = "android_system_properties" name = "android_system_properties"
version = "0.1.5" version = "0.1.5"
@ -127,14 +133,14 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "chrono" name = "chrono"
version = "0.4.23" version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [ dependencies = [
"android-tzdata",
"iana-time-zone", "iana-time-zone",
"num-integer",
"num-traits", "num-traits",
"winapi", "windows-targets 0.48.0",
] ]
[[package]] [[package]]
@ -741,16 +747,6 @@ dependencies = [
"windows-sys 0.45.0", "windows-sys 0.45.0",
] ]
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.14" version = "0.2.14"