Skip to content

Commit 53cc0ff

Browse files
committed
fix: open GridRowActionSheet with appflowy overlay
1 parent 4d83575 commit 53cc0ff

File tree

25 files changed

+250
-186
lines changed

25 files changed

+250
-186
lines changed

frontend/app_flowy/lib/plugins/board/presentation/card/board_select_option_cell.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class _BoardSelectOptionCellState extends State<BoardSelectOptionCell> {
8787
SelectOptionCellEditor.editorPanelWidth,
8888
300,
8989
));
90-
return AppFlowyStylePopover(
90+
return AppFlowyPopover(
9191
controller: _popover,
9292
constraints: constraints,
9393
direction: PopoverDirection.bottomWithLeftAligned,

frontend/app_flowy/lib/plugins/board/presentation/card/card.dart

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import 'package:app_flowy/plugins/board/application/card/card_bloc.dart';
22
import 'package:app_flowy/plugins/board/application/card/card_data_controller.dart';
33
import 'package:app_flowy/plugins/grid/presentation/widgets/row/row_action_sheet.dart';
4+
import 'package:appflowy_popover/popover.dart';
45
import 'package:flowy_infra/image.dart';
56
import 'package:flowy_infra/theme.dart';
6-
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
7+
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
78
import 'package:flutter/foundation.dart';
89
import 'package:flutter/material.dart';
910
import 'package:flutter_bloc/flutter_bloc.dart';
1011
import 'board_cell.dart';
1112
import 'card_cell_builder.dart';
12-
import 'card_container.dart';
13+
import 'container/accessory.dart';
14+
import 'container/card_container.dart';
1315

1416
class BoardCard extends StatefulWidget {
1517
final String gridId;
@@ -38,6 +40,8 @@ class BoardCard extends StatefulWidget {
3840
class _BoardCardState extends State<BoardCard> {
3941
late BoardCardBloc _cardBloc;
4042
late EditableRowNotifier rowNotifier;
43+
late PopoverController popoverController;
44+
AccessoryType? accessoryType;
4145

4246
@override
4347
void initState() {
@@ -54,6 +58,7 @@ class _BoardCardState extends State<BoardCard> {
5458
_cardBloc.add(BoardCardEvent.setIsEditing(rowNotifier.isEditing.value));
5559
});
5660

61+
popoverController = PopoverController();
5762
super.initState();
5863
}
5964

@@ -64,39 +69,73 @@ class _BoardCardState extends State<BoardCard> {
6469
child: BlocBuilder<BoardCardBloc, BoardCardState>(
6570
buildWhen: (previous, current) {
6671
// Rebuild when:
67-
// 1.If the lenght of the cells is not the same
72+
// 1.If the length of the cells is not the same
6873
// 2.isEditing changed
6974
if (previous.cells.length != current.cells.length ||
7075
previous.isEditing != current.isEditing) {
7176
return true;
7277
}
7378

74-
// 3.Compare the content of the cells. The cells consisits of
79+
// 3.Compare the content of the cells. The cells consists of
7580
// list of [BoardCellEquatable] that extends the [Equatable].
7681
return !listEquals(previous.cells, current.cells);
7782
},
7883
builder: (context, state) {
79-
return BoardCardContainer(
80-
buildAccessoryWhen: () => state.isEditing == false,
81-
accessoryBuilder: (context) {
82-
return [
83-
_CardEditOption(rowNotifier: rowNotifier),
84-
const _CardMoreOption(),
85-
];
86-
},
87-
onTap: (context) => widget.openCard(context),
88-
child: _CellColumn(
89-
groupId: widget.groupId,
90-
rowNotifier: rowNotifier,
91-
cellBuilder: widget.cellBuilder,
92-
cells: state.cells,
84+
return AppFlowyPopover(
85+
controller: popoverController,
86+
constraints: BoxConstraints.loose(const Size(140, 200)),
87+
direction: PopoverDirection.rightWithCenterAligned,
88+
popupBuilder: (popoverContext) => _handlePopoverBuilder(
89+
context,
90+
popoverContext,
91+
),
92+
child: BoardCardContainer(
93+
buildAccessoryWhen: () => state.isEditing == false,
94+
accessoryBuilder: (context) {
95+
return [
96+
_CardEditOption(rowNotifier: rowNotifier),
97+
_CardMoreOption(),
98+
];
99+
},
100+
openAccessory: _handleOpenAccessory,
101+
openCard: (context) => widget.openCard(context),
102+
child: _CellColumn(
103+
groupId: widget.groupId,
104+
rowNotifier: rowNotifier,
105+
cellBuilder: widget.cellBuilder,
106+
cells: state.cells,
107+
),
93108
),
94109
);
95110
},
96111
),
97112
);
98113
}
99114

115+
void _handleOpenAccessory(AccessoryType newAccessoryType) {
116+
accessoryType = newAccessoryType;
117+
switch (newAccessoryType) {
118+
case AccessoryType.edit:
119+
break;
120+
case AccessoryType.more:
121+
popoverController.show();
122+
break;
123+
}
124+
}
125+
126+
Widget _handlePopoverBuilder(
127+
BuildContext context,
128+
BuildContext popoverContext,
129+
) {
130+
switch (accessoryType!) {
131+
case AccessoryType.edit:
132+
throw UnimplementedError();
133+
case AccessoryType.more:
134+
return GridRowActionSheet(
135+
rowData: context.read<BoardCardBloc>().rowInfo());
136+
}
137+
}
138+
100139
@override
101140
Future<void> dispose() async {
102141
rowNotifier.dispose();
@@ -163,7 +202,7 @@ class _CellColumn extends StatelessWidget {
163202
}
164203

165204
class _CardMoreOption extends StatelessWidget with CardAccessory {
166-
const _CardMoreOption({Key? key}) : super(key: key);
205+
_CardMoreOption({Key? key}) : super(key: key);
167206

168207
@override
169208
Widget build(BuildContext context) {
@@ -175,11 +214,7 @@ class _CardMoreOption extends StatelessWidget with CardAccessory {
175214
}
176215

177216
@override
178-
void onTap(BuildContext context) {
179-
GridRowActionSheet(
180-
rowData: context.read<BoardCardBloc>().rowInfo(),
181-
).show(context, direction: AnchorDirection.bottomWithCenterAligned);
182-
}
217+
AccessoryType get type => AccessoryType.more;
183218
}
184219

185220
class _CardEditOption extends StatelessWidget with CardAccessory {
@@ -201,7 +236,8 @@ class _CardEditOption extends StatelessWidget with CardAccessory {
201236
}
202237

203238
@override
204-
void onTap(BuildContext context) {
205-
rowNotifier.becomeFirstResponder();
206-
}
239+
void onTap(BuildContext context) => rowNotifier.becomeFirstResponder();
240+
241+
@override
242+
AccessoryType get type => AccessoryType.edit;
207243
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import 'package:flowy_infra/theme.dart';
2+
import 'package:flowy_infra_ui/style_widget/hover.dart';
3+
import 'package:flutter/material.dart';
4+
import 'package:flutter_bloc/flutter_bloc.dart';
5+
6+
enum AccessoryType {
7+
edit,
8+
more,
9+
}
10+
11+
abstract class CardAccessory implements Widget {
12+
AccessoryType get type;
13+
void onTap(BuildContext context) {}
14+
}
15+
16+
typedef CardAccessoryBuilder = List<CardAccessory> Function(
17+
BuildContext buildContext,
18+
);
19+
20+
class CardAccessoryContainer extends StatelessWidget {
21+
final void Function(AccessoryType) onTapAccessory;
22+
final List<CardAccessory> accessories;
23+
const CardAccessoryContainer({
24+
required this.accessories,
25+
required this.onTapAccessory,
26+
Key? key,
27+
}) : super(key: key);
28+
29+
@override
30+
Widget build(BuildContext context) {
31+
final theme = context.read<AppTheme>();
32+
final children = accessories.map((accessory) {
33+
return GestureDetector(
34+
behavior: HitTestBehavior.opaque,
35+
onTap: () {
36+
accessory.onTap(context);
37+
onTapAccessory(accessory.type);
38+
},
39+
child: _wrapHover(theme, accessory),
40+
);
41+
}).toList();
42+
return _wrapDecoration(context, Row(children: children));
43+
}
44+
45+
FlowyHover _wrapHover(AppTheme theme, CardAccessory accessory) {
46+
return FlowyHover(
47+
style: HoverStyle(
48+
hoverColor: theme.hover,
49+
backgroundColor: theme.surface,
50+
borderRadius: BorderRadius.zero,
51+
),
52+
builder: (_, onHover) => SizedBox(
53+
width: 24,
54+
height: 24,
55+
child: accessory,
56+
),
57+
);
58+
}
59+
60+
Widget _wrapDecoration(BuildContext context, Widget child) {
61+
final theme = context.read<AppTheme>();
62+
final borderSide = BorderSide(color: theme.shader6, width: 1.0);
63+
final decoration = BoxDecoration(
64+
color: Colors.transparent,
65+
border: Border.fromBorderSide(borderSide),
66+
borderRadius: const BorderRadius.all(Radius.circular(4)),
67+
);
68+
return Container(
69+
clipBehavior: Clip.hardEdge,
70+
decoration: decoration,
71+
child: child,
72+
);
73+
}
74+
}

frontend/app_flowy/lib/plugins/board/presentation/card/card_container.dart renamed to frontend/app_flowy/lib/plugins/board/presentation/card/container/card_container.dart

Lines changed: 21 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1-
import 'package:flowy_infra/theme.dart';
2-
import 'package:flowy_infra_ui/style_widget/hover.dart';
31
import 'package:flutter/material.dart';
42
import 'package:provider/provider.dart';
53
import 'package:styled_widget/styled_widget.dart';
64

5+
import 'accessory.dart';
6+
77
class BoardCardContainer extends StatelessWidget {
88
final Widget child;
99
final CardAccessoryBuilder? accessoryBuilder;
1010
final bool Function()? buildAccessoryWhen;
11-
final void Function(BuildContext) onTap;
11+
final void Function(BuildContext) openCard;
12+
final void Function(AccessoryType) openAccessory;
1213
const BoardCardContainer({
1314
required this.child,
14-
required this.onTap,
15+
required this.openCard,
16+
required this.openAccessory,
1517
this.accessoryBuilder,
1618
this.buildAccessoryWhen,
1719
Key? key,
@@ -34,13 +36,14 @@ class BoardCardContainer extends StatelessWidget {
3436
if (accessories.isNotEmpty) {
3537
container = _CardEnterRegion(
3638
accessories: accessories,
39+
onTapAccessory: openAccessory,
3740
child: container,
3841
);
3942
}
4043
}
4144

4245
return GestureDetector(
43-
onTap: () => onTap(context),
46+
onTap: () => openCard(context),
4447
child: Padding(
4548
padding: const EdgeInsets.all(8),
4649
child: ConstrainedBox(
@@ -55,69 +58,16 @@ class BoardCardContainer extends StatelessWidget {
5558
}
5659
}
5760

58-
abstract class CardAccessory implements Widget {
59-
void onTap(BuildContext context);
60-
}
61-
62-
typedef CardAccessoryBuilder = List<CardAccessory> Function(
63-
BuildContext buildContext,
64-
);
65-
66-
class CardAccessoryContainer extends StatelessWidget {
67-
final List<CardAccessory> accessories;
68-
const CardAccessoryContainer({required this.accessories, Key? key})
69-
: super(key: key);
70-
71-
@override
72-
Widget build(BuildContext context) {
73-
final theme = context.read<AppTheme>();
74-
final children = accessories.map((accessory) {
75-
return GestureDetector(
76-
behavior: HitTestBehavior.opaque,
77-
onTap: () => accessory.onTap(context),
78-
child: _wrapHover(theme, accessory),
79-
);
80-
}).toList();
81-
return _wrapDecoration(context, Row(children: children));
82-
}
83-
84-
FlowyHover _wrapHover(AppTheme theme, CardAccessory accessory) {
85-
return FlowyHover(
86-
style: HoverStyle(
87-
hoverColor: theme.hover,
88-
backgroundColor: theme.surface,
89-
borderRadius: BorderRadius.zero,
90-
),
91-
builder: (_, onHover) => SizedBox(
92-
width: 24,
93-
height: 24,
94-
child: accessory,
95-
),
96-
);
97-
}
98-
99-
Widget _wrapDecoration(BuildContext context, Widget child) {
100-
final theme = context.read<AppTheme>();
101-
final borderSide = BorderSide(color: theme.shader6, width: 1.0);
102-
final decoration = BoxDecoration(
103-
color: Colors.transparent,
104-
border: Border.fromBorderSide(borderSide),
105-
borderRadius: const BorderRadius.all(Radius.circular(4)),
106-
);
107-
return Container(
108-
clipBehavior: Clip.hardEdge,
109-
decoration: decoration,
110-
child: child,
111-
);
112-
}
113-
}
114-
11561
class _CardEnterRegion extends StatelessWidget {
11662
final Widget child;
11763
final List<CardAccessory> accessories;
118-
const _CardEnterRegion(
119-
{required this.child, required this.accessories, Key? key})
120-
: super(key: key);
64+
final void Function(AccessoryType) onTapAccessory;
65+
const _CardEnterRegion({
66+
required this.child,
67+
required this.accessories,
68+
required this.onTapAccessory,
69+
Key? key,
70+
}) : super(key: key);
12171

12272
@override
12373
Widget build(BuildContext context) {
@@ -126,9 +76,12 @@ class _CardEnterRegion extends StatelessWidget {
12676
builder: (context, onEnter, _) {
12777
List<Widget> children = [child];
12878
if (onEnter) {
129-
children.add(CardAccessoryContainer(
130-
accessories: accessories,
131-
).positioned(right: 0));
79+
children.add(
80+
CardAccessoryContainer(
81+
accessories: accessories,
82+
onTapAccessory: onTapAccessory,
83+
).positioned(right: 0),
84+
);
13285
}
13386

13487
return MouseRegion(

frontend/app_flowy/lib/plugins/board/presentation/toolbar/board_toolbar.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class _SettingButtonState extends State<_SettingButton> {
6262
@override
6363
Widget build(BuildContext context) {
6464
final theme = context.read<AppTheme>();
65-
return AppFlowyStylePopover(
65+
return AppFlowyPopover(
6666
controller: popoverController,
6767
constraints: BoxConstraints.loose(const Size(260, 400)),
6868
triggerActions: PopoverTriggerActionFlags.click,

frontend/app_flowy/lib/plugins/grid/presentation/widgets/cell/date_cell/date_cell.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class _DateCellState extends GridCellState<GridDateCell> {
6363
value: _cellBloc,
6464
child: BlocBuilder<DateCellBloc, DateCellState>(
6565
builder: (context, state) {
66-
return AppFlowyStylePopover(
66+
return AppFlowyPopover(
6767
controller: _popover,
6868
offset: const Offset(0, 20),
6969
direction: PopoverDirection.bottomWithLeftAligned,

0 commit comments

Comments
 (0)