feat: hide url cell accessory when the content is empty (#2754)

This commit is contained in:
Nathan.fooo 2023-06-10 15:48:56 +08:00 committed by GitHub
parent 4ce94a9ceb
commit 2ecd0a67ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 106 additions and 59 deletions

View File

@ -19,8 +19,8 @@ class GridCellAccessoryBuildContext {
});
}
class GridCellAccessoryBuilder {
final GlobalKey _key = GlobalKey();
class GridCellAccessoryBuilder<T extends State<StatefulWidget>> {
final GlobalKey<T> _key = GlobalKey();
final Widget Function(Key key) _builder;
@ -67,9 +67,16 @@ class _PrimaryCellAccessoryState extends State<PrimaryCellAccessory>
Widget build(BuildContext context) {
return Tooltip(
message: LocaleKeys.tooltip_openAsPage.tr(),
child: svgWidget(
"grid/expander",
color: Theme.of(context).colorScheme.primary,
child: SizedBox(
width: 26,
height: 26,
child: Padding(
padding: const EdgeInsets.all(3.0),
child: svgWidget(
"grid/expander",
color: Theme.of(context).colorScheme.primary,
),
),
),
);
}
@ -183,12 +190,7 @@ class CellAccessoryContainer extends StatelessWidget {
final hover = FlowyHover(
style:
HoverStyle(hoverColor: AFThemeExtension.of(context).lightGreyHover),
builder: (_, onHover) => Container(
width: 26,
height: 26,
padding: const EdgeInsets.all(3),
child: accessory.build(),
),
builder: (_, onHover) => accessory.build(),
);
return GestureDetector(
behavior: HitTestBehavior.opaque,

View File

@ -1,5 +1,6 @@
import 'dart:async';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/database_view/application/cell/cell_controller.dart';
import 'package:appflowy/plugins/database_view/application/cell/cell_controller_builder.dart';
import 'package:appflowy/workspace/presentation/home/toast.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
@ -35,12 +36,14 @@ enum GridURLCellAccessoryType {
visitURL,
}
typedef URLCellDataNotifier = CellDataNotifier<String>;
class GridURLCell extends GridCellWidget {
GridURLCell({
super.key,
required this.cellControllerBuilder,
GridCellStyle? style,
}) {
}) : _cellDataNotifier = CellDataNotifier(value: '') {
if (style != null) {
cellStyle = (style as GridURLCellStyle);
} else {
@ -48,36 +51,14 @@ class GridURLCell extends GridCellWidget {
}
}
/// Use
final URLCellDataNotifier _cellDataNotifier;
final CellControllerBuilder cellControllerBuilder;
late final GridURLCellStyle? cellStyle;
@override
GridCellState<GridURLCell> createState() => _GridURLCellState();
GridCellAccessoryBuilder accessoryFromType(
GridURLCellAccessoryType ty,
GridCellAccessoryBuildContext buildContext,
) {
switch (ty) {
case GridURLCellAccessoryType.visitURL:
final cellContext = cellControllerBuilder.build() as URLCellController;
return GridCellAccessoryBuilder(
builder: (Key key) => _VisitURLAccessory(
key: key,
cellContext: cellContext,
),
);
case GridURLCellAccessoryType.copyURL:
final cellContext = cellControllerBuilder.build() as URLCellController;
return GridCellAccessoryBuilder(
builder: (Key key) => _CopyURLAccessory(
key: key,
cellContext: cellContext,
),
);
}
}
@override
List<GridCellAccessoryBuilder> Function(
GridCellAccessoryBuildContext buildContext,
@ -86,7 +67,7 @@ class GridURLCell extends GridCellWidget {
if (cellStyle != null) {
accessories.addAll(
cellStyle!.accessoryTypes.map((ty) {
return accessoryFromType(ty, buildContext);
return _accessoryFromType(ty, buildContext);
}),
);
}
@ -94,7 +75,7 @@ class GridURLCell extends GridCellWidget {
// If the accessories is empty then the default accessory will be GridURLCellAccessoryType.visitURL
if (accessories.isEmpty) {
accessories.add(
accessoryFromType(
_accessoryFromType(
GridURLCellAccessoryType.visitURL,
buildContext,
),
@ -103,6 +84,28 @@ class GridURLCell extends GridCellWidget {
return accessories;
};
GridCellAccessoryBuilder _accessoryFromType(
GridURLCellAccessoryType ty,
GridCellAccessoryBuildContext buildContext,
) {
switch (ty) {
case GridURLCellAccessoryType.visitURL:
return VisitURLCellAccessoryBuilder(
builder: (Key key) => _VisitURLAccessory(
key: key,
cellDataNotifier: _cellDataNotifier,
),
);
case GridURLCellAccessoryType.copyURL:
return CopyURLCellAccessoryBuilder(
builder: (Key key) => _CopyURLAccessory(
key: key,
cellDataNotifier: _cellDataNotifier,
),
);
}
}
}
class _GridURLCellState extends GridFocusNodeCellState<GridURLCell> {
@ -133,8 +136,11 @@ class _GridURLCellState extends GridFocusNodeCellState<GridURLCell> {
value: _cellBloc,
child: BlocConsumer<URLCellBloc, URLCellState>(
listenWhen: (previous, current) => previous.content != current.content,
listener: (context, state) => _controller.text = state.content,
listener: (context, state) {
_controller.text = state.content;
},
builder: (context, state) {
widget._cellDataNotifier.value = state.content;
final urlEditor = Padding(
padding: EdgeInsets.only(
left: GridSize.cellContentInsets.left,
@ -232,33 +238,41 @@ class _EditURLAccessoryState extends State<_EditURLAccessory>
}
}
typedef CopyURLCellAccessoryBuilder
= GridCellAccessoryBuilder<State<_CopyURLAccessory>>;
class _CopyURLAccessory extends StatefulWidget {
const _CopyURLAccessory({
super.key,
required this.cellContext,
required this.cellDataNotifier,
});
final URLCellController cellContext;
final URLCellDataNotifier cellDataNotifier;
@override
State<StatefulWidget> createState() => _CopyURLAccessoryState();
State<_CopyURLAccessory> createState() => _CopyURLAccessoryState();
}
class _CopyURLAccessoryState extends State<_CopyURLAccessory>
with GridCellAccessoryState {
@override
Widget build(BuildContext context) {
return svgWidget(
"editor/copy",
color: AFThemeExtension.of(context).textColor,
);
if (widget.cellDataNotifier.value.isNotEmpty) {
return _URLAccessoryIconContainer(
child: svgWidget(
"editor/copy",
color: AFThemeExtension.of(context).textColor,
),
);
} else {
return const SizedBox.shrink();
}
}
@override
void onTap() {
final content =
widget.cellContext.getCellData(loadIfNotExist: false)?.content;
if (content == null) {
final content = widget.cellDataNotifier.value;
if (content.isEmpty) {
return;
}
Clipboard.setData(ClipboardData(text: content));
@ -266,33 +280,46 @@ class _CopyURLAccessoryState extends State<_CopyURLAccessory>
}
}
typedef VisitURLCellAccessoryBuilder
= GridCellAccessoryBuilder<State<_VisitURLAccessory>>;
class _VisitURLAccessory extends StatefulWidget {
const _VisitURLAccessory({
super.key,
required this.cellContext,
required this.cellDataNotifier,
});
final URLCellController cellContext;
final URLCellDataNotifier cellDataNotifier;
@override
State<StatefulWidget> createState() => _VisitURLAccessoryState();
State<_VisitURLAccessory> createState() => _VisitURLAccessoryState();
}
class _VisitURLAccessoryState extends State<_VisitURLAccessory>
with GridCellAccessoryState {
@override
Widget build(BuildContext context) {
return svgWidget(
"editor/link",
color: AFThemeExtension.of(context).textColor,
);
if (widget.cellDataNotifier.value.isNotEmpty) {
return _URLAccessoryIconContainer(
child: svgWidget(
"editor/link",
color: AFThemeExtension.of(context).textColor,
),
);
} else {
return const SizedBox.shrink();
}
}
@override
bool enable() {
return widget.cellDataNotifier.value.isNotEmpty;
}
@override
void onTap() {
final content =
widget.cellContext.getCellData(loadIfNotExist: false)?.content;
if (content == null) {
final content = widget.cellDataNotifier.value;
if (content.isEmpty) {
return;
}
final shouldAddScheme =
@ -301,3 +328,21 @@ class _VisitURLAccessoryState extends State<_VisitURLAccessory>
canLaunchUrlString(url).then((value) => launchUrlString(url));
}
}
class _URLAccessoryIconContainer extends StatelessWidget {
const _URLAccessoryIconContainer({required this.child});
final Widget child;
@override
Widget build(BuildContext context) {
return SizedBox(
width: 26,
height: 26,
child: Padding(
padding: const EdgeInsets.all(3.0),
child: child,
),
);
}
}