fix: double click to select / unselect options (#4094)

Co-authored-by: Richard Shiue <71320345+richardshiue@users.noreply.github.com>
This commit is contained in:
Lucas.Xu 2023-12-05 20:23:20 +08:00 committed by GitHub
parent 7d55153475
commit 48d6967d3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 50 deletions

View File

@ -1,13 +1,11 @@
import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/size.dart';
import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
extension SelectOptionColorExtension on SelectOptionColorPB { extension SelectOptionColorExtension on SelectOptionColorPB {
Color toColor(BuildContext context) { Color toColor(BuildContext context) {
@ -131,11 +129,7 @@ class SelectOptionTagCell extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FlowyHover( return Row(
style: HoverStyle(
hoverColor: AFThemeExtension.of(context).lightGreyHover,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Expanded( Expanded(
@ -157,7 +151,6 @@ class SelectOptionTagCell extends StatelessWidget {
), ),
...children, ...children,
], ],
),
); );
} }
} }

View File

@ -6,9 +6,9 @@ import 'package:appflowy/plugins/database_view/application/cell/cell_controller_
import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart';
import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra/theme_extension.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flowy_infra_ui/style_widget/hover.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:textfield_tags/textfield_tags.dart'; import 'package:textfield_tags/textfield_tags.dart';
@ -340,10 +340,17 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
asBarrier: true, asBarrier: true,
constraints: BoxConstraints.loose(const Size(200, 470)), constraints: BoxConstraints.loose(const Size(200, 470)),
mutex: widget.popoverMutex, mutex: widget.popoverMutex,
clickHandler: PopoverClickHandler.gestureDetector,
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0), padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: FlowyHover(
resetHoverOnRebuild: false,
style: HoverStyle(
hoverColor: AFThemeExtension.of(context).lightGreyHover,
),
child: child, child: child,
), ),
),
popupBuilder: (BuildContext popoverContext) { popupBuilder: (BuildContext popoverContext) {
return SelectOptionTypeOptionEditor( return SelectOptionTypeOptionEditor(
option: widget.option, option: widget.option,

View File

@ -1,10 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart'; import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy_backend/log.dart';
import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/select_option.pb.dart';
import 'package:dartz/dartz.dart'; import 'package:dartz/dartz.dart';
import 'package:appflowy_backend/log.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import '../../../../application/cell/select_option_cell_service.dart'; import '../../../../application/cell/select_option_cell_service.dart';
part 'select_option_editor_bloc.freezed.dart'; part 'select_option_editor_bloc.freezed.dart';
@ -61,9 +63,27 @@ class SelectOptionCellEditorBloc
}, },
selectOption: (_SelectOption value) async { selectOption: (_SelectOption value) async {
await _selectOptionService.select(optionIds: [value.optionId]); await _selectOptionService.select(optionIds: [value.optionId]);
final selectedOption = [
...state.selectedOptions,
state.options.firstWhere(
(element) => element.id == value.optionId,
),
];
emit(
state.copyWith(
selectedOptions: selectedOption,
),
);
}, },
unSelectOption: (_UnSelectOption value) async { unSelectOption: (_UnSelectOption value) async {
await _selectOptionService.unSelect(optionIds: [value.optionId]); await _selectOptionService.unSelect(optionIds: [value.optionId]);
final selectedOptions = [...state.selectedOptions]
..removeWhere((e) => e.id == value.optionId);
emit(
state.copyWith(
selectedOptions: selectedOptions,
),
);
}, },
trySelectOption: (_TrySelectOption value) { trySelectOption: (_TrySelectOption value) {
_trySelectOption(value.optionName, emit); _trySelectOption(value.optionName, emit);

View File

@ -138,7 +138,7 @@ class _PropertyCellState extends State<_PropertyCell> {
final PopoverController _popoverController = PopoverController(); final PopoverController _popoverController = PopoverController();
final PopoverController _fieldPopoverController = PopoverController(); final PopoverController _fieldPopoverController = PopoverController();
bool _isFieldHover = false; final ValueNotifier<bool> _isFieldHover = ValueNotifier(false);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -159,15 +159,19 @@ class _PropertyCellState extends State<_PropertyCell> {
triggerActions: PopoverTriggerFlags.none, triggerActions: PopoverTriggerFlags.none,
direction: PopoverDirection.bottomWithLeftAligned, direction: PopoverDirection.bottomWithLeftAligned,
popupBuilder: (popoverContext) => buildFieldEditor(), popupBuilder: (popoverContext) => buildFieldEditor(),
child: _isFieldHover child: ValueListenableBuilder(
? BlockActionButton( valueListenable: _isFieldHover,
builder: ((context, value, child) {
return value ? child! : const SizedBox.shrink();
}),
child: BlockActionButton(
onTap: () => _fieldPopoverController.show(), onTap: () => _fieldPopoverController.show(),
svg: FlowySvgs.drag_element_s, svg: FlowySvgs.drag_element_s,
richMessage: TextSpan( richMessage: TextSpan(
text: LocaleKeys.grid_rowPage_fieldDragElementTooltip.tr(), text: LocaleKeys.grid_rowPage_fieldDragElementTooltip.tr(),
), ),
) ),
: const SizedBox.shrink(), ),
), ),
), ),
); );
@ -185,16 +189,21 @@ class _PropertyCellState extends State<_PropertyCell> {
margin: const EdgeInsets.only(bottom: 8), margin: const EdgeInsets.only(bottom: 8),
constraints: const BoxConstraints(minHeight: 30), constraints: const BoxConstraints(minHeight: 30),
child: MouseRegion( child: MouseRegion(
onEnter: (event) => setState(() => _isFieldHover = true), onEnter: (event) => _isFieldHover.value = true,
onExit: (event) => setState(() => _isFieldHover = false), onExit: (event) => _isFieldHover.value = false,
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
ReorderableDragStartListener( ValueListenableBuilder(
valueListenable: _isFieldHover,
builder: (context, value, _) {
return ReorderableDragStartListener(
index: widget.index, index: widget.index,
enabled: _isFieldHover, enabled: value,
child: dragThumb, child: dragThumb,
);
},
), ),
const HSpace(4), const HSpace(4),
AppFlowyPopover( AppFlowyPopover(