diff --git a/example/pubspec.lock b/example/pubspec.lock index 585d42eae..9ec3a1dc4 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.12.0" + version: "2.13.0" boolean_selector: dependency: transitive description: @@ -93,10 +93,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.3.3" ffi: dependency: transitive description: @@ -365,18 +365,18 @@ packages: dependency: transitive description: name: intl - sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" url: "https://pub.dev" source: hosted - version: "0.19.0" + version: "0.20.2" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" url: "https://pub.dev" source: hosted - version: "10.0.8" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: @@ -738,10 +738,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "14.3.1" + version: "15.0.0" web: dependency: transitive description: @@ -754,10 +754,10 @@ packages: dependency: transitive description: name: webdriver - sha256: "3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8" + sha256: "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade" url: "https://pub.dev" source: hosted - version: "3.0.4" + version: "3.1.0" win32: dependency: transitive description: diff --git a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart index 814f79fd1..9bb40fe90 100644 --- a/flutter_quill_extensions/lib/src/editor/image/image_menu.dart +++ b/flutter_quill_extensions/lib/src/editor/image/image_menu.dart @@ -184,8 +184,7 @@ class ImageOptionsMenu extends StatelessWidget { content: Text(localizations.successImageSavedGallery), action: SnackBarAction( label: localizations.openGallery, - onPressed: () => - QuillNativeProvider.instance.openGalleryApp(), + onPressed: QuillNativeProvider.instance.openGalleryApp, ), )); return; diff --git a/lib/src/editor/editor.dart b/lib/src/editor/editor.dart index 117819392..f1b23db34 100644 --- a/lib/src/editor/editor.dart +++ b/lib/src/editor/editor.dart @@ -1326,10 +1326,10 @@ class RenderEditor extends RenderEditableContainerBox Offset calculateBoundedFloatingCursorOffset( Offset rawCursorOffset, double preferredLineHeight) { var deltaPosition = Offset.zero; - final topBound = _kFloatingCursorAddedMargin.top; + const topBound = 4.0; // _kFloatingCursorAddedMargin.top is 4.0 final bottomBound = size.height - preferredLineHeight + _kFloatingCursorAddedMargin.bottom; - final leftBound = _kFloatingCursorAddedMargin.left; + const leftBound = 4.0; // _kFloatingCursorAddedMargin.left is 4.0 final rightBound = size.width - _kFloatingCursorAddedMargin.right; if (_previousOffset != null) { diff --git a/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions.dart b/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions.dart index 58ef34b51..c0b9b14b3 100644 --- a/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions.dart +++ b/lib/src/editor/raw_editor/keyboard_shortcuts/editor_keyboard_shortcut_actions.dart @@ -18,7 +18,7 @@ class QuillEditorDeleteTextAction final QuillEditorTextBoundary Function(T intent) getTextBoundariesForIntent; TextRange _expandNonCollapsedRange(TextEditingValue value) { - final TextRange selection = value.selection; + final selection = value.selection; assert(selection.isValid); assert(!selection.isCollapsed); final atomicBoundary = QuillEditorCharacterBoundary(value); diff --git a/lib/src/l10n/generated/quill_localizations.dart b/lib/src/l10n/generated/quill_localizations.dart index 8fef06a0d..93e9ce6bc 100644 --- a/lib/src/l10n/generated/quill_localizations.dart +++ b/lib/src/l10n/generated/quill_localizations.dart @@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:intl/intl.dart' as intl; +import 'quill_localizations_am.dart'; import 'quill_localizations_ar.dart'; import 'quill_localizations_bg.dart'; import 'quill_localizations_bn.dart'; @@ -138,6 +139,7 @@ abstract class FlutterQuillLocalizations { /// A list of this localizations delegate's supported locales. static const List supportedLocales = [ + Locale('am'), Locale('ar'), Locale('bg'), Locale('bn'), @@ -840,6 +842,7 @@ class _FlutterQuillLocalizationsDelegate @override bool isSupported(Locale locale) => [ + 'am', 'ar', 'bg', 'bn', @@ -940,6 +943,8 @@ FlutterQuillLocalizations lookupFlutterQuillLocalizations(Locale locale) { // Lookup logic when only language code is specified. switch (locale.languageCode) { + case 'am': + return FlutterQuillLocalizationsAm(); case 'ar': return FlutterQuillLocalizationsAr(); case 'bg': diff --git a/lib/src/l10n/generated/quill_localizations_am.dart b/lib/src/l10n/generated/quill_localizations_am.dart new file mode 100644 index 000000000..d263c1993 --- /dev/null +++ b/lib/src/l10n/generated/quill_localizations_am.dart @@ -0,0 +1,334 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'quill_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for Amharic (`am`). +class FlutterQuillLocalizationsAm extends FlutterQuillLocalizations { + FlutterQuillLocalizationsAm([String locale = 'am']) : super(locale); + + @override + String get pasteLink => 'ሊንክ ይለጥፉ'; + + @override + String get ok => 'እሺ'; + + @override + String get selectColor => 'ቀለም ይምረጡ'; + + @override + String get gallery => 'ጋለሪ'; + + @override + String get link => 'ሊንክ'; + + @override + String get open => 'ክፈት'; + + @override + String get copy => 'ቅዳ'; + + @override + String get remove => 'አስወግድ'; + + @override + String get save => 'አስቀምጥ'; + + @override + String get zoom => 'አጉላ'; + + @override + String get saved => 'ተቀምጧል'; + + @override + String get text => 'ጽሑፍ'; + + @override + String get resize => 'መጠን አስተካክል'; + + @override + String get width => 'ስፋት'; + + @override + String get height => 'ቁመት'; + + @override + String get size => 'መጠን'; + + @override + String get small => 'ትንሽ'; + + @override + String get large => 'ትልቅ'; + + @override + String get huge => 'ግዙፍ'; + + @override + String get clear => 'አጥፋ'; + + @override + String get font => 'ፊደል'; + + @override + String get search => 'ፈልግ'; + + @override + String get camera => 'ካሜራ'; + + @override + String get video => 'ቪዲዮ'; + + @override + String get undo => 'መልስ'; + + @override + String get redo => 'ድገም'; + + @override + String get fontFamily => 'የፊደል ቤተሰብ'; + + @override + String get fontSize => 'የፊደል መጠን'; + + @override + String get bold => 'ደማቅ'; + + @override + String get subscript => 'ታች ጽሑፍ'; + + @override + String get superscript => 'ላይ ጽሑፍ'; + + @override + String get italic => 'ዘንበል ያለ'; + + @override + String get underline => 'ከስር መስመር'; + + @override + String get strikeThrough => 'የተሰረዘ'; + + @override + String get inlineCode => 'የውስጥ ኮድ'; + + @override + String get fontColor => 'የፊደል ቀለም'; + + @override + String get backgroundColor => 'የጀርባ ቀለም'; + + @override + String get clearFormat => 'ቅርጸት አጥፋ'; + + @override + String get alignLeft => 'ወደ ግራ አስተካክል'; + + @override + String get alignCenter => 'ወደ መሃል አስተካክል'; + + @override + String get alignRight => 'ወደ ቀኝ አስተካክል'; + + @override + String get alignJustify => 'አሰልፍ'; + + @override + String get justifyWinWidth => 'የመስኮት ስፋት አሰልፍ'; + + @override + String get textDirection => 'የጽሑፍ አቅጣጫ'; + + @override + String get headerStyle => 'የራስጌ ስልት'; + + @override + String get normal => 'መደበኛ'; + + @override + String get heading1 => 'ራስጌ 1'; + + @override + String get heading2 => 'ራስጌ 2'; + + @override + String get heading3 => 'ራስጌ 3'; + + @override + String get heading4 => 'ራስጌ 4'; + + @override + String get heading5 => 'ራስጌ 5'; + + @override + String get heading6 => 'ራስጌ 6'; + + @override + String get numberedList => 'ቁጥር ያለው ዝርዝር'; + + @override + String get bulletList => 'ነጥብ ያለው ዝርዝር'; + + @override + String get checkedList => 'ምልክት የተደረገበት ዝርዝር'; + + @override + String get codeBlock => 'የኮድ ክፍል'; + + @override + String get quote => 'ጥቅስ'; + + @override + String get increaseIndent => 'ገብ ጨምር'; + + @override + String get decreaseIndent => 'ገብ ቀንስ'; + + @override + String get insertURL => 'URL አስገባ'; + + @override + String get visitLink => 'ሊንክ ጎብኝ'; + + @override + String get enterLink => 'ሊንክ አስገባ'; + + @override + String get enterMedia => 'ሚዲያ አስገባ'; + + @override + String get edit => 'አስተካክል'; + + @override + String get apply => 'ተግብር'; + + @override + String get hex => 'ሄክስ'; + + @override + String get material => 'ማቴሪያል'; + + @override + String get color => 'ቀለም'; + + @override + String get lineheight => 'የመስመር ቁመት'; + + @override + String get findText => 'ጽሑፍ ፈልግ'; + + @override + String get moveToPreviousOccurrence => 'ወደ ቀዳሚው ክስተት ሂድ'; + + @override + String get moveToNextOccurrence => 'ወደ ቀጣዩ ክስተት ሂድ'; + + @override + String get savedUsingTheNetwork => 'ኔትወርኩን በመጠቀም ተቀምጧል'; + + @override + String get savedUsingLocalStorage => 'የአካባቢ ማከማቻን በመጠቀም ተቀምጧል'; + + @override + String theImageHasBeenSavedAt(String imagePath) { + return 'ምስሉ የተቀመጠው በ: $imagePath'; + } + + @override + String get errorWhileSavingImage => 'ምስሉን በማስቀመጥ ላይ ስህተት ተፈጥሯል'; + + @override + String get pleaseEnterTextForYourLink => + 'እባክዎ ለሊንክዎ ጽሑፍ ያስገቡ (ለምሳሌ \'ተጨማሪ ይወቁ\')'; + + @override + String get pleaseEnterTheLinkURL => + 'እባክዎ የሊንኩን URL ያስገቡ (ለምሳሌ \'https://example.com\')'; + + @override + String get pleaseEnterAValidImageURL => 'እባክዎ ትክክለኛ የምስል URL ያስገቡ'; + + @override + String get pleaseEnterAValidVideoURL => 'እባክዎ ትክክለኛ የቪዲዮ URL ያስገቡ'; + + @override + String get photo => 'ፎቶ'; + + @override + String get image => 'ምስል'; + + @override + String get caseSensitivityAndWholeWordSearch => 'የ регистр እና ሙሉ ቃል ፍለጋ'; + + @override + String get caseSensitive => 'ለ регистр ትኩረት የሚሰጥ'; + + @override + String get wholeWord => 'ሙሉ ቃል'; + + @override + String get insertImage => 'ምስል አስገባ'; + + @override + String get pickAPhotoFromYourGallery => 'ከጋለሪዎ ፎቶ ይምረጡ'; + + @override + String get takeAPhotoUsingYourCamera => 'ካሜራዎን ተጠቅመው ፎቶ አንሱ'; + + @override + String get pasteAPhotoUsingALink => 'ሊንክ ተጠቅመው ፎቶ ይለጥፉ'; + + @override + String get pickAVideoFromYourGallery => 'ከጋለሪዎ ቪዲዮ ይምረጡ'; + + @override + String get recordAVideoUsingYourCamera => 'ካሜራዎን ተጠቅመው ቪዲዮ ይቅረጹ'; + + @override + String get pasteAVideoUsingALink => 'ሊንክ ተጠቅመው ቪዲዮ ይለጥፉ'; + + @override + String get close => 'ዝጋ'; + + @override + String get searchSettings => 'የፍለጋ ቅንብሮች'; + + @override + String get cut => 'ቁረጥ'; + + @override + String get paste => 'ለጥፍ'; + + @override + String get insertTable => 'ሠንጠረዥ አስገባ'; + + @override + String get insertVideo => 'ቪዲዮ አስገባ'; + + @override + String get errorUnexpectedSavingImage => + 'ምስሉን በማስቀመጥ ላይ ያልተጠበቀ ስህተት ተፈጥሯል። እባክዎ እንደገና ይሞክሩ።'; + + @override + String get successImageSavedGallery => 'ምስሉ በጋለሪዎ ውስጥ ተቀምጧል።'; + + @override + String get successImageSaved => 'ምስሉ በተሳካ ሁኔታ ተቀምጧል።'; + + @override + String get successImageDownloaded => 'ምስሉ በተሳካ ሁኔታ ወርዷል።'; + + @override + String get openGallery => 'ጋለሪ ክፈት'; + + @override + String get openFileLocation => 'የፋይል ቦታ ክፈት'; + + @override + String get openFile => 'ፋይል ክፈት'; + + @override + String get saveImagePermissionDenied => + 'የሚያስፈልገው ፈቃድ ስለሌለ ምስሉን ማስቀመጥ አልተቻለም።'; +} diff --git a/lib/src/l10n/quill_am.arb b/lib/src/l10n/quill_am.arb new file mode 100644 index 000000000..1392df57d --- /dev/null +++ b/lib/src/l10n/quill_am.arb @@ -0,0 +1,145 @@ +{ + "@@locale": "am", + "pasteLink": "ሊንክ ይለጥፉ", + "ok": "እሺ", + "selectColor": "ቀለም ይምረጡ", + "gallery": "ጋለሪ", + "link": "ሊንክ", + "open": "ክፈት", + "copy": "ቅዳ", + "remove": "አስወግድ", + "save": "አስቀምጥ", + "zoom": "አጉላ", + "saved": "ተቀምጧል", + "text": "ጽሑፍ", + "resize": "መጠን አስተካክል", + "width": "ስፋት", + "height": "ቁመት", + "size": "መጠን", + "small": "ትንሽ", + "large": "ትልቅ", + "huge": "ግዙፍ", + "clear": "አጥፋ", + "font": "ፊደል", + "search": "ፈልግ", + "camera": "ካሜራ", + "video": "ቪዲዮ", + "undo": "መልስ", + "redo": "ድገም", + "fontFamily": "የፊደል ቤተሰብ", + "fontSize": "የፊደል መጠን", + "bold": "ደማቅ", + "subscript": "ታች ጽሑፍ", + "superscript": "ላይ ጽሑፍ", + "italic": "ዘንበል ያለ", + "underline": "ከስር መስመር", + "strikeThrough": "የተሰረዘ", + "inlineCode": "የውስጥ ኮድ", + "fontColor": "የፊደል ቀለም", + "backgroundColor": "የጀርባ ቀለም", + "clearFormat": "ቅርጸት አጥፋ", + "alignLeft": "ወደ ግራ አስተካክል", + "alignCenter": "ወደ መሃል አስተካክል", + "alignRight": "ወደ ቀኝ አስተካክል", + "alignJustify": "አሰልፍ", + "@alignJustify": { + "description": "Justify the text over the full window width" + }, + "justifyWinWidth": "የመስኮት ስፋት አሰልፍ", + "textDirection": "የጽሑፍ አቅጣጫ", + "headerStyle": "የራስጌ ስልት", + "normal": "መደበኛ", + "heading1": "ራስጌ 1", + "heading2": "ራስጌ 2", + "heading3": "ራስጌ 3", + "heading4": "ራስጌ 4", + "heading5": "ራስጌ 5", + "heading6": "ራስጌ 6", + "numberedList": "ቁጥር ያለው ዝርዝር", + "bulletList": "ነጥብ ያለው ዝርዝር", + "checkedList": "ምልክት የተደረገበት ዝርዝር", + "codeBlock": "የኮድ ክፍል", + "quote": "ጥቅስ", + "increaseIndent": "ገብ ጨምር", + "decreaseIndent": "ገብ ቀንስ", + "insertURL": "URL አስገባ", + "visitLink": "ሊንክ ጎብኝ", + "enterLink": "ሊንክ አስገባ", + "enterMedia": "ሚዲያ አስገባ", + "edit": "አስተካክል", + "apply": "ተግብር", + "hex": "ሄክስ", + "material": "ማቴሪያል", + "color": "ቀለም", + "lineheight": "የመስመር ቁመት", + "findText": "ጽሑፍ ፈልግ", + "moveToPreviousOccurrence": "ወደ ቀዳሚው ክስተት ሂድ", + "moveToNextOccurrence": "ወደ ቀጣዩ ክስተት ሂድ", + "savedUsingTheNetwork": "ኔትወርኩን በመጠቀም ተቀምጧል", + "savedUsingLocalStorage": "የአካባቢ ማከማቻን በመጠቀም ተቀምጧል", + "theImageHasBeenSavedAt": "ምስሉ የተቀመጠው በ: {imagePath}", + "@theImageHasBeenSavedAt": { + "description": "A message with a single parameter", + "placeholders": { + "imagePath": { + "type": "String", + "example": "path/to/location" + } + } + }, + "errorWhileSavingImage": "ምስሉን በማስቀመጥ ላይ ስህተት ተፈጥሯል", + "pleaseEnterTextForYourLink": "እባክዎ ለሊንክዎ ጽሑፍ ያስገቡ (ለምሳሌ 'ተጨማሪ ይወቁ')", + "pleaseEnterTheLinkURL": "እባክዎ የሊንኩን URL ያስገቡ (ለምሳሌ 'https://example.com')", + "pleaseEnterAValidImageURL": "እባክዎ ትክክለኛ የምስል URL ያስገቡ", + "pleaseEnterAValidVideoURL": "እባክዎ ትክክለኛ የቪዲዮ URL ያስገቡ", + "photo": "ፎቶ", + "image": "ምስል", + "caseSensitivityAndWholeWordSearch": "የ регистр እና ሙሉ ቃል ፍለጋ", + "caseSensitive": "ለ регистр ትኩረት የሚሰጥ", + "wholeWord": "ሙሉ ቃል", + "insertImage": "ምስል አስገባ", + "pickAPhotoFromYourGallery": "ከጋለሪዎ ፎቶ ይምረጡ", + "takeAPhotoUsingYourCamera": "ካሜራዎን ተጠቅመው ፎቶ አንሱ", + "pasteAPhotoUsingALink": "ሊንክ ተጠቅመው ፎቶ ይለጥፉ", + "pickAVideoFromYourGallery": "ከጋለሪዎ ቪዲዮ ይምረጡ", + "recordAVideoUsingYourCamera": "ካሜራዎን ተጠቅመው ቪዲዮ ይቅረጹ", + "pasteAVideoUsingALink": "ሊንክ ተጠቅመው ቪዲዮ ይለጥፉ", + "close": "ዝጋ", + "searchSettings": "የፍለጋ ቅንብሮች", + "cut": "ቁረጥ", + "paste": "ለጥፍ", + "insertTable": "ሠንጠረዥ አስገባ", + "insertVideo": "ቪዲዮ አስገባ", + "errorUnexpectedSavingImage": "ምስሉን በማስቀመጥ ላይ ያልተጠበቀ ስህተት ተፈጥሯል። እባክዎ እንደገና ይሞክሩ።", + "@errorUnexpectedSavingImage": { + "description": "A generic error message shown when an image cannot be saved due to an unknown issue" + }, + "successImageSavedGallery": "ምስሉ በጋለሪዎ ውስጥ ተቀምጧል።", + "@successImageSavedGallery": { + "description": "Message shown when an image is successfully saved to the system gallery" + }, + "successImageSaved": "ምስሉ በተሳካ ሁኔታ ተቀምጧል።", + "@successImageSaved": { + "description": "Message shown on desktop when an image is successfully saved. The user is prompted to open the file location" + }, + "successImageDownloaded": "ምስሉ በተሳካ ሁኔታ ወርዷል።", + "@successImageDownloaded": { + "description": "Message shown on web when an image is successfully downloaded" + }, + "openGallery": "ጋለሪ ክፈት", + "@openGallery": { + "description": "Label for the button that opens the system gallery" + }, + "openFileLocation": "የፋይል ቦታ ክፈት", + "@openFileLocation": { + "description": "Label for the button that opens the file explorer to the file's location" + }, + "openFile": "ፋይል ክፈት", + "@openFile": { + "description": "Label for the button that opens the file" + }, + "saveImagePermissionDenied": "የሚያስፈልገው ፈቃድ ስለሌለ ምስሉን ማስቀመጥ አልተቻለም።", + "@saveImagePermissionDenied": { + "description": "Message shown when the app is unable to save an image because a required permission was denied or skipped" + } +} \ No newline at end of file diff --git a/lib/src/rules/format.dart b/lib/src/rules/format.dart index 177da37ca..4b9223df8 100644 --- a/lib/src/rules/format.dart +++ b/lib/src/rules/format.dart @@ -133,13 +133,14 @@ class FormatLinkAtCaretPositionRule extends FormatRule { final delta = Delta(); final itr = DeltaIterator(document.toDelta()); final before = itr.skip(index), after = itr.next(); - int? beg = index, retain = 0; + int beg = index; + int retain = 0; if (before != null && before.hasAttribute(attribute.key)) { beg -= before.length!; - retain = before.length; + retain = before.length!; } if (after.hasAttribute(attribute.key)) { - if (retain != null) retain += after.length!; + retain += after.length!; } if (retain == 0) { return null; @@ -147,7 +148,7 @@ class FormatLinkAtCaretPositionRule extends FormatRule { delta ..retain(beg) - ..retain(retain!, attribute.toJson()); + ..retain(retain, attribute.toJson()); return delta; } } diff --git a/test/toolbar/buttons/color/color_dialog_test.dart b/test/toolbar/buttons/color/color_dialog_test.dart index 95109c7da..3d0ce057d 100644 --- a/test/toolbar/buttons/color/color_dialog_test.dart +++ b/test/toolbar/buttons/color/color_dialog_test.dart @@ -12,7 +12,7 @@ void main() { 'hexController is initialized correctly after selectedColor when isToggledColor is true', (tester) async { for (final isBackground in {true, false}) { - const Color exampleColor = Colors.red; + const exampleColor = Colors.red; final colorHex = colorToHex(exampleColor); final selectionStyle = const Style().put(