fix: select option mouse-click event conflict (#4003)

This commit is contained in:
Richard Shiue 2023-11-24 23:13:52 +08:00 committed by GitHub
parent c475a5d960
commit 29a6eab1ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 84 additions and 91 deletions

View File

@ -1,6 +1,8 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/database_view/grid/application/filter/select_option_filter_list_bloc.dart';
import 'package:appflowy/plugins/database_view/grid/presentation/layout/sizes.dart';
import 'package:appflowy/plugins/database_view/grid/presentation/widgets/filter/filter_info.dart';
import 'package:appflowy/plugins/database_view/widgets/row/cells/select_option_cell/extension.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart';
import 'package:flowy_infra_ui/widget/spacing.dart';
@ -8,8 +10,6 @@ import 'package:appflowy_backend/protobuf/flowy-database2/field_entities.pbenum.
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../../../widgets/row/cells/select_option_cell/extension.dart';
import '../../filter_info.dart';
import 'select_option_loader.dart';
class SelectOptionFilterList extends StatelessWidget {
@ -86,8 +86,8 @@ class SelectOptionFilterCell extends StatefulWidget {
const SelectOptionFilterCell({
required this.option,
required this.isSelected,
Key? key,
}) : super(key: key);
super.key,
});
@override
State<SelectOptionFilterCell> createState() => _SelectOptionFilterCellState();
@ -100,15 +100,15 @@ class _SelectOptionFilterCellState extends State<SelectOptionFilterCell> {
height: GridSize.popoverItemHeight,
child: SelectOptionTagCell(
option: widget.option,
onSelected: (option) {
onSelected: () {
if (widget.isSelected) {
context
.read<SelectOptionFilterListBloc>()
.add(SelectOptionFilterListEvent.unselectOption(option));
.add(SelectOptionFilterListEvent.unselectOption(widget.option));
} else {
context
.read<SelectOptionFilterListBloc>()
.add(SelectOptionFilterListEvent.selectOption(option));
.add(SelectOptionFilterListEvent.selectOption(widget.option));
}
},
children: [

View File

@ -31,10 +31,10 @@ class MultiSelectTypeOptionWidget extends TypeOptionWidget {
final PopoverMutex? popoverMutex;
const MultiSelectTypeOptionWidget({
Key? key,
super.key,
required this.selectOptionAction,
this.popoverMutex,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@ -21,12 +21,12 @@ class SelectOptionTypeOptionWidget extends StatelessWidget {
final PopoverMutex? popoverMutex;
const SelectOptionTypeOptionWidget({
super.key,
required this.options,
required this.beginEdit,
required this.typeOptionAction,
this.popoverMutex,
Key? key,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@ -96,8 +96,7 @@ class _OptionList extends StatelessWidget {
},
builder: (context, state) {
final cells = state.options.map((option) {
return _makeOptionCell(
context: context,
return _OptionCell(
option: option,
popoverMutex: popoverMutex,
);
@ -116,17 +115,6 @@ class _OptionList extends StatelessWidget {
},
);
}
_OptionCell _makeOptionCell({
required BuildContext context,
required SelectOptionPB option,
PopoverMutex? popoverMutex,
}) {
return _OptionCell(
option: option,
popoverMutex: popoverMutex,
);
}
}
class _OptionCell extends StatefulWidget {
@ -154,13 +142,13 @@ class _OptionCellState extends State<_OptionCell> {
height: 28,
child: SelectOptionTagCell(
option: widget.option,
onSelected: (SelectOptionPB pb) {
_popoverController.show();
},
onSelected: () => _popoverController.show(),
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 6.0),
child: FlowySvg(
FlowyIconButton(
onPressed: () => _popoverController.show(),
iconPadding: const EdgeInsets.symmetric(horizontal: 6.0),
hoverColor: Colors.transparent,
icon: FlowySvg(
FlowySvgs.details_s,
color: Theme.of(context).iconTheme.color,
),
@ -228,10 +216,11 @@ class _AddOptionButton extends StatelessWidget {
class CreateOptionTextField extends StatefulWidget {
final PopoverMutex? popoverMutex;
const CreateOptionTextField({
Key? key,
super.key,
this.popoverMutex,
}) : super(key: key);
});
@override
State<CreateOptionTextField> createState() => _CreateOptionTextFieldState();

View File

@ -30,10 +30,10 @@ class SingleSelectTypeOptionWidget extends TypeOptionWidget {
final PopoverMutex? popoverMutex;
const SingleSelectTypeOptionWidget({
Key? key,
super.key,
required this.selectOptionAction,
this.popoverMutex,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View File

@ -64,26 +64,23 @@ extension SelectOptionColorExtension on SelectOptionColorPB {
class SelectOptionTag extends StatelessWidget {
final String name;
final Color color;
final VoidCallback? onSelected;
final void Function(String)? onRemove;
const SelectOptionTag({
required this.name,
required this.color,
this.onSelected,
this.onRemove,
Key? key,
}) : super(key: key);
super.key,
});
factory SelectOptionTag.fromOption({
required BuildContext context,
required SelectOptionPB option,
VoidCallback? onSelected,
Function(String)? onRemove,
}) {
return SelectOptionTag(
name: option.name,
color: option.color.toColor(context),
onSelected: onSelected,
onRemove: onRemove,
);
}
@ -119,9 +116,7 @@ class SelectOptionTag extends StatelessWidget {
width: 18.0,
onPressed: () => onRemove?.call(name),
hoverColor: Colors.transparent,
icon: const FlowySvg(
FlowySvgs.close_s,
),
icon: const FlowySvg(FlowySvgs.close_s),
),
],
],
@ -131,9 +126,6 @@ class SelectOptionTag extends StatelessWidget {
}
class SelectOptionTagCell extends StatelessWidget {
final List<Widget> children;
final void Function(SelectOptionPB) onSelected;
final SelectOptionPB option;
const SelectOptionTagCell({
super.key,
required this.option,
@ -141,34 +133,37 @@ class SelectOptionTagCell extends StatelessWidget {
this.children = const [],
});
final SelectOptionPB option;
final VoidCallback onSelected;
final List<Widget> children;
@override
Widget build(BuildContext context) {
return FlowyHover(
style: HoverStyle(
hoverColor: AFThemeExtension.of(context).lightGreyHover,
),
child: InkWell(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: onSelected,
child: Align(
alignment: Alignment.centerLeft,
alignment: AlignmentDirectional.centerStart,
child: Padding(
padding: const EdgeInsets.all(5.0),
child: SelectOptionTag.fromOption(
context: context,
option: option,
onSelected: () => onSelected(option),
),
),
),
),
...children,
],
),
// TODO(richard): find alternative solution to onTapDown
onTapDown: (_) => onSelected(option),
),
...children,
],
),
);
}

View File

@ -246,27 +246,30 @@ class _CreateOptionCell extends StatelessWidget {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: SizedBox(
height: GridSize.popoverItemHeight,
child: Row(
children: [
FlowyText.medium(
LocaleKeys.grid_selectOption_create.tr(),
color: Theme.of(context).hintColor,
),
const HSpace(10),
Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: SelectOptionTag(
name: name,
color: AFThemeExtension.of(context).greyHover,
onSelected: () => context
.read<SelectOptionCellEditorBloc>()
.add(SelectOptionEditorEvent.newOption(name)),
height: 28,
child: FlowyButton(
hoverColor: AFThemeExtension.of(context).lightGreyHover,
onTap: () => context
.read<SelectOptionCellEditorBloc>()
.add(SelectOptionEditorEvent.newOption(name)),
text: Row(
children: [
FlowyText.medium(
LocaleKeys.grid_selectOption_create.tr(),
color: Theme.of(context).hintColor,
),
const HSpace(10),
Expanded(
child: Align(
alignment: Alignment.centerLeft,
child: SelectOptionTag(
name: name,
color: Theme.of(context).colorScheme.surfaceVariant,
),
),
),
),
],
],
),
),
),
);
@ -304,27 +307,20 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
height: 28,
child: SelectOptionTagCell(
option: widget.option,
onSelected: (option) {
if (widget.isSelected) {
context
.read<SelectOptionCellEditorBloc>()
.add(SelectOptionEditorEvent.unSelectOption(option.id));
} else {
context
.read<SelectOptionCellEditorBloc>()
.add(SelectOptionEditorEvent.selectOption(option.id));
}
},
onSelected: _onTap,
children: [
if (widget.isSelected)
Padding(
padding: const EdgeInsets.only(left: 6),
child: FlowySvg(
FlowyIconButton(
width: 20,
hoverColor: Colors.transparent,
onPressed: _onTap,
icon: FlowySvg(
FlowySvgs.check_s,
color: Theme.of(context).iconTheme.color,
),
),
FlowyIconButton(
width: 30,
onPressed: () => _popoverController.show(),
iconPadding: const EdgeInsets.symmetric(horizontal: 6.0),
hoverColor: Colors.transparent,
@ -368,4 +364,17 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
},
);
}
void _onTap() {
widget.popoverMutex.close();
if (widget.isSelected) {
context
.read<SelectOptionCellEditorBloc>()
.add(SelectOptionEditorEvent.unSelectOption(widget.option.id));
} else {
context
.read<SelectOptionCellEditorBloc>()
.add(SelectOptionEditorEvent.selectOption(widget.option.id));
}
}
}