From 639f583046e3edf4028cc4d73dc6e0b7daf130e1 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Tue, 24 Oct 2023 20:59:54 +0200 Subject: [PATCH 1/3] Desktop UI improvements --- lib/screens/home/home.dart | 59 --------------------------------- lib/screens/home/top_items.dart | 49 +++++++++++++++------------ 2 files changed, 27 insertions(+), 81 deletions(-) diff --git a/lib/screens/home/home.dart b/lib/screens/home/home.dart index 59fb0bf..fcac0cc 100644 --- a/lib/screens/home/home.dart +++ b/lib/screens/home/home.dart @@ -176,65 +176,6 @@ class _HomeState extends State { ), TopItemsLists(order: appConfigProvider.homeTopItemsOrder), - - // if (width > 700) Column( - // children: [ - // Wrap( - // alignment: WrapAlignment.center, - // children: appConfigProvider.homeTopItemsOrder.map((item) { - // switch (item) { - // case HomeTopItems.queriedDomains: - // return Padding( - // padding: const EdgeInsets.only(bottom: 16), - // child: ConstrainedBox( - // constraints: const BoxConstraints( - // maxWidth: 500 - // ), - // child: TopItems( - // label: AppLocalizations.of(context)!.topQueriedDomains, - // data: statusProvider.serverStatus!.stats.topQueriedDomains, - // type: 'topQueriedDomains', - // ), - // ), - // ); - - // case HomeTopItems.blockedDomains: - // return Padding( - // padding: const EdgeInsets.only(bottom: 16), - // child: ConstrainedBox( - // constraints: const BoxConstraints( - // maxWidth: 500 - // ), - // child: TopItems( - // label: AppLocalizations.of(context)!.topBlockedDomains, - // data: statusProvider.serverStatus!.stats.topBlockedDomains, - // type: 'topBlockedDomains', - // ), - // ), - // ); - - // case HomeTopItems.recurrentClients: - // return Padding( - // padding: const EdgeInsets.only(bottom: 16), - // child: ConstrainedBox( - // constraints: const BoxConstraints( - // maxWidth: 500 - // ), - // child: TopItems( - // label: AppLocalizations.of(context)!.topClients, - // data: statusProvider.serverStatus!.stats.topClients, - // type: 'topClients', - // ), - // ), - // ); - - // default: - // return const SizedBox(); - // } - // }).toList(), - // ), - // ], - // ) ]; } diff --git a/lib/screens/home/top_items.dart b/lib/screens/home/top_items.dart index 24dd6db..06ef00e 100644 --- a/lib/screens/home/top_items.dart +++ b/lib/screens/home/top_items.dart @@ -157,41 +157,46 @@ class _TopItemsState extends State { const SizedBox(height: 24), if (widget.data.isEmpty) noItems, - if (widget.data.isNotEmpty && width > 700) SizedBox( - height: 240, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Expanded( - flex: 1, + if (widget.data.isNotEmpty && width > 700) Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + flex: 1, + child: ConstrainedBox( + constraints: const BoxConstraints( + maxHeight: 250 + ), child: Padding( padding: const EdgeInsets.all(16), child: chart, - ) - ), - Expanded( - flex: 2, - child: Column( - children: [ - ...itemsList, - OthersRowItem(items: widget.data) - ] ), ) - ], - ), + ), + Expanded( + flex: 2, + child: Column( + children: [ + ...itemsList, + OthersRowItem(items: widget.data) + ] + ), + ) + ], ), if (widget.data.isNotEmpty && width <= 700) ...[ if (_showChart) ...[ - chart, + SizedBox( + height: 300, + child: chart + ), const SizedBox(height: 16), ], ...itemsList, - if (_showChart) OthersRowItem(items: widget.data) + if (_showChart) OthersRowItem(items: widget.data), + const SizedBox(height: 16), ], - if (widget.data.length > 5) ...[ - const SizedBox(height: 20), + if (widget.data.length > 5) ...[ Padding( padding: const EdgeInsets.only(right: 20), child: Row( From 6f3ba647f42b2d8782c38beb9a01cd7e10e01472 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Tue, 24 Oct 2023 21:19:03 +0200 Subject: [PATCH 2/3] Added scrollbar desktop management modal --- lib/screens/home/management_modal.dart | 88 +++++++++++++++----------- 1 file changed, 51 insertions(+), 37 deletions(-) diff --git a/lib/screens/home/management_modal.dart b/lib/screens/home/management_modal.dart index d23ddd4..9b94b58 100644 --- a/lib/screens/home/management_modal.dart +++ b/lib/screens/home/management_modal.dart @@ -31,6 +31,8 @@ class _ManagementModalState extends State with SingleTickerProv late Animation animation; final ExpandableController expandableController = ExpandableController(); + final _chipsScrollController = ScrollController(); + @override void initState() { expandableController.addListener(() async { @@ -155,46 +157,58 @@ class _ManagementModalState extends State with SingleTickerProv Widget bottomRow() { return Container( - height: 40, + height: Platform.isMacOS || Platform.isLinux || Platform.isWindows ? 50 : 40, margin: const EdgeInsets.only(top: 8), - child: ListView( - scrollDirection: Axis.horizontal, - children: [ - ActionChip( - label: Text(AppLocalizations.of(context)!.seconds(30)), - onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true - ? () => disableWithCountdown(29000) - : null, + child: Scrollbar( + controller: _chipsScrollController, + thumbVisibility: Platform.isMacOS || Platform.isLinux || Platform.isWindows, + interactive: Platform.isMacOS || Platform.isLinux || Platform.isWindows, + thickness: Platform.isMacOS || Platform.isLinux || Platform.isWindows ? 8 : 0, + child: Padding( + padding: EdgeInsets.only( + bottom: Platform.isMacOS || Platform.isLinux || Platform.isWindows ? 16 : 0 ), - const SizedBox(width: 8), - ActionChip( - label: Text(AppLocalizations.of(context)!.minute(1)), - onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true - ? () => disableWithCountdown(59000) - : null, + child: ListView( + controller: _chipsScrollController, + scrollDirection: Axis.horizontal, + children: [ + ActionChip( + label: Text(AppLocalizations.of(context)!.seconds(30)), + onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true + ? () => disableWithCountdown(29000) + : null, + ), + const SizedBox(width: 8), + ActionChip( + label: Text(AppLocalizations.of(context)!.minute(1)), + onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true + ? () => disableWithCountdown(59000) + : null, + ), + const SizedBox(width: 8), + ActionChip( + label: Text(AppLocalizations.of(context)!.minutes(10)), + onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true + ? () => disableWithCountdown(599000) + : null, + ), + const SizedBox(width: 8), + ActionChip( + label: Text(AppLocalizations.of(context)!.hour(1)), + onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true + ? () => disableWithCountdown(3599000) + : null, + ), + const SizedBox(width: 8), + ActionChip( + label: Text(AppLocalizations.of(context)!.hours(24)), + onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true + ? () => disableWithCountdown(86399000) + : null, + ), + ], ), - const SizedBox(width: 8), - ActionChip( - label: Text(AppLocalizations.of(context)!.minutes(10)), - onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true - ? () => disableWithCountdown(599000) - : null, - ), - const SizedBox(width: 8), - ActionChip( - label: Text(AppLocalizations.of(context)!.hour(1)), - onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true - ? () => disableWithCountdown(3599000) - : null, - ), - const SizedBox(width: 8), - ActionChip( - label: Text(AppLocalizations.of(context)!.hours(24)), - onPressed: statusProvider.protectionsManagementProcess.contains('general') == false && statusProvider.serverStatus!.generalEnabled == true - ? () => disableWithCountdown(86399000) - : null, - ), - ], + ), ), ); } From 229d329936e6861fa66ea890dc4b766db3b97bd5 Mon Sep 17 00:00:00 2001 From: Juan Gilsanz Polo Date: Tue, 24 Oct 2023 21:28:57 +0200 Subject: [PATCH 3/3] Fixed settings sliver list --- lib/screens/settings/settings.dart | 311 +++++++++++++++-------------- 1 file changed, 162 insertions(+), 149 deletions(-) diff --git a/lib/screens/settings/settings.dart b/lib/screens/settings/settings.dart index 709a245..2f9a24d 100644 --- a/lib/screens/settings/settings.dart +++ b/lib/screens/settings/settings.dart @@ -129,158 +129,171 @@ class SettingsWidget extends StatelessWidget { ) ) ], - body: ListView( - children: [ - if ( - serversProvider.selectedServer != null && - statusProvider.serverStatus != null && - serversProvider.apiClient != null - ) ...[ - SectionLabel(label: AppLocalizations.of(context)!.serverSettings), - if (serverVersionIsAhead( - currentVersion: statusProvider.serverStatus!.serverVersion, - referenceVersion: 'v0.107.28', - referenceVersionBeta: 'v0.108.0-b.33' - ) == true) settingsTile( - icon: Icons.search_rounded, - title: AppLocalizations.of(context)!.safeSearch, - subtitle: AppLocalizations.of(context)!.safeSearchSettings, - thisItem: 0, - screenToNavigate: const SafeSearchSettingsScreen(), - ), - settingsTile( - icon: Icons.lock_rounded, - title: AppLocalizations.of(context)!.accessSettings, - subtitle: AppLocalizations.of(context)!.accessSettingsDescription, - thisItem: 1, - screenToNavigate: const AccessSettings(), - ), - settingsTile( - icon: Icons.install_desktop_rounded, - title: AppLocalizations.of(context)!.dhcpSettings, - subtitle: AppLocalizations.of(context)!.dhcpSettingsDescription, - thisItem: 2, - screenToNavigate: const DhcpScreen(), - ), - settingsTile( - icon: Icons.dns_rounded, - title: AppLocalizations.of(context)!.dnsSettings, - subtitle: AppLocalizations.of(context)!.dnsSettingsDescription, - thisItem: 3, - screenToNavigate: const DnsSettings(), - ), - settingsTile( - icon: Icons.security_rounded, - title: AppLocalizations.of(context)!.encryptionSettings, - subtitle: AppLocalizations.of(context)!.encryptionSettingsDescription, - thisItem: 4, - screenToNavigate: const EncryptionSettings(), - ), - settingsTile( - icon: Icons.route_rounded, - title: AppLocalizations.of(context)!.dnsRewrites, - subtitle: AppLocalizations.of(context)!.dnsRewritesDescription, - thisItem: 5, - screenToNavigate: const DnsRewritesScreen(), - ), - if (serversProvider.updateAvailable.data != null) settingsTile( - icon: Icons.system_update_rounded, - title: AppLocalizations.of(context)!.updates, - subtitle: AppLocalizations.of(context)!.updatesDescription, - trailing: serversProvider.updateAvailable.data != null && - serversProvider.updateAvailable.data!.canAutoupdate == true - ? Container( - width: 10, - height: 10, - margin: const EdgeInsets.only(right: 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - color: Colors.red - ), - ) - : null, - thisItem: 6, - screenToNavigate: const UpdateScreen(), - ), - settingsTile( - icon: Icons.info_rounded, - title: AppLocalizations.of(context)!.serverInformation, - subtitle: AppLocalizations.of(context)!.serverInformationDescription, - thisItem: 7, - screenToNavigate: const ServerInformation(), - ), - ], - SectionLabel(label: AppLocalizations.of(context)!.appSettings), - settingsTile( - icon: Icons.palette_rounded, - title: AppLocalizations.of(context)!.customization, - subtitle: AppLocalizations.of(context)!.customizationDescription, - thisItem: 8, - screenToNavigate: const Customization(), - ), - settingsTile( - icon: Icons.storage_rounded, - title: AppLocalizations.of(context)!.servers, - subtitle: serversProvider.selectedServer != null - ? statusProvider.serverStatus != null - ? "${AppLocalizations.of(context)!.connectedTo} ${serversProvider.selectedServer!.name}" - : "${AppLocalizations.of(context)!.selectedServer} ${serversProvider.selectedServer!.name}" - : AppLocalizations.of(context)!.noServerSelected, - thisItem: 9, - screenToNavigate: const Servers(), - ), - settingsTile( - icon: Icons.settings, - title: AppLocalizations.of(context)!.generalSettings, - subtitle: AppLocalizations.of(context)!.generalSettingsDescription, - thisItem: 10, - screenToNavigate: const GeneralSettings(), - ), - settingsTile( - icon: Icons.build_outlined, - title: AppLocalizations.of(context)!.advancedSettings, - subtitle: AppLocalizations.of(context)!.advancedSetupDescription, - thisItem: 11, - screenToNavigate: const AdvancedSettings(), - ), - SectionLabel(label: AppLocalizations.of(context)!.aboutApp), - CustomListTile( - title: AppLocalizations.of(context)!.appVersion, - subtitle: appConfigProvider.getAppInfo!.version, - ), - CustomListTile( - title: AppLocalizations.of(context)!.createdBy, - subtitle: Strings.createdBy, - ), - Padding( - padding: const EdgeInsets.all(15), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - if (Platform.isAndroid) IconButton( - onPressed: () => openUrl(Urls.playStore), - icon: SvgPicture.asset( - 'assets/resources/google-play.svg', - color: Theme.of(context).colorScheme.onSurfaceVariant, - width: 30, - height: 30, + body: SafeArea( + top: false, + bottom: false, + child: Builder( + builder: (context) => CustomScrollView( + slivers: [ + SliverOverlapInjector( + handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), + ), + SliverList.list( + children: [ + if ( + serversProvider.selectedServer != null && + statusProvider.serverStatus != null && + serversProvider.apiClient != null + ) ...[ + SectionLabel(label: AppLocalizations.of(context)!.serverSettings), + if (serverVersionIsAhead( + currentVersion: statusProvider.serverStatus!.serverVersion, + referenceVersion: 'v0.107.28', + referenceVersionBeta: 'v0.108.0-b.33' + ) == true) settingsTile( + icon: Icons.search_rounded, + title: AppLocalizations.of(context)!.safeSearch, + subtitle: AppLocalizations.of(context)!.safeSearchSettings, + thisItem: 0, + screenToNavigate: const SafeSearchSettingsScreen(), + ), + settingsTile( + icon: Icons.lock_rounded, + title: AppLocalizations.of(context)!.accessSettings, + subtitle: AppLocalizations.of(context)!.accessSettingsDescription, + thisItem: 1, + screenToNavigate: const AccessSettings(), + ), + settingsTile( + icon: Icons.install_desktop_rounded, + title: AppLocalizations.of(context)!.dhcpSettings, + subtitle: AppLocalizations.of(context)!.dhcpSettingsDescription, + thisItem: 2, + screenToNavigate: const DhcpScreen(), + ), + settingsTile( + icon: Icons.dns_rounded, + title: AppLocalizations.of(context)!.dnsSettings, + subtitle: AppLocalizations.of(context)!.dnsSettingsDescription, + thisItem: 3, + screenToNavigate: const DnsSettings(), + ), + settingsTile( + icon: Icons.security_rounded, + title: AppLocalizations.of(context)!.encryptionSettings, + subtitle: AppLocalizations.of(context)!.encryptionSettingsDescription, + thisItem: 4, + screenToNavigate: const EncryptionSettings(), + ), + settingsTile( + icon: Icons.route_rounded, + title: AppLocalizations.of(context)!.dnsRewrites, + subtitle: AppLocalizations.of(context)!.dnsRewritesDescription, + thisItem: 5, + screenToNavigate: const DnsRewritesScreen(), + ), + if (serversProvider.updateAvailable.data != null) settingsTile( + icon: Icons.system_update_rounded, + title: AppLocalizations.of(context)!.updates, + subtitle: AppLocalizations.of(context)!.updatesDescription, + trailing: serversProvider.updateAvailable.data != null && + serversProvider.updateAvailable.data!.canAutoupdate == true + ? Container( + width: 10, + height: 10, + margin: const EdgeInsets.only(right: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Colors.red + ), + ) + : null, + thisItem: 6, + screenToNavigate: const UpdateScreen(), + ), + settingsTile( + icon: Icons.info_rounded, + title: AppLocalizations.of(context)!.serverInformation, + subtitle: AppLocalizations.of(context)!.serverInformationDescription, + thisItem: 7, + screenToNavigate: const ServerInformation(), + ), + ], + SectionLabel(label: AppLocalizations.of(context)!.appSettings), + settingsTile( + icon: Icons.palette_rounded, + title: AppLocalizations.of(context)!.customization, + subtitle: AppLocalizations.of(context)!.customizationDescription, + thisItem: 8, + screenToNavigate: const Customization(), ), - tooltip: AppLocalizations.of(context)!.visitGooglePlay, - ), - IconButton( - onPressed: () => openUrl(Urls.gitHub), - icon: SvgPicture.asset( - 'assets/resources/github.svg', - color: Theme.of(context).colorScheme.onSurfaceVariant, - width: 30, - height: 30, + settingsTile( + icon: Icons.storage_rounded, + title: AppLocalizations.of(context)!.servers, + subtitle: serversProvider.selectedServer != null + ? statusProvider.serverStatus != null + ? "${AppLocalizations.of(context)!.connectedTo} ${serversProvider.selectedServer!.name}" + : "${AppLocalizations.of(context)!.selectedServer} ${serversProvider.selectedServer!.name}" + : AppLocalizations.of(context)!.noServerSelected, + thisItem: 9, + screenToNavigate: const Servers(), ), - tooltip: AppLocalizations.of(context)!.gitHub, - ), - ], - ), + settingsTile( + icon: Icons.settings, + title: AppLocalizations.of(context)!.generalSettings, + subtitle: AppLocalizations.of(context)!.generalSettingsDescription, + thisItem: 10, + screenToNavigate: const GeneralSettings(), + ), + settingsTile( + icon: Icons.build_outlined, + title: AppLocalizations.of(context)!.advancedSettings, + subtitle: AppLocalizations.of(context)!.advancedSetupDescription, + thisItem: 11, + screenToNavigate: const AdvancedSettings(), + ), + SectionLabel(label: AppLocalizations.of(context)!.aboutApp), + CustomListTile( + title: AppLocalizations.of(context)!.appVersion, + subtitle: appConfigProvider.getAppInfo!.version, + ), + CustomListTile( + title: AppLocalizations.of(context)!.createdBy, + subtitle: Strings.createdBy, + ), + Padding( + padding: const EdgeInsets.all(15), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + if (Platform.isAndroid) IconButton( + onPressed: () => openUrl(Urls.playStore), + icon: SvgPicture.asset( + 'assets/resources/google-play.svg', + color: Theme.of(context).colorScheme.onSurfaceVariant, + width: 30, + height: 30, + ), + tooltip: AppLocalizations.of(context)!.visitGooglePlay, + ), + IconButton( + onPressed: () => openUrl(Urls.gitHub), + icon: SvgPicture.asset( + 'assets/resources/github.svg', + color: Theme.of(context).colorScheme.onSurfaceVariant, + width: 30, + height: 30, + ), + tooltip: AppLocalizations.of(context)!.gitHub, + ), + ], + ), + ) + ], + ) + ], ) - ], + ), ), ) );