瀏覽代碼

Merge branch 'main' into double_tilde_to_strikethrough

# Conflicts:
#	frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart
#	frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart
Lucas.Xu 2 年之前
父節點
當前提交
09bf373e92
共有 28 個文件被更改,包括 458 次插入207 次删除
  1. 30 10
      frontend/app_flowy/assets/translations/fr-FR.json
  2. 20 4
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart
  3. 8 3
      frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/date.dart
  4. 1 0
      frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart
  5. 1 1
      frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart
  6. 4 3
      frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart
  7. 1 1
      frontend/app_flowy/packages/appflowy_editor/example/lib/plugin/code_block_node_widget.dart
  8. 35 0
      frontend/app_flowy/packages/appflowy_editor/lib/l10n/intl_cs_CZ.arb
  9. 16 16
      frontend/app_flowy/packages/appflowy_editor/lib/l10n/intl_fr_CA.arb
  10. 16 16
      frontend/app_flowy/packages/appflowy_editor/lib/l10n/intl_hu_HU.arb
  11. 16 16
      frontend/app_flowy/packages/appflowy_editor/lib/l10n/intl_id_ID.arb
  12. 16 16
      frontend/app_flowy/packages/appflowy_editor/lib/l10n/intl_pt_PT.arb
  13. 8 0
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_all.dart
  14. 44 0
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_cs-CZ.dart
  15. 16 16
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_fr-CA.dart
  16. 16 16
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_fr-FR.dart
  17. 16 16
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_hu-HU.dart
  18. 16 16
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_id-ID.dart
  19. 16 16
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_it-IT.dart
  20. 43 0
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_nl-NL.dart
  21. 17 16
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_pt-BR.dart
  22. 17 16
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_pt-PT.dart
  23. 2 0
      frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/l10n.dart
  24. 8 0
      frontend/app_flowy/packages/appflowy_editor/lib/src/render/selection_menu/selection_menu_service.dart
  25. 7 0
      frontend/app_flowy/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart
  26. 56 2
      frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart
  27. 5 0
      frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart
  28. 7 7
      frontend/app_flowy/packages/appflowy_editor/test/render/selection_menu/selection_menu_widget_test.dart

+ 30 - 10
frontend/app_flowy/assets/translations/fr-FR.json

@@ -94,7 +94,20 @@
   },
   "tooltip": {
     "lightMode": "Passer en mode clair",
-    "darkMode": "Passer en mode sombre"
+    "darkMode": "Passer en mode sombre",
+    "openAsPage": "Ouvrir en tant que page",
+    "addNewRow": "Ajouter une ligne",
+    "openMenu": "Cliquer pour ouvrir le menu"
+  },
+  "sideBar": {
+    "closeSidebar": "Fermer le menu latéral",
+    "openSidebar": "Ouvrir le menu latéral"
+  },
+  "notifications": {
+    "export": {
+      "markdown": "Note exportée en Markdown",
+      "path": "Documents/flowy"
+    }
   },
   "contactsPage": {
     "title": "Contacts",
@@ -123,7 +136,7 @@
       "failedMsg": "Assurez-vous d'avoir terminé le processus de connexion dans votre navigateur."
     },
     "google": {
-      "title": "CONNEXION GOOGLE",
+      "title": "CONNEXION VIA GOOGLE",
       "instruction1": "Pour importer vos contacts Google, vous devez autoriser cette application à l'aide de votre navigateur web.",
       "instruction2": "Copiez ce code dans votre presse-papiers en cliquant sur l'icône ou en sélectionnant le texte:",
       "instruction3": "Accédez au lien suivant dans votre navigateur web et saisissez le code ci-dessus:",
@@ -135,6 +148,7 @@
     "menu": {
       "appearance": "Apparence",
       "language": "Langue",
+      "user": "Utilisateur",
       "open": "Ouvrir les paramètres"
     },
     "appearance": {
@@ -142,15 +156,12 @@
       "darkLabel": "Mode sombre"
     }
   },
-  "sideBar": {
-    "openSidebar": "Open sidebar",
-    "closeSidebar": "Close sidebar"
-  },
   "grid": {
     "settings": {
       "filter": "Filtrer",
       "sortBy": "Filtrer par",
-      "Properties": "Propriétés"
+      "Properties": "Propriétés",
+      "group": "Groupe"
     },
     "field": {
       "hide": "Cacher",
@@ -179,13 +190,17 @@
       "addSelectOption": "Ajouter une option",
       "optionTitle": "Options",
       "addOption": "Ajouter une option",
-      "editProperty": "Modifier la propriété"
+      "editProperty": "Modifier la propriété",
+      "newColumn": "Nouvelle colonne",
+      "deleteFieldPromptMessage": "Vous voulez supprimer cette propriété ?"
     },
     "row": {
       "duplicate": "Dupliquer",
       "delete": "Supprimer",
       "textPlaceholder": "Vide",
-      "copyProperty": "Copie de la propriété dans le presse-papiers"
+      "copyProperty": "Copie de la propriété dans le presse-papiers",
+      "count": "Nombre",
+      "newRow": "Nouvelle ligne"
     },
     "selectOption": {
       "create": "Créer",
@@ -211,5 +226,10 @@
       "timeHintTextInTwelveHour": "01:00 PM",
       "timeHintTextInTwentyFourHour": "13:00"
     }
+  },
+  "board": {
+    "column": {
+      "create_new_card": "Nouveau"
+    }
   }
-}
+}

+ 20 - 4
frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart

@@ -1,6 +1,8 @@
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:app_flowy/plugins/grid/application/cell/date_cal_bloc.dart';
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
+import 'package:app_flowy/workspace/presentation/widgets/toggle/toggle.dart';
+import 'package:app_flowy/workspace/presentation/widgets/toggle/toggle_style.dart';
 import 'package:appflowy_popover/appflowy_popover.dart';
 import 'package:dartz/dartz.dart' show Either;
 import 'package:easy_localization/easy_localization.dart';
@@ -167,6 +169,18 @@ class _CellCalendarWidgetState extends State<_CellCalendarWidget> {
             rightChevronMargin: EdgeInsets.zero,
             rightChevronIcon: svgWidget("home/arrow_right"),
           ),
