From a1a7321f4ca01039d54a261ab372bebada85f040 Mon Sep 17 00:00:00 2001 From: Richard Shiue <71320345+richardshiue@users.noreply.github.com> Date: Wed, 10 Apr 2024 15:28:26 +0800 Subject: [PATCH] fix: regression selected options not scrolling automatically (#5058) --- .../select_option_cell_editor.dart | 8 ++++++- .../cell_editor/select_option_text_field.dart | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart index 7f76cb26b3..25f85232ed 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_cell_editor.dart @@ -33,7 +33,8 @@ class SelectOptionCellEditor extends StatefulWidget { } class _SelectOptionCellEditorState extends State { - final TextEditingController textEditingController = TextEditingController(); + final textEditingController = TextEditingController(); + final scrollController = ScrollController(); final popoverMutex = PopoverMutex(); late final bloc = SelectOptionCellEditorBloc( cellController: widget.cellController, @@ -86,6 +87,7 @@ class _SelectOptionCellEditorState extends State { void dispose() { popoverMutex.dispose(); textEditingController.dispose(); + scrollController.dispose(); bloc.close(); focusNode.dispose(); super.dispose(); @@ -101,6 +103,7 @@ class _SelectOptionCellEditorState extends State { children: [ _TextField( textEditingController: textEditingController, + scrollController: scrollController, focusNode: focusNode, popoverMutex: popoverMutex, ), @@ -209,11 +212,13 @@ class _OptionList extends StatelessWidget { class _TextField extends StatelessWidget { const _TextField({ required this.textEditingController, + required this.scrollController, required this.focusNode, required this.popoverMutex, }); final TextEditingController textEditingController; + final ScrollController scrollController; final FocusNode focusNode; final PopoverMutex popoverMutex; @@ -237,6 +242,7 @@ class _TextField extends StatelessWidget { selectedOptionMap: optionMap, distanceToText: _editorPanelWidth * 0.7, textController: textEditingController, + scrollController: scrollController, textSeparators: const [','], onClick: () => popoverMutex.close(), newText: (text) { diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart index d6ad3ffebe..f16500f601 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/cell_editor/select_option_text_field.dart @@ -20,6 +20,7 @@ class SelectOptionTextField extends StatefulWidget { required this.newText, required this.onPaste, required this.onRemove, + this.scrollController, this.onClick, }); @@ -28,6 +29,7 @@ class SelectOptionTextField extends StatefulWidget { final double distanceToText; final List textSeparators; final TextEditingController textController; + final ScrollController? scrollController; final FocusNode focusNode; final Function() onSubmitted; @@ -46,10 +48,21 @@ class _SelectOptionTextFieldState extends State { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { widget.focusNode.requestFocus(); + _scrollToEnd(); }); widget.textController.addListener(_onChanged); } + @override + void didUpdateWidget(covariant oldWidget) { + if (oldWidget.selectedOptionMap.length < widget.selectedOptionMap.length) { + WidgetsBinding.instance.addPostFrameCallback((_) { + _scrollToEnd(); + }); + } + super.didUpdateWidget(oldWidget); + } + @override void dispose() { widget.textController.removeListener(_onChanged); @@ -80,6 +93,16 @@ class _SelectOptionTextFieldState extends State { ); } + void _scrollToEnd() { + if (widget.scrollController?.hasClients ?? false) { + widget.scrollController?.animateTo( + widget.scrollController!.position.maxScrollExtent, + duration: const Duration(milliseconds: 150), + curve: Curves.easeOut, + ); + } + } + void _onChanged() { if (!widget.textController.value.composing.isCollapsed) { return; @@ -132,6 +155,7 @@ class _SelectOptionTextFieldState extends State { ), child: SingleChildScrollView( scrollDirection: Axis.horizontal, + controller: widget.scrollController, child: Wrap(spacing: 4, children: children), ), ),