diff --git a/frontend/app_flowy/lib/plugins/board/presentation/card/card.dart b/frontend/app_flowy/lib/plugins/board/presentation/card/card.dart index 6e555b87c7..c08ece7474 100644 --- a/frontend/app_flowy/lib/plugins/board/presentation/card/card.dart +++ b/frontend/app_flowy/lib/plugins/board/presentation/card/card.dart @@ -85,6 +85,7 @@ class _BoardCardState extends State { controller: popoverController, triggerActions: PopoverTriggerFlags.none, constraints: BoxConstraints.loose(const Size(140, 200)), + margin: const EdgeInsets.all(6), direction: PopoverDirection.rightWithCenterAligned, popupBuilder: (popoverContext) => _handlePopoverBuilder( context, @@ -133,7 +134,8 @@ class _BoardCardState extends State { throw UnimplementedError(); case AccessoryType.more: return GridRowActionSheet( - rowData: context.read().rowInfo()); + rowData: context.read().rowInfo(), + ); } } diff --git a/frontend/app_flowy/lib/plugins/doc/document.dart b/frontend/app_flowy/lib/plugins/doc/document.dart index 128eabfd20..9ef30f037e 100644 --- a/frontend/app_flowy/lib/plugins/doc/document.dart +++ b/frontend/app_flowy/lib/plugins/doc/document.dart @@ -233,7 +233,7 @@ class ShareActionWrapper extends ActionItem { ShareActionWrapper(this.inner); @override - Widget? get icon => null; + Widget? icon(Color iconColor) => null; @override String get name => inner.name; diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart index f478c8cc2b..63917da8f9 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_editor.dart @@ -76,7 +76,7 @@ class _DateCellEditor extends State { } } -class _CellCalendarWidget extends StatelessWidget { +class _CellCalendarWidget extends StatefulWidget { final GridDateCellController cellContext; final DateTypeOptionPB dateTypeOptionPB; @@ -86,26 +86,43 @@ class _CellCalendarWidget extends StatelessWidget { Key? key, }) : super(key: key); + @override + State<_CellCalendarWidget> createState() => _CellCalendarWidgetState(); +} + +class _CellCalendarWidgetState extends State<_CellCalendarWidget> { + late PopoverMutex popoverMutex; + late DateCalBloc bloc; + + @override + void initState() { + popoverMutex = PopoverMutex(); + + bloc = DateCalBloc( + dateTypeOptionPB: widget.dateTypeOptionPB, + cellData: widget.cellContext.getCellData(), + cellController: widget.cellContext, + )..add(const DateCalEvent.initial()); + super.initState(); + } + @override Widget build(BuildContext context) { final theme = context.watch(); - return BlocProvider( - create: (context) { - return DateCalBloc( - dateTypeOptionPB: dateTypeOptionPB, - cellData: cellContext.getCellData(), - cellController: cellContext, - )..add(const DateCalEvent.initial()); - }, + return BlocProvider.value( + value: bloc, child: BlocBuilder( buildWhen: (p, c) => false, builder: (context, state) { List children = [ _buildCalendar(theme, context), - _TimeTextField(bloc: context.read()), + _TimeTextField( + bloc: context.read(), + popoverMutex: popoverMutex, + ), Divider(height: 1, color: theme.shader5), const _IncludeTimeButton(), - const _DateTypeOptionButton() + _DateTypeOptionButton(popoverMutex: popoverMutex) ]; return ListView.separated( @@ -124,6 +141,13 @@ class _CellCalendarWidget extends StatelessWidget { ); } + @override + void dispose() { + bloc.close(); + popoverMutex.dispose(); + super.dispose(); + } + Widget _buildCalendar(AppTheme theme, BuildContext context) { return BlocBuilder( builder: (context, state) { @@ -223,8 +247,10 @@ class _IncludeTimeButton extends StatelessWidget { class _TimeTextField extends StatefulWidget { final DateCalBloc bloc; + final PopoverMutex popoverMutex; const _TimeTextField({ required this.bloc, + required this.popoverMutex, Key? key, }) : super(key: key); @@ -245,9 +271,18 @@ class _TimeTextFieldState extends State<_TimeTextField> { if (mounted) { widget.bloc.add(DateCalEvent.setTime(_controller.text)); } + + if (_focusNode.hasFocus) { + widget.popoverMutex.close(); + } + }); + + widget.popoverMutex.listenOnPopoverChanged(() { + if (_focusNode.hasFocus) { + _focusNode.unfocus(); + } }); } - super.initState(); } @@ -295,7 +330,11 @@ class _TimeTextFieldState extends State<_TimeTextField> { } class _DateTypeOptionButton extends StatelessWidget { - const _DateTypeOptionButton({Key? key}) : super(key: key); + final PopoverMutex popoverMutex; + const _DateTypeOptionButton({ + required this.popoverMutex, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -306,6 +345,7 @@ class _DateTypeOptionButton extends StatelessWidget { selector: (state) => state.dateTypeOptionPB, builder: (context, dateTypeOptionPB) { return AppFlowyPopover( + mutex: popoverMutex, triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click, offset: const Offset(20, 0), constraints: BoxConstraints.loose(const Size(140, 100)), @@ -318,7 +358,10 @@ class _DateTypeOptionButton extends StatelessWidget { popupBuilder: (BuildContext popContext) { return _CalDateTimeSetting( dateTypeOptionPB: dateTypeOptionPB, - onEvent: (event) => context.read().add(event), + onEvent: (event) { + context.read().add(event); + popoverMutex.close(); + }, ); }, ); @@ -330,46 +373,49 @@ class _DateTypeOptionButton extends StatelessWidget { class _CalDateTimeSetting extends StatefulWidget { final DateTypeOptionPB dateTypeOptionPB; final Function(DateCalEvent) onEvent; - const _CalDateTimeSetting( - {required this.dateTypeOptionPB, required this.onEvent, Key? key}) - : super(key: key); + const _CalDateTimeSetting({ + required this.dateTypeOptionPB, + required this.onEvent, + Key? key, + }) : super(key: key); @override State<_CalDateTimeSetting> createState() => _CalDateTimeSettingState(); } class _CalDateTimeSettingState extends State<_CalDateTimeSetting> { + final timeSettingPopoverMutex = PopoverMutex(); String? overlayIdentifier; - final _popoverMutex = PopoverMutex(); @override Widget build(BuildContext context) { List children = [ AppFlowyPopover( - mutex: _popoverMutex, - asBarrier: true, + mutex: timeSettingPopoverMutex, triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click, offset: const Offset(20, 0), popupBuilder: (BuildContext context) { return DateFormatList( selectedFormat: widget.dateTypeOptionPB.dateFormat, - onSelected: (format) => - widget.onEvent(DateCalEvent.setDateFormat(format)), + onSelected: (format) { + widget.onEvent(DateCalEvent.setDateFormat(format)); + timeSettingPopoverMutex.close(); + }, ); }, child: const DateFormatButton(), ), AppFlowyPopover( - mutex: _popoverMutex, - asBarrier: true, + mutex: timeSettingPopoverMutex, triggerActions: PopoverTriggerFlags.hover | PopoverTriggerFlags.click, offset: const Offset(20, 0), popupBuilder: (BuildContext context) { return TimeFormatList( - selectedFormat: widget.dateTypeOptionPB.timeFormat, - onSelected: (format) => - widget.onEvent(DateCalEvent.setTimeFormat(format)), - ); + selectedFormat: widget.dateTypeOptionPB.timeFormat, + onSelected: (format) { + widget.onEvent(DateCalEvent.setTimeFormat(format)); + timeSettingPopoverMutex.close(); + }); }, child: TimeFormatButton(timeFormat: widget.dateTypeOptionPB.timeFormat), ), diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart index fd6133770f..80b94762ec 100755 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_cell.dart @@ -162,6 +162,7 @@ class FieldCellButton extends StatelessWidget { Widget build(BuildContext context) { final theme = context.watch(); return FlowyButton( + radius: BorderRadius.zero, hoverColor: theme.shader6, onTap: onTap, leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart index 1b3e579029..6e55a345a2 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/field_editor.dart @@ -139,7 +139,6 @@ class _FieldNameTextField extends StatefulWidget { class _FieldNameTextFieldState extends State<_FieldNameTextField> { FocusNode focusNode = FocusNode(); - VoidCallback? _popoverCallback; late TextEditingController controller; @override @@ -151,6 +150,12 @@ class _FieldNameTextFieldState extends State<_FieldNameTextField> { } }); + widget.popoverMutex.listenOnPopoverChanged(() { + if (focusNode.hasFocus) { + focusNode.unfocus(); + } + }); + super.initState(); } @@ -176,8 +181,6 @@ class _FieldNameTextFieldState extends State<_FieldNameTextField> { buildWhen: (previous, current) => previous.errorText != current.errorText, builder: (context, state) { - listenOnPopoverChanged(context); - return RoundedInputField( height: 36, focusNode: focusNode, @@ -198,18 +201,6 @@ class _FieldNameTextFieldState extends State<_FieldNameTextField> { ), ); } - - void listenOnPopoverChanged(BuildContext context) { - if (_popoverCallback != null) { - widget.popoverMutex.removePopoverListener(_popoverCallback!); - } - _popoverCallback = widget.popoverMutex.listenOnPopoverChanged(() { - if (focusNode.hasFocus) { - final node = FocusScope.of(context); - node.unfocus(); - } - }); - } } class _DeleteFieldButton extends StatelessWidget { @@ -236,9 +227,10 @@ class _DeleteFieldButton extends StatelessWidget { color: enable ? null : theme.shader4, ), onTap: () => onDeleted?.call(), + hoverColor: theme.hover, + onHover: (_) => popoverMutex.close(), ); - // if (enable) button = button; - return button; + return SizedBox(height: 36, child: button); }, ); } diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart index dbd12119b5..735a179c1e 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/header/grid_header.dart @@ -180,6 +180,7 @@ class CreateFieldButton extends StatelessWidget { asBarrier: true, constraints: BoxConstraints.loose(const Size(240, 600)), child: FlowyButton( + radius: BorderRadius.zero, text: FlowyText.medium( LocaleKeys.grid_field_newColumn.tr(), fontSize: 12, diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/grid_row.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/grid_row.dart index 2c3065196f..79643f48fb 100755 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/grid_row.dart @@ -109,6 +109,7 @@ class _RowLeadingState extends State<_RowLeading> { triggerActions: PopoverTriggerFlags.none, constraints: BoxConstraints.loose(const Size(140, 200)), direction: PopoverDirection.rightWithCenterAligned, + margin: const EdgeInsets.all(6), popupBuilder: (BuildContext popoverContext) { return GridRowActionSheet( rowData: context.read().state.rowInfo); diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart index 13a71166d8..51a161be57 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/row/row_detail.dart @@ -280,6 +280,7 @@ class _RowDetailCellState extends State<_RowDetailCell> { AppFlowyPopover( controller: popover, constraints: BoxConstraints.loose(const Size(240, 600)), + triggerActions: PopoverTriggerFlags.none, popupBuilder: (popoverContext) => buildFieldEditor(), child: SizedBox( width: 150, diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart index 197dfb3dd5..7b5ca129ce 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_toolbar.dart @@ -55,6 +55,7 @@ class _SettingButton extends StatelessWidget { return AppFlowyPopover( constraints: BoxConstraints.loose(const Size(260, 400)), offset: const Offset(0, 10), + margin: const EdgeInsets.all(6), child: FlowyIconButton( width: 22, hoverColor: theme.hover, diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart index 48f4f0d399..727b18762b 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/header.dart @@ -86,7 +86,8 @@ class MenuAppHeader extends StatelessWidget { ?.toggle(), onSecondaryTap: () { final actionList = AppDisclosureActionSheet( - onSelected: (action) => _handleAction(context, action)); + onSelected: (action) => _handleAction(context, action), + ); actionList.show( context, anchorDirection: AnchorDirection.bottomWithCenterAligned, @@ -158,12 +159,12 @@ extension AppDisclosureExtension on AppDisclosureAction { } } - Widget get icon { + Widget icon(Color iconColor) { switch (this) { case AppDisclosureAction.rename: - return svgWidget('editor/edit', color: const Color(0xffe5e5e5)); + return svgWidget('editor/edit', color: iconColor); case AppDisclosureAction.delete: - return svgWidget('editor/delete', color: const Color(0xffe5e5e5)); + return svgWidget('editor/delete', color: iconColor); } } } diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/right_click_action.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/right_click_action.dart index be6a97dbfb..387f161732 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/right_click_action.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/header/right_click_action.dart @@ -5,9 +5,12 @@ import 'package:flutter/material.dart'; import 'header.dart'; -class AppDisclosureActionSheet with ActionList, FlowyOverlayDelegate { +class AppDisclosureActionSheet + with ActionList, FlowyOverlayDelegate { final Function(dartz.Option) onSelected; - final _items = AppDisclosureAction.values.map((action) => DisclosureActionWrapper(action)).toList(); + final _items = AppDisclosureAction.values + .map((action) => DisclosureActionWrapper(action)) + .toList(); AppDisclosureActionSheet({ required this.onSelected, @@ -17,7 +20,8 @@ class AppDisclosureActionSheet with ActionList, FlowyOv List get items => _items; @override - void Function(dartz.Option p1) get selectCallback => (result) { + void Function(dartz.Option p1) get selectCallback => + (result) { result.fold( () => onSelected(dartz.none()), (wrapper) => onSelected( @@ -40,7 +44,7 @@ class DisclosureActionWrapper extends ActionItem { DisclosureActionWrapper(this.inner); @override - Widget? get icon => inner.icon; + Widget? icon(Color iconColor) => inner.icon(iconColor); @override String get name => inner.name; diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart index 019f674b01..f420ec30e6 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/disclosure_action.dart @@ -80,7 +80,7 @@ class ViewDisclosureRegion extends StatelessWidget @override Widget build(BuildContext context) { return Listener( - onPointerDown: (event) => {_handleClick(event, context)}, + onPointerDown: (event) => _handleClick(event, context), child: child, ); } @@ -123,7 +123,7 @@ class ViewDisclosureActionWrapper extends ActionItem { ViewDisclosureActionWrapper(this.inner); @override - Widget? get icon => inner.icon; + Widget? icon(Color iconColor) => inner.icon(iconColor); @override String get name => inner.name; diff --git a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart index 9c9b5a0895..e66e69e414 100644 --- a/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart +++ b/frontend/app_flowy/lib/workspace/presentation/home/menu/app/section/item.dart @@ -147,14 +147,14 @@ extension ViewDisclosureExtension on ViewDisclosureAction { } } - Widget get icon { + Widget icon(Color iconColor) { switch (this) { case ViewDisclosureAction.rename: - return svgWidget('editor/edit', color: const Color(0xff999999)); + return svgWidget('editor/edit', color: iconColor); case ViewDisclosureAction.delete: - return svgWidget('editor/delete', color: const Color(0xff999999)); + return svgWidget('editor/delete', color: iconColor); case ViewDisclosureAction.duplicate: - return svgWidget('editor/copy', color: const Color(0xff999999)); + return svgWidget('editor/copy', color: iconColor); } } } diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart index dbcafe2e44..67e5f4ba25 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart @@ -101,9 +101,11 @@ class _DebugToast { } } -class QuestionBubbleActionSheet with ActionList, FlowyOverlayDelegate { +class QuestionBubbleActionSheet + with ActionList, FlowyOverlayDelegate { final Function(dartz.Option) onSelected; - final _items = BubbleAction.values.map((action) => BubbleActionWrapper(action)).toList(); + final _items = + BubbleAction.values.map((action) => BubbleActionWrapper(action)).toList(); QuestionBubbleActionSheet({ required this.onSelected, @@ -119,7 +121,8 @@ class QuestionBubbleActionSheet with ActionList, FlowyOverl List get items => _items; @override - void Function(dartz.Option p1) get selectCallback => (result) { + void Function(dartz.Option p1) get selectCallback => + (result) { result.fold( () => onSelected(dartz.none()), (wrapper) => onSelected( @@ -156,7 +159,8 @@ class FlowyVersionDescription extends StatelessWidget { builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasError) { - return FlowyText("Error: ${snapshot.error}", fontSize: 12, color: theme.shader4); + return FlowyText("Error: ${snapshot.error}", + fontSize: 12, color: theme.shader4); } PackageInfo packageInfo = snapshot.data; @@ -170,7 +174,8 @@ class FlowyVersionDescription extends StatelessWidget { children: [ Divider(height: 1, color: theme.shader6, thickness: 1.0), const VSpace(6), - FlowyText("$appName $version.$buildNumber", fontSize: 12, color: theme.shader4), + FlowyText("$appName $version.$buildNumber", + fontSize: 12, color: theme.shader4), ], ).padding( horizontal: ActionListSizes.itemHPadding + ActionListSizes.padding, @@ -190,7 +195,7 @@ class BubbleActionWrapper extends ActionItem { BubbleActionWrapper(this.inner); @override - Widget? get icon => inner.emoji; + Widget? icon(Color iconColor) => inner.emoji; @override String get name => inner.name; diff --git a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart index cbcec14fee..64f29036e0 100644 --- a/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart +++ b/frontend/app_flowy/lib/workspace/presentation/widgets/pop_up_action.dart @@ -59,7 +59,7 @@ abstract class ActionList { } abstract class ActionItem { - Widget? get icon; + Widget? icon(Color iconColor); String get name; } @@ -83,6 +83,7 @@ class ActionCell extends StatelessWidget { @override Widget build(BuildContext context) { final theme = context.watch(); + final icon = action.icon(theme.iconColor); return FlowyHover( style: HoverStyle(hoverColor: theme.hover), @@ -94,12 +95,9 @@ class ActionCell extends StatelessWidget { child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - if (action.icon != null) action.icon!, + if (icon != null) icon, HSpace(ActionListSizes.itemHPadding), - FlowyText.medium( - action.name, - fontSize: 12, - ), + FlowyText.medium(action.name, fontSize: 12), ], ), ).padding( diff --git a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart index ba2b3049af..159513dd49 100644 --- a/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart +++ b/frontend/app_flowy/packages/flowy_infra_ui/lib/style_widget/button.dart @@ -12,6 +12,8 @@ class FlowyButton extends StatelessWidget { final Widget? rightIcon; final Color hoverColor; final bool isSelected; + final BorderRadius radius; + const FlowyButton({ Key? key, required this.text, @@ -22,6 +24,7 @@ class FlowyButton extends StatelessWidget { this.rightIcon, this.hoverColor = Colors.transparent, this.isSelected = false, + this.radius = const BorderRadius.all(Radius.circular(6)), }) : super(key: key); @override @@ -29,8 +32,10 @@ class FlowyButton extends StatelessWidget { return InkWell( onTap: onTap, child: FlowyHover( - style: - HoverStyle(borderRadius: BorderRadius.zero, hoverColor: hoverColor), + style: HoverStyle( + borderRadius: radius, + hoverColor: hoverColor, + ), onHover: onHover, setSelected: () => isSelected, builder: (context, onHover) => _render(), diff --git a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/default_controller.rs b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/default_controller.rs index 2489df8af2..ddcdd7f3e1 100644 --- a/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/default_controller.rs +++ b/frontend/rust-lib/flowy-grid/src/services/group/controller_impls/default_controller.rs @@ -55,7 +55,7 @@ impl GroupControllerSharedOperation for DefaultGroupController { _row_rev: &RowRevision, _field_rev: &FieldRevision, ) -> FlowyResult> { - todo!() + Ok(vec![]) } fn did_delete_row( @@ -63,7 +63,7 @@ impl GroupControllerSharedOperation for DefaultGroupController { _row_rev: &RowRevision, _field_rev: &FieldRevision, ) -> FlowyResult> { - todo!() + Ok(vec![]) } fn move_group_row(&mut self, _context: MoveGroupRowContext) -> FlowyResult> {