+          daysOfWeekStyle: DaysOfWeekStyle(
+            dowTextFormatter: (date, locale) =>
+                DateFormat.E(locale).format(date).toUpperCase(),
+            weekdayStyle: TextStyle(
+              fontSize: 13,
+              color: theme.shader3,
+            ),
+            weekendStyle: TextStyle(
+              fontSize: 13,
+              color: theme.shader3,
+            ),
+          ),
           calendarStyle: CalendarStyle(
             selectedDecoration: BoxDecoration(
               color: theme.main1,
@@ -230,11 +244,13 @@ class _IncludeTimeButton extends StatelessWidget {
                 FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(),
                     fontSize: 14),
                 const Spacer(),
-                Switch(
+                Toggle(
                   value: includeTime,
-                  onChanged: (newValue) => context
+                  onChanged: (value) => context
                       .read<DateCalBloc>()
-                      .add(DateCalEvent.setIncludeTime(newValue)),
+                      .add(DateCalEvent.setIncludeTime(!value)),
+                  style: ToggleStyle.big(theme),
+                  padding: EdgeInsets.zero,
                 ),
               ],
             ),
@@ -350,7 +366,7 @@ class _DateTypeOptionButton extends StatelessWidget {
           offset: const Offset(20, 0),
           constraints: BoxConstraints.loose(const Size(140, 100)),
           child: FlowyButton(
-            text: FlowyText.medium(title, fontSize: 12),
+            text: FlowyText.medium(title, fontSize: 14),
             hoverColor: theme.hover,
             margin: kMargin,
             rightIcon: svgWidget("grid/more", color: theme.iconColor),

+ 8 - 3
frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/type_option/date.dart

@@ -1,5 +1,7 @@
 import 'package:app_flowy/plugins/grid/application/field/type_option/date_bloc.dart';
 import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart';
+import 'package:app_flowy/workspace/presentation/widgets/toggle/toggle.dart';
+import 'package:app_flowy/workspace/presentation/widgets/toggle/toggle_style.dart';
 import 'package:easy_localization/easy_localization.dart' hide DateFormat;
 import 'package:app_flowy/generated/locale_keys.g.dart';
 import 'package:flowy_infra/image.dart';
@@ -161,6 +163,7 @@ class _IncludeTimeButton extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
+    final theme = context.watch<AppTheme>();
     return BlocSelector<DateTypeOptionBloc, DateTypeOptionState, bool>(
       selector: (state) => state.typeOption.includeTime,
       builder: (context, includeTime) {
@@ -173,13 +176,15 @@ class _IncludeTimeButton extends StatelessWidget {
                 FlowyText.medium(LocaleKeys.grid_field_includeTime.tr(),
                     fontSize: 12),
                 const Spacer(),
-                Switch(
+                Toggle(
                   value: includeTime,
-                  onChanged: (newValue) {
+                  onChanged: (value) {
                     context
                         .read<DateTypeOptionBloc>()
-                        .add(DateTypeOptionEvent.includeTime(newValue));
+                        .add(DateTypeOptionEvent.includeTime(!value));
                   },
+                  style: ToggleStyle.big(theme),
+                  padding: EdgeInsets.zero,
                 ),
               ],
             ),

+ 1 - 0
frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart

@@ -99,6 +99,7 @@ class MenuAppHeader extends StatelessWidget {
               app.name,
               fontSize: 12,
               color: theme.textColor,
+              overflow: TextOverflow.ellipsis,
             ),
           ),
         ),

+ 1 - 1
frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart

@@ -82,7 +82,7 @@ class ViewSectionItem extends StatelessWidget {
         child: FlowyText.regular(
           state.view.name,
           fontSize: 12,
-          overflow: TextOverflow.clip,
+          overflow: TextOverflow.ellipsis,
         ),
       ),
     ];

+ 4 - 3
frontend/app_flowy/lib/workspace/presentation/home/menu/menu_user.dart

@@ -28,8 +28,9 @@ class MenuUser extends StatelessWidget {
           children: [
             _renderAvatar(context),
             const HSpace(10),
-            _renderUserName(context),
-            const Spacer(),
+            Expanded(
+              child: _renderUserName(context),
+            ),
             _renderSettingsButton(context),
             //ToDo: when the user is allowed to create another workspace,
             //we get the below block back
@@ -63,7 +64,7 @@ class MenuUser extends StatelessWidget {
     if (name.isEmpty) {
       name = context.read<MenuUserBloc>().state.userProfile.email;
     }
-    return FlowyText(name, fontSize: 12);
+    return FlowyText(name, fontSize: 12, overflow: TextOverflow.ellipsis);
   }
 
   Widget _renderSettingsButton(BuildContext context) {

+ 1 - 1
frontend/app_flowy/packages/appflowy_editor/example/lib/plugin/code_block_node_widget.dart

@@ -45,7 +45,7 @@ ShortcutEventHandler _ignorekHandler = (editorState, event) {
 };
 
 SelectionMenuItem codeBlockItem = SelectionMenuItem(
-  name: 'Code Block',
+  name: () => 'Code Block',
   icon: const Icon(Icons.abc),
   keywords: ['code block'],
   handler: (editorState, _, __) {

+ 35 - 0
frontend/app_flowy/packages/appflowy_editor/lib/l10n/intl_cs_CZ.arb

@@ -0,0 +1,35 @@
+{
+  "@@locale": "cs-CZ",
+  "bold": "Tučně",
+  "@bold": {},
+  "bulletedList": "Odrážkový seznam",
+  "@bulletedList": {},
+  "checkbox": "Zaškrtávací políčko",
+  "@checkbox": {},
+  "embedCode": "Vložit kód",
+  "@embedCode": {},
+  "heading1": "Nadpis 1",
+  "@heading1": {},
+  "heading2": "Nadpis 2",
+  "@heading2": {},
+  "heading3": "Nadpis 3",
+  "@heading3": {},
+  "highlight": "Zvýraznění",
+  "@highlight": {},
+  "image": "Obrázek",
+  "@image": {},
+  "italic": "Kurzíva",
+  "@italic": {},
+  "link": "Odkaz",
+  "@link": {},
+  "numberedList": "Číslovaný seznam",
+  "@numberedList": {},
+  "quote": "Citace",
+  "@quote": {},
+  "strikethrough": "Přeškrtnutí",
+  "@strikethrough": {},
+  "text": "Text",
+  "@text": {},
+  "underline": "Podtržení",
+  "@underline": {}
+}

+ 16 - 16
frontend/app_flowy/packages/appflowy_editor/lib/l10n/intl_fr_CA.arb

@@ -1,35 +1,35 @@
 {
   "@@locale": "fr-CA",
-  "bold": "",
+  "bold": "gras",
   "@bold": {},
-  "bulletedList": "",
+  "bulletedList": "liste à puces",
   "@bulletedList": {},
-  "checkbox": "",
+  "checkbox": "case à cocher",
   "@checkbox": {},
-  "embedCode": "",
+  "embedCode": "incorporer Code",
   "@embedCode": {},
-  "heading1": "",
+  "heading1": "en-tête1",
   "@heading1": {},
-  "heading2": "",
+  "heading2": "en-tête2",
   "@heading2": {},
-  "heading3": "",
+  "heading3": "en-tête3",
   "@heading3": {},
-  "highlight": "",
+  "highlight": "mettre en évidence",
   "@highlight": {},
-  "image": "",
+  "image": "l’image",
   "@image": {},
-  "italic": "",
+  "italic": "italique",
   "@italic": {},
-  "link": "",
+  "link": "lien",
   "@link": {},
-  "numberedList": "",
+  "numberedList": "liste numérotée",
   "@numberedList": {},
-  "quote": "",
+  "quote": "citation",
   "@quote": {},
-  "strikethrough": "",
+  "strikethrough": "barré",
   "@strikethrough": {},
-  "text": "",
+  "text": "texte",
   "@text": {},
-  "underline": "",
+  "underline": "souligner",
   "@underline": {}
 }

+ 16 - 16
frontend/app_flowy/packages/appflowy_editor/lib/l10n/intl_hu_HU.arb

@@ -1,35 +1,35 @@
 {
   "@@locale": "hu-HU",
-  "bold": "",
+  "bold": "bátor",
   "@bold": {},
-  "bulletedList": "",
+  "bulletedList": "pontozott lista",
   "@bulletedList": {},
-  "checkbox": "",
+  "checkbox": "jelölőnégyzetet",
   "@checkbox": {},
-  "embedCode": "",
+  "embedCode": "Beágyazás",
   "@embedCode": {},
-  "heading1": "",
+  "heading1": "címsor1",
   "@heading1": {},
-  "heading2": "",
+  "heading2": "címsor2",
   "@heading2": {},
-  "heading3": "",
+  "heading3": "címsor3",
   "@heading3": {},
-  "highlight": "",
+  "highlight": "Kiemel",
   "@highlight": {},
-  "image": "",
+  "image": "kép",
   "@image": {},
-  "italic": "",
+  "italic": "dőlt",
   "@italic": {},
-  "link": "",
+  "link": "link",
   "@link": {},
-  "numberedList": "",
+  "numberedList": "számozottLista",
   "@numberedList": {},
-  "quote": "",
+  "quote": "idézet",
   "@quote": {},
-  "strikethrough": "",
+  "strikethrough": "áthúzott",
   "@strikethrough": {},
-  "text": "",
+  "text": "szöveg",
   "@text": {},
-  "underline": "",
+  "underline": "aláhúzás",
   "@underline": {}
 }

+ 16 - 16
frontend/app_flowy/packages/appflowy_editor/lib/l10n/intl_id_ID.arb

@@ -1,35 +1,35 @@
 {
   "@@locale": "id-ID",
-  "bold": "",
+  "bold": "berani",
   "@bold": {},
-  "bulletedList": "",
+  "bulletedList": "daftar berpoin",
   "@bulletedList": {},
-  "checkbox": "",
+  "checkbox": "kotak centang",
   "@checkbox": {},
-  "embedCode": "",
+  "embedCode": "menyematkan Kode",
   "@embedCode": {},
-  "heading1": "",
+  "heading1": "pos1",
   "@heading1": {},
-  "heading2": "",
+  "heading2": "pos2",
   "@heading2": {},
-  "heading3": "",
+  "heading3": "pos3",
   "@heading3": {},
-  "highlight": "",
+  "highlight": "menyorot",
   "@highlight": {},
-  "image": "",
+  "image": "gambar",
   "@image": {},
-  "italic": "",
+  "italic": "miring",
   "@italic": {},
-  "link": "",
+  "link": "tautan",
   "@link": {},
-  "numberedList": "",
+  "numberedList": "daftar bernomor",
   "@numberedList": {},
-  "quote": "",
+  "quote": "mengutip",
   "@quote": {},
-  "strikethrough": "",
+  "strikethrough": "coret",
   "@strikethrough": {},
-  "text": "",
+  "text": "teks",
   "@text": {},
-  "underline": "",
+  "underline": "menggarisbawahi",
   "@underline": {}
 }

+ 16 - 16
frontend/app_flowy/packages/appflowy_editor/lib/l10n/intl_pt_PT.arb

@@ -1,35 +1,35 @@
 {
   "@@locale": "pt-PT",
-  "bold": "",
+  "bold": "negrito",
   "@bold": {},
-  "bulletedList": "",
+  "bulletedList": "lista com marcadores",
   "@bulletedList": {},
-  "checkbox": "",
+  "checkbox": "caixa de seleção",
   "@checkbox": {},
-  "embedCode": "",
+  "embedCode": "Código embutido",
   "@embedCode": {},
-  "heading1": "",
+  "heading1": "Cabeçallho 1",
   "@heading1": {},
-  "heading2": "",
+  "heading2": "Cabeçallho 2",
   "@heading2": {},
-  "heading3": "",
+  "heading3": "Cabeçallho 3",
   "@heading3": {},
-  "highlight": "",
+  "highlight": "realçar",
   "@highlight": {},
-  "image": "",
+  "image": "imagem",
   "@image": {},
-  "italic": "",
+  "italic": "itálico",
   "@italic": {},
-  "link": "",
+  "link": "link",
   "@link": {},
-  "numberedList": "",
+  "numberedList": "lista numerada",
   "@numberedList": {},
-  "quote": "",
+  "quote": "citar",
   "@quote": {},
-  "strikethrough": "",
+  "strikethrough": "tachado",
   "@strikethrough": {},
-  "text": "",
+  "text": "texto",
   "@text": {},
-  "underline": "",
+  "underline": "sublinhado",
   "@underline": {}
 }

+ 8 - 0
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_all.dart

@@ -16,6 +16,7 @@ import 'package:intl/message_lookup_by_library.dart';
 import 'package:intl/src/intl_helpers.dart';
 
 import 'messages_ca.dart' as messages_ca;
+import 'messages_cs-CZ.dart' as messages_cs_cz;
 import 'messages_de-DE.dart' as messages_de_de;
 import 'messages_en.dart' as messages_en;
 import 'messages_es-VE.dart' as messages_es_ve;
@@ -25,6 +26,7 @@ import 'messages_hu-HU.dart' as messages_hu_hu;
 import 'messages_id-ID.dart' as messages_id_id;
 import 'messages_it-IT.dart' as messages_it_it;
 import 'messages_ja-JP.dart' as messages_ja_jp;
+import 'messages_nl-NL.dart' as messages_nl_nl;
 import 'messages_pl-PL.dart' as messages_pl_pl;
 import 'messages_pt-BR.dart' as messages_pt_br;
 import 'messages_pt-PT.dart' as messages_pt_pt;
@@ -36,6 +38,7 @@ import 'messages_zh-TW.dart' as messages_zh_tw;
 typedef Future<dynamic> LibraryLoader();
 Map<String, LibraryLoader> _deferredLibraries = {
   'ca': () => new Future.value(null),
+  'cs_CZ': () => new Future.value(null),
   'de_DE': () => new Future.value(null),
   'en': () => new Future.value(null),
   'es_VE': () => new Future.value(null),
@@ -45,6 +48,7 @@ Map<String, LibraryLoader> _deferredLibraries = {
   'id_ID': () => new Future.value(null),
   'it_IT': () => new Future.value(null),
   'ja_JP': () => new Future.value(null),
+  'nl_NL': () => new Future.value(null),
   'pl_PL': () => new Future.value(null),
   'pt_BR': () => new Future.value(null),
   'pt_PT': () => new Future.value(null),
@@ -58,6 +62,8 @@ MessageLookupByLibrary? _findExact(String localeName) {
   switch (localeName) {
     case 'ca':
       return messages_ca.messages;
+    case 'cs_CZ':
+      return messages_cs_cz.messages;
     case 'de_DE':
       return messages_de_de.messages;
     case 'en':
@@ -76,6 +82,8 @@ MessageLookupByLibrary? _findExact(String localeName) {
       return messages_it_it.messages;
     case 'ja_JP':
       return messages_ja_jp.messages;
+    case 'nl_NL':
+      return messages_nl_nl.messages;
     case 'pl_PL':
       return messages_pl_pl.messages;
     case 'pt_BR':

+ 44 - 0
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_cs-CZ.dart

@@ -0,0 +1,44 @@
+// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
+// This is a library that provides messages for a cs_CZ locale. All the
+// messages from the main program should be duplicated here with the same
+// function name.
+
+// Ignore issues from commonly used lints in this file.
+// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
+// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
+// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
+// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
+// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
+
+import 'package:intl/intl.dart';
+import 'package:intl/message_lookup_by_library.dart';
+
+final messages = new MessageLookup();
+
+typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
+
+class MessageLookup extends MessageLookupByLibrary {
+  String get localeName => 'cs_CZ';
+
+  final messages = _notInlinedMessages(_notInlinedMessages);
+  static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
+        "bold": MessageLookupByLibrary.simpleMessage("Tučně"),
+        "bulletedList":
+            MessageLookupByLibrary.simpleMessage("Odrážkový seznam"),
+        "checkbox": MessageLookupByLibrary.simpleMessage("Zaškrtávací políčko"),
+        "embedCode": MessageLookupByLibrary.simpleMessage("Vložit kód"),
+        "heading1": MessageLookupByLibrary.simpleMessage("Nadpis 1"),
+        "heading2": MessageLookupByLibrary.simpleMessage("Nadpis 2"),
+        "heading3": MessageLookupByLibrary.simpleMessage("Nadpis 3"),
+        "highlight": MessageLookupByLibrary.simpleMessage("Zvýraznění"),
+        "image": MessageLookupByLibrary.simpleMessage("Obrázek"),
+        "italic": MessageLookupByLibrary.simpleMessage("Kurzíva"),
+        "link": MessageLookupByLibrary.simpleMessage("Odkaz"),
+        "numberedList":
+            MessageLookupByLibrary.simpleMessage("Číslovaný seznam"),
+        "quote": MessageLookupByLibrary.simpleMessage("Citace"),
+        "strikethrough": MessageLookupByLibrary.simpleMessage("Přeškrtnutí"),
+        "text": MessageLookupByLibrary.simpleMessage("Text"),
+        "underline": MessageLookupByLibrary.simpleMessage("Podtržení")
+      };
+}

+ 16 - 16
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_fr-CA.dart

@@ -22,21 +22,21 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "bold": MessageLookupByLibrary.simpleMessage(""),
-        "bulletedList": MessageLookupByLibrary.simpleMessage(""),
-        "checkbox": MessageLookupByLibrary.simpleMessage(""),
-        "embedCode": MessageLookupByLibrary.simpleMessage(""),
-        "heading1": MessageLookupByLibrary.simpleMessage(""),
-        "heading2": MessageLookupByLibrary.simpleMessage(""),
-        "heading3": MessageLookupByLibrary.simpleMessage(""),
-        "highlight": MessageLookupByLibrary.simpleMessage(""),
-        "image": MessageLookupByLibrary.simpleMessage(""),
-        "italic": MessageLookupByLibrary.simpleMessage(""),
-        "link": MessageLookupByLibrary.simpleMessage(""),
-        "numberedList": MessageLookupByLibrary.simpleMessage(""),
-        "quote": MessageLookupByLibrary.simpleMessage(""),
-        "strikethrough": MessageLookupByLibrary.simpleMessage(""),
-        "text": MessageLookupByLibrary.simpleMessage(""),
-        "underline": MessageLookupByLibrary.simpleMessage("")
+        "bold": MessageLookupByLibrary.simpleMessage("gras"),
+        "bulletedList": MessageLookupByLibrary.simpleMessage("liste à puces"),
+        "checkbox": MessageLookupByLibrary.simpleMessage("case à cocher"),
+        "embedCode": MessageLookupByLibrary.simpleMessage("incorporer Code"),
+        "heading1": MessageLookupByLibrary.simpleMessage("en-tête1"),
+        "heading2": MessageLookupByLibrary.simpleMessage("en-tête2"),
+        "heading3": MessageLookupByLibrary.simpleMessage("en-tête3"),
+        "highlight": MessageLookupByLibrary.simpleMessage("mettre en évidence"),
+        "image": MessageLookupByLibrary.simpleMessage("l’image"),
+        "italic": MessageLookupByLibrary.simpleMessage("italique"),
+        "link": MessageLookupByLibrary.simpleMessage("lien"),
+        "numberedList": MessageLookupByLibrary.simpleMessage("liste numérotée"),
+        "quote": MessageLookupByLibrary.simpleMessage("citation"),
+        "strikethrough": MessageLookupByLibrary.simpleMessage("barré"),
+        "text": MessageLookupByLibrary.simpleMessage("texte"),
+        "underline": MessageLookupByLibrary.simpleMessage("souligner")
       };
 }

+ 16 - 16
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_fr-FR.dart

@@ -22,21 +22,21 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "bold": MessageLookupByLibrary.simpleMessage(""),
-        "bulletedList": MessageLookupByLibrary.simpleMessage(""),
-        "checkbox": MessageLookupByLibrary.simpleMessage(""),
-        "embedCode": MessageLookupByLibrary.simpleMessage(""),
-        "heading1": MessageLookupByLibrary.simpleMessage(""),
-        "heading2": MessageLookupByLibrary.simpleMessage(""),
-        "heading3": MessageLookupByLibrary.simpleMessage(""),
-        "highlight": MessageLookupByLibrary.simpleMessage(""),
-        "image": MessageLookupByLibrary.simpleMessage(""),
-        "italic": MessageLookupByLibrary.simpleMessage(""),
-        "link": MessageLookupByLibrary.simpleMessage(""),
-        "numberedList": MessageLookupByLibrary.simpleMessage(""),
-        "quote": MessageLookupByLibrary.simpleMessage(""),
-        "strikethrough": MessageLookupByLibrary.simpleMessage(""),
-        "text": MessageLookupByLibrary.simpleMessage(""),
-        "underline": MessageLookupByLibrary.simpleMessage("")
+        "bold": MessageLookupByLibrary.simpleMessage("Gras"),
+        "bulletedList": MessageLookupByLibrary.simpleMessage("List à puces"),
+        "checkbox": MessageLookupByLibrary.simpleMessage("Case à cocher"),
+        "embedCode": MessageLookupByLibrary.simpleMessage("Incorporer code"),
+        "heading1": MessageLookupByLibrary.simpleMessage("Titre 1"),
+        "heading2": MessageLookupByLibrary.simpleMessage("Titre 2"),
+        "heading3": MessageLookupByLibrary.simpleMessage("Titre 3"),
+        "highlight": MessageLookupByLibrary.simpleMessage("Surligné"),
+        "image": MessageLookupByLibrary.simpleMessage("Image"),
+        "italic": MessageLookupByLibrary.simpleMessage("Italique"),
+        "link": MessageLookupByLibrary.simpleMessage("Lien"),
+        "numberedList": MessageLookupByLibrary.simpleMessage("Liste numérotée"),
+        "quote": MessageLookupByLibrary.simpleMessage("Citation"),
+        "strikethrough": MessageLookupByLibrary.simpleMessage("Barré"),
+        "text": MessageLookupByLibrary.simpleMessage("Texte"),
+        "underline": MessageLookupByLibrary.simpleMessage("Souligné")
       };
 }

+ 16 - 16
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_hu-HU.dart

@@ -22,21 +22,21 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "bold": MessageLookupByLibrary.simpleMessage(""),
-        "bulletedList": MessageLookupByLibrary.simpleMessage(""),
-        "checkbox": MessageLookupByLibrary.simpleMessage(""),
-        "embedCode": MessageLookupByLibrary.simpleMessage(""),
-        "heading1": MessageLookupByLibrary.simpleMessage(""),
-        "heading2": MessageLookupByLibrary.simpleMessage(""),
-        "heading3": MessageLookupByLibrary.simpleMessage(""),
-        "highlight": MessageLookupByLibrary.simpleMessage(""),
-        "image": MessageLookupByLibrary.simpleMessage(""),
-        "italic": MessageLookupByLibrary.simpleMessage(""),
-        "link": MessageLookupByLibrary.simpleMessage(""),
-        "numberedList": MessageLookupByLibrary.simpleMessage(""),
-        "quote": MessageLookupByLibrary.simpleMessage(""),
-        "strikethrough": MessageLookupByLibrary.simpleMessage(""),
-        "text": MessageLookupByLibrary.simpleMessage(""),
-        "underline": MessageLookupByLibrary.simpleMessage("")
+        "bold": MessageLookupByLibrary.simpleMessage("bátor"),
+        "bulletedList": MessageLookupByLibrary.simpleMessage("pontozott lista"),
+        "checkbox": MessageLookupByLibrary.simpleMessage("jelölőnégyzetet"),
+        "embedCode": MessageLookupByLibrary.simpleMessage("Beágyazás"),
+        "heading1": MessageLookupByLibrary.simpleMessage("címsor1"),
+        "heading2": MessageLookupByLibrary.simpleMessage("címsor2"),
+        "heading3": MessageLookupByLibrary.simpleMessage("címsor3"),
+        "highlight": MessageLookupByLibrary.simpleMessage("Kiemel"),
+        "image": MessageLookupByLibrary.simpleMessage("kép"),
+        "italic": MessageLookupByLibrary.simpleMessage("dőlt"),
+        "link": MessageLookupByLibrary.simpleMessage("link"),
+        "numberedList": MessageLookupByLibrary.simpleMessage("számozottLista"),
+        "quote": MessageLookupByLibrary.simpleMessage("idézet"),
+        "strikethrough": MessageLookupByLibrary.simpleMessage("áthúzott"),
+        "text": MessageLookupByLibrary.simpleMessage("szöveg"),
+        "underline": MessageLookupByLibrary.simpleMessage("aláhúzás")
       };
 }

+ 16 - 16
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_id-ID.dart

@@ -22,21 +22,21 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "bold": MessageLookupByLibrary.simpleMessage(""),
-        "bulletedList": MessageLookupByLibrary.simpleMessage(""),
-        "checkbox": MessageLookupByLibrary.simpleMessage(""),
-        "embedCode": MessageLookupByLibrary.simpleMessage(""),
-        "heading1": MessageLookupByLibrary.simpleMessage(""),
-        "heading2": MessageLookupByLibrary.simpleMessage(""),
-        "heading3": MessageLookupByLibrary.simpleMessage(""),
-        "highlight": MessageLookupByLibrary.simpleMessage(""),
-        "image": MessageLookupByLibrary.simpleMessage(""),
-        "italic": MessageLookupByLibrary.simpleMessage(""),
-        "link": MessageLookupByLibrary.simpleMessage(""),
-        "numberedList": MessageLookupByLibrary.simpleMessage(""),
-        "quote": MessageLookupByLibrary.simpleMessage(""),
-        "strikethrough": MessageLookupByLibrary.simpleMessage(""),
-        "text": MessageLookupByLibrary.simpleMessage(""),
-        "underline": MessageLookupByLibrary.simpleMessage("")
+        "bold": MessageLookupByLibrary.simpleMessage("berani"),
+        "bulletedList": MessageLookupByLibrary.simpleMessage("daftar berpoin"),
+        "checkbox": MessageLookupByLibrary.simpleMessage("kotak centang"),
+        "embedCode": MessageLookupByLibrary.simpleMessage("menyematkan Kode"),
+        "heading1": MessageLookupByLibrary.simpleMessage("pos1"),
+        "heading2": MessageLookupByLibrary.simpleMessage("pos2"),
+        "heading3": MessageLookupByLibrary.simpleMessage("pos3"),
+        "highlight": MessageLookupByLibrary.simpleMessage("menyorot"),
+        "image": MessageLookupByLibrary.simpleMessage("gambar"),
+        "italic": MessageLookupByLibrary.simpleMessage("miring"),
+        "link": MessageLookupByLibrary.simpleMessage("tautan"),
+        "numberedList": MessageLookupByLibrary.simpleMessage("daftar bernomor"),
+        "quote": MessageLookupByLibrary.simpleMessage("mengutip"),
+        "strikethrough": MessageLookupByLibrary.simpleMessage("coret"),
+        "text": MessageLookupByLibrary.simpleMessage("teks"),
+        "underline": MessageLookupByLibrary.simpleMessage("menggarisbawahi")
       };
 }

+ 16 - 16
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_it-IT.dart

@@ -22,21 +22,21 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "bold": MessageLookupByLibrary.simpleMessage(""),
-        "bulletedList": MessageLookupByLibrary.simpleMessage(""),
-        "checkbox": MessageLookupByLibrary.simpleMessage(""),
-        "embedCode": MessageLookupByLibrary.simpleMessage(""),
-        "heading1": MessageLookupByLibrary.simpleMessage(""),
-        "heading2": MessageLookupByLibrary.simpleMessage(""),
-        "heading3": MessageLookupByLibrary.simpleMessage(""),
-        "highlight": MessageLookupByLibrary.simpleMessage(""),
-        "image": MessageLookupByLibrary.simpleMessage(""),
-        "italic": MessageLookupByLibrary.simpleMessage(""),
-        "link": MessageLookupByLibrary.simpleMessage(""),
-        "numberedList": MessageLookupByLibrary.simpleMessage(""),
-        "quote": MessageLookupByLibrary.simpleMessage(""),
-        "strikethrough": MessageLookupByLibrary.simpleMessage(""),
-        "text": MessageLookupByLibrary.simpleMessage(""),
-        "underline": MessageLookupByLibrary.simpleMessage("")
+        "bold": MessageLookupByLibrary.simpleMessage("Grassetto"),
+        "bulletedList": MessageLookupByLibrary.simpleMessage("Elenco puntato"),
+        "checkbox": MessageLookupByLibrary.simpleMessage("Casella di spunta"),
+        "embedCode": MessageLookupByLibrary.simpleMessage("Incorpora codice"),
+        "heading1": MessageLookupByLibrary.simpleMessage("H1"),
+        "heading2": MessageLookupByLibrary.simpleMessage("H2"),
+        "heading3": MessageLookupByLibrary.simpleMessage("H3"),
+        "highlight": MessageLookupByLibrary.simpleMessage("Evidenzia"),
+        "image": MessageLookupByLibrary.simpleMessage("Immagine"),
+        "italic": MessageLookupByLibrary.simpleMessage("Corsivo"),
+        "link": MessageLookupByLibrary.simpleMessage("Collegamento"),
+        "numberedList": MessageLookupByLibrary.simpleMessage("Elenco numerato"),
+        "quote": MessageLookupByLibrary.simpleMessage("Cita"),
+        "strikethrough": MessageLookupByLibrary.simpleMessage("Barrato"),
+        "text": MessageLookupByLibrary.simpleMessage("Testo"),
+        "underline": MessageLookupByLibrary.simpleMessage("Sottolineato")
       };
 }

+ 43 - 0
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_nl-NL.dart

@@ -0,0 +1,43 @@
+// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
+// This is a library that provides messages for a nl_NL locale. All the
+// messages from the main program should be duplicated here with the same
+// function name.
+
+// Ignore issues from commonly used lints in this file.
+// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
+// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
+// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
+// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
+// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
+
+import 'package:intl/intl.dart';
+import 'package:intl/message_lookup_by_library.dart';
+
+final messages = new MessageLookup();
+
+typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
+
+class MessageLookup extends MessageLookupByLibrary {
+  String get localeName => 'nl_NL';
+
+  final messages = _notInlinedMessages(_notInlinedMessages);
+  static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
+        "bold": MessageLookupByLibrary.simpleMessage("Vet"),
+        "bulletedList":
+            MessageLookupByLibrary.simpleMessage("Opsommingstekens"),
+        "checkbox": MessageLookupByLibrary.simpleMessage("Selectievakje"),
+        "embedCode": MessageLookupByLibrary.simpleMessage("Invoegcode"),
+        "heading1": MessageLookupByLibrary.simpleMessage("H1"),
+        "heading2": MessageLookupByLibrary.simpleMessage("H2"),
+        "heading3": MessageLookupByLibrary.simpleMessage("H3"),
+        "highlight": MessageLookupByLibrary.simpleMessage("Highlight"),
+        "image": MessageLookupByLibrary.simpleMessage("Afbeelding"),
+        "italic": MessageLookupByLibrary.simpleMessage("Cursief"),
+        "link": MessageLookupByLibrary.simpleMessage(""),
+        "numberedList": MessageLookupByLibrary.simpleMessage("Nummering"),
+        "quote": MessageLookupByLibrary.simpleMessage("Quote"),
+        "strikethrough": MessageLookupByLibrary.simpleMessage("Doorhalen"),
+        "text": MessageLookupByLibrary.simpleMessage("Tekst"),
+        "underline": MessageLookupByLibrary.simpleMessage("Onderstrepen")
+      };
+}

+ 17 - 16
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_pt-BR.dart

@@ -22,21 +22,22 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "bold": MessageLookupByLibrary.simpleMessage(""),
-        "bulletedList": MessageLookupByLibrary.simpleMessage(""),
-        "checkbox": MessageLookupByLibrary.simpleMessage(""),
-        "embedCode": MessageLookupByLibrary.simpleMessage(""),
-        "heading1": MessageLookupByLibrary.simpleMessage(""),
-        "heading2": MessageLookupByLibrary.simpleMessage(""),
-        "heading3": MessageLookupByLibrary.simpleMessage(""),
-        "highlight": MessageLookupByLibrary.simpleMessage(""),
-        "image": MessageLookupByLibrary.simpleMessage(""),
-        "italic": MessageLookupByLibrary.simpleMessage(""),
-        "link": MessageLookupByLibrary.simpleMessage(""),
-        "numberedList": MessageLookupByLibrary.simpleMessage(""),
-        "quote": MessageLookupByLibrary.simpleMessage(""),
-        "strikethrough": MessageLookupByLibrary.simpleMessage(""),
-        "text": MessageLookupByLibrary.simpleMessage(""),
-        "underline": MessageLookupByLibrary.simpleMessage("")
+        "bold": MessageLookupByLibrary.simpleMessage("Negrito"),
+        "bulletedList":
+            MessageLookupByLibrary.simpleMessage("Lista de marcadores"),
+        "checkbox": MessageLookupByLibrary.simpleMessage("Caixa de seleção"),
+        "embedCode": MessageLookupByLibrary.simpleMessage("Código incorporado"),
+        "heading1": MessageLookupByLibrary.simpleMessage("H1"),
+        "heading2": MessageLookupByLibrary.simpleMessage("H2"),
+        "heading3": MessageLookupByLibrary.simpleMessage("H3"),
+        "highlight": MessageLookupByLibrary.simpleMessage("Destacar"),
+        "image": MessageLookupByLibrary.simpleMessage("Imagem"),
+        "italic": MessageLookupByLibrary.simpleMessage("Itálico"),
+        "link": MessageLookupByLibrary.simpleMessage("Link"),
+        "numberedList": MessageLookupByLibrary.simpleMessage("Lista numerada"),
+        "quote": MessageLookupByLibrary.simpleMessage("Citar"),
+        "strikethrough": MessageLookupByLibrary.simpleMessage("Rasurar"),
+        "text": MessageLookupByLibrary.simpleMessage("Texto"),
+        "underline": MessageLookupByLibrary.simpleMessage("Sublinhar")
       };
 }

