mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
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
This commit is contained in:
@ -264,10 +264,10 @@ class _MentionDateBlockState extends State<MentionDateBlock> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (timeFormat == TimeFormatPB.TwelveHour) {
|
if (timeFormat == TimeFormatPB.TwelveHour) {
|
||||||
return twelveHourFormat.parse(timeStr);
|
return twelveHourFormat.parseStrict(timeStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return twentyFourHourFormat.parse(timeStr);
|
return twentyFourHourFormat.parseStrict(timeStr);
|
||||||
} on FormatException {
|
} on FormatException {
|
||||||
Log.error("failed to parse time string ($timeStr)");
|
Log.error("failed to parse time string ($timeStr)");
|
||||||
return DateTime.now();
|
return DateTime.now();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pbenum.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database2/date_entities.pbenum.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
@ -96,8 +97,50 @@ class _TimeTextFieldState extends State<TimeTextField> {
|
|||||||
? _maxLengthTwelveHour
|
? _maxLengthTwelveHour
|
||||||
: _maxLengthTwentyFourHour,
|
: _maxLengthTwentyFourHour,
|
||||||
showCounter: false,
|
showCounter: false,
|
||||||
|
inputFormatters: [TimeInputFormatter(widget.timeFormat)],
|
||||||
onSubmitted: widget.onSubmitted,
|
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),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -31,6 +31,7 @@ class FlowyTextField extends StatefulWidget {
|
|||||||
final InputDecoration? decoration;
|
final InputDecoration? decoration;
|
||||||
final TextAlignVertical? textAlignVertical;
|
final TextAlignVertical? textAlignVertical;
|
||||||
final TextInputAction? textInputAction;
|
final TextInputAction? textInputAction;
|
||||||
|
final List<TextInputFormatter>? inputFormatters;
|
||||||
|
|
||||||
const FlowyTextField({
|
const FlowyTextField({
|
||||||
super.key,
|
super.key,
|
||||||
@ -60,6 +61,7 @@ class FlowyTextField extends StatefulWidget {
|
|||||||
this.decoration,
|
this.decoration,
|
||||||
this.textAlignVertical,
|
this.textAlignVertical,
|
||||||
this.textInputAction,
|
this.textInputAction,
|
||||||
|
this.inputFormatters,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -153,6 +155,7 @@ class FlowyTextFieldState extends State<FlowyTextField> {
|
|||||||
style: widget.textStyle ?? Theme.of(context).textTheme.bodySmall,
|
style: widget.textStyle ?? Theme.of(context).textTheme.bodySmall,
|
||||||
textAlignVertical: widget.textAlignVertical ?? TextAlignVertical.center,
|
textAlignVertical: widget.textAlignVertical ?? TextAlignVertical.center,
|
||||||
keyboardType: TextInputType.multiline,
|
keyboardType: TextInputType.multiline,
|
||||||
|
inputFormatters: widget.inputFormatters,
|
||||||
decoration: widget.decoration ??
|
decoration: widget.decoration ??
|
||||||
InputDecoration(
|
InputDecoration(
|
||||||
constraints: widget.hintTextConstraints ??
|
constraints: widget.hintTextConstraints ??
|
||||||
|
Reference in New Issue
Block a user