From 946f779567ef57f4b70f8d3504a01758b7d1f4c5 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Mon, 27 Nov 2023 15:05:26 +0100 Subject: [PATCH 1/6] Fixed encryption error message --- lib/services/api_client.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/api_client.dart b/lib/services/api_client.dart index 25b6fa3..636cc34 100644 --- a/lib/services/api_client.dart +++ b/lib/services/api_client.dart @@ -743,7 +743,7 @@ class ApiClientV2 { return ApiResponse( successful: result.successful, content: result.body != null ? EncryptionValidationResult( - isObject: false, + isObject: true, encryptionValidation: EncryptionValidation.fromJson(jsonDecode(result.body!)) ) : null ); From bddfac7e721b13f701943fc241a28b7b82a164a9 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Wed, 29 Nov 2023 10:32:12 +0100 Subject: [PATCH 2/6] Removed fixed text size --- lib/main.dart | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 5b38138..9734263 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -236,20 +236,9 @@ class _MainState extends State
{ ], scaffoldMessengerKey: scaffoldMessengerKey, navigatorKey: globalNavigatorKey, - builder: (context, child) { - return CustomMenuBar( - child: MediaQuery( - data: MediaQuery.of(context).copyWith( - textScaler: TextScaler.linear( - !(Platform.isAndroid || Platform.isIOS) - ? 0.9 - : 1.0 - ) - ), - child: child!, - ), - ); - }, + builder: (context, child) => CustomMenuBar( + child: child!, + ), home: const Layout(), ), ); From c9c960d1ee38f52667aa533ade8d76cbc7e6e106 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Wed, 29 Nov 2023 11:56:28 +0100 Subject: [PATCH 3/6] Adapt ui to support text scale --- .../client/blocked_services_section.dart | 60 +-- lib/screens/clients/client/client_form.dart | 16 +- lib/screens/clients/client/client_screen.dart | 4 +- lib/screens/clients/client/tags_modal.dart | 18 +- .../modals/update_interval_lists_modal.dart | 340 +++++++++-------- .../filters/selection/selection_screen.dart | 11 +- lib/screens/home/chart.dart | 4 +- .../home/management_modal/main_switch.dart | 64 ++-- .../management_modal/management_modal.dart | 3 +- lib/screens/home/server_status.dart | 99 +++-- lib/screens/home/status_box.dart | 4 +- .../logs/configuration/config_widgets.dart | 34 +- .../logs/configuration/logs_config_modal.dart | 1 - lib/screens/logs/filters/clients_modal.dart | 10 +- .../logs/filters/filter_status_modal.dart | 354 ++++++++++-------- .../settings/dhcp/add_static_lease_modal.dart | 42 ++- lib/screens/settings/dhcp/dhcp.dart | 1 + .../settings/dhcp/dhcp_interface_item.dart | 17 +- .../settings/dhcp/select_interface_modal.dart | 4 +- .../settings/dns/clear_dns_cache_dialog.dart | 5 +- .../settings/dns_rewrites/dns_rewrites.dart | 4 +- .../settings/safe_search_settings.dart | 10 +- lib/widgets/custom_list_tile_dialog.dart | 14 +- 23 files changed, 624 insertions(+), 495 deletions(-) diff --git a/lib/screens/clients/client/blocked_services_section.dart b/lib/screens/clients/client/blocked_services_section.dart index 37c01d3..f6effd4 100644 --- a/lib/screens/clients/client/blocked_services_section.dart +++ b/lib/screens/clients/client/blocked_services_section.dart @@ -10,12 +10,12 @@ class BlockedServicesSection extends StatelessWidget { final void Function(bool) onUpdateServicesGlobalSettings; const BlockedServicesSection({ - Key? key, + super.key, required this.useGlobalSettingsServices, required this.blockedServices, required this.onUpdatedBlockedServices, required this.onUpdateServicesGlobalSettings - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -37,11 +37,13 @@ class BlockedServicesSection extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - AppLocalizations.of(context)!.useGlobalSettings, - style: TextStyle( - fontSize: 16, - color: Theme.of(context).colorScheme.onSurface + Flexible( + child: Text( + AppLocalizations.of(context)!.useGlobalSettings, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface + ), ), ), Switch( @@ -78,30 +80,32 @@ class BlockedServicesSection extends StatelessWidget { : Theme.of(context).colorScheme.onSurface.withOpacity(0.38), ), const SizedBox(width: 16), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context)!.selectBlockedServices, - style: TextStyle( - fontSize: 16, - color: useGlobalSettingsServices == false - ? Theme.of(context).colorScheme.onSurface - : Theme.of(context).colorScheme.onSurface.withOpacity(0.38), - ), - ), - if (useGlobalSettingsServices == false) ...[ - const SizedBox(height: 5), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ Text( - blockedServices.isNotEmpty - ? "${blockedServices.length} ${AppLocalizations.of(context)!.servicesBlocked}" - : AppLocalizations.of(context)!.noBlockedServicesSelected, + AppLocalizations.of(context)!.selectBlockedServices, style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor + fontSize: 16, + color: useGlobalSettingsServices == false + ? Theme.of(context).colorScheme.onSurface + : Theme.of(context).colorScheme.onSurface.withOpacity(0.38), ), - ) - ] - ], + ), + if (useGlobalSettingsServices == false) ...[ + const SizedBox(height: 5), + Text( + blockedServices.isNotEmpty + ? "${blockedServices.length} ${AppLocalizations.of(context)!.servicesBlocked}" + : AppLocalizations.of(context)!.noBlockedServicesSelected, + style: TextStyle( + color: Theme.of(context).listTileTheme.iconColor + ), + ) + ] + ], + ), ) ], ), diff --git a/lib/screens/clients/client/client_form.dart b/lib/screens/clients/client/client_form.dart index 5d54b86..2151288 100644 --- a/lib/screens/clients/client/client_form.dart +++ b/lib/screens/clients/client/client_form.dart @@ -47,7 +47,7 @@ class ClientForm extends StatelessWidget { final void Function(bool) updateUseGlobalSettingsServices; const ClientForm({ - Key? key, + super.key, required this.isFullScreen, required this.client, required this.nameController, @@ -75,7 +75,7 @@ class ClientForm extends StatelessWidget { required this.updateEnableSafeSearch, required this.updateSafeSearch, required this.updateUseGlobalSettingsServices, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -154,11 +154,13 @@ class ClientForm extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - AppLocalizations.of(context)!.useGlobalSettings, - style: TextStyle( - fontSize: 16, - color: Theme.of(context).colorScheme.onSurface + Flexible( + child: Text( + AppLocalizations.of(context)!.useGlobalSettings, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface + ), ), ), Switch( diff --git a/lib/screens/clients/client/client_screen.dart b/lib/screens/clients/client/client_screen.dart index 34fb88b..2ab5c75 100644 --- a/lib/screens/clients/client/client_screen.dart +++ b/lib/screens/clients/client/client_screen.dart @@ -27,12 +27,12 @@ class ClientScreen extends StatefulWidget { final bool fullScreen; const ClientScreen({ - Key? key, + super.key, this.client, required this.onConfirm, this.onDelete, required this.fullScreen - }) : super(key: key); + }); @override State createState() => _ClientScreenState(); diff --git a/lib/screens/clients/client/tags_modal.dart b/lib/screens/clients/client/tags_modal.dart index 42843b1..0756c83 100644 --- a/lib/screens/clients/client/tags_modal.dart +++ b/lib/screens/clients/client/tags_modal.dart @@ -7,11 +7,11 @@ class TagsModal extends StatefulWidget { final void Function(List) onConfirm; const TagsModal({ - Key? key, + super.key, required this.selectedTags, required this.tags, required this.onConfirm, - }) : super(key: key); + }); @override State createState() => _TagsModalState(); @@ -82,12 +82,14 @@ class _TagsModalState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - widget.tags[index], - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: Theme.of(context).colorScheme.onSurface, + Flexible( + child: Text( + widget.tags[index], + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface, + ), ), ), Checkbox( diff --git a/lib/screens/filters/modals/update_interval_lists_modal.dart b/lib/screens/filters/modals/update_interval_lists_modal.dart index deb714f..4827082 100644 --- a/lib/screens/filters/modals/update_interval_lists_modal.dart +++ b/lib/screens/filters/modals/update_interval_lists_modal.dart @@ -12,11 +12,11 @@ class UpdateIntervalListsModal extends StatefulWidget { final bool dialog; const UpdateIntervalListsModal({ - Key? key, + super.key, required this.interval, required this.onChange, required this.dialog - }) : super(key: key); + }); @override State createState() => _UpdateIntervalListsModalState(); @@ -25,7 +25,7 @@ class UpdateIntervalListsModal extends StatefulWidget { class _UpdateIntervalListsModalState extends State { int? selectedOption; - void _updateRadioValue(value) { + void _updateRadioValue(int value) { setState(() { selectedOption = value; }); @@ -41,18 +41,67 @@ class _UpdateIntervalListsModalState extends State { Widget build(BuildContext context) { final MediaQueryData mediaQueryData = MediaQuery.of(context); - Widget content() { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - Flexible( - child: SingleChildScrollView( - child: Wrap( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Column( + if (widget.dialog == true) { + return Dialog( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 500 + ), + child: _Content( + selectedOption: selectedOption, + onUpdateValue: _updateRadioValue, + onConfirm: () => widget.onChange(selectedOption!), + ) + ), + ); + } + else { + return Padding( + padding: mediaQueryData.viewInsets, + child: Container( + decoration: BoxDecoration( + color: Theme.of(context).dialogBackgroundColor, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(28), + topRight: Radius.circular(28) + ), + ), + child: _Content( + selectedOption: selectedOption, + onUpdateValue: _updateRadioValue, + onConfirm: () => widget.onChange(selectedOption!), + ) + ), + ); + } + } +} + +class _Content extends StatelessWidget { + final int? selectedOption; + final void Function(int) onUpdateValue; + final void Function() onConfirm; + + const _Content({ + required this.selectedOption, + required this.onUpdateValue, + required this.onConfirm, + }); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible( + child: SingleChildScrollView( + child: Wrap( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Flexible( + child: Column( children: [ Padding( padding: const EdgeInsets.only(top: 24), @@ -62,7 +111,7 @@ class _UpdateIntervalListsModalState extends State { color: Theme.of(context).listTileTheme.iconColor ), ), - Container( + Padding( padding: const EdgeInsets.symmetric( horizontal: 24, vertical: 16 @@ -78,157 +127,128 @@ class _UpdateIntervalListsModalState extends State { ), ), ], - ) + ), + ) + ], + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Wrap( + runSpacing: 16, + children: [ + FractionallySizedBox( + widthFactor: 0.5, + child: Padding( + padding: const EdgeInsets.only(right: 6), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 0, + onTap: (v) => onUpdateValue(v as int), + label: AppLocalizations.of(context)!.never, + ), + ), + ), + FractionallySizedBox( + widthFactor: 0.5, + child: Padding( + padding: const EdgeInsets.only(left: 6), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 1, + onTap: (v) => onUpdateValue(v as int), + label: AppLocalizations.of(context)!.hour1, + ), + ), + ), + FractionallySizedBox( + widthFactor: 0.5, + child: Padding( + padding: const EdgeInsets.only(right: 6), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 12, + onTap: (v) => onUpdateValue(v as int), + label: AppLocalizations.of(context)!.hours12, + ), + ), + ), + FractionallySizedBox( + widthFactor: 0.5, + child: Padding( + padding: const EdgeInsets.only(left: 6), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 24, + onTap: (v) => onUpdateValue(v as int), + label: AppLocalizations.of(context)!.hours24, + ), + ), + ), + FractionallySizedBox( + widthFactor: 0.5, + child: Padding( + padding: const EdgeInsets.only(right: 6), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 72, + onTap: (v) => onUpdateValue(v as int), + label: AppLocalizations.of(context)!.days3, + ), + ), + ), + FractionallySizedBox( + widthFactor: 0.5, + child: Padding( + padding: const EdgeInsets.only(left: 6), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 168, + onTap: (v) => onUpdateValue(v as int), + label: AppLocalizations.of(context)!.days7, + ), + ), + ), ], ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 24), - child: Wrap( - runSpacing: 16, - children: [ - FractionallySizedBox( - widthFactor: 0.5, - child: Padding( - padding: const EdgeInsets.only(right: 6), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 0, - onTap: _updateRadioValue, - label: AppLocalizations.of(context)!.never, - ), - ), - ), - FractionallySizedBox( - widthFactor: 0.5, - child: Padding( - padding: const EdgeInsets.only(left: 6), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 1, - onTap: _updateRadioValue, - label: AppLocalizations.of(context)!.hour1, - ), - ), - ), - FractionallySizedBox( - widthFactor: 0.5, - child: Padding( - padding: const EdgeInsets.only(right: 6), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 12, - onTap: _updateRadioValue, - label: AppLocalizations.of(context)!.hours12, - ), - ), - ), - FractionallySizedBox( - widthFactor: 0.5, - child: Padding( - padding: const EdgeInsets.only(left: 6), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 24, - onTap: _updateRadioValue, - label: AppLocalizations.of(context)!.hours24, - - ), - ), - ), - FractionallySizedBox( - widthFactor: 0.5, - child: Padding( - padding: const EdgeInsets.only(right: 6), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 72, - onTap: _updateRadioValue, - label: AppLocalizations.of(context)!.days3, - - ), - ), - ), - FractionallySizedBox( - widthFactor: 0.5, - child: Padding( - padding: const EdgeInsets.only(left: 6), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 168, - onTap: _updateRadioValue, - label: AppLocalizations.of(context)!.days7, - ), - ), - ), - ], - ), - ) - ], - ), - ), - ), - Padding( - padding: const EdgeInsets.all(24), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: Text(AppLocalizations.of(context)!.cancel), - ), - const SizedBox(width: 20), - TextButton( - onPressed: selectedOption != null - ? () { - Navigator.pop(context); - widget.onChange(selectedOption!); - } - : null, - style: ButtonStyle( - overlayColor: MaterialStateProperty.all( - Theme.of(context).colorScheme.primary.withOpacity(0.1) - ), - foregroundColor: MaterialStateProperty.all( - selectedOption != null - ? Theme.of(context).colorScheme.primary - : Colors.grey, - ), - ), - child: Text(AppLocalizations.of(context)!.confirm), - ), + ) ], ), ), - if (Platform.isIOS) const SizedBox(height: 16) - ], - ); - } - - if (widget.dialog == true) { - return Dialog( - child: ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 500 - ), - child: content() ), - ); - } - else { - return Padding( - padding: mediaQueryData.viewInsets, - child: Container( - height: Platform.isIOS ? 406 : 390, - decoration: BoxDecoration( - color: Theme.of(context).dialogBackgroundColor, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(28), - topRight: Radius.circular(28) - ), + Padding( + padding: const EdgeInsets.all(24), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text(AppLocalizations.of(context)!.cancel), + ), + const SizedBox(width: 20), + TextButton( + onPressed: selectedOption != null + ? () { + Navigator.pop(context); + onConfirm(); + } + : null, + style: ButtonStyle( + overlayColor: MaterialStateProperty.all( + Theme.of(context).colorScheme.primary.withOpacity(0.1) + ), + foregroundColor: MaterialStateProperty.all( + selectedOption != null + ? Theme.of(context).colorScheme.primary + : Colors.grey, + ), + ), + child: Text(AppLocalizations.of(context)!.confirm), + ), + ], ), - child: content() ), - ); - } + if (Platform.isIOS) const SizedBox(height: 16) + ], + ); } } \ No newline at end of file diff --git a/lib/screens/filters/selection/selection_screen.dart b/lib/screens/filters/selection/selection_screen.dart index 11539b2..1475454 100644 --- a/lib/screens/filters/selection/selection_screen.dart +++ b/lib/screens/filters/selection/selection_screen.dart @@ -197,7 +197,7 @@ class _SelectionScreenState extends State with TickerProviderSt ), _Tab( icon: Icons.gpp_bad_rounded, - text: AppLocalizations.of(context)!.blacklist, + text: AppLocalizations.of(context)!.blacklists, quantity: _selectedBlacklists.length ), ] @@ -263,7 +263,7 @@ class _SelectionScreenState extends State with TickerProviderSt ), _Tab( icon: Icons.gpp_bad_rounded, - text: AppLocalizations.of(context)!.blacklist, + text: AppLocalizations.of(context)!.blacklists, quantity: _selectedBlacklists.length ), ] @@ -336,7 +336,12 @@ class _Tab extends StatelessWidget { children: [ Icon(icon), const SizedBox(width: 8), - Text(text), + Flexible( + child: Text( + text, + overflow: TextOverflow.ellipsis, + ) + ), const SizedBox(width: 8), Container( height: 22, diff --git a/lib/screens/home/chart.dart b/lib/screens/home/chart.dart index 682d5b9..ba97f79 100644 --- a/lib/screens/home/chart.dart +++ b/lib/screens/home/chart.dart @@ -14,14 +14,14 @@ class HomeChart extends StatelessWidget { final int hoursInterval; const HomeChart({ - Key? key, + super.key, required this.data, required this.label, required this.primaryValue, required this.secondaryValue, required this.color, required this.hoursInterval - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/screens/home/management_modal/main_switch.dart b/lib/screens/home/management_modal/main_switch.dart index d4ce5ed..3dbe0ec 100644 --- a/lib/screens/home/management_modal/main_switch.dart +++ b/lib/screens/home/management_modal/main_switch.dart @@ -15,12 +15,12 @@ class MainSwitch extends StatelessWidget { final Animation animation; const MainSwitch({ - Key? key, + super.key, required this.expandableController, required this.updateBlocking, required this.disableWithCountdown, required this.animation, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -88,12 +88,11 @@ class _TopRow extends StatelessWidget { final Animation animation; const _TopRow({ - Key? key, required this.legacyMode, required this.expandableController, required this.updateBlocking, required this.animation, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -102,9 +101,9 @@ class _TopRow extends StatelessWidget { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - children: [ - if (legacyMode == false) ...[ + Expanded( + child: Row( + children: [ RotationTransition( turns: animation, child: Icon( @@ -116,26 +115,30 @@ class _TopRow extends StatelessWidget { ), ), const SizedBox(width: 8), - ], - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context)!.allProtections, - style: const TextStyle( - fontSize: 18, - ), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + AppLocalizations.of(context)!.allProtections, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 18, + ), + ), + if (statusProvider.serverStatus!.timeGeneralDisabled > 0) ...[ + const SizedBox(height: 2), + if (statusProvider.currentDeadline != null) Text( + "${AppLocalizations.of(context)!.remainingTime}: ${formatRemainingSeconds(statusProvider.remainingTime)}" + ) + ] + ], ), - if (statusProvider.serverStatus!.timeGeneralDisabled > 0) ...[ - const SizedBox(height: 2), - if (statusProvider.currentDeadline != null) Text( - "${AppLocalizations.of(context)!.remainingTime}: ${formatRemainingSeconds(statusProvider.remainingTime)}" - ) - ] - ], - ), - ], + ), + ], + ), ), + const SizedBox(width: 8), Switch( value: statusProvider.serverStatus!.generalEnabled, onChanged: statusProvider.protectionsManagementProcess.contains('general') == false @@ -145,7 +148,7 @@ class _TopRow extends StatelessWidget { } updateBlocking( value: value, - filter: legacyMode == true ? 'general_legacy' : 'general' + filter: 'general' ); } : null, ) @@ -158,9 +161,8 @@ class _BottomRow extends StatefulWidget { final void Function(int) disableWithCountdown; const _BottomRow({ - Key? key, required this.disableWithCountdown, - }) : super(key: key); + }); @override State<_BottomRow> createState() => _BottomRowState(); @@ -173,8 +175,12 @@ class _BottomRowState extends State<_BottomRow> { Widget build(BuildContext context) { final statusProvider = Provider.of(context); + final textScale = MediaQuery.of(context).textScaleFactor; + return Container( - height: Platform.isMacOS || Platform.isLinux || Platform.isWindows ? 50 : 40, + height: Platform.isMacOS || Platform.isLinux || Platform.isWindows + ? 50 * textScale + : 40 * textScale, margin: const EdgeInsets.only(top: 8), child: Scrollbar( controller: _chipsScrollController, diff --git a/lib/screens/home/management_modal/management_modal.dart b/lib/screens/home/management_modal/management_modal.dart index 5096a9d..79fe043 100644 --- a/lib/screens/home/management_modal/management_modal.dart +++ b/lib/screens/home/management_modal/management_modal.dart @@ -181,12 +181,11 @@ class _Modal extends StatelessWidget { final Animation animation; const _Modal({ - Key? key, required this.expandableController, required this.updateBlocking, required this.disableWithCountdown, required this.animation, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/screens/home/server_status.dart b/lib/screens/home/server_status.dart index c130564..a0e1715 100644 --- a/lib/screens/home/server_status.dart +++ b/lib/screens/home/server_status.dart @@ -9,17 +9,43 @@ class ServerStatusWidget extends StatelessWidget { final ServerStatus serverStatus; const ServerStatusWidget({ - Key? key, + super.key, required this.serverStatus, - }) : super(key: key); + }); @override Widget build(BuildContext context) { final width = MediaQuery.of(context).size.width; - - return Container( + final textScaleFactor = MediaQuery.of(context).textScaleFactor; + + double boxSize() { + if (textScaleFactor < 1 || (textScaleFactor >= 1 && textScaleFactor < 1.15)) { + return 65; + } + else if (textScaleFactor >= 1.15 && textScaleFactor < 1.3) { + return 75; + } + else if (textScaleFactor >= 1.3 && textScaleFactor < 1.45) { + return 80; + } + else if (textScaleFactor >= 1.45 && textScaleFactor < 1.6) { + return 85; + } + else if (textScaleFactor >= 1.6 && textScaleFactor < 1.85) { + return 100; + } + else if (textScaleFactor >= 1.85) { + return 110; + } + else { + return 65; + } + } + + return Padding( padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16), child: Column( + mainAxisSize: MainAxisSize.min, children: [ Text( AppLocalizations.of(context)!.serverStatus, @@ -30,40 +56,39 @@ class ServerStatusWidget extends StatelessWidget { ), ), const SizedBox(height: 16), - SizedBox( - height: width > 700 ? 66 : 146, - child: GridView( - padding: const EdgeInsets.all(0), - physics: const NeverScrollableScrollPhysics(), - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: width > 700 ? 4 : 2, - crossAxisSpacing: 10, - mainAxisSpacing: 10, - mainAxisExtent: 65 - ), - children: [ - StatusBox( - icon: Icons.filter_list_rounded, - label: AppLocalizations.of(context)!.ruleFilteringWidget, - isEnabled: serverStatus.filteringEnabled - ), - StatusBox( - icon: Icons.vpn_lock_rounded, - label: AppLocalizations.of(context)!.safeBrowsingWidget, - isEnabled: serverStatus.safeBrowsingEnabled - ), - StatusBox( - icon: Icons.block, - label: AppLocalizations.of(context)!.parentalFilteringWidget, - isEnabled: serverStatus.parentalControlEnabled - ), - StatusBox( - icon: Icons.search_rounded, - label: AppLocalizations.of(context)!.safeSearchWidget, - isEnabled: serverStatus.safeSearchEnabled - ), - ], + GridView( + primary: false, + shrinkWrap: true, + padding: const EdgeInsets.all(0), + physics: const NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: width > 700 ? 4 : 2, + crossAxisSpacing: 10, + mainAxisSpacing: 10, + mainAxisExtent: boxSize() ), + children: [ + StatusBox( + icon: Icons.filter_list_rounded, + label: AppLocalizations.of(context)!.ruleFilteringWidget, + isEnabled: serverStatus.filteringEnabled + ), + StatusBox( + icon: Icons.vpn_lock_rounded, + label: AppLocalizations.of(context)!.safeBrowsingWidget, + isEnabled: serverStatus.safeBrowsingEnabled + ), + StatusBox( + icon: Icons.block, + label: AppLocalizations.of(context)!.parentalFilteringWidget, + isEnabled: serverStatus.parentalControlEnabled + ), + StatusBox( + icon: Icons.search_rounded, + label: AppLocalizations.of(context)!.safeSearchWidget, + isEnabled: serverStatus.safeSearchEnabled + ), + ], ) ], ), diff --git a/lib/screens/home/status_box.dart b/lib/screens/home/status_box.dart index 2f57106..38f6c95 100644 --- a/lib/screens/home/status_box.dart +++ b/lib/screens/home/status_box.dart @@ -9,11 +9,11 @@ class StatusBox extends StatelessWidget { final bool isEnabled; const StatusBox({ - Key? key, + super.key, required this.icon, required this.label, required this.isEnabled - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/screens/logs/configuration/config_widgets.dart b/lib/screens/logs/configuration/config_widgets.dart index 2d70285..1fa59f9 100644 --- a/lib/screens/logs/configuration/config_widgets.dart +++ b/lib/screens/logs/configuration/config_widgets.dart @@ -17,7 +17,7 @@ class LogsConfigOptions extends StatelessWidget { final void Function() onConfirm; const LogsConfigOptions({ - Key? key, + super.key, required this.generalSwitch, required this.updateGeneralSwitch, required this.anonymizeClientIp, @@ -27,10 +27,12 @@ class LogsConfigOptions extends StatelessWidget { required this.updateRetentionTime, required this.onClear, required this.onConfirm - }) : super(key: key); + }); @override Widget build(BuildContext context) { + final width = MediaQuery.of(context).size.width; + return Column( mainAxisSize: MainAxisSize.min, children: [ @@ -111,10 +113,12 @@ class LogsConfigOptions extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - AppLocalizations.of(context)!.anonymizeClientIp, - style: const TextStyle( - fontSize: 16 + Flexible( + child: Text( + AppLocalizations.of(context)!.anonymizeClientIp, + style: const TextStyle( + fontSize: 16 + ), ), ), Switch( @@ -159,13 +163,21 @@ class LogsConfigOptions extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - TextButton( + if (width > 500) TextButton( onPressed: () { Navigator.pop(context); onClear(); }, child: Text(AppLocalizations.of(context)!.clearLogs) ), + if (width <= 500) IconButton( + onPressed: () { + Navigator.pop(context); + onClear(); + }, + icon: const Icon(Icons.delete_rounded), + tooltip: AppLocalizations.of(context)!.clearLogs, + ), Row( children: [ TextButton( @@ -174,7 +186,7 @@ class LogsConfigOptions extends StatelessWidget { ), const SizedBox(width: 20), TextButton( - onPressed: retentionTime != '' + onPressed: retentionTime != null ? () { Navigator.pop(context); onConfirm(); @@ -183,7 +195,7 @@ class LogsConfigOptions extends StatelessWidget { child: Text( AppLocalizations.of(context)!.confirm, style: TextStyle( - color: retentionTime != '' + color: retentionTime != null ? Theme.of(context).colorScheme.primary : Colors.grey ), @@ -201,7 +213,7 @@ class LogsConfigOptions extends StatelessWidget { } class ConfigLogsLoading extends StatelessWidget { - const ConfigLogsLoading({Key? key}) : super(key: key); + const ConfigLogsLoading({super.key}); @override Widget build(BuildContext context) { @@ -232,7 +244,7 @@ class ConfigLogsLoading extends StatelessWidget { } class ConfigLogsError extends StatelessWidget { - const ConfigLogsError({Key? key}) : super(key: key); + const ConfigLogsError({super.key}); @override Widget build(BuildContext context) { diff --git a/lib/screens/logs/configuration/logs_config_modal.dart b/lib/screens/logs/configuration/logs_config_modal.dart index fb260b9..1b6c641 100644 --- a/lib/screens/logs/configuration/logs_config_modal.dart +++ b/lib/screens/logs/configuration/logs_config_modal.dart @@ -143,7 +143,6 @@ class _LogsConfigModalState extends State { } else { return Container( - height: Platform.isIOS ? 436 : 420, decoration: BoxDecoration( borderRadius: const BorderRadius.only( topLeft: Radius.circular(28), diff --git a/lib/screens/logs/filters/clients_modal.dart b/lib/screens/logs/filters/clients_modal.dart index 7bb0574..1730d8e 100644 --- a/lib/screens/logs/filters/clients_modal.dart +++ b/lib/screens/logs/filters/clients_modal.dart @@ -12,10 +12,10 @@ class ClientsModal extends StatefulWidget { final bool dialog; const ClientsModal({ - Key? key, + super.key, required this.value, required this.dialog - }) : super(key: key); + }); @override State createState() => _ClientsModalState(); @@ -75,10 +75,9 @@ class _ModalContent extends StatelessWidget { final void Function(List) onClientsSelected; const _ModalContent({ - Key? key, required this.selectedClients, required this.onClientsSelected, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -188,11 +187,10 @@ class _ListItem extends StatelessWidget { final void Function(bool) onChanged; const _ListItem({ - Key? key, required this.label, required this.checkboxActive, required this.onChanged, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/screens/logs/filters/filter_status_modal.dart b/lib/screens/logs/filters/filter_status_modal.dart index aec5aac..d3c1079 100644 --- a/lib/screens/logs/filters/filter_status_modal.dart +++ b/lib/screens/logs/filters/filter_status_modal.dart @@ -11,10 +11,10 @@ class FilterStatusModal extends StatefulWidget { final bool dialog; const FilterStatusModal({ - Key? key, + super.key, required this.value, required this.dialog - }) : super(key: key); + }); @override State createState() => _FilterStatusModalState(); @@ -39,164 +39,17 @@ class _FilterStatusModalState extends State { Navigator.pop(context); } - Widget filterStatusListItem({ - required String id, - required IconData icon, - required String label, - required void Function(String?) onChanged - }) { - return Material( - color: Colors.transparent, - child: InkWell( - onTap: () => onChanged(id), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Icon( - icon, - size: 24, - color: Theme.of(context).listTileTheme.iconColor - ), - const SizedBox(width: 16), - Text( - label, - style: TextStyle( - fontSize: 16, - color: Theme.of(context).colorScheme.onSurface - ), - ) - ], - ), - Radio( - value: id, - groupValue: selectedResultStatus, - onChanged: onChanged - ) - ], - ), - ), - ), - ); - } - - Widget content() { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - 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( - padding: const EdgeInsets.all(24), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: apply, - child: Text(AppLocalizations.of(context)!.apply) - ) - ], - ), - ), - if (Platform.isIOS) const SizedBox(height: 16) - ], - ); - } - if (widget.dialog == true) { return Dialog( child: ConstrainedBox( constraints: const BoxConstraints( maxWidth: 400 ), - child: content() + child: _Content( + onApply: apply, + updateSelectedResultStatus: (v) => setState(() => selectedResultStatus = v), + selectedResultStatus: selectedResultStatus, + ) ), ); } @@ -209,8 +62,199 @@ class _FilterStatusModalState extends State { ), color: Theme.of(context).dialogBackgroundColor ), - child: content() + child: _Content( + onApply: apply, + updateSelectedResultStatus: (v) => setState(() => selectedResultStatus = v), + selectedResultStatus: selectedResultStatus, + ) ); } } +} + +class _Content extends StatelessWidget { + final String selectedResultStatus; + final void Function(String) updateSelectedResultStatus; + final void Function() onApply; + + const _Content({ + required this.selectedResultStatus, + required this.updateSelectedResultStatus, + required this.onApply, + }); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + 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), + _Item( + selectedResultStatus: selectedResultStatus, + id: "all", + icon: Icons.shield_rounded, + label: AppLocalizations.of(context)!.all, + onChanged: updateSelectedResultStatus + ), + _Item( + selectedResultStatus: selectedResultStatus, + id: "filtered", + icon: Icons.shield_rounded, + label: AppLocalizations.of(context)!.filtered, + onChanged: updateSelectedResultStatus + ), + _Item( + selectedResultStatus: selectedResultStatus, + id: "processed", + icon: Icons.verified_user_rounded, + label: AppLocalizations.of(context)!.processedRow, + onChanged: updateSelectedResultStatus + ), + _Item( + selectedResultStatus: selectedResultStatus, + id: "whitelisted", + icon: Icons.verified_user_rounded, + label: AppLocalizations.of(context)!.processedWhitelistRow, + onChanged: updateSelectedResultStatus + ), + _Item( + selectedResultStatus: selectedResultStatus, + id: "blocked", + icon: Icons.gpp_bad_rounded, + label: AppLocalizations.of(context)!.blocked, + onChanged: updateSelectedResultStatus + ), + _Item( + selectedResultStatus: selectedResultStatus, + id: "blocked_safebrowsing", + icon: Icons.gpp_bad_rounded, + label: AppLocalizations.of(context)!.blockedSafeBrowsingRow, + onChanged: updateSelectedResultStatus + ), + _Item( + selectedResultStatus: selectedResultStatus, + id: "blocked_parental", + icon: Icons.gpp_bad_rounded, + label: AppLocalizations.of(context)!.blockedParentalRow, + onChanged: updateSelectedResultStatus + ), + _Item( + selectedResultStatus: selectedResultStatus, + id: "safe_search", + icon: Icons.gpp_bad_rounded, + label: AppLocalizations.of(context)!.blockedSafeSearchRow, + onChanged: updateSelectedResultStatus + ), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(24), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + TextButton( + onPressed: onApply, + child: Text(AppLocalizations.of(context)!.apply) + ) + ], + ), + ), + if (Platform.isIOS) const SizedBox(height: 16) + ], + ); + } +} + +class _Item extends StatelessWidget { + final String selectedResultStatus; + final String id; + final IconData icon; + final String label; + final void Function(String) onChanged; + + const _Item({ + required this.selectedResultStatus, + required this.id, + required this.icon, + required this.label, + required this.onChanged, + }); + + @override + Widget build(BuildContext context) { + return Material( + color: Colors.transparent, + child: InkWell( + onTap: () => onChanged(id), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: Row( + children: [ + Icon( + icon, + size: 24, + color: Theme.of(context).listTileTheme.iconColor + ), + const SizedBox(width: 16), + Flexible( + child: Text( + label, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface + ), + ), + ) + ], + ), + ), + Radio( + value: id, + groupValue: selectedResultStatus, + onChanged: (v) => onChanged(v!) + ) + ], + ), + ), + ), + ); + } } \ No newline at end of file diff --git a/lib/screens/settings/dhcp/add_static_lease_modal.dart b/lib/screens/settings/dhcp/add_static_lease_modal.dart index a7f2f5f..fd222d3 100644 --- a/lib/screens/settings/dhcp/add_static_lease_modal.dart +++ b/lib/screens/settings/dhcp/add_static_lease_modal.dart @@ -8,10 +8,10 @@ class AddStaticLeaseModal extends StatefulWidget { final bool dialog; const AddStaticLeaseModal({ - Key? key, + super.key, required this.onConfirm, required this.dialog - }) : super(key: key); + }); @override State createState() => _AddStaticLeaseModalState(); @@ -80,26 +80,28 @@ class _AddStaticLeaseModalState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Column( - children: [ - Padding( - padding: const EdgeInsets.only(top: 24), - child: Icon( - Icons.add, - size: 24, - color: Theme.of(context).listTileTheme.iconColor + Flexible( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(top: 24), + child: Icon( + Icons.add, + size: 24, + color: Theme.of(context).listTileTheme.iconColor + ), ), - ), - const SizedBox(height: 16), - Text( - AppLocalizations.of(context)!.addStaticLease, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 24, - color: Theme.of(context).colorScheme.onSurface + const SizedBox(height: 16), + Text( + AppLocalizations.of(context)!.addStaticLease, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface + ), ), - ), - ], + ], + ), ), ], ), diff --git a/lib/screens/settings/dhcp/dhcp.dart b/lib/screens/settings/dhcp/dhcp.dart index 84a4e76..88f1dad 100644 --- a/lib/screens/settings/dhcp/dhcp.dart +++ b/lib/screens/settings/dhcp/dhcp.dart @@ -414,6 +414,7 @@ class _DhcpScreenState extends State { const SizedBox(height: 30), Text( AppLocalizations.of(context)!.loadingDhcp, + textAlign: TextAlign.center, style: TextStyle( fontSize: 22, color: Theme.of(context).colorScheme.onSurfaceVariant, diff --git a/lib/screens/settings/dhcp/dhcp_interface_item.dart b/lib/screens/settings/dhcp/dhcp_interface_item.dart index 900328e..9d68f4e 100644 --- a/lib/screens/settings/dhcp/dhcp_interface_item.dart +++ b/lib/screens/settings/dhcp/dhcp_interface_item.dart @@ -8,10 +8,10 @@ class DhcpInterfaceItem extends StatelessWidget { final void Function(NetworkInterface) onSelect; const DhcpInterfaceItem({ - Key? key, + super.key, required this.networkInterface, required this.onSelect - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -56,6 +56,7 @@ class DhcpInterfaceItem extends StatelessWidget { const SizedBox(height: 5), if (networkInterface.flags.isNotEmpty) ...[ Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Flags: ", @@ -64,11 +65,13 @@ class DhcpInterfaceItem extends StatelessWidget { color: Theme.of(context).colorScheme.onSurfaceVariant ), ), - Text( - networkInterface.flags.join(', '), - style: TextStyle( - fontSize: 14, - color: Theme.of(context).colorScheme.onSurfaceVariant + Flexible( + child: Text( + networkInterface.flags.join(', '), + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant + ), ), ), ], diff --git a/lib/screens/settings/dhcp/select_interface_modal.dart b/lib/screens/settings/dhcp/select_interface_modal.dart index 0a740fd..e2dc26d 100644 --- a/lib/screens/settings/dhcp/select_interface_modal.dart +++ b/lib/screens/settings/dhcp/select_interface_modal.dart @@ -13,11 +13,11 @@ class SelectInterfaceModal extends StatelessWidget { final bool dialog; const SelectInterfaceModal({ - Key? key, + super.key, required this.interfaces, required this.onSelect, required this.dialog - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/screens/settings/dns/clear_dns_cache_dialog.dart b/lib/screens/settings/dns/clear_dns_cache_dialog.dart index 425d11d..b04c889 100644 --- a/lib/screens/settings/dns/clear_dns_cache_dialog.dart +++ b/lib/screens/settings/dns/clear_dns_cache_dialog.dart @@ -5,9 +5,9 @@ class ClearDnsCacheDialog extends StatelessWidget { final void Function() onConfirm; const ClearDnsCacheDialog({ - Key? key, + super.key, required this.onConfirm - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -22,6 +22,7 @@ class ClearDnsCacheDialog extends StatelessWidget { const SizedBox(height: 16), Text( AppLocalizations.of(context)!.clearDnsCache, + textAlign: TextAlign.center, style: TextStyle( fontSize: 24, color: Theme.of(context).colorScheme.onSurface diff --git a/lib/screens/settings/dns_rewrites/dns_rewrites.dart b/lib/screens/settings/dns_rewrites/dns_rewrites.dart index 236b107..8b5ee0d 100644 --- a/lib/screens/settings/dns_rewrites/dns_rewrites.dart +++ b/lib/screens/settings/dns_rewrites/dns_rewrites.dart @@ -19,7 +19,7 @@ import 'package:adguard_home_manager/models/rewrite_rules.dart'; import 'package:adguard_home_manager/classes/process_modal.dart'; class DnsRewritesScreen extends StatefulWidget { - const DnsRewritesScreen({Key? key}) : super(key: key); + const DnsRewritesScreen({super.key}); @override State createState() => _DnsRewritesScreenState(); @@ -152,6 +152,7 @@ class _DnsRewritesScreenState extends State { const SizedBox(height: 30), Text( AppLocalizations.of(context)!.loadingRewriteRules, + textAlign: TextAlign.center, style: TextStyle( fontSize: 22, color: Theme.of(context).colorScheme.onSurfaceVariant, @@ -305,6 +306,7 @@ class _DnsRewritesScreenState extends State { const SizedBox(height: 30), Text( AppLocalizations.of(context)!.rewriteRulesNotLoaded, + textAlign: TextAlign.center, style: TextStyle( fontSize: 22, color: Theme.of(context).colorScheme.onSurfaceVariant, diff --git a/lib/screens/settings/safe_search_settings.dart b/lib/screens/settings/safe_search_settings.dart index 4f6713a..99f6ad7 100644 --- a/lib/screens/settings/safe_search_settings.dart +++ b/lib/screens/settings/safe_search_settings.dart @@ -177,10 +177,12 @@ class _SafeSearchSettingsScreenState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - AppLocalizations.of(context)!.enableSafeSearch, - style: const TextStyle( - fontSize: 18 + Flexible( + child: Text( + AppLocalizations.of(context)!.enableSafeSearch, + style: const TextStyle( + fontSize: 18 + ), ), ), Switch( diff --git a/lib/widgets/custom_list_tile_dialog.dart b/lib/widgets/custom_list_tile_dialog.dart index 2e3cff4..3faf8d4 100644 --- a/lib/widgets/custom_list_tile_dialog.dart +++ b/lib/widgets/custom_list_tile_dialog.dart @@ -29,12 +29,14 @@ class CustomListTileDialog extends StatelessWidget { ), const SizedBox(width: 24), ], - Text( - title, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: Theme.of(context).colorScheme.onSurface, + Flexible( + child: Text( + title, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface, + ), ), ) ], From e01cc5ba65a52dcd5587cf870125b83fa131efd0 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Wed, 29 Nov 2023 11:57:14 +0100 Subject: [PATCH 4/6] Removed unused import --- lib/screens/logs/configuration/logs_config_modal.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/screens/logs/configuration/logs_config_modal.dart b/lib/screens/logs/configuration/logs_config_modal.dart index 1b6c641..6352f36 100644 --- a/lib/screens/logs/configuration/logs_config_modal.dart +++ b/lib/screens/logs/configuration/logs_config_modal.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; From 5f9d24cc5fb129a920739cf89d39bb719c513941 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Wed, 29 Nov 2023 17:18:35 +0100 Subject: [PATCH 5/6] Changed top items --- .../home/top_items/top_items_lists.dart | 12 +- .../home/top_items/top_items_screen.dart | 324 ++++++++++++++++++ ...{top_items.dart => top_items_section.dart} | 72 ++-- lib/screens/top_items/top_items.dart | 241 ------------- lib/screens/top_items/top_items_modal.dart | 218 ------------ 5 files changed, 365 insertions(+), 502 deletions(-) create mode 100644 lib/screens/home/top_items/top_items_screen.dart rename lib/screens/home/top_items/{top_items.dart => top_items_section.dart} (86%) delete mode 100644 lib/screens/top_items/top_items.dart delete mode 100644 lib/screens/top_items/top_items_modal.dart diff --git a/lib/screens/home/top_items/top_items_lists.dart b/lib/screens/home/top_items/top_items_lists.dart index 2f8820d..7f230fb 100644 --- a/lib/screens/home/top_items/top_items_lists.dart +++ b/lib/screens/home/top_items/top_items_lists.dart @@ -4,7 +4,7 @@ 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/top_items.dart'; +import 'package:adguard_home_manager/screens/home/top_items/top_items_section.dart'; import 'package:adguard_home_manager/functions/number_format.dart'; import 'package:adguard_home_manager/functions/snackbar.dart'; @@ -106,7 +106,7 @@ class TopItemsLists extends StatelessWidget { case HomeTopItems.queriedDomains: return Column( children: [ - TopItems( + TopItemsSection( label: AppLocalizations.of(context)!.topQueriedDomains, type: HomeTopItems.queriedDomains, data: statusProvider.serverStatus?.stats.topQueriedDomains ?? [], @@ -134,7 +134,7 @@ class TopItemsLists extends StatelessWidget { case HomeTopItems.blockedDomains: return Column( children: [ - TopItems( + TopItemsSection( label: AppLocalizations.of(context)!.topBlockedDomains, type: HomeTopItems.blockedDomains, data: statusProvider.serverStatus?.stats.topBlockedDomains ?? [], @@ -162,7 +162,7 @@ class TopItemsLists extends StatelessWidget { case HomeTopItems.recurrentClients: return Column( children: [ - TopItems( + TopItemsSection( label: AppLocalizations.of(context)!.topClients, type: HomeTopItems.recurrentClients, data: statusProvider.serverStatus?.stats.topClients ?? [], @@ -186,7 +186,7 @@ class TopItemsLists extends StatelessWidget { return statusProvider.serverStatus!.stats.topUpstreamResponses != null ? Column( children: [ - TopItems( + TopItemsSection( label: AppLocalizations.of(context)!.topUpstreams, type: HomeTopItems.topUpstreams, data: statusProvider.serverStatus?.stats.topUpstreamResponses ?? [], @@ -210,7 +210,7 @@ class TopItemsLists extends StatelessWidget { return statusProvider.serverStatus!.stats.topUpstreamsAvgTime != null ? Column( children: [ - TopItems( + TopItemsSection( label: AppLocalizations.of(context)!.averageUpstreamResponseTime, type: HomeTopItems.avgUpstreamResponseTime, data: statusProvider.serverStatus?.stats.topUpstreamsAvgTime ?? [], diff --git a/lib/screens/home/top_items/top_items_screen.dart b/lib/screens/home/top_items/top_items_screen.dart new file mode 100644 index 0000000..01ac83e --- /dev/null +++ b/lib/screens/home/top_items/top_items_screen.dart @@ -0,0 +1,324 @@ +// ignore_for_file: use_build_context_synchronously + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:percent_indicator/percent_indicator.dart'; +import 'package:provider/provider.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +import 'package:adguard_home_manager/widgets/options_menu.dart'; +import 'package:adguard_home_manager/widgets/custom_list_tile.dart'; + +import 'package:adguard_home_manager/models/menu_option.dart'; +import 'package:adguard_home_manager/constants/enums.dart'; +import 'package:adguard_home_manager/functions/number_format.dart'; +import 'package:adguard_home_manager/providers/status_provider.dart'; + +class TopItemsScreen extends StatefulWidget { + final HomeTopItems type; + final String title; + final bool? isClient; + final List> data; + final bool withProgressBar; + final String Function(dynamic) buildValue; + final List options; + final void Function(dynamic)? onTapEntry; + final bool isFullscreen; + + const TopItemsScreen({ + super.key, + required this.type, + required this.title, + this.isClient, + required this.data, + required this.withProgressBar, + required this.buildValue, + required this.options, + this.onTapEntry, + required this.isFullscreen, + }); + + @override + State createState() => _TopItemsScreenState(); +} + +class _TopItemsScreenState extends State { + bool searchActive = false; + final TextEditingController searchController = TextEditingController(); + + List> data = []; + List> screenData = []; + + void search(String value) { + List> newValues = widget.data.where((item) => item.keys.toList()[0].contains(value)).toList(); + setState(() => screenData = newValues); + } + + @override + void initState() { + data = widget.data; + screenData = widget.data; + super.initState(); + } + + @override + Widget build(BuildContext context) { + double total = 0; + for (var element in data) { + total = total + double.parse(element.values.toList()[0].toString()); + } + + if (widget.isFullscreen == true) { + return Dialog.fullscreen( + child: Scaffold( + appBar: AppBar( + title: searchActive == true + ? Padding( + padding: const EdgeInsets.only(bottom: 3), + child: TextFormField( + controller: searchController, + onChanged: search, + decoration: InputDecoration( + hintText: AppLocalizations.of(context)!.search, + hintStyle: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 18 + ), + border: InputBorder.none, + ), + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 18 + ), + autofocus: true, + ), + ) + : Text(widget.title), + leading: searchActive == true ? + IconButton( + onPressed: () => setState(() { + searchActive = false; + searchController.text = ''; + screenData = data; + }), + icon: const Icon(Icons.arrow_back), + tooltip: AppLocalizations.of(context)!.exitSearch, + ) : null, + actions: [ + if (searchActive == false) IconButton( + onPressed: () => setState(() => searchActive = true), + icon: const Icon(Icons.search), + tooltip: AppLocalizations.of(context)!.search, + ), + if (searchActive == true) IconButton( + onPressed: () => setState(() { + searchController.text = ''; + screenData = data; + }), + icon: const Icon(Icons.clear_rounded), + tooltip: AppLocalizations.of(context)!.clearSearch, + ), + const SizedBox(width: 8) + ], + ), + body: _Content( + buildValue: widget.buildValue, + isClient: widget.isClient, + onTapEntry: widget.onTapEntry, + options: widget.options, + screenData: screenData, + total: total, + withProgressBar: widget.withProgressBar, + ), + ), + ); + } + else { + return Dialog( + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 500 + ), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(16), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 1, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + IconButton( + onPressed: () => Navigator.pop(context), + icon: const Icon(Icons.clear_rounded), + tooltip: AppLocalizations.of(context)!.close, + ), + ], + ), + ), + Expanded( + flex: 1, + child: TextField( + controller: searchController, + onChanged: search, + decoration: InputDecoration( + filled: true, + fillColor: Theme.of(context).colorScheme.primary.withOpacity(0.1), + hintText: AppLocalizations.of(context)!.search, + prefixIcon: const Icon(Icons.search_rounded), + contentPadding: const EdgeInsets.only(left: 14, bottom: 9, top: 11), + focusedBorder: OutlineInputBorder( + borderSide: const BorderSide(color: Colors.transparent), + borderRadius: BorderRadius.circular(25.7), + ), + enabledBorder: UnderlineInputBorder( + borderSide: const BorderSide(color: Colors.transparent), + borderRadius: BorderRadius.circular(25.7), + ), + ), + ), + ), + ], + ), + ), + Expanded( + child: _Content( + buildValue: widget.buildValue, + isClient: widget.isClient, + onTapEntry: widget.onTapEntry, + options: widget.options, + screenData: screenData, + total: total, + withProgressBar: widget.withProgressBar, + ), + ), + ], + ), + ), + ); + } + } +} + +class _Content extends StatelessWidget { + final List> screenData; + final bool? isClient; + final List options; + final bool withProgressBar; + final void Function(dynamic)? onTapEntry; + final String Function(dynamic) buildValue; + final double total; + + const _Content({ + required this.screenData, + required this.isClient, + required this.options, + required this.withProgressBar, + required this.onTapEntry, + required this.buildValue, + required this.total, + }); + + @override + Widget build(BuildContext context) { + final statusProvider = Provider.of(context); + + if (screenData.isNotEmpty) { + return ListView.builder( + padding: const EdgeInsets.only(top: 0), + itemCount: screenData.length, + itemBuilder: (context, index) { + String? name; + if (isClient != null && isClient == true) { + try { + name = statusProvider.serverStatus!.clients.firstWhere((c) => c.ids.contains(screenData[index].keys.toList()[0])).name; + } catch (e) { + // ---- // + } + } + + return OptionsMenu( + options: options, + value: screenData[index].keys.toList()[0], + onTap: onTapEntry != null + ? (v) { + onTapEntry!(v); + Navigator.pop(context); + } + : null, + child: CustomListTile( + title: screenData[index].keys.toList()[0], + trailing: Text( + buildValue(screenData[index].values.toList()[0]), + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), + subtitleWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (name != null) ...[ + Text( + name, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurface + ), + ), + const SizedBox(height: 5), + ], + if (withProgressBar == true) Row( + children: [ + SizedBox( + width: 50, + child: Text( + "${doubleFormat((screenData[index].values.toList()[0]/total*100), Platform.localeName)}%", + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor + ), + ), + ), + const SizedBox(width: 10), + Flexible( + child: LinearPercentIndicator( + animation: true, + lineHeight: 4, + animationDuration: 500, + curve: Curves.easeOut, + percent: screenData[index].values.toList()[0]/total, + barRadius: const Radius.circular(5), + progressColor: Theme.of(context).colorScheme.primary, + backgroundColor: Theme.of(context).colorScheme.surfaceVariant, + ), + ), + const SizedBox(width: 10), + ], + ), + ], + ) + ), + ); + } + ); + } + else { + return Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Text( + AppLocalizations.of(context)!.noItemsSearch, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22, + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ), + ); + } + } +} \ No newline at end of file diff --git a/lib/screens/home/top_items/top_items.dart b/lib/screens/home/top_items/top_items_section.dart similarity index 86% rename from lib/screens/home/top_items/top_items.dart rename to lib/screens/home/top_items/top_items_section.dart index 00fa63c..f084b3f 100644 --- a/lib/screens/home/top_items/top_items.dart +++ b/lib/screens/home/top_items/top_items_section.dart @@ -7,15 +7,14 @@ import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:adguard_home_manager/screens/home/top_items/row_item.dart'; -import 'package:adguard_home_manager/screens/top_items/top_items_modal.dart'; -import 'package:adguard_home_manager/screens/top_items/top_items.dart'; +import 'package:adguard_home_manager/screens/home/top_items/top_items_screen.dart'; import 'package:adguard_home_manager/widgets/custom_pie_chart.dart'; import 'package:adguard_home_manager/models/menu_option.dart'; import 'package:adguard_home_manager/constants/enums.dart'; import 'package:adguard_home_manager/providers/app_config_provider.dart'; -class TopItems extends StatefulWidget { +class TopItemsSection extends StatefulWidget { final HomeTopItems type; final String label; final List> data; @@ -25,7 +24,7 @@ class TopItems extends StatefulWidget { final List menuOptions; final void Function(dynamic)? onTapEntry; - const TopItems({ + const TopItemsSection({ super.key, required this.type, required this.label, @@ -38,10 +37,10 @@ class TopItems extends StatefulWidget { }); @override - State createState() => _TopItemsState(); + State createState() => _TopItemsState(); } -class _TopItemsState extends State { +class _TopItemsState extends State { bool _showChart = true; final colors = [ @@ -289,38 +288,37 @@ class _TopItemsState extends State { children: [ TextButton( onPressed: () => { - if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) { - showDialog( - context: context, - barrierDismissible: false, - builder: (context) => TopItemsModal( - type: widget.type, - title: widget.label, - isClient: widget.type == HomeTopItems.recurrentClients, - data: widget.data, - withProgressBar: widget.withProgressBar, - buildValue: widget.buildValue, - options: widget.menuOptions, - onTapEntry: widget.onTapEntry, - ) + showGeneralDialog( + context: context, + barrierColor: !(width > 700 || !(Platform.isAndroid | Platform.isIOS)) + ?Colors.transparent + : Colors.black54, + transitionBuilder: (context, anim1, anim2, child) { + return SlideTransition( + position: Tween( + begin: const Offset(0, 1), + end: const Offset(0, 0) + ).animate( + CurvedAnimation( + parent: anim1, + curve: Curves.easeInOutCubicEmphasized + ) + ), + child: child, + ); + }, + pageBuilder: (context, animation, secondaryAnimation) => TopItemsScreen( + type: widget.type, + title: widget.label, + isClient: widget.type == HomeTopItems.recurrentClients, + data: widget.data, + withProgressBar: widget.withProgressBar, + buildValue: widget.buildValue, + options: widget.menuOptions, + onTapEntry: widget.onTapEntry, + isFullscreen: !(width > 700 || !(Platform.isAndroid | Platform.isIOS)), ) - } - else { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => TopItemsScreen( - type: widget.type, - title: widget.label, - isClient: widget.type == HomeTopItems.recurrentClients, - data: widget.data, - withProgressBar: widget.withProgressBar, - buildValue: widget.buildValue, - menuOptions: widget.menuOptions, - onTapEntry: widget.onTapEntry, - ) - ) - ) - } + ) }, child: Row( mainAxisSize: MainAxisSize.min, diff --git a/lib/screens/top_items/top_items.dart b/lib/screens/top_items/top_items.dart deleted file mode 100644 index 498ce75..0000000 --- a/lib/screens/top_items/top_items.dart +++ /dev/null @@ -1,241 +0,0 @@ -// ignore_for_file: use_build_context_synchronously - -import 'dart:io'; - -import 'package:flutter/material.dart'; -import 'package:percent_indicator/percent_indicator.dart'; -import 'package:provider/provider.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -import 'package:adguard_home_manager/widgets/options_menu.dart'; -import 'package:adguard_home_manager/widgets/custom_list_tile.dart'; - -import 'package:adguard_home_manager/models/menu_option.dart'; -import 'package:adguard_home_manager/constants/enums.dart'; -import 'package:adguard_home_manager/providers/status_provider.dart'; -import 'package:adguard_home_manager/functions/snackbar.dart'; -import 'package:adguard_home_manager/functions/number_format.dart'; -import 'package:adguard_home_manager/providers/app_config_provider.dart'; - -class TopItemsScreen extends StatefulWidget { - final HomeTopItems type; - final String title; - final bool? isClient; - final List> data; - final bool withProgressBar; - final String Function(dynamic) buildValue; - final List menuOptions; - final void Function(dynamic)? onTapEntry; - - const TopItemsScreen({ - super.key, - required this.type, - required this.title, - this.isClient, - required this.data, - required this.withProgressBar, - required this.buildValue, - required this.menuOptions, - this.onTapEntry, - }); - - @override - State createState() => _TopItemsScreenState(); -} - -class _TopItemsScreenState extends State { - bool searchActive = false; - final TextEditingController searchController = TextEditingController(); - - List> data = []; - List> screenData = []; - - void search(String value) { - List> newValues = widget.data.where((item) => item.keys.toList()[0].contains(value)).toList(); - setState(() => screenData = newValues); - } - - @override - void initState() { - data = widget.data; - screenData = widget.data; - super.initState(); - } - - @override - Widget build(BuildContext context) { - final statusProvider = Provider.of(context); - final appConfigProvider = Provider.of(context); - - double total = 0; - for (var element in data) { - total = total + double.parse(element.values.toList()[0].toString()); - } - - return Scaffold( - appBar: AppBar( - title: searchActive == true - ? Padding( - padding: const EdgeInsets.only(bottom: 3), - child: TextFormField( - controller: searchController, - onChanged: search, - decoration: InputDecoration( - hintText: AppLocalizations.of(context)!.search, - hintStyle: const TextStyle( - fontWeight: FontWeight.normal, - fontSize: 18 - ), - border: InputBorder.none, - ), - style: const TextStyle( - fontWeight: FontWeight.normal, - fontSize: 18 - ), - autofocus: true, - ), - ) - : Text(widget.title), - leading: searchActive == true ? - IconButton( - onPressed: () => setState(() { - searchActive = false; - searchController.text = ''; - screenData = data; - }), - icon: const Icon(Icons.arrow_back), - tooltip: AppLocalizations.of(context)!.exitSearch, - ) : null, - actions: [ - if (searchActive == false) IconButton( - onPressed: () => setState(() => searchActive = true), - icon: const Icon(Icons.search), - tooltip: AppLocalizations.of(context)!.search, - ), - if (searchActive == true) IconButton( - onPressed: () => setState(() { - searchController.text = ''; - screenData = data; - }), - icon: const Icon(Icons.clear_rounded), - tooltip: AppLocalizations.of(context)!.clearSearch, - ), - const SizedBox(width: 10) - ], - bottom: PreferredSize( - preferredSize: const Size(double.maxFinite, 1), - child: Container( - width: double.maxFinite, - height: 1, - decoration: BoxDecoration( - color: searchActive == true - ? Colors.grey.withOpacity(0.5) - : Colors.transparent - ), - ), - ), - ), - body: RefreshIndicator( - onRefresh: () async { - final result = await statusProvider.getServerStatus(); - if (mounted && result == false) { - showSnacbkar( - appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.serverStatusNotRefreshed, - color: Colors.red - ); - } - }, - child: screenData.isNotEmpty - ? ListView.builder( - itemCount: screenData.length, - itemBuilder: (context, index) { - String? name; - if (widget.isClient != null && widget.isClient == true) { - try { - name = statusProvider.serverStatus!.clients.firstWhere((c) => c.ids.contains(screenData[index].keys.toList()[0])).name; - } catch (e) { - // ---- // - } - } - - return OptionsMenu( - value: screenData[index].keys.toList()[0], - options: widget.menuOptions, - onTap: widget.onTapEntry != null - ? (v) { - widget.onTapEntry!(v); - Navigator.pop(context); - } - : null, - child: CustomListTile( - title: screenData[index].keys.toList()[0], - trailing: Text( - widget.buildValue(screenData[index].values.toList()[0]), - style: TextStyle( - color: Theme.of(context).colorScheme.onSurfaceVariant - ), - ), - subtitleWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (name != null) ...[ - Text( - name, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).colorScheme.onSurface - ), - ), - const SizedBox(height: 5), - ], - if (widget.withProgressBar == true) Row( - children: [ - SizedBox( - width: 50, - child: Text( - "${doubleFormat((screenData[index].values.toList()[0]/total*100), Platform.localeName)}%", - style: TextStyle( - color: Theme.of(context).listTileTheme.textColor - ), - ), - ), - const SizedBox(width: 10), - Flexible( - child: LinearPercentIndicator( - animation: true, - lineHeight: 4, - animationDuration: 500, - curve: Curves.easeOut, - percent: screenData[index].values.toList()[0]/total, - barRadius: const Radius.circular(5), - progressColor: Theme.of(context).colorScheme.primary, - backgroundColor: Theme.of(context).colorScheme.surfaceVariant, - ), - ), - const SizedBox(width: 10), - ], - ), - ], - ) - ), - ); - } - ) - : Center( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Text( - AppLocalizations.of(context)!.noItemsSearch, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 22, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - ) - ), - ); - } -} \ No newline at end of file diff --git a/lib/screens/top_items/top_items_modal.dart b/lib/screens/top_items/top_items_modal.dart deleted file mode 100644 index 36ea793..0000000 --- a/lib/screens/top_items/top_items_modal.dart +++ /dev/null @@ -1,218 +0,0 @@ -// ignore_for_file: use_build_context_synchronously - -import 'dart:io'; - -import 'package:flutter/material.dart'; -import 'package:percent_indicator/percent_indicator.dart'; -import 'package:provider/provider.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -import 'package:adguard_home_manager/widgets/options_menu.dart'; -import 'package:adguard_home_manager/widgets/custom_list_tile.dart'; - -import 'package:adguard_home_manager/models/menu_option.dart'; -import 'package:adguard_home_manager/constants/enums.dart'; -import 'package:adguard_home_manager/functions/number_format.dart'; -import 'package:adguard_home_manager/providers/status_provider.dart'; - -class TopItemsModal extends StatefulWidget { - final HomeTopItems type; - final String title; - final bool? isClient; - final List> data; - final bool withProgressBar; - final String Function(dynamic) buildValue; - final List options; - final void Function(dynamic)? onTapEntry; - - const TopItemsModal({ - super.key, - required this.type, - required this.title, - this.isClient, - required this.data, - required this.withProgressBar, - required this.buildValue, - required this.options, - this.onTapEntry, - }); - - @override - State createState() => _TopItemsModalState(); -} - -class _TopItemsModalState extends State { - bool searchActive = false; - final TextEditingController searchController = TextEditingController(); - - List> data = []; - List> screenData = []; - - void search(String value) { - List> newValues = widget.data.where((item) => item.keys.toList()[0].contains(value)).toList(); - setState(() => screenData = newValues); - } - - @override - void initState() { - data = widget.data; - screenData = widget.data; - super.initState(); - } - - @override - Widget build(BuildContext context) { - final statusProvider = Provider.of(context); - - double total = 0; - for (var element in data) { - total = total + double.parse(element.values.toList()[0].toString()); - } - - return Dialog( - child: ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 500 - ), - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(16), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - flex: 1, - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - IconButton( - onPressed: () => Navigator.pop(context), - icon: const Icon(Icons.clear_rounded), - tooltip: AppLocalizations.of(context)!.close, - ), - ], - ), - ), - Expanded( - flex: 1, - child: TextField( - controller: searchController, - onChanged: search, - decoration: InputDecoration( - filled: true, - fillColor: Theme.of(context).colorScheme.primary.withOpacity(0.1), - hintText: AppLocalizations.of(context)!.search, - prefixIcon: const Icon(Icons.search_rounded), - contentPadding: const EdgeInsets.only(left: 14, bottom: 9, top: 11), - focusedBorder: OutlineInputBorder( - borderSide: const BorderSide(color: Colors.transparent), - borderRadius: BorderRadius.circular(25.7), - ), - enabledBorder: UnderlineInputBorder( - borderSide: const BorderSide(color: Colors.transparent), - borderRadius: BorderRadius.circular(25.7), - ), - ), - ), - ) - ], - ), - ), - if (screenData.isNotEmpty) Flexible( - child: ListView.builder( - padding: const EdgeInsets.only(top: 0), - itemCount: screenData.length, - itemBuilder: (context, index) { - String? name; - if (widget.isClient != null && widget.isClient == true) { - try { - name = statusProvider.serverStatus!.clients.firstWhere((c) => c.ids.contains(screenData[index].keys.toList()[0])).name; - } catch (e) { - // ---- // - } - } - - return OptionsMenu( - options: widget.options, - value: screenData[index].keys.toList()[0], - onTap: widget.onTapEntry != null - ? (v) { - widget.onTapEntry!(v); - Navigator.pop(context); - } - : null, - child: CustomListTile( - title: screenData[index].keys.toList()[0], - trailing: Text( - widget.buildValue(screenData[index].values.toList()[0]), - style: TextStyle( - color: Theme.of(context).colorScheme.onSurfaceVariant - ), - ), - subtitleWidget: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (name != null) ...[ - Text( - name, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).colorScheme.onSurface - ), - ), - const SizedBox(height: 5), - ], - if (widget.withProgressBar == true) Row( - children: [ - SizedBox( - width: 50, - child: Text( - "${doubleFormat((screenData[index].values.toList()[0]/total*100), Platform.localeName)}%", - style: TextStyle( - color: Theme.of(context).listTileTheme.textColor - ), - ), - ), - const SizedBox(width: 10), - Flexible( - child: LinearPercentIndicator( - animation: true, - lineHeight: 4, - animationDuration: 500, - curve: Curves.easeOut, - percent: screenData[index].values.toList()[0]/total, - barRadius: const Radius.circular(5), - progressColor: Theme.of(context).colorScheme.primary, - backgroundColor: Theme.of(context).colorScheme.surfaceVariant, - ), - ), - const SizedBox(width: 10), - ], - ), - ], - ) - ), - ); - } - ), - ), - if (screenData.isEmpty) Center( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Text( - AppLocalizations.of(context)!.noItemsSearch, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 22, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ), - ) - ], - ), - ), - ); - } -} \ No newline at end of file From d8eeb7a51b4c78697318263f3616f50577a8a684 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Wed, 29 Nov 2023 17:28:50 +0100 Subject: [PATCH 6/6] Improved text scale factor --- .../home/management_modal/main_switch.dart | 2 +- lib/screens/home/server_status.dart | 28 ++----------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/lib/screens/home/management_modal/main_switch.dart b/lib/screens/home/management_modal/main_switch.dart index 3dbe0ec..f746b0e 100644 --- a/lib/screens/home/management_modal/main_switch.dart +++ b/lib/screens/home/management_modal/main_switch.dart @@ -175,7 +175,7 @@ class _BottomRowState extends State<_BottomRow> { Widget build(BuildContext context) { final statusProvider = Provider.of(context); - final textScale = MediaQuery.of(context).textScaleFactor; + final textScale = MediaQuery.of(context).textScaler.scale(1); return Container( height: Platform.isMacOS || Platform.isLinux || Platform.isWindows diff --git a/lib/screens/home/server_status.dart b/lib/screens/home/server_status.dart index a0e1715..b716c82 100644 --- a/lib/screens/home/server_status.dart +++ b/lib/screens/home/server_status.dart @@ -16,31 +16,7 @@ class ServerStatusWidget extends StatelessWidget { @override Widget build(BuildContext context) { final width = MediaQuery.of(context).size.width; - final textScaleFactor = MediaQuery.of(context).textScaleFactor; - - double boxSize() { - if (textScaleFactor < 1 || (textScaleFactor >= 1 && textScaleFactor < 1.15)) { - return 65; - } - else if (textScaleFactor >= 1.15 && textScaleFactor < 1.3) { - return 75; - } - else if (textScaleFactor >= 1.3 && textScaleFactor < 1.45) { - return 80; - } - else if (textScaleFactor >= 1.45 && textScaleFactor < 1.6) { - return 85; - } - else if (textScaleFactor >= 1.6 && textScaleFactor < 1.85) { - return 100; - } - else if (textScaleFactor >= 1.85) { - return 110; - } - else { - return 65; - } - } + final textScaleFactor = MediaQuery.of(context).textScaler.scale(1); return Padding( padding: const EdgeInsets.only(left: 16, right: 16, bottom: 16), @@ -65,7 +41,7 @@ class ServerStatusWidget extends StatelessWidget { crossAxisCount: width > 700 ? 4 : 2, crossAxisSpacing: 10, mainAxisSpacing: 10, - mainAxisExtent: boxSize() + mainAxisExtent: 70*textScaleFactor ), children: [ StatusBox(