Skip to content

Commit

Permalink
Merge pull request #3878 from canonical/gui-click-to-copy
Browse files Browse the repository at this point in the history
use CopyableText (click-to-copy) in GUI for instance info
  • Loading branch information
andrei-toterman authored Feb 3, 2025
2 parents c9f0e24 + 2f58580 commit f85e60f
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 17 deletions.
46 changes: 46 additions & 0 deletions src/client/gui/lib/copyable_text.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import 'package:flutter/material.dart' hide Tooltip;
import 'package:flutter/services.dart';

import 'tooltip.dart';

class CopyableText extends StatefulWidget {
final String text;
final TextStyle? style;

const CopyableText(this.text, {super.key, this.style});

@override
State<CopyableText> createState() => _CopyableTextState();
}

class _CopyableTextState extends State<CopyableText> {
var _copied = false;

@override
Widget build(BuildContext context) {
Widget text = Text(
widget.text,
style: widget.style,
maxLines: 1,
overflow: TextOverflow.ellipsis,
);

// if there is no value, display "-"
if (widget.text == '-') return text;

return MouseRegion(
cursor: SystemMouseCursors.click,
onExit: (_) => setState(() => _copied = false),
child: GestureDetector(
onTap: () async {
await Clipboard.setData(ClipboardData(text: widget.text));
setState(() => _copied = true);
},
child: Tooltip(
message: _copied ? 'Copied' : 'Click to copy',
child: text,
),
),
);
}
}
1 change: 1 addition & 0 deletions src/client/gui/lib/tooltip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Tooltip extends fl.StatelessWidget {
return fl.TooltipVisibility(
visible: visible,
child: fl.Tooltip(
key: fl.Key(message),
message: message,
textAlign: fl.TextAlign.center,
decoration: fl.BoxDecoration(
Expand Down
8 changes: 2 additions & 6 deletions src/client/gui/lib/vm_details/ip_addresses.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart' hide Tooltip;

import '../copyable_text.dart';
import '../extensions.dart';
import '../tooltip.dart';

Expand All @@ -14,12 +15,7 @@ class IpAddresses extends StatelessWidget {
final restIps = ips.skip(1).toList();

return Row(children: [
Expanded(
child: Tooltip(
message: firstIp,
child: Text(firstIp.nonBreaking, overflow: TextOverflow.ellipsis),
),
),
Expanded(child: CopyableText(firstIp)),
if (restIps.isNotEmpty)
Badge.count(
count: restIps.length,
Expand Down
14 changes: 7 additions & 7 deletions src/client/gui/lib/vm_details/vm_details_general.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';

import '../copyable_text.dart';
import '../extensions.dart';
import '../providers.dart';
import '../tooltip.dart';
import 'cpu_sparkline.dart';
import 'memory_usage.dart';
import 'vm_action_buttons.dart';
Expand Down Expand Up @@ -76,11 +78,9 @@ class VmDetailsHeader extends ConsumerWidget {

final list = [
Expanded(
child: Text(
child: CopyableText(
name.nonBreaking,
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w300),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
locationButtons,
Expand Down Expand Up @@ -150,28 +150,28 @@ class GeneralDetails extends ConsumerWidget {
width: 150,
height: baseVmStatHeight,
label: 'IMAGE',
child: Text(info.instanceInfo.currentRelease),
child: CopyableText(info.instanceInfo.currentRelease),
);

final privateIp = VmStat(
width: 150,
height: baseVmStatHeight,
label: 'PRIVATE IP',
child: Text(info.instanceInfo.ipv4.firstOrNull ?? '-'),
child: CopyableText(info.instanceInfo.ipv4.firstOrNull ?? '-'),
);

final publicIp = VmStat(
width: 150,
height: baseVmStatHeight,
label: 'PUBLIC IP',
child: Text(info.instanceInfo.ipv4.skip(1).firstOrNull ?? '-'),
child: CopyableText(info.instanceInfo.ipv4.skip(1).firstOrNull ?? '-'),
);

final created = VmStat(
width: 140,
height: baseVmStatHeight,
label: 'CREATED',
child: Text(
child: CopyableText(
DateFormat('yyyy-MM-dd HH:mm:ss')
.format(info.instanceInfo.creationTimestamp.toDateTime()),
),
Expand Down
6 changes: 2 additions & 4 deletions src/client/gui/lib/vm_table/vm_table_headers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart' hide Tooltip;
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../copyable_text.dart';
import '../extensions.dart';
import '../providers.dart';
import '../sidebar.dart';
Expand Down Expand Up @@ -72,10 +73,7 @@ final headers = <TableHeader<VmInfo>>[
minWidth: 70,
cellBuilder: (info) {
final image = info.instanceInfo.currentRelease;
return Text(
image.isNotBlank ? image.nonBreaking : '-',
overflow: TextOverflow.ellipsis,
);
return CopyableText(image.isNotBlank ? image.nonBreaking : '-');
},
),
TableHeader(
Expand Down

0 comments on commit f85e60f

Please sign in to comment.