fix: select option pannel didn't disappear

This commit is contained in:
appflowy 2022-09-19 12:04:06 +08:00
parent 39b0fe69b5
commit 4d835757d2
3 changed files with 61 additions and 25 deletions

View File

@ -50,7 +50,6 @@ class BoardSettingList extends StatelessWidget {
previous.selectedAction != current.selectedAction, previous.selectedAction != current.selectedAction,
listener: (context, state) { listener: (context, state) {
state.selectedAction.foldLeft(null, (_, action) { state.selectedAction.foldLeft(null, (_, action) {
// FlowyOverlay.of(context).remove(identifier());
onAction(action, settingContext); onAction(action, settingContext);
}); });
}, },

View File

@ -25,31 +25,47 @@ import 'text_field.dart';
const double _editorPanelWidth = 300; const double _editorPanelWidth = 300;
class SelectOptionCellEditor extends StatelessWidget { class SelectOptionCellEditor extends StatefulWidget {
final GridSelectOptionCellController cellController; final GridSelectOptionCellController cellController;
static double editorPanelWidth = 300; static double editorPanelWidth = 300;
const SelectOptionCellEditor({required this.cellController, Key? key}) const SelectOptionCellEditor({required this.cellController, Key? key})
: super(key: key); : super(key: key);
@override
State<SelectOptionCellEditor> createState() => _SelectOptionCellEditorState();
}
class _SelectOptionCellEditorState extends State<SelectOptionCellEditor> {
late PopoverMutex popoverMutex;
@override
void initState() {
popoverMutex = PopoverMutex();
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => SelectOptionCellEditorBloc( create: (context) => SelectOptionCellEditorBloc(
cellController: cellController, cellController: widget.cellController,
)..add(const SelectOptionEditorEvent.initial()), )..add(const SelectOptionEditorEvent.initial()),
child: BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>( child: BlocBuilder<SelectOptionCellEditorBloc, SelectOptionEditorState>(
builder: (context, state) { builder: (context, state) {
return CustomScrollView( return CustomScrollView(
shrinkWrap: true, shrinkWrap: true,
slivers: [ slivers: [
SliverToBoxAdapter(child: _TextField()), SliverToBoxAdapter(
child: _TextField(popoverMutex: popoverMutex),
),
const SliverToBoxAdapter(child: VSpace(6)), const SliverToBoxAdapter(child: VSpace(6)),
const SliverToBoxAdapter(child: TypeOptionSeparator()), const SliverToBoxAdapter(child: TypeOptionSeparator()),
const SliverToBoxAdapter(child: VSpace(6)), const SliverToBoxAdapter(child: VSpace(6)),
const SliverToBoxAdapter(child: _Title()), const SliverToBoxAdapter(child: _Title()),
const SliverToBoxAdapter(child: _OptionList()), SliverToBoxAdapter(
child: _OptionList(popoverMutex: popoverMutex),
),
], ],
); );
}, },
@ -59,7 +75,11 @@ class SelectOptionCellEditor extends StatelessWidget {
} }
class _OptionList extends StatelessWidget { class _OptionList extends StatelessWidget {
const _OptionList({Key? key}) : super(key: key); final PopoverMutex popoverMutex;
const _OptionList({
required this.popoverMutex,
Key? key,
}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -68,7 +88,10 @@ class _OptionList extends StatelessWidget {
List<Widget> cells = []; List<Widget> cells = [];
cells.addAll(state.options.map((option) { cells.addAll(state.options.map((option) {
return _SelectOptionCell( return _SelectOptionCell(
option, state.selectedOptions.contains(option)); option: option,
isSelected: state.selectedOptions.contains(option),
popoverMutex: popoverMutex,
);
}).toList()); }).toList());
state.createOption.fold( state.createOption.fold(
@ -101,9 +124,13 @@ class _OptionList extends StatelessWidget {
} }
class _TextField extends StatelessWidget { class _TextField extends StatelessWidget {
final PopoverMutex popoverMutex;
final TextfieldTagsController _tagController = TextfieldTagsController(); final TextfieldTagsController _tagController = TextfieldTagsController();
_TextField({Key? key}) : super(key: key); _TextField({
required this.popoverMutex,
Key? key,
}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -121,8 +148,11 @@ class _TextField extends StatelessWidget {
selectedOptionMap: optionMap, selectedOptionMap: optionMap,
distanceToText: _editorPanelWidth * 0.7, distanceToText: _editorPanelWidth * 0.7,
tagController: _tagController, tagController: _tagController,
onClick: () => FlowyOverlay.of(context) onClick: () {
.remove(SelectOptionTypeOptionEditor.identifier), popoverMutex.close();
// FlowyOverlay.of(context)
// .remove(SelectOptionTypeOptionEditor.identifier);
},
newText: (text) { newText: (text) {
context context
.read<SelectOptionCellEditorBloc>() .read<SelectOptionCellEditorBloc>()
@ -189,9 +219,14 @@ class _CreateOptionCell extends StatelessWidget {
class _SelectOptionCell extends StatefulWidget { class _SelectOptionCell extends StatefulWidget {
final SelectOptionPB option; final SelectOptionPB option;
final PopoverMutex popoverMutex;
final bool isSelected; final bool isSelected;
const _SelectOptionCell(this.option, this.isSelected, {Key? key}) const _SelectOptionCell({
: super(key: key); required this.option,
required this.isSelected,
required this.popoverMutex,
Key? key,
}) : super(key: key);
@override @override
State<_SelectOptionCell> createState() => _SelectOptionCellState(); State<_SelectOptionCell> createState() => _SelectOptionCellState();
@ -213,6 +248,7 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
controller: _popoverController, controller: _popoverController,
offset: const Offset(20, 0), offset: const Offset(20, 0),
constraints: BoxConstraints.loose(const Size(200, 300)), constraints: BoxConstraints.loose(const Size(200, 300)),
mutex: widget.popoverMutex,
child: SizedBox( child: SizedBox(
height: GridSize.typeOptionItemHeight, height: GridSize.typeOptionItemHeight,
child: Row( child: Row(
@ -257,8 +293,9 @@ class _SelectOptionCellState extends State<_SelectOptionCell> {
.read<SelectOptionCellEditorBloc>() .read<SelectOptionCellEditorBloc>()
.add(SelectOptionEditorEvent.updateOption(updatedOption)); .add(SelectOptionEditorEvent.updateOption(updatedOption));
}, },
key: ValueKey(widget.option key: ValueKey(
.id), // Use ValueKey to refresh the UI, otherwise, it will remain the old value. widget.option.id,
), // Use ValueKey to refresh the UI, otherwise, it will remain the old value.
); );
}, },
); );

View File

@ -6,11 +6,11 @@ import 'package:flutter/services.dart';
/// If multiple popovers are exclusive, /// If multiple popovers are exclusive,
/// pass the same mutex to them. /// pass the same mutex to them.
class PopoverMutex { class PopoverMutex {
final ValueNotifier<PopoverState?> _stateNofitier = ValueNotifier(null); final ValueNotifier<PopoverState?> _stateNotifier = ValueNotifier(null);
PopoverMutex(); PopoverMutex();
void removePopoverStateListener(VoidCallback listener) { void removePopoverStateListener(VoidCallback listener) {
_stateNofitier.removeListener(listener); _stateNotifier.removeListener(listener);
} }
VoidCallback listenOnPopoverStateChanged(VoidCallback callback) { VoidCallback listenOnPopoverStateChanged(VoidCallback callback) {
@ -18,29 +18,29 @@ class PopoverMutex {
callback(); callback();
} }
_stateNofitier.addListener(listenerCallback); _stateNotifier.addListener(listenerCallback);
return listenerCallback; return listenerCallback;
} }
void close() { void close() {
_stateNofitier.value?.close(); _stateNotifier.value?.close();
} }
PopoverState? get state => _stateNofitier.value; PopoverState? get state => _stateNotifier.value;
set state(PopoverState? newState) { set state(PopoverState? newState) {
if (_stateNofitier.value != null && _stateNofitier.value != newState) { if (_stateNotifier.value != null && _stateNotifier.value != newState) {
_stateNofitier.value?.close(); _stateNotifier.value?.close();
} }
_stateNofitier.value = newState; _stateNotifier.value = newState;
} }
void _removeState() { void _removeState() {
_stateNofitier.value = null; _stateNotifier.value = null;
} }
void dispose() { void dispose() {
_stateNofitier.dispose(); _stateNotifier.dispose();
} }
} }