mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: kanban UX bugs (#5227)
* chore: improve title editing behavior * chore: fix editable text field * chore: fix autoscroll
This commit is contained in:
@ -83,7 +83,9 @@ class _TextCellState extends State<TextCardCell> {
|
||||
|
||||
void _bindEditableNotifier() {
|
||||
widget.editableNotifier?.isCellEditing.addListener(() {
|
||||
if (!mounted) return;
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
final isEditing = widget.editableNotifier?.isCellEditing.value ?? false;
|
||||
if (isEditing) {
|
||||
@ -106,15 +108,14 @@ class _TextCellState extends State<TextCardCell> {
|
||||
return BlocProvider.value(
|
||||
value: cellBloc,
|
||||
child: BlocConsumer<TextCellBloc, TextCellState>(
|
||||
listenWhen: (previous, current) =>
|
||||
previous.content != current.content && !current.enableEdit,
|
||||
listener: (context, state) {
|
||||
if (_textEditingController.text != state.content) {
|
||||
_textEditingController.text = state.content;
|
||||
}
|
||||
_textEditingController.text = state.content;
|
||||
},
|
||||
buildWhen: (previous, current) {
|
||||
if (previous.content != current.content &&
|
||||
_textEditingController.text == current.content &&
|
||||
current.enableEdit) {
|
||||
_textEditingController.text == current.content) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -129,10 +130,10 @@ class _TextCellState extends State<TextCardCell> {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final icon = _buildIcon(state, isTitle);
|
||||
final child = state.enableEdit || focusWhenInit
|
||||
? _buildTextField()
|
||||
: _buildText(state, isTitle);
|
||||
final icon = isTitle ? _buildIcon(state) : null;
|
||||
final child = isTitle
|
||||
? _buildTextField(state.enableEdit || focusWhenInit)
|
||||
: _buildText(state.content);
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
@ -156,10 +157,7 @@ class _TextCellState extends State<TextCardCell> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Widget? _buildIcon(TextCellState state, bool isTitle) {
|
||||
if (!isTitle) {
|
||||
return null;
|
||||
}
|
||||
Widget? _buildIcon(TextCellState state) {
|
||||
if (state.emoji.isNotEmpty) {
|
||||
return Text(
|
||||
state.emoji,
|
||||
@ -178,43 +176,52 @@ class _TextCellState extends State<TextCardCell> {
|
||||
return null;
|
||||
}
|
||||
|
||||
Widget _buildText(TextCellState state, bool isTitle) {
|
||||
final text = state.content.isEmpty
|
||||
? isTitle
|
||||
? LocaleKeys.grid_row_titlePlaceholder.tr()
|
||||
: LocaleKeys.grid_row_textPlaceholder.tr()
|
||||
: state.content;
|
||||
final color = state.content.isEmpty ? Theme.of(context).hintColor : null;
|
||||
final textStyle =
|
||||
isTitle ? widget.style.titleTextStyle : widget.style.textStyle;
|
||||
Widget _buildText(String content) {
|
||||
final text =
|
||||
content.isEmpty ? LocaleKeys.grid_row_textPlaceholder.tr() : content;
|
||||
final color = content.isEmpty ? Theme.of(context).hintColor : null;
|
||||
|
||||
return Padding(
|
||||
padding: widget.style.padding,
|
||||
child: Text(
|
||||
text,
|
||||
style: textStyle.copyWith(color: color),
|
||||
style: widget.style.textStyle.copyWith(color: color),
|
||||
maxLines: widget.style.maxLines,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTextField() {
|
||||
Widget _buildTextField(bool isEditing) {
|
||||
final padding =
|
||||
widget.style.padding.add(const EdgeInsets.symmetric(vertical: 4.0));
|
||||
return TextField(
|
||||
controller: _textEditingController,
|
||||
focusNode: focusNode,
|
||||
onChanged: (_) =>
|
||||
cellBloc.add(TextCellEvent.updateText(_textEditingController.text)),
|
||||
onEditingComplete: () => focusNode.unfocus(),
|
||||
maxLines: null,
|
||||
style: widget.style.titleTextStyle,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: padding,
|
||||
border: InputBorder.none,
|
||||
isDense: true,
|
||||
isCollapsed: true,
|
||||
hintText: LocaleKeys.grid_row_titlePlaceholder.tr(),
|
||||
return IgnorePointer(
|
||||
ignoring: !isEditing,
|
||||
child: TextField(
|
||||
controller: _textEditingController,
|
||||
focusNode: focusNode,
|
||||
onChanged: (_) {
|
||||
if (_textEditingController.value.composing.isCollapsed) {
|
||||
cellBloc.add(TextCellEvent.updateText(_textEditingController.text));
|
||||
}
|
||||
},
|
||||
onEditingComplete: () => focusNode.unfocus(),
|
||||
maxLines: isEditing ? null : 2,
|
||||
minLines: 1,
|
||||
textInputAction: TextInputAction.done,
|
||||
readOnly: !isEditing,
|
||||
enableInteractiveSelection: isEditing,
|
||||
style: widget.style.titleTextStyle,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: padding,
|
||||
border: InputBorder.none,
|
||||
enabledBorder: InputBorder.none,
|
||||
isDense: true,
|
||||
isCollapsed: true,
|
||||
hintText: LocaleKeys.grid_row_titlePlaceholder.tr(),
|
||||
hintStyle: widget.style.titleTextStyle.copyWith(
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ CardCellStyleMap desktopBoardCardCellStyleMap(BuildContext context) {
|
||||
FieldType.RichText: TextCardCellStyle(
|
||||
padding: padding,
|
||||
textStyle: textStyle,
|
||||
maxLines: null,
|
||||
maxLines: 2,
|
||||
titleTextStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
|
@ -180,8 +180,7 @@ class _DatabasePropertyCellState extends State<DatabasePropertyCell> {
|
||||
return;
|
||||
}
|
||||
|
||||
final newVisiblity =
|
||||
widget.fieldInfo.fieldSettings!.visibility.toggle();
|
||||
final newVisiblity = widget.fieldInfo.visibility!.toggle();
|
||||
context.read<DatabasePropertyBloc>().add(
|
||||
DatabasePropertyEvent.setFieldVisibility(
|
||||
widget.fieldInfo.id,
|
||||
|
Reference in New Issue
Block a user