From 3a4247c3049b26f2f658ffc7c02a4a80806494ef Mon Sep 17 00:00:00 2001 From: Ansah Mohammad Date: Mon, 19 Feb 2024 19:00:28 +0530 Subject: [PATCH 1/3] feat: convert time format from HHmm to HH:mm in time field (#4641) * feat: add a HHmm to HH:mm function * fix: Replaced string.parse() with string.parseStrict() to address time input bug * feat: add TextFormatter for formatting the time input --- .../mention/mention_date_block.dart | 4 +- .../date_picker/widgets/time_text_field.dart | 43 +++++++++++++++++++ .../lib/style_widget/text_field.dart | 3 ++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mention/mention_date_block.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mention/mention_date_block.dart index 001135f447d2f..b9c0a8c7d392a 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mention/mention_date_block.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mention/mention_date_block.dart @@ -264,10 +264,10 @@ class _MentionDateBlockState extends State { try { if (timeFormat == TimeFormatPB.TwelveHour) { - return twelveHourFormat.parse(timeStr); + return twelveHourFormat.parseStrict(timeStr); } - return twentyFourHourFormat.parse(timeStr); + return twentyFourHourFormat.parseStrict(timeStr); } on FormatException { Log.error("failed to parse time string ($timeStr)"); return DateTime.now(); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/time_text_field.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/time_text_field.dart index d0c5d74b66ea2..46c2e08a31099 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/time_text_field.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/date_picker/widgets/time_text_field.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pbenum.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; @@ -96,8 +97,50 @@ class _TimeTextFieldState extends State { ? _maxLengthTwelveHour : _maxLengthTwentyFourHour, showCounter: false, + inputFormatters: [TimeInputFormatter(widget.timeFormat)], onSubmitted: widget.onSubmitted, ), ); } } + +class TimeInputFormatter extends TextInputFormatter { + TimeInputFormatter(this.timeFormat); + + final TimeFormatPB timeFormat; + static const int colonPosition = 2; + static const int spacePosition = 5; + + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, + TextEditingValue newValue, + ) { + final oldText = oldValue.text; + final newText = newValue.text; + + // If the user has typed enough for a time separator(:) and hasn't already typed + if (newText.length == colonPosition + 1 && + oldText.length == colonPosition && + !newText.contains(":")) { + return _formatText(newText, colonPosition, ':'); + } + + // If the user has typed enough for an AM/PM separator and hasn't already typed + if (timeFormat == TimeFormatPB.TwelveHour && + newText.length == spacePosition + 1 && + oldText.length == spacePosition && + newText[newText.length - 1] != ' ') { + return _formatText(newText, spacePosition, ' '); + } + + return newValue; + } + + TextEditingValue _formatText(String text, int index, String separator) { + return TextEditingValue( + text: '${text.substring(0, index)}$separator${text.substring(index)}', + selection: TextSelection.collapsed(offset: text.length + 1), + ); + } +} diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart index ffedd06bd14ca..994e42720203b 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text_field.dart @@ -31,6 +31,7 @@ class FlowyTextField extends StatefulWidget { final InputDecoration? decoration; final TextAlignVertical? textAlignVertical; final TextInputAction? textInputAction; + final List? inputFormatters; const FlowyTextField({ super.key, @@ -60,6 +61,7 @@ class FlowyTextField extends StatefulWidget { this.decoration, this.textAlignVertical, this.textInputAction, + this.inputFormatters, }); @override @@ -153,6 +155,7 @@ class FlowyTextFieldState extends State { style: widget.textStyle ?? Theme.of(context).textTheme.bodySmall, textAlignVertical: widget.textAlignVertical ?? TextAlignVertical.center, keyboardType: TextInputType.multiline, + inputFormatters: widget.inputFormatters, decoration: widget.decoration ?? InputDecoration( constraints: widget.hintTextConstraints ?? From a3a5709b70b78013120f50d33fa062c0063e90d1 Mon Sep 17 00:00:00 2001 From: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:32:01 +0100 Subject: [PATCH 2/3] fix: dispose of previous applaunch tasks (#4631) --- frontend/appflowy_flutter/lib/startup/startup.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/appflowy_flutter/lib/startup/startup.dart b/frontend/appflowy_flutter/lib/startup/startup.dart index e7422ded8f24d..4b5c97346812e 100644 --- a/frontend/appflowy_flutter/lib/startup/startup.dart +++ b/frontend/appflowy_flutter/lib/startup/startup.dart @@ -76,6 +76,11 @@ class FlowyRunner { IntegrationTestHelper.rustEnvsBuilder = rustEnvsBuilder; } + // Clear and dispose tasks from previous AppLaunch + if (getIt.isRegistered(instance: AppLauncher)) { + await getIt().dispose(); + } + // Clear all the states in case of rebuilding. await getIt.reset(); From 42cb032bca6ebc4125e5b1356fd1805eabfbae3b Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Mon, 19 Feb 2024 20:48:06 +0700 Subject: [PATCH 3/3] fix: flutter analyze (#4680) --- .../settings/widgets/emoji_picker/emoji_shortcut_event.dart | 2 +- .../appflowy_flutter/packages/flowy_infra/lib/language.dart | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/emoji_picker/emoji_shortcut_event.dart b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/emoji_picker/emoji_shortcut_event.dart index e55d0325f477c..078cf64963f47 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/emoji_picker/emoji_shortcut_event.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/settings/widgets/emoji_picker/emoji_shortcut_event.dart @@ -1,6 +1,6 @@ +import 'package:appflowy/workspace/presentation/settings/widgets/emoji_picker/emoji_picker.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:flutter/material.dart'; -import 'package:appflowy/workspace/presentation/settings/widgets/emoji_picker/emoji_picker.dart'; final CommandShortcutEvent emojiShortcutEvent = CommandShortcutEvent( key: 'Ctrl + Alt + E to show emoji picker', diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart index fc3c61515002e..2d21a67dc8a84 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/language.dart @@ -26,6 +26,8 @@ String languageFromLocale(Locale locale) { switch (locale.countryCode) { case "KU": return "کوردی"; + default: + return locale.languageCode; } case "de": return "Deutsch";