Skip to content

Commit 4a48812

Browse files
committed
address code review: simplify copyable text functionality and tooltip implementation
1 parent e4e0678 commit 4a48812

File tree

5 files changed

+22
-62
lines changed

5 files changed

+22
-62
lines changed

src/client/gui/lib/copyable_text.dart

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:flutter/material.dart' hide Tooltip;
22
import 'package:flutter/services.dart';
3+
34
import 'tooltip.dart';
45

56
class CopyableText extends StatefulWidget {
@@ -13,20 +14,7 @@ class CopyableText extends StatefulWidget {
1314
}
1415

1516
class _CopyableTextState extends State<CopyableText> {
16-
bool _copied = false;
17-
bool get _isCopyable => widget.text != '-';
18-
19-
void _copyToClipboard() async {
20-
if (!_isCopyable) return;
21-
await Clipboard.setData(ClipboardData(text: widget.text));
22-
setState(() => _copied = true);
23-
}
24-
25-
void _resetCopied() {
26-
if (_copied) {
27-
setState(() => _copied = false);
28-
}
29-
}
17+
var _copied = false;
3018

3119
@override
3220
Widget build(BuildContext context) {
@@ -37,13 +25,17 @@ class _CopyableTextState extends State<CopyableText> {
3725
overflow: TextOverflow.ellipsis,
3826
);
3927

40-
if (!_isCopyable) return text;
28+
// if there is no value, display "-"
29+
if (widget.text == '-') return text;
4130

4231
return MouseRegion(
4332
cursor: SystemMouseCursors.click,
44-
onExit: (_) => _resetCopied(),
33+
onExit: (_) => setState(() => _copied = false),
4534
child: GestureDetector(
46-
onTap: _copyToClipboard,
35+
onTap: () async {
36+
await Clipboard.setData(ClipboardData(text: widget.text));
37+
setState(() => _copied = true);
38+
},
4739
child: Tooltip(
4840
message: _copied ? 'Copied' : 'Click to copy',
4941
child: text,

src/client/gui/lib/tooltip.dart

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import 'package:flutter/material.dart' as fl;
22

3-
class Tooltip extends fl.StatefulWidget {
3+
class Tooltip extends fl.StatelessWidget {
44
final fl.Widget child;
55
final String message;
66
final bool visible;
@@ -12,40 +12,19 @@ class Tooltip extends fl.StatefulWidget {
1212
this.visible = true,
1313
});
1414

15-
@override
16-
fl.State<Tooltip> createState() => _TooltipState();
17-
}
18-
19-
class _TooltipState extends fl.State<Tooltip> {
20-
final _key = fl.GlobalKey<fl.TooltipState>();
21-
bool _forceShow = false;
22-
23-
@override
24-
void didUpdateWidget(Tooltip oldWidget) {
25-
super.didUpdateWidget(oldWidget);
26-
if (oldWidget.message != widget.message) {
27-
setState(() => _forceShow = true);
28-
Future.delayed(const Duration(milliseconds: 1), () {
29-
if (mounted) {
30-
setState(() => _forceShow = false);
31-
}
32-
});
33-
}
34-
}
35-
3615
@override
3716
fl.Widget build(fl.BuildContext context) {
3817
return fl.TooltipVisibility(
39-
visible: widget.visible,
18+
visible: visible,
4019
child: fl.Tooltip(
41-
key: _forceShow ? _key : null,
42-
message: widget.message,
20+
key: fl.Key(message),
21+
message: message,
4322
textAlign: fl.TextAlign.center,
4423
decoration: fl.BoxDecoration(
4524
color: const fl.Color(0xff111111),
4625
borderRadius: fl.BorderRadius.circular(2),
4726
),
48-
child: widget.child,
27+
child: child,
4928
),
5029
);
5130
}

src/client/gui/lib/vm_details/ip_addresses.dart

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,21 @@
11
import 'package:flutter/material.dart' hide Tooltip;
2-
import '../copyable_text.dart';
32

3+
import '../copyable_text.dart';
44
import '../extensions.dart';
55
import '../tooltip.dart';
66

77
class IpAddresses extends StatelessWidget {
88
final Iterable<String> ips;
9-
final bool copyable;
109

11-
const IpAddresses(this.ips, {this.copyable = false, super.key});
10+
const IpAddresses(this.ips, {super.key});
1211

1312
@override
1413
Widget build(BuildContext context) {
1514
final firstIp = ips.firstOrNull ?? '-';
1615
final restIps = ips.skip(1).toList();
1716

1817
return Row(children: [
19-
Expanded(
20-
child: copyable
21-
? CopyableText(firstIp)
22-
: Tooltip(
23-
message: firstIp,
24-
child:
25-
Text(firstIp.nonBreaking, overflow: TextOverflow.ellipsis),
26-
),
27-
),
18+
Expanded(child: CopyableText(firstIp)),
2819
if (restIps.isNotEmpty)
2920
Badge.count(
3021
count: restIps.length,

src/client/gui/lib/vm_details/vm_details_general.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
import 'package:basics/basics.dart';
2-
import 'package:flutter/material.dart' hide Tooltip;
2+
import 'package:flutter/material.dart';
33
import 'package:flutter_riverpod/flutter_riverpod.dart';
44
import 'package:intl/intl.dart';
5-
import 'package:flutter/services.dart';
65

6+
import '../copyable_text.dart';
77
import '../extensions.dart';
88
import '../providers.dart';
9+
import '../tooltip.dart';
910
import 'cpu_sparkline.dart';
1011
import 'memory_usage.dart';
1112
import 'vm_action_buttons.dart';
1213
import 'vm_details.dart';
1314
import 'vm_status_icon.dart';
14-
import '../tooltip.dart';
15-
import '../copyable_text.dart';
1615

1716
class VmDetailsHeader extends ConsumerWidget {
1817
final String name;

src/client/gui/lib/vm_table/vm_table_headers.dart

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import 'package:built_collection/built_collection.dart';
33
import 'package:flutter/material.dart' hide Tooltip;
44
import 'package:flutter_riverpod/flutter_riverpod.dart';
55

6+
import '../copyable_text.dart';
67
import '../extensions.dart';
78
import '../providers.dart';
89
import '../sidebar.dart';
@@ -14,7 +15,7 @@ import '../vm_details/vm_status_icon.dart';
1415
import 'search_box.dart';
1516
import 'table.dart';
1617
import 'vms.dart';
17-
import '../copyable_text.dart';
18+
1819

1920
final headers = <TableHeader<VmInfo>>[
2021
TableHeader(
@@ -84,7 +85,6 @@ final headers = <TableHeader<VmInfo>>[
8485
minWidth: 100,
8586
cellBuilder: (info) => IpAddresses(
8687
info.instanceInfo.ipv4.take(1),
87-
copyable: true,
8888
),
8989
),
9090
TableHeader(
@@ -93,7 +93,6 @@ final headers = <TableHeader<VmInfo>>[
9393
minWidth: 100,
9494
cellBuilder: (info) => IpAddresses(
9595
info.instanceInfo.ipv4.skip(1),
96-
copyable: true,
9796
),
9897
),
9998
];

0 commit comments

Comments
 (0)