diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 45b4526..8017577 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -606,5 +606,6 @@ "remainingTime": "Remaining time", "safeSearchSettings": "Safe search settings", "loadingSafeSearchSettings": "Loading safe search settings...", - "safeSearchSettingsNotLoaded": "Error when loading safe search settings." + "safeSearchSettingsNotLoaded": "Error when loading safe search settings.", + "loadingLogsSettings": "Loading logs settings..." } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 97967c8..61aa7de 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -606,5 +606,6 @@ "remainingTime": "Tiempo restante", "safeSearchSettings": "Configuración de búsqueda segura", "loadingSafeSearchSettings": "Cargando configuración de búsqueda segura...", - "safeSearchSettingsNotLoaded": "Error al cargar la configuración de búsqueda segura." + "safeSearchSettingsNotLoaded": "Error al cargar la configuración de búsqueda segura.", + "loadingLogsSettings": "Cargando configuración de registros..." } \ No newline at end of file diff --git a/lib/screens/logs/clients_modal.dart b/lib/screens/logs/clients_modal.dart index f9b9099..bd39541 100644 --- a/lib/screens/logs/clients_modal.dart +++ b/lib/screens/logs/clients_modal.dart @@ -8,10 +8,12 @@ import 'package:adguard_home_manager/providers/logs_provider.dart'; class ClientsModal extends StatefulWidget { final List? value; + final bool dialog; const ClientsModal({ Key? key, - required this.value + required this.value, + required this.dialog }) : super(key: key); @override @@ -94,44 +96,36 @@ class _ClientsModalState extends State { }); } - return Container( - height: height >= (logsProvider.clients!.length*64) == true - ? logsProvider.clients!.length*64 - : height-50, - decoration: BoxDecoration( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(28), - topRight: Radius.circular(28) - ), - color: Theme.of(context).dialogBackgroundColor - ), - child: Column( + Widget content() { + return Column( + mainAxisSize: MainAxisSize.min, children: [ - Padding( - padding: const EdgeInsets.only( - top: 24, - bottom: 16, - ), - child: Icon( - Icons.smartphone_rounded, - size: 24, - color: Theme.of(context).listTileTheme.iconColor - ), + Column( + children: [ + Padding( + padding: const EdgeInsets.only( + top: 24, + bottom: 16, + ), + child: Icon( + Icons.smartphone_rounded, + size: 24, + color: Theme.of(context).listTileTheme.iconColor + ), + ), + Text( + AppLocalizations.of(context)!.clients, + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface + ), + ), + const SizedBox(height: 16), + ], ), - Text( - AppLocalizations.of(context)!.clients, - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.w400, - color: Theme.of(context).colorScheme.onSurface - ), - ), - const SizedBox(height: 16), - Expanded( + Flexible( child: ListView.builder( - physics: height >= (logsProvider.clients!.length*64) == true - ? const NeverScrollableScrollPhysics() - : null, itemCount: logsProvider.clients!.length, itemBuilder: (context, index) => listItem( label: logsProvider.clients![index].ip, @@ -150,7 +144,7 @@ class _ClientsModalState extends State { } } ) - ), + ) ), Padding( padding: const EdgeInsets.all(24), @@ -176,7 +170,35 @@ class _ClientsModalState extends State { ), if (Platform.isIOS) const SizedBox(height: 16) ], - ), - ); + ); + } + + if (widget.dialog == true) { + return Dialog( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 500 + ), + child: content() + ), + ); + } + else { + return ConstrainedBox( + constraints: BoxConstraints( + maxHeight: height-50 + ), + child: Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(28), + topRight: Radius.circular(28) + ), + color: Theme.of(context).dialogBackgroundColor + ), + child: content() + ), + ); + } } } \ No newline at end of file diff --git a/lib/screens/logs/filter_status_modal.dart b/lib/screens/logs/filter_status_modal.dart index 16d9c5c..aec5aac 100644 --- a/lib/screens/logs/filter_status_modal.dart +++ b/lib/screens/logs/filter_status_modal.dart @@ -8,10 +8,12 @@ import 'package:adguard_home_manager/providers/logs_provider.dart'; class FilterStatusModal extends StatefulWidget { final String value; + final bool dialog; const FilterStatusModal({ Key? key, - required this.value + required this.value, + required this.dialog }) : super(key: key); @override @@ -31,8 +33,6 @@ class _FilterStatusModalState extends State { Widget build(BuildContext context) { final logsProvider = Provider.of(context); - final height = MediaQuery.of(context).size.height; - void apply() async { logsProvider.setSelectedResultStatus(selectedResultStatus); @@ -83,95 +83,94 @@ class _FilterStatusModalState extends State { ); } - return Container( - height: height >= (Platform.isIOS ? 736 : 720) == true - ? (Platform.isIOS ? 736 : 720) - : height-25, - decoration: BoxDecoration( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(28), - topRight: Radius.circular(28) - ), - color: Theme.of(context).dialogBackgroundColor - ), - child: Column( + Widget content() { + return Column( + mainAxisSize: MainAxisSize.min, children: [ - Padding( - padding: const EdgeInsets.only( - top: 24, - bottom: 16, - ), - child: Icon( - Icons.shield_rounded, - size: 24, - color: Theme.of(context).listTileTheme.iconColor - ), - ), - Text( - AppLocalizations.of(context)!.responseStatus, - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.w400, - color: Theme.of(context).colorScheme.onSurface - ), - ), - const SizedBox(height: 16), - Expanded( - child: ListView( - physics: height >= 720 == true - ? const NeverScrollableScrollPhysics() - : null, - children: [ - filterStatusListItem( - id: "all", - icon: Icons.shield_rounded, - label: AppLocalizations.of(context)!.all, - onChanged: (value) => setState(() => selectedResultStatus = value!) - ), - filterStatusListItem( - id: "filtered", - icon: Icons.shield_rounded, - label: AppLocalizations.of(context)!.filtered, - onChanged: (value) => setState(() => selectedResultStatus = value!) - ), - filterStatusListItem( - id: "processed", - icon: Icons.verified_user_rounded, - label: AppLocalizations.of(context)!.processedRow, - onChanged: (value) => setState(() => selectedResultStatus = value!) - ), - filterStatusListItem( - id: "whitelisted", - icon: Icons.verified_user_rounded, - label: AppLocalizations.of(context)!.processedWhitelistRow, - onChanged: (value) => setState(() => selectedResultStatus = value!) - ), - filterStatusListItem( - id: "blocked", - icon: Icons.gpp_bad_rounded, - label: AppLocalizations.of(context)!.blocked, - onChanged: (value) => setState(() => selectedResultStatus = value!) - ), - filterStatusListItem( - id: "blocked_safebrowsing", - icon: Icons.gpp_bad_rounded, - label: AppLocalizations.of(context)!.blockedSafeBrowsingRow, - onChanged: (value) => setState(() => selectedResultStatus = value!) - ), - filterStatusListItem( - id: "blocked_parental", - icon: Icons.gpp_bad_rounded, - label: AppLocalizations.of(context)!.blockedParentalRow, - onChanged: (value) => setState(() => selectedResultStatus = value!) - ), - filterStatusListItem( - id: "safe_search", - icon: Icons.gpp_bad_rounded, - label: AppLocalizations.of(context)!.blockedSafeSearchRow, - onChanged: (value) => setState(() => selectedResultStatus = value!) - ), - - ], + Flexible( + child: SingleChildScrollView( + child: Wrap( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + children: [ + Padding( + padding: const EdgeInsets.only( + top: 24, + bottom: 16, + ), + child: Icon( + Icons.shield_rounded, + size: 24, + color: Theme.of(context).listTileTheme.iconColor + ), + ), + Text( + AppLocalizations.of(context)!.responseStatus, + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface + ), + ), + ], + ) + ], + ), + Container(height: 16), + filterStatusListItem( + id: "all", + icon: Icons.shield_rounded, + label: AppLocalizations.of(context)!.all, + onChanged: (value) => setState(() => selectedResultStatus = value!) + ), + filterStatusListItem( + id: "filtered", + icon: Icons.shield_rounded, + label: AppLocalizations.of(context)!.filtered, + onChanged: (value) => setState(() => selectedResultStatus = value!) + ), + filterStatusListItem( + id: "processed", + icon: Icons.verified_user_rounded, + label: AppLocalizations.of(context)!.processedRow, + onChanged: (value) => setState(() => selectedResultStatus = value!) + ), + filterStatusListItem( + id: "whitelisted", + icon: Icons.verified_user_rounded, + label: AppLocalizations.of(context)!.processedWhitelistRow, + onChanged: (value) => setState(() => selectedResultStatus = value!) + ), + filterStatusListItem( + id: "blocked", + icon: Icons.gpp_bad_rounded, + label: AppLocalizations.of(context)!.blocked, + onChanged: (value) => setState(() => selectedResultStatus = value!) + ), + filterStatusListItem( + id: "blocked_safebrowsing", + icon: Icons.gpp_bad_rounded, + label: AppLocalizations.of(context)!.blockedSafeBrowsingRow, + onChanged: (value) => setState(() => selectedResultStatus = value!) + ), + filterStatusListItem( + id: "blocked_parental", + icon: Icons.gpp_bad_rounded, + label: AppLocalizations.of(context)!.blockedParentalRow, + onChanged: (value) => setState(() => selectedResultStatus = value!) + ), + filterStatusListItem( + id: "safe_search", + icon: Icons.gpp_bad_rounded, + label: AppLocalizations.of(context)!.blockedSafeSearchRow, + onChanged: (value) => setState(() => selectedResultStatus = value!) + ), + + ], + ), ), ), Padding( @@ -188,7 +187,30 @@ class _FilterStatusModalState extends State { ), if (Platform.isIOS) const SizedBox(height: 16) ], - ), - ); + ); + } + + if (widget.dialog == true) { + return Dialog( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 400 + ), + child: content() + ), + ); + } + else { + return Container( + decoration: BoxDecoration( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(28), + topRight: Radius.circular(28) + ), + color: Theme.of(context).dialogBackgroundColor + ), + child: content() + ); + } } } \ No newline at end of file diff --git a/lib/screens/logs/log_tile.dart b/lib/screens/logs/log_tile.dart index ff7b058..5e10280 100644 --- a/lib/screens/logs/log_tile.dart +++ b/lib/screens/logs/log_tile.dart @@ -1,10 +1,10 @@ // ignore_for_file: use_build_context_synchronously + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:adguard_home_manager/screens/home/top_items_options_modal.dart'; -import 'package:adguard_home_manager/screens/logs/log_details_screen.dart'; import 'package:adguard_home_manager/functions/copy_clipboard.dart'; import 'package:adguard_home_manager/functions/block_unblock_domain.dart'; @@ -18,12 +18,16 @@ class LogTile extends StatelessWidget { final Log log; final int length; final int index; + final bool? isLogSelected; + final void Function(Log) onLogTap; const LogTile({ Key? key, required this.log, required this.length, - required this.index + required this.index, + this.isLogSelected, + required this.onLogTap }) : super(key: key); @override @@ -95,133 +99,250 @@ class LogTile extends StatelessWidget { ) ); } - - return Material( - color: Colors.transparent, - child: InkWell( - onTap: () => Navigator.push(context, MaterialPageRoute( - builder: (context) => LogDetailsScreen(log: log) - )), - onLongPress: () => openOptionsModal(log), - child: Container( - width: double.maxFinite, - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox( - width: width-130, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - log.question.name, - style: TextStyle( - fontSize: 16, - height: 1.5, - fontWeight: FontWeight.w400, - color: Theme.of(context).colorScheme.onSurface - ), - ), - const SizedBox(height: 5), - if (log.client.length <= 15 && appConfigProvider.showNameTimeLogs == false) Row( + + if (width > 1100) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Material( + color: Colors.transparent, + borderRadius: BorderRadius.circular(28), + child: InkWell( + borderRadius: BorderRadius.circular(28), + onTap: () => onLogTap(log), + child: Container( + width: double.maxFinite, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(28), + color: isLogSelected == true + ? Theme.of(context).colorScheme.primaryContainer + : null + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Row( + mainAxisSize: MainAxisSize.min, children: [ - ...[ - Icon( - Icons.smartphone_rounded, - size: 16, - color: Theme.of(context).listTileTheme.textColor, - ), - const SizedBox(width: 5), - Flexible( - child: Text( - log.client, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Theme.of(context).listTileTheme.textColor, - fontSize: 14, - height: 1.4, - fontWeight: FontWeight.w400, + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + log.question.name, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface, + ), ), - ), - ) - ], - const SizedBox(width: 15), - ...[ - Icon( - Icons.schedule_rounded, - size: 16, - color: Theme.of(context).listTileTheme.textColor, - ), - const SizedBox(width: 5), - Flexible( - child: Text( - convertTimestampLocalTimezone(log.time, 'HH:mm:ss'), - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Theme.of(context).listTileTheme.textColor, - fontSize: 13 + const SizedBox(height: 5), + if (log.client.length <= 15 && appConfigProvider.showNameTimeLogs == false) Row( + children: [ + ...[ + Icon( + Icons.smartphone_rounded, + size: 16, + color: Theme.of(context).listTileTheme.textColor, + ), + const SizedBox(width: 5), + Flexible( + child: Text( + log.client, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor, + fontSize: 14, + height: 1.4, + fontWeight: FontWeight.w400, + ), + ), + ) + ], + const SizedBox(width: 15), + ...[ + Icon( + Icons.schedule_rounded, + size: 16, + color: Theme.of(context).listTileTheme.textColor, + ), + const SizedBox(width: 5), + Flexible( + child: Text( + convertTimestampLocalTimezone(log.time, 'HH:mm:ss'), + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor, + fontSize: 13 + ), + ), + ), + ], + ], ), - ), + if (log.client.length > 15 || appConfigProvider.showNameTimeLogs == true) Column( + children: [ + Row( + children: [ + Icon( + Icons.smartphone_rounded, + size: 16, + color: Theme.of(context).listTileTheme.textColor, + ), + const SizedBox(width: 15), + Flexible( + child: Text( + log.client, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor, + fontSize: 13 + ), + ), + ) + ], + ), + if (appConfigProvider.showNameTimeLogs == true && log.clientInfo!.name != '') ...[ + const SizedBox(height: 10), + Row( + children: [ + Icon( + Icons.badge_rounded, + size: 16, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + const SizedBox(width: 15), + Flexible( + child: Text( + log.clientInfo!.name, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor, + fontSize: 13 + ), + ), + ) + ], + ), + ], + const SizedBox(height: 10), + Row( + children: [ + Icon( + Icons.schedule_rounded, + size: 16, + color: Theme.of(context).listTileTheme.textColor, + ), + const SizedBox(width: 15), + SizedBox( + child: Text( + convertTimestampLocalTimezone(log.time, 'HH:mm:ss'), + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor, + fontSize: 13 + ), + ), + ) + ], + ), + if (appConfigProvider.showNameTimeLogs == true && log.elapsedMs != '') ...[ + const SizedBox(height: 10), + Row( + children: [ + Icon( + Icons.timer, + size: 16, + color: Theme.of(context).listTileTheme.textColor, + ), + const SizedBox(width: 15), + SizedBox( + child: Text( + "${double.parse(log.elapsedMs).toStringAsFixed(2)} ms", + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor, + fontSize: 13 + ), + ), + ) + ], + ), + ], + ], + ), + ], ), - ], + ) ], ), - if (log.client.length > 15 || appConfigProvider.showNameTimeLogs == true) Column( - children: [ - Row( - children: [ + ), + generateLogStatus() + ], + ) + ), + ), + ), + ); + } + else { + return Material( + color: Colors.transparent, + child: InkWell( + onTap: () => onLogTap(log), + onLongPress: () => openOptionsModal(log), + child: Container( + width: double.maxFinite, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + log.question.name, + style: TextStyle( + fontSize: 16, + height: 1.5, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface + ), + ), + const SizedBox(height: 5), + if (log.client.length <= 15 && appConfigProvider.showNameTimeLogs == false) Row( + children: [ + ...[ Icon( Icons.smartphone_rounded, size: 16, color: Theme.of(context).listTileTheme.textColor, ), - const SizedBox(width: 15), + const SizedBox(width: 5), Flexible( child: Text( log.client, overflow: TextOverflow.ellipsis, style: TextStyle( color: Theme.of(context).listTileTheme.textColor, - fontSize: 13 + fontSize: 14, + height: 1.4, + fontWeight: FontWeight.w400, ), ), ) ], - ), - if (appConfigProvider.showNameTimeLogs == true && log.clientInfo!.name != '') ...[ - const SizedBox(height: 10), - Row( - children: [ - Icon( - Icons.badge_rounded, - size: 16, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - const SizedBox(width: 15), - Flexible( - child: Text( - log.clientInfo!.name, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Theme.of(context).listTileTheme.textColor, - fontSize: 13 - ), - ), - ) - ], - ), - ], - const SizedBox(height: 10), - Row( - children: [ + const SizedBox(width: 15), + ...[ Icon( Icons.schedule_rounded, size: 16, color: Theme.of(context).listTileTheme.textColor, ), - const SizedBox(width: 15), - SizedBox( + const SizedBox(width: 5), + Flexible( child: Text( convertTimestampLocalTimezone(log.time, 'HH:mm:ss'), overflow: TextOverflow.ellipsis, @@ -230,22 +351,23 @@ class LogTile extends StatelessWidget { fontSize: 13 ), ), - ) + ), ], - ), - if (appConfigProvider.showNameTimeLogs == true && log.elapsedMs != '') ...[ - const SizedBox(height: 10), + ], + ), + if (log.client.length > 15 || appConfigProvider.showNameTimeLogs == true) Column( + children: [ Row( children: [ Icon( - Icons.timer, + Icons.smartphone_rounded, size: 16, color: Theme.of(context).listTileTheme.textColor, ), const SizedBox(width: 15), - SizedBox( + Flexible( child: Text( - "${double.parse(log.elapsedMs).toStringAsFixed(2)} ms", + log.client, overflow: TextOverflow.ellipsis, style: TextStyle( color: Theme.of(context).listTileTheme.textColor, @@ -255,18 +377,85 @@ class LogTile extends StatelessWidget { ) ], ), + if (appConfigProvider.showNameTimeLogs == true && log.clientInfo!.name != '') ...[ + const SizedBox(height: 10), + Row( + children: [ + Icon( + Icons.badge_rounded, + size: 16, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + const SizedBox(width: 15), + Flexible( + child: Text( + log.clientInfo!.name, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor, + fontSize: 13 + ), + ), + ) + ], + ), + ], + const SizedBox(height: 10), + Row( + children: [ + Icon( + Icons.schedule_rounded, + size: 16, + color: Theme.of(context).listTileTheme.textColor, + ), + const SizedBox(width: 15), + SizedBox( + child: Text( + convertTimestampLocalTimezone(log.time, 'HH:mm:ss'), + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor, + fontSize: 13 + ), + ), + ) + ], + ), + if (appConfigProvider.showNameTimeLogs == true && log.elapsedMs != '') ...[ + const SizedBox(height: 10), + Row( + children: [ + Icon( + Icons.timer, + size: 16, + color: Theme.of(context).listTileTheme.textColor, + ), + const SizedBox(width: 15), + SizedBox( + child: Text( + "${double.parse(log.elapsedMs).toStringAsFixed(2)} ms", + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor, + fontSize: 13 + ), + ), + ) + ], + ), + ], ], - ], - ), - ], + ), + ], + ), ), - ), - const SizedBox(width: 10), - generateLogStatus() - ], + const SizedBox(width: 10), + generateLogStatus() + ], + ), ), ), - ), - ); + ); + } } } \ No newline at end of file diff --git a/lib/screens/logs/logs.dart b/lib/screens/logs/logs.dart index 5393c04..a900964 100644 --- a/lib/screens/logs/logs.dart +++ b/lib/screens/logs/logs.dart @@ -1,5 +1,7 @@ // ignore_for_file: use_build_context_synchronously +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -7,6 +9,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:adguard_home_manager/screens/logs/logs_filters_modal.dart'; import 'package:adguard_home_manager/screens/logs/logs_config_modal.dart'; import 'package:adguard_home_manager/screens/logs/log_tile.dart'; +import 'package:adguard_home_manager/screens/logs/log_details_screen.dart'; import 'package:adguard_home_manager/functions/snackbar.dart'; import 'package:adguard_home_manager/classes/process_modal.dart'; @@ -64,6 +67,8 @@ class _LogsWidgetState extends State { bool showDivider = true; + Log? selectedLog; + Future fetchLogs({ int? inOffset, bool? loadingMore, @@ -188,6 +193,8 @@ class _LogsWidgetState extends State { final appConfigProvider = Provider.of(context); final logsProvider = Provider.of(context); + final width = MediaQuery.of(context).size.width; + void updateConfig(Map data) async { ProcessModal processModal = ProcessModal(context: context); processModal.open(AppLocalizations.of(context)!.updatingSettings); @@ -252,12 +259,25 @@ class _LogsWidgetState extends State { void openFilersModal() { - showModalBottomSheet( - context: context, - builder: (context) => const LogsFiltersModal(), - backgroundColor: Colors.transparent, - isScrollControlled: true - ); + if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) { + showDialog( + context: context, + builder: (context) => const LogsFiltersModal( + dialog: true, + ), + barrierDismissible: false + ); + } + else { + showModalBottomSheet( + context: context, + builder: (context) => const LogsFiltersModal( + dialog: false, + ), + backgroundColor: Colors.transparent, + isScrollControlled: true + ); + } } final Map translatedString = { @@ -319,6 +339,15 @@ class _LogsWidgetState extends State { log: logsProvider.logsData!.data[index], index: index, length: logsProvider.logsData!.data.length, + isLogSelected: selectedLog != null && selectedLog == logsProvider.logsData!.data[index], + onLogTap: (log) { + if (width <= 700) { + Navigator.push(context, MaterialPageRoute( + builder: (context) => LogDetailsScreen(log: log) + )); + } + setState(() => selectedLog = log); + } ); } } @@ -383,161 +412,207 @@ class _LogsWidgetState extends State { } } - return Scaffold( - appBar: AppBar( - title: Text(AppLocalizations.of(context)!.logs), - centerTitle: false, - actions: [ - logsProvider.loadStatus == 1 - ? IconButton( - onPressed: openFilersModal, - icon: const Icon(Icons.filter_list_rounded) - ) - : const SizedBox(), - IconButton( - onPressed: () => { - showModalBottomSheet( - context: context, - builder: (context) => LogsConfigModal( - onConfirm: updateConfig, - onClear: clearQueries, - ), - backgroundColor: Colors.transparent, - isScrollControlled: true - ) - }, - icon: const Icon(Icons.settings) - ), - const SizedBox(width: 5), - ], - bottom: logsProvider.appliedFilters.searchText != null || logsProvider.appliedFilters.selectedResultStatus != 'all' || logsProvider.appliedFilters.clients != null - ? PreferredSize( - preferredSize: const Size(double.maxFinite, 50), - child: Container( - height: 50, - width: double.maxFinite, - padding: const EdgeInsets.only(bottom: 10), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: showDivider == true - ? Theme.of(context).colorScheme.onSurface.withOpacity(0.1) - : Colors.transparent, - ) + Widget logsScreen() { + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.logs), + centerTitle: false, + actions: [ + if (!(Platform.isAndroid || Platform.isIOS)) IconButton( + onPressed: () => fetchLogs(inOffset: 0), + icon: const Icon(Icons.refresh_rounded), + tooltip: AppLocalizations.of(context)!.refresh, + ), + logsProvider.loadStatus == 1 + ? IconButton( + onPressed: openFilersModal, + icon: const Icon(Icons.filter_list_rounded), + tooltip: AppLocalizations.of(context)!.filters, + ) + : const SizedBox(), + IconButton( + tooltip: AppLocalizations.of(context)!.settings, + onPressed: () => { + if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) { + showDialog( + context: context, + builder: (context) => LogsConfigModal( + onConfirm: updateConfig, + onClear: clearQueries, + dialog: true, + ), + barrierDismissible: false ) - ), - child: ListView( - scrollDirection: Axis.horizontal, - children: [ - if (logsProvider.appliedFilters.searchText != null) ...[ + } + else { + showModalBottomSheet( + context: context, + builder: (context) => LogsConfigModal( + onConfirm: updateConfig, + onClear: clearQueries, + dialog: false, + ), + backgroundColor: Colors.transparent, + isScrollControlled: true + ) + } + }, + icon: const Icon(Icons.settings) + ), + const SizedBox(width: 5), + ], + bottom: logsProvider.appliedFilters.searchText != null || logsProvider.appliedFilters.selectedResultStatus != 'all' || logsProvider.appliedFilters.clients != null + ? PreferredSize( + preferredSize: const Size(double.maxFinite, 50), + child: Container( + height: 50, + width: double.maxFinite, + padding: const EdgeInsets.only(bottom: 10), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: showDivider == true + ? Theme.of(context).colorScheme.onSurface.withOpacity(0.1) + : Colors.transparent, + ) + ) + ), + child: ListView( + scrollDirection: Axis.horizontal, + children: [ + if (logsProvider.appliedFilters.searchText != null) ...[ + const SizedBox(width: 15), + Chip( + avatar: const Icon( + Icons.link_rounded, + ), + label: Row( + children: [ + Text( + logsProvider.appliedFilters.searchText!, + ), + ], + ), + deleteIcon: const Icon( + Icons.clear, + size: 18, + ), + onDeleted: () { + logsProvider.setAppliedFilters( + AppliedFiters( + selectedResultStatus: logsProvider.appliedFilters.selectedResultStatus, + searchText: null, + clients: logsProvider.appliedFilters.clients + ) + ); + logsProvider.setSearchText(null); + fetchLogs( + inOffset: 0, + searchText: '' + ); + }, + ), + ], + if (logsProvider.appliedFilters.selectedResultStatus != 'all') ...[ + const SizedBox(width: 15), + Chip( + avatar: const Icon( + Icons.shield_rounded, + ), + label: Row( + children: [ + Text( + translatedString[logsProvider.appliedFilters.selectedResultStatus]!, + ), + ], + ), + deleteIcon: const Icon( + Icons.clear, + size: 18, + ), + onDeleted: () { + logsProvider.setAppliedFilters( + AppliedFiters( + selectedResultStatus: 'all', + searchText: logsProvider.appliedFilters.searchText, + clients: logsProvider.appliedFilters.clients + ) + ); + logsProvider.setSelectedResultStatus('all'); + fetchLogs( + inOffset: 0, + responseStatus: 'all' + ); + }, + ), + ], + if (logsProvider.appliedFilters.clients != null) ...[ + const SizedBox(width: 15), + Chip( + avatar: const Icon( + Icons.smartphone_rounded, + ), + label: Row( + children: [ + Text( + logsProvider.appliedFilters.clients!.length == 1 + ? logsProvider.appliedFilters.clients![0] + : "${logsProvider.appliedFilters.clients!.length} ${AppLocalizations.of(context)!.clients}", + ), + ], + ), + deleteIcon: const Icon( + Icons.clear, + size: 18, + ), + onDeleted: () { + logsProvider.setAppliedFilters( + AppliedFiters( + selectedResultStatus: logsProvider.appliedFilters.selectedResultStatus, + searchText: logsProvider.appliedFilters.searchText, + clients: null + ) + ); + logsProvider.setSelectedClients(null); + fetchLogs( + inOffset: 0, + responseStatus: logsProvider.appliedFilters.selectedResultStatus + ); + }, + ), + ], const SizedBox(width: 15), - Chip( - avatar: const Icon( - Icons.link_rounded, - ), - label: Row( - children: [ - Text( - logsProvider.appliedFilters.searchText!, - ), - ], - ), - deleteIcon: const Icon( - Icons.clear, - size: 18, - ), - onDeleted: () { - logsProvider.setAppliedFilters( - AppliedFiters( - selectedResultStatus: logsProvider.appliedFilters.selectedResultStatus, - searchText: null, - clients: logsProvider.appliedFilters.clients - ) - ); - logsProvider.setSearchText(null); - fetchLogs( - inOffset: 0, - searchText: '' - ); - }, - ), ], - if (logsProvider.appliedFilters.selectedResultStatus != 'all') ...[ - const SizedBox(width: 15), - Chip( - avatar: const Icon( - Icons.shield_rounded, - ), - label: Row( - children: [ - Text( - translatedString[logsProvider.appliedFilters.selectedResultStatus]!, - ), - ], - ), - deleteIcon: const Icon( - Icons.clear, - size: 18, - ), - onDeleted: () { - logsProvider.setAppliedFilters( - AppliedFiters( - selectedResultStatus: 'all', - searchText: logsProvider.appliedFilters.searchText, - clients: logsProvider.appliedFilters.clients - ) - ); - logsProvider.setSelectedResultStatus('all'); - fetchLogs( - inOffset: 0, - responseStatus: 'all' - ); - }, - ), - ], - if (logsProvider.appliedFilters.clients != null) ...[ - const SizedBox(width: 15), - Chip( - avatar: const Icon( - Icons.smartphone_rounded, - ), - label: Row( - children: [ - Text( - logsProvider.appliedFilters.clients!.length == 1 - ? logsProvider.appliedFilters.clients![0] - : "${logsProvider.appliedFilters.clients!.length} ${AppLocalizations.of(context)!.clients}", - ), - ], - ), - deleteIcon: const Icon( - Icons.clear, - size: 18, - ), - onDeleted: () { - logsProvider.setAppliedFilters( - AppliedFiters( - selectedResultStatus: logsProvider.appliedFilters.selectedResultStatus, - searchText: logsProvider.appliedFilters.searchText, - clients: null - ) - ); - logsProvider.setSelectedClients(null); - fetchLogs( - inOffset: 0, - responseStatus: logsProvider.appliedFilters.selectedResultStatus - ); - }, - ), - ], - const SizedBox(width: 15), - ], - ), + ), + ) ) + : null, + ), + body: generateBody() + ); + } + + if (width > 1100) { + return Material( + color: Colors.transparent, + child: Row( + children: [ + Expanded( + flex: 1, + child: logsScreen() + ), + Expanded( + flex: 2, + child: selectedLog != null + ? LogDetailsScreen(log: selectedLog!) + : const SizedBox() ) - : null, - ), - body: generateBody() - ); + ], + ), + ); + } + else { + return logsScreen(); + } } } \ No newline at end of file diff --git a/lib/screens/logs/logs_config_modal.dart b/lib/screens/logs/logs_config_modal.dart index 9af7335..a540559 100644 --- a/lib/screens/logs/logs_config_modal.dart +++ b/lib/screens/logs/logs_config_modal.dart @@ -12,11 +12,13 @@ import 'package:adguard_home_manager/providers/servers_provider.dart'; class LogsConfigModal extends StatelessWidget { final void Function(Map) onConfirm; final void Function() onClear; + final bool dialog; const LogsConfigModal({ Key? key, required this.onConfirm, required this.onClear, + required this.dialog }) : super(key: key); @override @@ -30,6 +32,7 @@ class LogsConfigModal extends StatelessWidget { context: context, onConfirm: onConfirm, onClear: onClear, + dialog: dialog, ); } } @@ -40,6 +43,7 @@ class LogsConfigModalWidget extends StatefulWidget { final BuildContext context; final void Function(Map) onConfirm; final void Function() onClear; + final bool dialog; const LogsConfigModalWidget({ Key? key, @@ -48,6 +52,7 @@ class LogsConfigModalWidget extends StatefulWidget { required this.context, required this.onConfirm, required this.onClear, + required this.dialog }) : super(key: key); @override @@ -146,125 +151,154 @@ class _LogsConfigModalWidgetState extends State { Widget generateBody() { switch (loadStatus) { case 0: - return const Center( - child: CircularProgressIndicator(), + return Padding( + padding: const EdgeInsets.all(24), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + const CircularProgressIndicator(), + const SizedBox(height: 30), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Text( + AppLocalizations.of(context)!.loadingLogsSettings, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22, + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), + ) + ], + ), ); case 1: return Column( + mainAxisSize: MainAxisSize.min, children: [ - Expanded( - child: ListView( - physics: (Platform.isIOS ? 436 : 420) < MediaQuery.of(context).size.height - ? const NeverScrollableScrollPhysics() - : null, - children: [ - Padding( - padding: const EdgeInsets.only(top: 24), - child: Icon( - Icons.settings, - size: 24, - color: Theme.of(context).listTileTheme.iconColor - ), - ), - const SizedBox(height: 16), - Text( - AppLocalizations.of(context)!.logsSettings, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 24, - color: Theme.of(context).colorScheme.onSurface - ), - ), - const SizedBox(height: 16), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24), - child: Material( - color: Theme.of(context).colorScheme.primary.withOpacity(0.1), - borderRadius: BorderRadius.circular(28), - child: InkWell( - onTap: () => setState(() => generalSwitch = !generalSwitch), - borderRadius: BorderRadius.circular(28), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 8 - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - AppLocalizations.of(context)!.enableLog, - style: const TextStyle( - fontSize: 18, - ), + Flexible( + child: SingleChildScrollView( + child: Wrap( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + children: [ + Padding( + padding: const EdgeInsets.only(top: 24), + child: Icon( + Icons.settings, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), - Switch( - value: generalSwitch, - onChanged: (value) => setState(() => generalSwitch = value), - ) - ], + ), + const SizedBox(height: 16), + Text( + AppLocalizations.of(context)!.logsSettings, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface + ), + ), + const SizedBox(height: 16), + ], + ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Material( + color: Theme.of(context).colorScheme.primary.withOpacity(0.1), + borderRadius: BorderRadius.circular(28), + child: InkWell( + onTap: () => setState(() => generalSwitch = !generalSwitch), + borderRadius: BorderRadius.circular(28), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 8 + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + AppLocalizations.of(context)!.enableLog, + style: const TextStyle( + fontSize: 18, + ), + ), + Switch( + value: generalSwitch, + onChanged: (value) => setState(() => generalSwitch = value), + ) + ], + ), ), ), ), ), - ), - const SizedBox(height: 16), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 14), - child: Column( - children: [ - Material( - color: Colors.transparent, - child: InkWell( - onTap: () => setState(() => anonymizeClientIp = !anonymizeClientIp), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - AppLocalizations.of(context)!.anonymizeClientIp, - style: const TextStyle( - fontSize: 16 + Container(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 14), + child: Column( + children: [ + Material( + color: Colors.transparent, + child: InkWell( + onTap: () => setState(() => anonymizeClientIp = !anonymizeClientIp), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 30), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + AppLocalizations.of(context)!.anonymizeClientIp, + style: const TextStyle( + fontSize: 16 + ), ), - ), - Switch( - value: anonymizeClientIp, - onChanged: (value) => setState(() => anonymizeClientIp = value), + Switch( + value: anonymizeClientIp, + onChanged: (value) => setState(() => anonymizeClientIp = value), + ) + ], + ), + ), + ), + ), + Container(height: 16), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: DropdownButtonFormField( + items: retentionItems.map>((Map item) { + return DropdownMenuItem( + value: item['value'].toString(), + child: Text(item['label']), + ); + }).toList(), + value: retentionTime, + onChanged: (value) => setState(() => retentionTime = value), + decoration: InputDecoration( + border: const OutlineInputBorder( + borderRadius: BorderRadius.all( + Radius.circular(10) ) - ], + ), + label: Text(AppLocalizations.of(context)!.retentionTime) ), + borderRadius: BorderRadius.circular(20), ), ), - ), - const SizedBox(height: 16), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24), - child: DropdownButtonFormField( - items: retentionItems.map>((Map item) { - return DropdownMenuItem( - value: item['value'].toString(), - child: Text(item['label']), - ); - }).toList(), - value: retentionTime, - onChanged: (value) => setState(() => retentionTime = value), - decoration: InputDecoration( - border: const OutlineInputBorder( - borderRadius: BorderRadius.all( - Radius.circular(10) - ) - ), - label: Text(AppLocalizations.of(context)!.retentionTime) - ), - borderRadius: BorderRadius.circular(20), - ), - ), - ], - ), - ) - ], + ], + ), + ) + ], + ), ), ), Padding( @@ -316,31 +350,29 @@ class _LogsConfigModalWidgetState extends State { ); case 2: - return SizedBox( - width: double.maxFinite, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Icon( - Icons.error, - color: Colors.red, - size: 50, - ), - const SizedBox(height: 30), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Text( - AppLocalizations.of(context)!.logSettingsNotLoaded, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 22, - color: Colors.grey, - ), + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + const Icon( + Icons.error, + color: Colors.red, + size: 50, + ), + const SizedBox(height: 30), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Text( + AppLocalizations.of(context)!.logSettingsNotLoaded, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22, + color: Theme.of(context).colorScheme.onSurfaceVariant ), - ) - ], - ), + ), + ) + ], ); default: @@ -348,16 +380,28 @@ class _LogsConfigModalWidgetState extends State { } } - return Container( - height: Platform.isIOS ? 436 : 420, - decoration: BoxDecoration( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(28), - topRight: Radius.circular(28) + if (widget.dialog == true) { + return Dialog( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 500 + ), + child: generateBody() ), - color: Theme.of(context).dialogBackgroundColor - ), - child: generateBody() - ); + ); + } + else { + return Container( + height: Platform.isIOS ? 436 : 420, + decoration: BoxDecoration( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(28), + topRight: Radius.circular(28) + ), + color: Theme.of(context).dialogBackgroundColor + ), + child: generateBody() + ); + } } } \ No newline at end of file diff --git a/lib/screens/logs/logs_filters_modal.dart b/lib/screens/logs/logs_filters_modal.dart index e9a6052..19ba0c0 100644 --- a/lib/screens/logs/logs_filters_modal.dart +++ b/lib/screens/logs/logs_filters_modal.dart @@ -18,24 +18,32 @@ import 'package:adguard_home_manager/models/applied_filters.dart'; import 'package:adguard_home_manager/providers/logs_provider.dart'; class LogsFiltersModal extends StatelessWidget { - const LogsFiltersModal({Key? key}) : super(key: key); + final bool dialog; + + const LogsFiltersModal({ + Key? key, + required this.dialog + }) : super(key: key); @override Widget build(BuildContext context) { final logsProvider = Provider.of(context); return LogsFiltersModalWidget( - logsProvider: logsProvider + logsProvider: logsProvider, + dialog: dialog, ); } } class LogsFiltersModalWidget extends StatefulWidget { final LogsProvider logsProvider; + final bool dialog; const LogsFiltersModalWidget({ Key? key, - required this.logsProvider + required this.logsProvider, + required this.dialog }) : super(key: key); @override @@ -57,6 +65,8 @@ class _LogsFiltersModalWidgetState extends State { final serversProvider = Provider.of(context); final appConfigProvider = Provider.of(context); + final width = MediaQuery.of(context).size.width; + final Map translatedString = { "all": AppLocalizations.of(context)!.all, "filtered": AppLocalizations.of(context)!.filtered, @@ -101,25 +111,51 @@ class _LogsFiltersModalWidgetState extends State { } void openSelectFilterStatus() { - showModalBottomSheet( - context: context, - builder: (context) => FilterStatusModal( - value: logsProvider.selectedResultStatus, - ), - isScrollControlled: true, - backgroundColor: Colors.transparent - ); + if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) { + showDialog( + barrierDismissible: false, + context: context, + builder: (context) => FilterStatusModal( + value: logsProvider.selectedResultStatus, + dialog: true, + ), + ); + } + else { + showModalBottomSheet( + context: context, + builder: (context) => FilterStatusModal( + value: logsProvider.selectedResultStatus, + dialog: false, + ), + isScrollControlled: true, + backgroundColor: Colors.transparent + ); + } } void openSelectClients() { - showModalBottomSheet( - context: context, - builder: (context) => ClientsModal( - value: logsProvider.selectedClients, - ), - isScrollControlled: true, - backgroundColor: Colors.transparent - ); + if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) { + showDialog( + context: context, + builder: (context) => ClientsModal( + value: logsProvider.selectedClients, + dialog: true, + ), + barrierDismissible: false + ); + } + else { + showModalBottomSheet( + context: context, + builder: (context) => ClientsModal( + value: logsProvider.selectedClients, + dialog: false, + ), + isScrollControlled: true, + backgroundColor: Colors.transparent + ); + } } void filterLogs() async { @@ -161,47 +197,45 @@ class _LogsFiltersModalWidgetState extends State { } } - return Padding( - padding: MediaQuery.of(context).viewInsets, - child: Container( - height: Platform.isIOS ? 446 : 430, - decoration: BoxDecoration( - color: Theme.of(context).dialogBackgroundColor, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(28), - topRight: Radius.circular(28) - ) - ), - child: Column( - children: [ - Expanded( - child: ListView( - physics: (Platform.isIOS ? 416 : 400) < MediaQuery.of(context).size.height - ? const NeverScrollableScrollPhysics() - : null, + Widget content() { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible( + child: SingleChildScrollView( + child: Wrap( children: [ - Padding( - padding: const EdgeInsets.only( - top: 24, - bottom: 16, - ), - child: Icon( - Icons.filter_list_rounded, - size: 24, - color: Theme.of(context).listTileTheme.iconColor - ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Column( + children: [ + Padding( + padding: const EdgeInsets.only( + top: 24, + bottom: 16, + ), + child: Icon( + Icons.filter_list_rounded, + size: 24, + color: Theme.of(context).listTileTheme.iconColor + ), + ), + Text( + AppLocalizations.of(context)!.filters, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w400, + height: 1.3, + color: Theme.of(context).colorScheme.onSurface + ), + ), + const SizedBox(height: 16), + ], + ), + ], ), - Text( - AppLocalizations.of(context)!.filters, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.w400, - height: 1.3, - color: Theme.of(context).colorScheme.onSurface - ), - ), - const SizedBox(height: 16), Padding( padding: const EdgeInsets.symmetric(horizontal: 24), child: Row( @@ -233,7 +267,7 @@ class _LogsFiltersModalWidgetState extends State { ], ), ), - const SizedBox(height: 16), + Container(height: 16), CustomListTile( title: AppLocalizations.of(context)!.client, subtitle: logsProvider.selectedClients != null @@ -270,26 +304,55 @@ class _LogsFiltersModalWidgetState extends State { ], ), ), - Padding( - padding: const EdgeInsets.all(24), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - TextButton( - onPressed: resetFilters, - child: Text(AppLocalizations.of(context)!.resetFilters) - ), - TextButton( - onPressed: () => filterLogs(), - child: Text(AppLocalizations.of(context)!.apply) - ), - ], - ), + ), + Padding( + padding: const EdgeInsets.all(24), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + TextButton( + onPressed: resetFilters, + child: Text(AppLocalizations.of(context)!.resetFilters) + ), + TextButton( + onPressed: () => filterLogs(), + child: Text(AppLocalizations.of(context)!.apply) + ), + ], ), - if (Platform.isIOS) const SizedBox(height: 16) - ], + ), + if (Platform.isIOS) const SizedBox(height: 16) + ], + ); + } + + if (widget.dialog == true) { + return Padding( + padding: MediaQuery.of(context).viewInsets, + child: Dialog( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 500 + ), + child: content() + ) ), - ), - ); + ); + } + else { + return Padding( + padding: MediaQuery.of(context).viewInsets, + child: Container( + decoration: BoxDecoration( + color: Theme.of(context).dialogBackgroundColor, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(28), + topRight: Radius.circular(28) + ) + ), + child: content() + ), + ); + } } } \ No newline at end of file