+ 17 - 16
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/intl/messages_pt-PT.dart

@@ -22,21 +22,22 @@ class MessageLookup extends MessageLookupByLibrary {
 
   final messages = _notInlinedMessages(_notInlinedMessages);
   static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
-        "bold": MessageLookupByLibrary.simpleMessage(""),
-        "bulletedList": MessageLookupByLibrary.simpleMessage(""),
-        "checkbox": MessageLookupByLibrary.simpleMessage(""),
-        "embedCode": MessageLookupByLibrary.simpleMessage(""),
-        "heading1": MessageLookupByLibrary.simpleMessage(""),
-        "heading2": MessageLookupByLibrary.simpleMessage(""),
-        "heading3": MessageLookupByLibrary.simpleMessage(""),
-        "highlight": MessageLookupByLibrary.simpleMessage(""),
-        "image": MessageLookupByLibrary.simpleMessage(""),
-        "italic": MessageLookupByLibrary.simpleMessage(""),
-        "link": MessageLookupByLibrary.simpleMessage(""),
-        "numberedList": MessageLookupByLibrary.simpleMessage(""),
-        "quote": MessageLookupByLibrary.simpleMessage(""),
-        "strikethrough": MessageLookupByLibrary.simpleMessage(""),
-        "text": MessageLookupByLibrary.simpleMessage(""),
-        "underline": MessageLookupByLibrary.simpleMessage("")
+        "bold": MessageLookupByLibrary.simpleMessage("negrito"),
+        "bulletedList":
+            MessageLookupByLibrary.simpleMessage("lista com marcadores"),
+        "checkbox": MessageLookupByLibrary.simpleMessage("caixa de seleção"),
+        "embedCode": MessageLookupByLibrary.simpleMessage("Código embutido"),
+        "heading1": MessageLookupByLibrary.simpleMessage("Cabeçallho 1"),
+        "heading2": MessageLookupByLibrary.simpleMessage("Cabeçallho 2"),
+        "heading3": MessageLookupByLibrary.simpleMessage("Cabeçallho 3"),
+        "highlight": MessageLookupByLibrary.simpleMessage("realçar"),
+        "image": MessageLookupByLibrary.simpleMessage("imagem"),
+        "italic": MessageLookupByLibrary.simpleMessage("itálico"),
+        "link": MessageLookupByLibrary.simpleMessage("link"),
+        "numberedList": MessageLookupByLibrary.simpleMessage("lista numerada"),
+        "quote": MessageLookupByLibrary.simpleMessage("citar"),
+        "strikethrough": MessageLookupByLibrary.simpleMessage("tachado"),
+        "text": MessageLookupByLibrary.simpleMessage("texto"),
+        "underline": MessageLookupByLibrary.simpleMessage("sublinhado")
       };
 }

