diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_accessory.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_accessory.dart index d5cca704fe..41e22b8b98 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_accessory.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_accessory.dart @@ -6,21 +6,29 @@ import 'package:provider/provider.dart'; import 'package:flowy_infra/size.dart'; import 'package:styled_widget/styled_widget.dart'; -abstract class GridCellAccessory implements Widget { - void onTap(BuildContext context); +class GridCellAccessoryBuildContext { + final BuildContext anchorContext; + + GridCellAccessoryBuildContext({required this.anchorContext}); } -abstract class AccessoryHoverChild extends Widget { - const AccessoryHoverChild({Key? key}) : super(key: key); +abstract class GridCellAccessory implements Widget { + void onTap(); +} + +typedef AccessoryBuilder = List Function(GridCellAccessoryBuildContext buildContext); + +abstract class AccessoryWidget extends Widget { + const AccessoryWidget({Key? key}) : super(key: key); // The hover will show if the onFocus's value is true ValueNotifier? get isFocus; - List accessories(); + AccessoryBuilder? get accessoryBuilder; } class AccessoryHover extends StatefulWidget { - final AccessoryHoverChild child; + final AccessoryWidget child; final EdgeInsets contentPadding; const AccessoryHover({ required this.child, @@ -62,8 +70,10 @@ class _AccessoryHoverState extends State { const _Background(), Padding(padding: widget.contentPadding, child: widget.child), ]; - final accessories = widget.child.accessories(); - if (accessories.isNotEmpty) { + + final accessoryBuilder = widget.child.accessoryBuilder; + if (accessoryBuilder != null) { + final accessories = accessoryBuilder((GridCellAccessoryBuildContext(anchorContext: context))); children.add( Padding( padding: const EdgeInsets.only(right: 6), @@ -152,7 +162,7 @@ class AccessoryContainer extends StatelessWidget { return GestureDetector( child: hover, behavior: HitTestBehavior.opaque, - onTap: () => accessory.onTap(context), + onTap: () => accessory.onTap(), ); }).toList(); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index d97ed086b4..65bff03ecf 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -48,14 +48,12 @@ class BlankCell extends StatelessWidget { } } -abstract class GridCellWidget implements AccessoryHoverChild, CellContainerFocustable { +abstract class GridCellWidget implements AccessoryWidget, CellContainerFocustable { @override final ValueNotifier isFocus = ValueNotifier(false); @override - List accessories() { - return List.empty(); - } + List Function(GridCellAccessoryBuildContext buildContext)? get accessoryBuilder => null; @override final GridCellRequestBeginFocus requestBeginFocus = GridCellRequestBeginFocus(); @@ -135,7 +133,7 @@ abstract class CellContainerFocustable { class CellContainer extends StatelessWidget { final GridCellWidget child; - final List accessories; + final AccessoryBuilder? accessoryBuilder; final double width; final RegionStateNotifier rowStateNotifier; const CellContainer({ @@ -143,7 +141,7 @@ class CellContainer extends StatelessWidget { required this.child, required this.width, required this.rowStateNotifier, - this.accessories = const [], + this.accessoryBuilder, }) : super(key: key); @override @@ -159,8 +157,12 @@ class CellContainer extends StatelessWidget { Provider.of(context, listen: false).isFocus = child.isFocus.value; }); - if (accessories.isNotEmpty) { - container = CellEnterRegion(child: container, accessories: accessories); + if (accessoryBuilder != null) { + final buildContext = GridCellAccessoryBuildContext(anchorContext: context); + final accessories = accessoryBuilder!(buildContext); + if (accessories.isNotEmpty) { + container = CellEnterRegion(child: container, accessories: accessories); + } } return GestureDetector( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/url_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/url_cell.dart index e823aedbfc..56f0b421a5 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/url_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/url_cell.dart @@ -48,32 +48,34 @@ class GridURLCell extends StatefulWidget with GridCellWidget { @override State createState() => _GridURLCellState(); - @override - List accessories() { - final List accessories = []; - if (cellStyle != null) { - accessories.addAll(cellStyle!.accessoryTypes.map(accessoryFromType)); - } - - // If the accessories is empty then the default accessory will be GridURLCellAccessoryType.edit - if (accessories.isEmpty) { - accessories.add(accessoryFromType(GridURLCellAccessoryType.edit)); - } - - return accessories; - } - - GridCellAccessory accessoryFromType(GridURLCellAccessoryType ty) { + GridCellAccessory accessoryFromType(GridURLCellAccessoryType ty, GridCellAccessoryBuildContext buildContext) { switch (ty) { case GridURLCellAccessoryType.edit: final cellContext = cellContextBuilder.build() as GridURLCellContext; - return _EditURLAccessory(cellContext: cellContext); + return _EditURLAccessory(cellContext: cellContext, anchorContext: buildContext.anchorContext); case GridURLCellAccessoryType.copyURL: final cellContext = cellContextBuilder.build() as GridURLCellContext; return _CopyURLAccessory(cellContext: cellContext); } } + + @override + List Function(GridCellAccessoryBuildContext buildContext) get accessoryBuilder => (buildContext) { + final List accessories = []; + if (cellStyle != null) { + accessories.addAll(cellStyle!.accessoryTypes.map((ty) { + return accessoryFromType(ty, buildContext); + })); + } + + // If the accessories is empty then the default accessory will be GridURLCellAccessoryType.edit + if (accessories.isEmpty) { + accessories.add(accessoryFromType(GridURLCellAccessoryType.edit, buildContext)); + } + + return accessories; + }; } class _GridURLCellState extends State { @@ -153,7 +155,12 @@ class _GridURLCellState extends State { class _EditURLAccessory extends StatelessWidget with GridCellAccessory { final GridURLCellContext cellContext; - const _EditURLAccessory({required this.cellContext, Key? key}) : super(key: key); + final BuildContext anchorContext; + const _EditURLAccessory({ + required this.cellContext, + required this.anchorContext, + Key? key, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -162,8 +169,8 @@ class _EditURLAccessory extends StatelessWidget with GridCellAccessory { } @override - void onTap(BuildContext context) { - URLCellEditor.show(context, cellContext); + void onTap() { + URLCellEditor.show(anchorContext, cellContext); } } @@ -178,10 +185,9 @@ class _CopyURLAccessory extends StatelessWidget with GridCellAccessory { } @override - void onTap(BuildContext context) { + void onTap() { final content = cellContext.getCellData(loadIfNoCache: false)?.content ?? ""; Clipboard.setData(ClipboardData(text: content)); - showMessageToast(LocaleKeys.grid_row_copyProperty.tr()); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart index 171c6d3d12..b646af6c40 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/grid_row.dart @@ -176,13 +176,25 @@ class _RowCells extends StatelessWidget { if (gridCell.field.isPrimary) { accessories.add(_PrimaryCellAccessory(onTapCallback: onExpand)); } - accessories.addAll(child.accessories()); + + accessoryBuilder(buildContext) { + final builder = child.accessoryBuilder; + List accessories = []; + if (gridCell.field.isPrimary) { + accessories.add(_PrimaryCellAccessory(onTapCallback: onExpand)); + } + + if (builder != null) { + accessories.addAll(builder(buildContext)); + } + return accessories; + } return CellContainer( width: gridCell.field.width.toDouble(), child: child, rowStateNotifier: Provider.of(context, listen: false), - accessories: accessories, + accessoryBuilder: accessoryBuilder, ); }, ).toList(); @@ -213,7 +225,7 @@ class _PrimaryCellAccessory extends StatelessWidget with GridCellAccessory { } @override - void onTap(BuildContext context) { + void onTap() { onTapCallback(); } }