diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 93b08af..3348119 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -791,5 +791,8 @@ "clientDisallowedSuccessfully": "Client disallowed successfully", "changesNotSaved": "Changes could not be saved", "allowingClient": "Allowing client...", - "disallowingClient": "Disallowing client..." + "disallowingClient": "Disallowing client...", + "clientIpCopied": "Client IP copied to the clipboard", + "clientNameCopied": "Client name copied to the clipboard", + "dnsServerAddressCopied": "DNS server address copied to the clipboard" } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index e777f48..811ee22 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -791,5 +791,8 @@ "clientDisallowedSuccessfully": "Cliente no permitido correctamente", "changesNotSaved": "Los cambios no han podido ser guardados", "allowingClient": "Permitiendo cliente...", - "disallowingClient": "No permitiendo cliente..." + "disallowingClient": "No permitiendo cliente...", + "clientIpCopied": "Dirección IP del cliente copiada al portapapeles", + "clientNameCopied": "Nombre del cliente copiado al portapapeles", + "dnsServerAddressCopied": "Dirección del servidor DNS copiada al portapapeles" } \ No newline at end of file diff --git a/lib/screens/logs/details/log_details_screen.dart b/lib/screens/logs/details/log_details_screen.dart index 0c35f35..5d78823 100644 --- a/lib/screens/logs/details/log_details_screen.dart +++ b/lib/screens/logs/details/log_details_screen.dart @@ -1,5 +1,6 @@ // ignore_for_file: use_build_context_synchronously +import 'package:adguard_home_manager/functions/copy_clipboard.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -275,10 +276,11 @@ class _Content extends StatelessWidget { subtitle: convertTimestampLocalTimezone(log.time, 'HH:mm:ss') ), SectionLabel(label: AppLocalizations.of(context)!.request), - LogListTile( + if (log.question.name != null) LogListTile( icon: Icons.domain_rounded, title: AppLocalizations.of(context)!.domain, - subtitle: log.question.name + subtitle: log.question.name, + onTap: () => copyToClipboard(value: log.question.name!, successMessage: AppLocalizations.of(context)!.domainCopiedClipboard), ), LogListTile( icon: Icons.category_rounded, @@ -294,7 +296,8 @@ class _Content extends StatelessWidget { if (log.upstream != null && log.upstream != '') LogListTile( icon: Icons.dns_rounded, title: AppLocalizations.of(context)!.dnsServer, - subtitle: log.upstream + subtitle: log.upstream, + onTap: () => copyToClipboard(value: log.upstream!, successMessage: AppLocalizations.of(context)!.dnsServerAddressCopied) ), LogListTile( icon: Icons.timer_rounded, @@ -310,12 +313,14 @@ class _Content extends StatelessWidget { LogListTile( icon: Icons.smartphone_rounded, title: AppLocalizations.of(context)!.deviceIp, - subtitle: log.client + subtitle: log.client, + onTap: () => copyToClipboard(value: log.client, successMessage: AppLocalizations.of(context)!.clientIpCopied), ), if (log.clientInfo != null && log.clientInfo!.name != '') LogListTile( icon: Icons.abc_rounded, title: AppLocalizations.of(context)!.deviceName, - subtitle: log.clientInfo!.name + subtitle: log.clientInfo!.name, + onTap: () => copyToClipboard(value: log.clientInfo!.name, successMessage: AppLocalizations.of(context)!.clientNameCopied), ), if (log.rules.isNotEmpty) ...[ SectionLabel(label: AppLocalizations.of(context)!.rules), diff --git a/lib/screens/logs/details/log_list_tile.dart b/lib/screens/logs/details/log_list_tile.dart index c45f0f8..15edd6b 100644 --- a/lib/screens/logs/details/log_list_tile.dart +++ b/lib/screens/logs/details/log_list_tile.dart @@ -6,63 +6,68 @@ class LogListTile extends StatelessWidget { final String? subtitle; final Widget? subtitleWidget; final Widget? trailing; + final void Function()? onTap; const LogListTile({ - Key? key, + super.key, required this.icon, required this.title, this.subtitle, this.subtitleWidget, this.trailing, - }) : super(key: key); + this.onTap, + }); @override Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: Row( - children: [ - Icon( - icon, - size: 24, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - const SizedBox(width: 16), - Flexible( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: Theme.of(context).colorScheme.onSurface - ), - ), - const SizedBox(height: 3), - subtitleWidget ?? Text( - subtitle!, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).listTileTheme.textColor, - ), - ) - ], + return InkWell( + onTap: onTap, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Row( + children: [ + Icon( + icon, + size: 24, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), - ), - ], + const SizedBox(width: 16), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface + ), + ), + const SizedBox(height: 3), + subtitleWidget ?? Text( + subtitle!, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).listTileTheme.textColor, + ), + ) + ], + ), + ), + ], + ), ), - ), - if (trailing != null) ...[ - const SizedBox(width: 16), - trailing! - ] - ], + if (trailing != null) ...[ + const SizedBox(width: 16), + trailing! + ] + ], + ), ), ); }