+ 2 - 0
frontend/app_flowy/packages/appflowy_editor/lib/src/l10n/l10n.dart

@@ -220,6 +220,7 @@ class AppLocalizationDelegate
     return const <Locale>[
       Locale.fromSubtags(languageCode: 'en'),
       Locale.fromSubtags(languageCode: 'ca'),
+      Locale.fromSubtags(languageCode: 'cs', countryCode: 'CZ'),
       Locale.fromSubtags(languageCode: 'de', countryCode: 'DE'),
       Locale.fromSubtags(languageCode: 'es', countryCode: 'VE'),
       Locale.fromSubtags(languageCode: 'fr', countryCode: 'CA'),
@@ -228,6 +229,7 @@ class AppLocalizationDelegate
       Locale.fromSubtags(languageCode: 'id', countryCode: 'ID'),
       Locale.fromSubtags(languageCode: 'it', countryCode: 'IT'),
       Locale.fromSubtags(languageCode: 'ja', countryCode: 'JP'),
+      Locale.fromSubtags(languageCode: 'nl', countryCode: 'NL'),
       Locale.fromSubtags(languageCode: 'pl', countryCode: 'PL'),
       Locale.fromSubtags(languageCode: 'pt', countryCode: 'BR'),
       Locale.fromSubtags(languageCode: 'pt', countryCode: 'PT'),

+ 8 - 0
frontend/app_flowy/packages/appflowy_editor/lib/src/render/selection_menu/selection_menu_service.dart

@@ -169,6 +169,14 @@ final List<SelectionMenuItem> _defaultSelectionMenuItems = [
       insertBulletedListAfterSelection(editorState);
     },
   ),
