diff --git a/src/client/gui/lib/selectable_text.dart b/src/client/gui/lib/selectable_text.dart new file mode 100644 index 0000000000..b2262582fd --- /dev/null +++ b/src/client/gui/lib/selectable_text.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +class WhiteSelectableText extends StatelessWidget { + final String text; + final TextStyle? style; + final TextAlign? textAlign; + final int? maxLines; + + const WhiteSelectableText( + this.text, { + super.key, + this.style, + this.textAlign, + this.maxLines, + }); + + @override + Widget build(BuildContext context) { + final textButtonStyle = Theme.of(context).textButtonTheme.style?.copyWith( + backgroundColor: const MaterialStatePropertyAll(Colors.white), + ); + + return SelectableText( + text, + style: style?.copyWith(overflow: TextOverflow.ellipsis) ?? const TextStyle(overflow: TextOverflow.ellipsis), + textAlign: textAlign, + maxLines: maxLines, + contextMenuBuilder: (context, editableTextState) { + return TapRegion( + onTapOutside: (_) => ContextMenuController.removeAny(), + child: TextButtonTheme( + data: TextButtonThemeData(style: textButtonStyle), + child: AdaptiveTextSelectionToolbar.buttonItems( + anchors: editableTextState.contextMenuAnchors, + buttonItems: editableTextState.contextMenuButtonItems, + ), + ), + ); + }, + ); + } +} diff --git a/src/client/gui/lib/vm_details/ip_addresses.dart b/src/client/gui/lib/vm_details/ip_addresses.dart index 84ce2c890e..cab2f4f0e7 100644 --- a/src/client/gui/lib/vm_details/ip_addresses.dart +++ b/src/client/gui/lib/vm_details/ip_addresses.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart' hide Tooltip; import '../extensions.dart'; +import '../selectable_text.dart'; import '../tooltip.dart'; class IpAddresses extends StatelessWidget { @@ -17,7 +18,7 @@ class IpAddresses extends StatelessWidget { Expanded( child: Tooltip( message: firstIp, - child: SelectableText(firstIp.nonBreaking, maxLines: 1), + child: WhiteSelectableText(firstIp.nonBreaking, maxLines: 1), ), ), if (restIps.isNotEmpty) diff --git a/src/client/gui/lib/vm_details/memory_usage.dart b/src/client/gui/lib/vm_details/memory_usage.dart index 6cba5047c7..cc0d5c5de2 100644 --- a/src/client/gui/lib/vm_details/memory_usage.dart +++ b/src/client/gui/lib/vm_details/memory_usage.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import '../selectable_text.dart'; + class MemoryUsage extends StatelessWidget { final String used; final String total; @@ -21,7 +23,7 @@ class MemoryUsage extends StatelessWidget { color: value < 0.8 ? normalColor : almostFullColor, ); - final label = SelectableText( + final label = WhiteSelectableText( value != 0 ? '${_formatMemory(used)} / ${_formatMemory(total)}' : '-', style: const TextStyle(fontSize: 11), ); diff --git a/src/client/gui/lib/vm_details/vm_details_general.dart b/src/client/gui/lib/vm_details/vm_details_general.dart index c8f3a6209c..10c7702384 100644 --- a/src/client/gui/lib/vm_details/vm_details_general.dart +++ b/src/client/gui/lib/vm_details/vm_details_general.dart @@ -5,6 +5,7 @@ import 'package:intl/intl.dart'; import '../extensions.dart'; import '../providers.dart'; +import '../selectable_text.dart'; import 'cpu_sparkline.dart'; import 'memory_usage.dart'; import 'vm_action_buttons.dart'; @@ -76,7 +77,7 @@ class VmDetailsHeader extends ConsumerWidget { final list = [ Expanded( - child: SelectableText( + child: WhiteSelectableText( name.nonBreaking, style: const TextStyle(fontSize: 24, fontWeight: FontWeight.w300), maxLines: 1, @@ -150,28 +151,28 @@ class GeneralDetails extends ConsumerWidget { width: 150, height: baseVmStatHeight, label: 'IMAGE', - child: SelectableText(info.instanceInfo.currentRelease), + child: WhiteSelectableText(info.instanceInfo.currentRelease), ); final privateIp = VmStat( width: 150, height: baseVmStatHeight, label: 'PRIVATE IP', - child: SelectableText(info.instanceInfo.ipv4.firstOrNull ?? '-'), + child: WhiteSelectableText(info.instanceInfo.ipv4.firstOrNull ?? '-'), ); final publicIp = VmStat( width: 150, height: baseVmStatHeight, label: 'PUBLIC IP', - child: SelectableText(info.instanceInfo.ipv4.skip(1).firstOrNull ?? '-'), + child: WhiteSelectableText(info.instanceInfo.ipv4.skip(1).firstOrNull ?? '-'), ); final created = VmStat( width: 140, height: baseVmStatHeight, label: 'CREATED', - child: SelectableText( + child: WhiteSelectableText( DateFormat('yyyy-MM-dd HH:mm:ss') .format(info.instanceInfo.creationTimestamp.toDateTime()), ), @@ -181,7 +182,7 @@ class GeneralDetails extends ConsumerWidget { width: 300, height: baseVmStatHeight, label: 'UPTIME', - child: SelectableText(info.instanceInfo.uptime), + child: WhiteSelectableText(info.instanceInfo.uptime), ); return Column( diff --git a/src/client/gui/lib/vm_table/vm_table_headers.dart b/src/client/gui/lib/vm_table/vm_table_headers.dart index ebac8f94aa..e548004af6 100644 --- a/src/client/gui/lib/vm_table/vm_table_headers.dart +++ b/src/client/gui/lib/vm_table/vm_table_headers.dart @@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../extensions.dart'; import '../providers.dart'; +import '../selectable_text.dart'; import '../sidebar.dart'; import '../tooltip.dart'; import '../vm_details/cpu_sparkline.dart'; @@ -72,7 +73,7 @@ final headers = >[ minWidth: 70, cellBuilder: (info) { final image = info.instanceInfo.currentRelease; - return SelectableText( + return WhiteSelectableText( image.isNotBlank ? image.nonBreaking : '-', maxLines: 1, );