diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart index 9d67dbd06f..44b590c11d 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -75,7 +75,8 @@ class _AppFlowyEditorPageState extends State { alignToolbarItem, buildTextColorItem(), buildHighlightColorItem(), - ...textDirectionItems + // TODO: enable it in version 0.3.3 + // ...textDirectionItems, ]; late final List slashMenuItems; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_option_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_option_button.dart index 9042d885ac..0bd27a516e 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_option_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/actions/block_action_option_button.dart @@ -2,11 +2,13 @@ import 'package:appflowy/generated/flowy_svgs.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/option_action.dart'; +import 'package:appflowy/workspace/application/appearance.dart'; import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; class BlockOptionButton extends StatelessWidget { const BlockOptionButton({ @@ -38,7 +40,11 @@ class BlockOptionButton extends StatelessWidget { }).toList(); return PopoverActionList( - direction: PopoverDirection.leftWithCenterAligned, + direction: + context.read().state.layoutDirection == + LayoutDirection.rtlLayout + ? PopoverDirection.rightWithCenterAligned + : PopoverDirection.leftWithCenterAligned, actions: popoverActions, onPopupBuilder: () { keepEditorFocusNotifier.value += 1; diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/callout/callout_block_component.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/callout/callout_block_component.dart index 0d0f4c0a6f..48b6325017 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/callout/callout_block_component.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/callout/callout_block_component.dart @@ -115,7 +115,12 @@ class CalloutBlockComponentWidget extends BlockComponentStatefulWidget { class _CalloutBlockComponentWidgetState extends State - with SelectableMixin, DefaultSelectableMixin, BlockComponentConfigurable { + with + SelectableMixin, + DefaultSelectableMixin, + BlockComponentConfigurable, + BlockComponentTextDirectionMixin, + BlockComponentAlignMixin { // the key used to forward focus to the richtext child @override final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text'); @@ -146,19 +151,28 @@ class _CalloutBlockComponentWidgetState String get emoji => node.attributes[CalloutBlockKeys.icon] ?? '📌'; // get access to the editor state via provider + @override late final editorState = Provider.of(context, listen: false); // build the callout block widget @override Widget build(BuildContext context) { + final textDirection = calculateTextDirection( + layoutDirection: Directionality.maybeOf(context), + ); + Widget child = Container( decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(8.0)), color: backgroundColor, ), width: double.infinity, + alignment: alignment, child: Row( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + textDirection: textDirection, children: [ // the emoji picker button for the note Padding( @@ -178,10 +192,10 @@ class _CalloutBlockComponentWidgetState }, ), ), - Expanded( + Flexible( child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), - child: buildCalloutBlockComponent(context), + child: buildCalloutBlockComponent(context, textDirection), ), ), const HSpace(8.0), @@ -218,7 +232,10 @@ class _CalloutBlockComponentWidgetState } // build the richtext child - Widget buildCalloutBlockComponent(BuildContext context) { + Widget buildCalloutBlockComponent( + BuildContext context, + TextDirection textDirection, + ) { return Padding( padding: padding, child: AppFlowyRichText( @@ -233,6 +250,7 @@ class _CalloutBlockComponentWidgetState placeholderTextSpanDecorator: (textSpan) => textSpan.updateTextStyle( placeholderTextStyle, ), + textDirection: textDirection, cursorColor: editorState.editorStyle.cursorColor, selectionColor: editorState.editorStyle.selectionColor, ), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_block_component.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_block_component.dart index ac417c90cd..dc6611a35d 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_block_component.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/code_block/code_block_component.dart @@ -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_editor/appflowy_editor.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:flutter/material.dart'; import 'package:highlight/highlight.dart' as highlight; @@ -98,7 +98,11 @@ class CodeBlockComponentWidget extends BlockComponentStatefulWidget { } class _CodeBlockComponentWidgetState extends State - with SelectableMixin, DefaultSelectableMixin, BlockComponentConfigurable { + with + SelectableMixin, + DefaultSelectableMixin, + BlockComponentConfigurable, + BlockComponentTextDirectionMixin { // the key used to forward focus to the richtext child @override final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text'); @@ -175,6 +179,7 @@ class _CodeBlockComponentWidgetState extends State ..add('c') ..sort(); + @override late final editorState = context.read(); String? get language => node.attributes[CodeBlockKeys.language] as String?; @@ -182,6 +187,9 @@ class _CodeBlockComponentWidgetState extends State @override Widget build(BuildContext context) { + final textDirection = calculateTextDirection( + layoutDirection: Directionality.maybeOf(context), + ); Widget child = Container( decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(8.0)), @@ -191,9 +199,10 @@ class _CodeBlockComponentWidgetState extends State child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, + textDirection: textDirection, children: [ _buildSwitchLanguageButton(context), - _buildCodeBlock(context), + _buildCodeBlock(context, textDirection), ], ), ); @@ -226,7 +235,7 @@ class _CodeBlockComponentWidgetState extends State return child; } - Widget _buildCodeBlock(BuildContext context) { + Widget _buildCodeBlock(BuildContext context, TextDirection textDirection) { final delta = node.delta ?? Delta(); final content = delta.toPlainText(); @@ -258,6 +267,7 @@ class _CodeBlockComponentWidgetState extends State placeholderTextSpanDecorator: (textSpan) => TextSpan( style: textStyle, ), + textDirection: textDirection, cursorColor: editorState.editorStyle.cursorColor, selectionColor: editorState.editorStyle.selectionColor, ), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/outline/outline_block_component.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/outline/outline_block_component.dart index 108cb4de9b..738b632041 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/outline/outline_block_component.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/outline/outline_block_component.dart @@ -2,7 +2,8 @@ import 'dart:async'; import 'package:appflowy/generated/locale_keys.g.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:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -70,7 +71,7 @@ class OutlineBlockWidget extends BlockComponentStatefulWidget { } class _OutlineBlockWidgetState extends State - with BlockComponentConfigurable { + with BlockComponentConfigurable, BlockComponentTextDirectionMixin { @override BlockComponentConfiguration get configuration => widget.configuration; @@ -87,6 +88,7 @@ class _OutlineBlockWidgetState extends State return colorString.tryToColor() ?? Colors.transparent; } + @override late EditorState editorState = context.read(); late Stream<(TransactionTime, Transaction)> stream = editorState.transactionStream; @@ -109,6 +111,10 @@ class _OutlineBlockWidgetState extends State } Widget _buildOutlineBlock() { + final textDirection = calculateTextDirection( + layoutDirection: Directionality.maybeOf(context), + ); + final children = getHeadingNodes() .map( (e) => Container( @@ -116,7 +122,10 @@ class _OutlineBlockWidgetState extends State bottom: 4.0, ), width: double.infinity, - child: OutlineItemWidget(node: e), + child: OutlineItemWidget( + node: e, + textDirection: textDirection, + ), ), ) .toList(); @@ -136,7 +145,9 @@ class _OutlineBlockWidgetState extends State ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + textDirection: textDirection, children: children, ), ); @@ -152,11 +163,13 @@ class OutlineItemWidget extends StatelessWidget { OutlineItemWidget({ super.key, required this.node, + required this.textDirection, }) { assert(node.type == HeadingBlockKeys.type); } final Node node; + final TextDirection textDirection; @override Widget build(BuildContext context) { @@ -170,15 +183,20 @@ class OutlineItemWidget extends StatelessWidget { builder: (context, onHover) { return GestureDetector( onTap: () => scrollToBlock(context), - child: Container( - padding: EdgeInsets.only(left: node.leftIndent), - child: Text( - node.outlineItemText, - style: style.copyWith( - color: - onHover ? Theme.of(context).colorScheme.onSecondary : null, + child: Row( + textDirection: textDirection, + children: [ + HSpace(node.leftIndent), + Text( + node.outlineItemText, + textDirection: textDirection, + style: style.copyWith( + color: onHover + ? Theme.of(context).colorScheme.onSecondary + : null, + ), ), - ), + ], ), ); }, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_component.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_component.dart index 3c8a514565..ea30fba04a 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_component.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/toggle/toggle_block_component.dart @@ -109,7 +109,8 @@ class _ToggleListBlockComponentWidgetState BlockComponentConfigurable, BlockComponentBackgroundColorMixin, NestedBlockComponentStatefulWidgetMixin, - BlockComponentTextDirectionMixin { + BlockComponentTextDirectionMixin, + BlockComponentAlignMixin { // the key used to forward focus to the richtext child @override final forwardKey = GlobalKey(debugLabel: 'flowy_rich_text'); @@ -157,8 +158,12 @@ class _ToggleListBlockComponentWidgetState Widget child = Container( color: backgroundColor, width: double.infinity, + alignment: alignment, child: Row( + mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + textDirection: textDirection, children: [ // the emoji picker button for the note FlowyIconButton( @@ -171,7 +176,7 @@ class _ToggleListBlockComponentWidgetState const SizedBox( width: 4.0, ), - Expanded( + Flexible( child: AppFlowyRichText( key: forwardKey, delegate: this, @@ -187,6 +192,7 @@ class _ToggleListBlockComponentWidgetState placeholderTextStyle, ), textDirection: textDirection, + textAlign: alignment?.toTextAlign, cursorColor: editorState.editorStyle.cursorColor, selectionColor: editorState.editorStyle.selectionColor, ), diff --git a/frontend/appflowy_flutter/lib/workspace/application/appearance.dart b/frontend/appflowy_flutter/lib/workspace/application/appearance.dart index b46d47a6a9..e92c633651 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/appearance.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/appearance.dart @@ -300,6 +300,10 @@ class AppearanceSettingsState with _$AppearanceSettingsState { ThemeData get lightTheme => _getThemeData(Brightness.light); 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) { // Poppins and SF Mono are not well supported in some languages, so use the // built-in font for the following languages. @@ -450,7 +454,7 @@ class AppearanceSettingsState with _$AppearanceSettingsState { fontWeight: FontWeight.w400, fontColor: theme.hint, ), - ) + ), ], ); return desktopThemeData; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart index 1c0c1faee9..498bf56362 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/settings_appearance_view.dart @@ -29,12 +29,13 @@ class SettingsAppearanceView extends StatelessWidget { ThemeFontFamilySetting( currentFontFamily: state.font, ), - LayoutDirectionSetting( - currentLayoutDirection: state.layoutDirection, - ), - TextDirectionSetting( - currentTextDirection: state.textDirection, - ), + // TODO: enablt them in version 0.3.3 + // LayoutDirectionSetting( + // currentLayoutDirection: state.layoutDirection, + // ), + // TextDirectionSetting( + // currentTextDirection: state.textDirection, + // ), CreateFileSettings(), ], ); diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock index b5c0cca55b..3dfd97f53f 100644 --- a/frontend/appflowy_flutter/pubspec.lock +++ b/frontend/appflowy_flutter/pubspec.lock @@ -54,8 +54,8 @@ packages: dependency: "direct main" description: path: "." - ref: a97c816 - resolved-ref: a97c816c1d8cfbc5644a8be49deae334c47261e3 + ref: "4a87ec4" + resolved-ref: "4a87ec4bd440344b8f51dd61ab84e2c68d4196d2" url: "https://github.com/AppFlowy-IO/appflowy-editor.git" source: git version: "1.3.0" diff --git a/frontend/appflowy_flutter/pubspec.yaml b/frontend/appflowy_flutter/pubspec.yaml index e4645c287e..bff129fd6b 100644 --- a/frontend/appflowy_flutter/pubspec.yaml +++ b/frontend/appflowy_flutter/pubspec.yaml @@ -47,7 +47,7 @@ dependencies: appflowy_editor: git: url: https://github.com/AppFlowy-IO/appflowy-editor.git - ref: a97c816 + ref: 4a87ec4 appflowy_popover: path: packages/appflowy_popover diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index ffd5a62872..f5127301fc 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -20,6 +20,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -127,14 +133,14 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ + "android-tzdata", "iana-time-zone", - "num-integer", "num-traits", - "winapi", + "windows-targets 0.48.0", ] [[package]] @@ -741,16 +747,6 @@ dependencies = [ "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]] name = "num-traits" version = "0.2.14"