+  SelectionMenuItem(
+    name: () => AppFlowyEditorLocalizations.current.numberedList,
+    icon: _selectionMenuIcon('number'),
+    keywords: ['numbered list', 'list', 'ordered list'],
+    handler: (editorState, _, __) {
+      insertNumberedListAfterSelection(editorState);
+    },
+  ),
   SelectionMenuItem(
     name: () => AppFlowyEditorLocalizations.current.checkbox,
     icon: _selectionMenuIcon('checkbox'),

+ 7 - 0
frontend/app_flowy/packages/appflowy_editor/lib/src/service/default_text_operations/format_rich_text_style.dart

@@ -34,6 +34,13 @@ void insertBulletedListAfterSelection(EditorState editorState) {
   });
 }
 
+void insertNumberedListAfterSelection(EditorState editorState) {
+  insertTextNodeAfterSelection(editorState, {
+    BuiltInAttributeKey.subtype: BuiltInAttributeKey.numberList,
+    BuiltInAttributeKey.number: 1,
+  });
+}
+
 bool insertTextNodeAfterSelection(
     EditorState editorState, Attributes attributes) {
   final selection = editorState.service.selectionService.currentSelection.value;

+ 56 - 2
frontend/app_flowy/packages/appflowy_editor/lib/src/service/internal_key_event_handlers/markdown_syntax_to_styled_text.dart

@@ -1,4 +1,3 @@
-import "dart:math";
 import 'package:appflowy_editor/appflowy_editor.dart';
 import 'package:appflowy_editor/src/extensions/text_node_extensions.dart';
 import 'package:appflowy_editor/src/service/default_text_operations/format_rich_text_style.dart';
@@ -49,7 +48,7 @@ ShortcutEventHandler backquoteToCodeHandler = (editorState, event) {
       .substring(selection.start.offset, selection.end.offset);
 
   // toggle code style when selected some text
-  if (selectionText.length > 0) {
+  if (selectionText.isNotEmpty) {
     formatEmbedCode(editorState);
     return KeyEventResult.handled;
   }
@@ -187,3 +186,58 @@ ShortcutEventHandler doubleTildeToStrikethrough = (editorState, event) {
 
   return KeyEventResult.handled;
 };
+
+/// To create a link, enclose the link text in brackets (e.g., [link text]).
+/// Then, immediately follow it with the URL in parentheses (e.g., (https://example.com)).
+ShortcutEventHandler markdownLinkToLinkHandler = (editorState, event) {
+  final selectionService = editorState.service.selectionService;
+  final selection = selectionService.currentSelection.value;
+  final textNodes = selectionService.currentSelectedNodes.whereType<TextNode>();
+  if (selection == null || !selection.isSingle || textNodes.length != 1) {
+    return KeyEventResult.ignored;
+  }
+
+  // find all of the indexs for important characters
+  final textNode = textNodes.first;
+  final text = textNode.toRawString();
+  final firstOpeningBracket = text.indexOf('[');
+  final firstClosingBracket = text.indexOf(']');
+
+  // use regex to validate the format of the link
+  // note: this enforces that the link has http or https
+  final regexp = RegExp(r'\[([\w\s\d]+)\]\(((?:\/|https?:\/\/)[\w\d./?=#]+)$');
+  final match = regexp.firstMatch(text);
+  if (match == null) {
+    return KeyEventResult.ignored;
+  }
+
+  // extract the text and the url of the link
+  final linkText = match.group(1);
+  final linkUrl = match.group(2);
+
+  // Delete the initial opening bracket,
+  // update the href attribute of the text surrounded by [ ] to the url,
+  // delete everything after the text,
+  // and update the cursor position.
+  TransactionBuilder(editorState)
+    ..deleteText(textNode, firstOpeningBracket, 1)
+    ..formatText(
+      textNode,
+      firstOpeningBracket,
+      firstClosingBracket - firstOpeningBracket - 1,
+      {
+        BuiltInAttributeKey.href: linkUrl,
+      },
+    )
+    ..deleteText(textNode, firstClosingBracket - 1,
+        selection.end.offset - firstClosingBracket)
+    ..afterSelection = Selection.collapsed(
+      Position(
+        path: textNode.path,
+        offset: firstOpeningBracket + linkText!.length,
+      ),
+    )
+    ..commit();
+
+  return KeyEventResult.handled;
+};

+ 5 - 0
frontend/app_flowy/packages/appflowy_editor/lib/src/service/shortcut_event/built_in_shortcut_events.dart

@@ -262,6 +262,11 @@ List<ShortcutEvent> builtInShortcutEvents = [
     command: 'shift+tilde',
     handler: doubleTildeToStrikethrough,
   ),
+  ShortcutEvent(
+    key: 'Markdown link to link',
+    command: 'shift+parenthesis right',
+    handler: markdownLinkToLinkHandler,
+  ),
   // https://github.com/flutter/flutter/issues/104944
   // Workaround: Using space editing on the web platform often results in errors,
   //  so adding a shortcut event to handle the space input instead of using the

+ 7 - 7
frontend/app_flowy/packages/appflowy_editor/test/render/selection_menu/selection_menu_widget_test.dart

@@ -1,7 +1,6 @@
 import 'package:appflowy_editor/appflowy_editor.dart';
 import 'package:appflowy_editor/src/render/selection_menu/selection_menu_item_widget.dart';
 import 'package:appflowy_editor/src/render/selection_menu/selection_menu_service.dart';
-import 'package:appflowy_editor/src/render/selection_menu/selection_menu_widget.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_test/flutter_test.dart';
 import '../../infra/test_editor.dart';
@@ -13,8 +12,8 @@ void main() async {
 
   group('selection_menu_widget.dart', () {
     for (var i = 0; i < defaultSelectionMenuItems.length; i += 1) {
-      testWidgets('Selects number.$i item in selection menu with enter', (
-          tester) async {
+      testWidgets('Selects number.$i item in selection menu with enter',
+          (tester) async {
         final editor = await _prepare(tester);
         for (var j = 0; j < i; j++) {
           await editor.pressLogicKey(LogicalKeyboardKey.arrowDown);
@@ -30,8 +29,8 @@ void main() async {
         }
       });
 
-      testWidgets('Selects number.$i item in selection menu with click', (
-          tester) async {
+      testWidgets('Selects number.$i item in selection menu with click',
+          (tester) async {
         final editor = await _prepare(tester);
 
         await tester.tap(find.byType(SelectionMenuItemWidget).at(i));
@@ -59,7 +58,7 @@ void main() async {
       await editor.pressLogicKey(LogicalKeyboardKey.backspace);
       expect(
         find.byType(SelectionMenuItemWidget, skipOffstage: false),
-        findsNWidgets(4),
+        findsNWidgets(5),
       );
       await editor.pressLogicKey(LogicalKeyboardKey.keyE);
       expect(
@@ -148,7 +147,8 @@ Future<void> _testDefaultSelectionMenuItems(
     int index, EditorWidgetTester editor) async {
   expect(editor.documentLength, 4);
   expect(editor.documentSelection, Selection.single(path: [2], startOffset: 0));
-  expect((editor.nodeAtPath([1]) as TextNode).toRawString(), 'Welcome to Appflowy 😁');
+  expect((editor.nodeAtPath([1]) as TextNode).toRawString(),
+      'Welcome to Appflowy 😁');
   final node = editor.nodeAtPath([2]);
   final item = defaultSelectionMenuItems[index];
   final itemName = item.name();