diff --git a/lib/config/theme.dart b/lib/config/theme.dart index 2ecc2af..532c4c8 100644 --- a/lib/config/theme.dart +++ b/lib/config/theme.dart @@ -25,11 +25,16 @@ ThemeData lightTheme(ColorScheme? dynamicColorScheme) => ThemeData( ), ), navigationBarTheme: NavigationBarThemeData( - indicatorColor: dynamicColorScheme != null ? dynamicColorScheme.primaryContainer : adguardGreenColor, + indicatorColor: dynamicColorScheme != null ? dynamicColorScheme.secondaryContainer : adguardGreenColor, + iconTheme: MaterialStateProperty.all( + IconThemeData( + color: dynamicColorScheme != null ? dynamicColorScheme.onSecondaryContainer : adguardGreenColor, + ) + ) ), floatingActionButtonTheme: FloatingActionButtonThemeData( - foregroundColor: Colors.white, - backgroundColor: dynamicColorScheme != null ? dynamicColorScheme.primary : adguardGreenColor + foregroundColor: dynamicColorScheme != null ? dynamicColorScheme.onPrimaryContainer : Colors.white, + backgroundColor: dynamicColorScheme != null ? dynamicColorScheme.primaryContainer : adguardGreenColor ), textButtonTheme: TextButtonThemeData( style: ButtonStyle( @@ -42,9 +47,10 @@ ThemeData lightTheme(ColorScheme? dynamicColorScheme) => ThemeData( ), ), dividerColor: Colors.black12, - listTileTheme: const ListTileThemeData( + listTileTheme: ListTileThemeData( tileColor: Colors.transparent, - iconColor: Color.fromRGBO(138, 138, 138, 1), + textColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(117, 117, 117, 1), + iconColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(117, 117, 117, 1), ), checkboxTheme: CheckboxThemeData( checkColor: MaterialStateProperty.all(Colors.white), @@ -79,7 +85,12 @@ ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData( scaffoldBackgroundColor: dynamicColorScheme != null ? dynamicColorScheme.background :const Color.fromRGBO(18, 18, 18, 1), dialogBackgroundColor: dynamicColorScheme != null ? dynamicColorScheme.background : const Color.fromRGBO(44, 44, 44, 1), navigationBarTheme: NavigationBarThemeData( - indicatorColor: dynamicColorScheme != null ? dynamicColorScheme.primaryContainer : adguardGreenColor, + indicatorColor: dynamicColorScheme != null ? dynamicColorScheme.secondaryContainer : adguardGreenColor, + iconTheme: MaterialStateProperty.all( + IconThemeData( + color: dynamicColorScheme != null ? dynamicColorScheme.onSecondaryContainer : adguardGreenColor, + ) + ) ), snackBarTheme: SnackBarThemeData( contentTextStyle: const TextStyle( @@ -92,8 +103,8 @@ ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData( elevation: 4, ), floatingActionButtonTheme: FloatingActionButtonThemeData( - foregroundColor: Colors.white, - backgroundColor: dynamicColorScheme != null ? dynamicColorScheme.primary : adguardGreenColor + foregroundColor: dynamicColorScheme != null ? dynamicColorScheme.onPrimaryContainer : Colors.white, + backgroundColor: dynamicColorScheme != null ? dynamicColorScheme.primaryContainer : adguardGreenColor ), textButtonTheme: TextButtonThemeData( style: ButtonStyle( @@ -115,14 +126,17 @@ ThemeData darkTheme(ColorScheme? dynamicColorScheme) => ThemeData( ), ), dividerColor: Colors.white12, - listTileTheme: const ListTileThemeData( + listTileTheme: ListTileThemeData( tileColor: Colors.transparent, - iconColor: Color.fromRGBO(187, 187, 187, 1), + textColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(187, 187, 187, 1), + iconColor: dynamicColorScheme != null ? dynamicColorScheme.onSurfaceVariant : const Color.fromRGBO(187, 187, 187, 1), ), checkboxTheme: CheckboxThemeData( - checkColor: MaterialStateProperty.all(Colors.white), + checkColor: MaterialStateProperty.all( + dynamicColorScheme != null ? dynamicColorScheme.onPrimary : Colors.white + ), fillColor: MaterialStateProperty.all( - dynamicColorScheme != null ? dynamicColorScheme.primary : adguardGreenColor + dynamicColorScheme != null ? dynamicColorScheme.onSurface : adguardGreenColor ), ), tabBarTheme: TabBarTheme( @@ -187,6 +201,9 @@ ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData( overlayColor: MaterialStateProperty.all(primaryColor.shade50), ) ), + cardTheme: CardTheme( + surfaceTintColor: primaryColor + ), navigationBarTheme: NavigationBarThemeData( surfaceTintColor: primaryColor, indicatorColor: primaryColor @@ -210,11 +227,12 @@ ThemeData lightThemeOldVersions(MaterialColor primaryColor) => ThemeData( dividerColor: Colors.black12, listTileTheme: const ListTileThemeData( tileColor: Colors.transparent, - iconColor: Color.fromRGBO(138, 138, 138, 1), + textColor: Color.fromRGBO(117, 117, 117, 1), + iconColor: Color.fromRGBO(117, 117, 117, 1), ), checkboxTheme: CheckboxThemeData( checkColor: MaterialStateProperty.all(Colors.white), - fillColor: MaterialStateProperty.all(primaryColor), + fillColor: MaterialStateProperty.all(primaryColor), ), tabBarTheme: TabBarTheme( unselectedLabelColor: Colors.black, @@ -250,7 +268,7 @@ ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData( ) ), appBarTheme: AppBarTheme( - color: Color.fromRGBO(18, 18, 18, 1), + color: const Color.fromRGBO(18, 18, 18, 1), foregroundColor: Colors.white, elevation: 0, surfaceTintColor: primaryColor @@ -283,6 +301,9 @@ ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData( overlayColor: MaterialStateProperty.all(primaryColor.shade50), ) ), + cardTheme: CardTheme( + surfaceTintColor: primaryColor + ), inputDecorationTheme: InputDecorationTheme( floatingLabelStyle: TextStyle( color: primaryColor @@ -295,6 +316,15 @@ ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData( ) ) ), + checkboxTheme: CheckboxThemeData( + checkColor: MaterialStateProperty.all(Colors.white), + fillColor: MaterialStateProperty.all(primaryColor), + ), + listTileTheme: const ListTileThemeData( + tileColor: Colors.transparent, + textColor: Color.fromRGBO(187, 187, 187, 1), + iconColor: Color.fromRGBO(187, 187, 187, 1), + ), textSelectionTheme: TextSelectionThemeData( cursorColor: primaryColor ), @@ -308,14 +338,6 @@ ThemeData darkThemeOldVersions(MaterialColor primaryColor) => ThemeData( ), ), dividerColor: Colors.white12, - listTileTheme: const ListTileThemeData( - tileColor: Colors.transparent, - iconColor: Color.fromRGBO(187, 187, 187, 1), - ), - checkboxTheme: CheckboxThemeData( - checkColor: MaterialStateProperty.all(Colors.white), - fillColor: MaterialStateProperty.all(Colors.blue), - ), tabBarTheme: TabBarTheme( unselectedLabelColor: Colors.white, labelColor: primaryColor, diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index c0622ba..56b0f89 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -569,5 +569,6 @@ "doNotRememberAgainUpdate": "Do not remember again for this version", "downloadingUpdate": "Downloading", "completed": "completed", - "permissionNotGranted": "Permission not granted" + "permissionNotGranted": "Permission not granted", + "inputSearchTerm": "Input a search term." } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 0b558bf..122512c 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -569,5 +569,6 @@ "doNotRememberAgainUpdate": "No recordar de nuevo para esta actualización", "downloadingUpdate": "Descargando", "completed": "completado", - "permissionNotGranted": "Permiso no concedido" + "permissionNotGranted": "Permiso no concedido", + "inputSearchTerm": "Introduce un término de búsqueda." } \ No newline at end of file diff --git a/lib/screens/app_logs/app_log_details_modal.dart b/lib/screens/app_logs/app_log_details_modal.dart index ed47d8f..70368cf 100644 --- a/lib/screens/app_logs/app_log_details_modal.dart +++ b/lib/screens/app_logs/app_log_details_modal.dart @@ -43,16 +43,18 @@ class _AppLogDetailsModalState extends State { return AlertDialog( title: Column( children: [ - const Icon( + Icon( Icons.description_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor, ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.logDetails, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ) ], diff --git a/lib/screens/app_logs/app_logs.dart b/lib/screens/app_logs/app_logs.dart index 78c3f34..05d3ec0 100644 --- a/lib/screens/app_logs/app_logs.dart +++ b/lib/screens/app_logs/app_logs.dart @@ -50,8 +50,22 @@ class AppLogs extends StatelessWidget { padding: const EdgeInsets.only(top: 0), itemCount: appConfigProvider.logs.length, itemBuilder: (context, index) => ListTile( - title: Text(appConfigProvider.logs[index].message), - subtitle: Text(appConfigProvider.logs[index].dateTime.toString()), + title: Text( + appConfigProvider.logs[index].message, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + color: Theme.of(context).colorScheme.onSurface + ), + ), + subtitle: Text( + appConfigProvider.logs[index].dateTime.toString(), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.normal, + color: Theme.of(context).listTileTheme.textColor + ), + ), trailing: Text(appConfigProvider.logs[index].type), onTap: () => { showDialog( diff --git a/lib/screens/clients/added_list.dart b/lib/screens/clients/added_list.dart index dc7f68b..29881ba 100644 --- a/lib/screens/clients/added_list.dart +++ b/lib/screens/clients/added_list.dart @@ -2,15 +2,14 @@ import 'package:flutter/material.dart'; import 'package:animations/animations.dart'; -import 'package:bottom_sheet/bottom_sheet.dart'; import 'package:flutter/rendering.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:adguard_home_manager/screens/clients/client_screen.dart'; import 'package:adguard_home_manager/screens/clients/remove_client_modal.dart'; import 'package:adguard_home_manager/screens/clients/fab.dart'; import 'package:adguard_home_manager/screens/clients/options_modal.dart'; -import 'package:adguard_home_manager/screens/clients/client_modal.dart'; import 'package:adguard_home_manager/functions/snackbar.dart'; import 'package:adguard_home_manager/classes/process_modal.dart'; @@ -141,23 +140,14 @@ class _AddedListState extends State { } void openClientModal(Client client) { - ScaffoldMessenger.of(context).clearSnackBars(); - showFlexibleBottomSheet( - minHeight: 0.6, - initHeight: 0.6, - maxHeight: 0.95, - isCollapsible: true, - duration: const Duration(milliseconds: 250), - anchors: [0.95], - context: context, - builder: (ctx, controller, offset) => ClientModal( - scrollController: controller, - client: client, + Navigator.push(context, MaterialPageRoute( + fullscreenDialog: true, + builder: (BuildContext context) => ClientScreen( onConfirm: confirmEditClient, onDelete: deleteClient, - ), - bottomSheetColor: Colors.transparent - ); + client: client, + ) + )); } void openDeleteModal(Client client) { @@ -209,7 +199,7 @@ class _AddedListState extends State { padding: const EdgeInsets.only(top: 0), itemCount: widget.data.length, itemBuilder: (context, index) => ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15), + contentPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), isThreeLine: true, onLongPress: () => openOptionsModal(widget.data[index]), onTap: () => openClientModal(widget.data[index]), @@ -217,16 +207,22 @@ class _AddedListState extends State { padding: const EdgeInsets.only(bottom: 5), child: Text( widget.data[index].name, - style: const TextStyle( + style: TextStyle( fontSize: 18, - fontWeight: FontWeight.normal + fontWeight: FontWeight.normal, + color: Theme.of(context).colorScheme.onSurface ), ), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(widget.data[index].ids.toString().replaceAll(RegExp(r'^\[|\]$'), '')), + Text( + widget.data[index].ids.toString().replaceAll(RegExp(r'^\[|\]$'), ''), + style: TextStyle( + color: Theme.of(context).listTileTheme.textColor + ), + ), const SizedBox(height: 7), Row( children: [ diff --git a/lib/screens/clients/client_modal.dart b/lib/screens/clients/client_modal.dart deleted file mode 100644 index 00bef63..0000000 --- a/lib/screens/clients/client_modal.dart +++ /dev/null @@ -1,706 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:uuid/uuid.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -import 'package:adguard_home_manager/screens/clients/remove_client_modal.dart'; -import 'package:adguard_home_manager/screens/clients/services_modal.dart'; -import 'package:adguard_home_manager/screens/clients/tags_modal.dart'; - -import 'package:adguard_home_manager/providers/servers_provider.dart'; -import 'package:adguard_home_manager/models/clients.dart'; - -class ClientModal extends StatefulWidget { - final ScrollController scrollController; - final Client? client; - final void Function(Client) onConfirm; - final void Function(Client)? onDelete; - - const ClientModal({ - Key? key, - required this.scrollController, - this.client, - required this.onConfirm, - this.onDelete, - }) : super(key: key); - - @override - State createState() => _ClientModalState(); -} - -class _ClientModalState extends State { - final Uuid uuid = const Uuid(); - bool editMode = true; - - TextEditingController nameController = TextEditingController(); - - List selectedTags = []; - - List> identifiersControllers = [ - { - 'id': 0, - 'controller': TextEditingController() - } - ]; - - bool useGlobalSettingsFiltering = true; - bool? enableFiltering; - bool? enableSafeBrowsing; - bool? enableParentalControl; - bool? enableSafeSearch; - - bool useGlobalSettingsServices = true; - List blockedServices = []; - - List> upstreamServers = []; - - - bool checkValidValues() { - if ( - nameController.text != '' && - identifiersControllers.isNotEmpty && - identifiersControllers[0]['controller'].text != '' - ) { - return true; - } - else { - return false; - } - } - - @override - void initState() { - if (widget.client != null) { - editMode = false; - - nameController.text = widget.client!.name; - selectedTags = widget.client!.tags; - identifiersControllers = widget.client!.ids.map((e) => { - 'id': uuid.v4(), - 'controller': TextEditingController(text: e) - }).toList(); - useGlobalSettingsFiltering = widget.client!.useGlobalSettings; - enableFiltering = widget.client!.filteringEnabled; - enableParentalControl = widget.client!.parentalEnabled; - enableSafeBrowsing = widget.client!.safebrowsingEnabled; - enableSafeSearch = widget.client!.safesearchEnabled; - useGlobalSettingsServices = widget.client!.useGlobalBlockedServices; - blockedServices = widget.client!.blockedServices; - upstreamServers = widget.client!.upstreams.map((e) => { - 'id': uuid.v4(), - 'controller': TextEditingController(text: e) - }).toList(); - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - final serversProvider = Provider.of(context); - - void createClient() { - final Client client = Client( - name: nameController.text, - ids: List.from(identifiersControllers.map((e) => e['controller'].text)), - useGlobalSettings: useGlobalSettingsFiltering, - filteringEnabled: enableFiltering ?? false, - parentalEnabled: enableParentalControl ?? false, - safebrowsingEnabled: enableSafeBrowsing ?? false, - safesearchEnabled: enableSafeSearch ?? false, - useGlobalBlockedServices: useGlobalSettingsServices, - blockedServices: blockedServices, - upstreams: List.from(upstreamServers.map((e) => e['controller'].text)), - tags: selectedTags - ); - widget.onConfirm(client); - } - - Widget sectionLabel(String label) { - return Padding( - padding: const EdgeInsets.symmetric( - vertical: 30, - horizontal: 20 - ), - child: Text( - label, - style: TextStyle( - fontWeight: FontWeight.w500, - fontSize: 16, - color: Theme.of(context).primaryColor - ), - ), - ); - } - - void enableDisableGlobalSettingsFiltering() { - if (useGlobalSettingsFiltering == true) { - setState(() { - useGlobalSettingsFiltering = false; - - enableFiltering = false; - enableSafeBrowsing = false; - enableParentalControl = false; - enableSafeSearch = false; - }); - } - else if (useGlobalSettingsFiltering == false) { - setState(() { - useGlobalSettingsFiltering = true; - - enableFiltering = null; - enableSafeBrowsing = null; - enableParentalControl = null; - enableSafeSearch = null; - }); - } - } - - void openTagsModal() { - showDialog( - context: context, - builder: (context) => TagsModal( - selectedTags: selectedTags, - tags: serversProvider.clients.data!.supportedTags, - onConfirm: (selected) => setState(() => selectedTags = selected), - ) - ); - } - - void openServicesModal() { - showDialog( - context: context, - builder: (context) => ServicesModal( - blockedServices: blockedServices, - onConfirm: (values) => setState(() => blockedServices = values), - ) - ); - } - - void updateServicesGlobalSettings(bool value) { - if (value == true) { - setState(() { - blockedServices = []; - useGlobalSettingsServices = true; - }); - } - else if (value == false) { - setState(() { - useGlobalSettingsServices = false; - }); - } - } - - void openDeleteClientModal() { - showDialog( - context: context, - builder: (ctx) => RemoveClientModal( - onConfirm: () { - Navigator.pop(context); - widget.onDelete!(widget.client!); - } - ) - ); - } - - Widget settignsTile({ - required String label, - required bool? value, - void Function(bool)? onChange - }) { - return Material( - color: Colors.transparent, - child: InkWell( - onTap: onChange != null - ? value != null ? () => onChange(!value) : null - : null, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 30, - vertical: 5 - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - label, - style: const TextStyle( - fontSize: 15 - ), - ), - useGlobalSettingsFiltering == false - ? Switch( - value: value!, - onChanged: onChange, - activeColor: Theme.of(context).primaryColor, - ) - : Padding( - padding: const EdgeInsets.symmetric(vertical: 14), - child: Text( - "Global", - style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor, - ), - ), - ) - ], - ), - ), - ), - ); - } - - return Padding( - padding: MediaQuery.of(context).viewInsets, - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).dialogBackgroundColor, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(28), - topRight: Radius.circular(28) - ) - ), - child: Column( - children: [ - Expanded( - child: ListView( - controller: widget.scrollController, - children: [ - const SizedBox(height: 28), - const Icon( - Icons.add, - size: 26, - ), - const SizedBox(height: 20), - Text( - AppLocalizations.of(context)!.addClient, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 - ), - ), - const SizedBox(height: 30), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: TextFormField( - enabled: widget.client != null ? false : true, - controller: nameController, - onChanged: (_) => checkValidValues(), - decoration: InputDecoration( - prefixIcon: const Icon(Icons.badge_rounded), - border: const OutlineInputBorder( - borderRadius: BorderRadius.all( - Radius.circular(10) - ) - ), - labelText: AppLocalizations.of(context)!.name, - ), - ), - ), - sectionLabel(AppLocalizations.of(context)!.tags), - Material( - color: Colors.transparent, - child: InkWell( - onTap: editMode == true ? () => openTagsModal() : null, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 10, horizontal: 20 - ), - child: Row( - children: [ - const Icon( - Icons.label_rounded, - ), - const SizedBox(width: 20), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context)!.selectTags, - style: const TextStyle( - fontSize: 16, - ), - ), - const SizedBox(height: 5), - Text( - selectedTags.isNotEmpty - ? "${selectedTags.length} ${AppLocalizations.of(context)!.tagsSelected}" - : AppLocalizations.of(context)!.noTagsSelected, - style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor, - ), - ) - ], - ) - ], - ), - ), - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - sectionLabel(AppLocalizations.of(context)!.identifiers), - if (editMode == true) Padding( - padding: const EdgeInsets.only(right: 20), - child: IconButton( - onPressed: () => setState(() => identifiersControllers.add({ - 'id': uuid.v4(), - 'controller': TextEditingController() - })), - icon: const Icon(Icons.add) - ), - ) - ], - ), - if (identifiersControllers.isNotEmpty) ...identifiersControllers.map((controller) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Padding( - padding: const EdgeInsets.only(bottom: 20), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - width: editMode == true - ? MediaQuery.of(context).size.width - 108 - : MediaQuery.of(context).size.width - 40, - child: TextFormField( - enabled: editMode, - controller: controller['controller'], - onChanged: (_) => checkValidValues(), - decoration: InputDecoration( - prefixIcon: const Icon(Icons.tag), - border: const OutlineInputBorder( - borderRadius: BorderRadius.all( - Radius.circular(10) - ) - ), - helperText: AppLocalizations.of(context)!.identifierHelper, - labelText: AppLocalizations.of(context)!.identifier, - ), - ), - ), - if (editMode == true) ...[ - const SizedBox(width: 20), - Padding( - padding: const EdgeInsets.only(bottom: 25), - child: IconButton( - onPressed: () => setState( - () => identifiersControllers = identifiersControllers.where((e) => e['id'] != controller['id']).toList() - ), - icon: const Icon(Icons.remove_circle_outline_outlined) - ), - ) - ] - ], - ), - ), - )).toList(), - if (identifiersControllers.isEmpty) Container( - padding: const EdgeInsets.only(top: 10), - child: Text( - AppLocalizations.of(context)!.noIdentifiers, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 18, - color: Colors.grey - ), - ), - ), - sectionLabel(AppLocalizations.of(context)!.settings), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Material( - color: Theme.of(context).primaryColor.withOpacity(0.1), - borderRadius: BorderRadius.circular(28), - child: InkWell( - onTap: editMode - ? () => enableDisableGlobalSettingsFiltering() - : null, - borderRadius: BorderRadius.circular(28), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 5 - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - AppLocalizations.of(context)!.useGlobalSettings, - style: const TextStyle( - fontSize: 16, - ), - ), - Switch( - value: useGlobalSettingsFiltering, - onChanged: editMode == true - ? (value) => enableDisableGlobalSettingsFiltering() - : null, - activeColor: Theme.of(context).primaryColor, - ) - ], - ), - ), - ), - ), - ), - const SizedBox(height: 10), - settignsTile( - label: AppLocalizations.of(context)!.enableFiltering, - value: enableFiltering, - onChange: editMode == true - ? (value) => setState(() => enableFiltering = value) - : null - ), - settignsTile( - label: AppLocalizations.of(context)!.enableSafeBrowsing, - value: enableSafeBrowsing, - onChange: editMode == true - ? (value) => setState(() => enableSafeBrowsing = value) - : null - ), - settignsTile( - label: AppLocalizations.of(context)!.enableParentalControl, - value: enableParentalControl, - onChange: editMode == true - ? (value) => setState(() => enableParentalControl = value) - : null - ), - settignsTile( - label: AppLocalizations.of(context)!.enableSafeSearch, - value: enableSafeSearch, - onChange: editMode == true - ? (value) => setState(() => enableSafeSearch = value) - : null - ), - sectionLabel(AppLocalizations.of(context)!.blockedServices), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Material( - color: Theme.of(context).primaryColor.withOpacity(0.1), - borderRadius: BorderRadius.circular(28), - child: InkWell( - onTap: editMode == true - ? () => updateServicesGlobalSettings(!useGlobalSettingsServices) - : null, - borderRadius: BorderRadius.circular(28), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 5 - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - AppLocalizations.of(context)!.useGlobalSettings, - style: const TextStyle( - fontSize: 16, - ), - ), - Switch( - value: useGlobalSettingsServices, - onChanged: editMode == true - ? (value) => updateServicesGlobalSettings(value) - : null, - activeColor: Theme.of(context).primaryColor, - ) - ], - ), - ), - ), - ), - ), - const SizedBox(height: 10), - Material( - color: Colors.transparent, - child: InkWell( - onTap: editMode == true - ? useGlobalSettingsServices == false - ? openServicesModal - : null - : null, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 10, horizontal: 20 - ), - child: Row( - children: [ - Icon( - Icons.public, - color: useGlobalSettingsServices == false - ? null - : Colors.grey, - ), - const SizedBox(width: 20), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - AppLocalizations.of(context)!.selectBlockedServices, - style: TextStyle( - fontSize: 16, - color: useGlobalSettingsServices == false - ? null - : Theme.of(context).listTileTheme.iconColor, - ), - ), - 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, - ), - ) - ] - ], - ) - ], - ), - ), - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - sectionLabel(AppLocalizations.of(context)!.upstreamServers), - if (editMode == true) Padding( - padding: const EdgeInsets.only(right: 20), - child: IconButton( - onPressed: () => setState(() => upstreamServers.add({ - 'id': uuid.v4(), - 'controller': TextEditingController() - })), - icon: const Icon(Icons.add) - ), - ) - ], - ), - if (upstreamServers.isNotEmpty) ...upstreamServers.map((controller) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Padding( - padding: const EdgeInsets.only(bottom: 20), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - width: editMode == true - ? MediaQuery.of(context).size.width - 108 - : MediaQuery.of(context).size.width - 40, - child: TextFormField( - enabled: editMode, - controller: controller['controller'], - onChanged: (_) => checkValidValues(), - decoration: InputDecoration( - prefixIcon: const Icon(Icons.dns_rounded), - border: const OutlineInputBorder( - borderRadius: BorderRadius.all( - Radius.circular(10) - ) - ), - labelText: AppLocalizations.of(context)!.serverAddress, - ), - ), - ), - if (editMode == true) ...[ - const SizedBox(width: 20), - IconButton( - onPressed: () => setState( - () => upstreamServers = upstreamServers.where((e) => e['id'] != controller['id']).toList() - ), - icon: const Icon(Icons.remove_circle_outline_outlined) - ) - ] - ], - ), - ), - )).toList(), - if (upstreamServers.isEmpty) Container( - padding: const EdgeInsets.only(top: 10), - child: Column( - children: [ - Text( - AppLocalizations.of(context)!.noUpstreamServers, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 18, - color: Colors.grey - ), - ), - const SizedBox(height: 10), - Text( - AppLocalizations.of(context)!.willBeUsedGeneralServers, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 15, - color: Colors.grey - ), - ), - ], - ), - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.all(20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (widget.client != null && editMode == false) ...[ - IconButton( - onPressed: () => setState(() => editMode = true), - icon: const Icon(Icons.edit) - ), - const SizedBox(width: 10), - ], - if (widget.client != null && widget.onDelete != null) IconButton( - onPressed: openDeleteClientModal, - icon: const Icon(Icons.delete) - ), - ], - ), - Row( - children: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: Text(AppLocalizations.of(context)!.cancel) - ), - if (widget.client == null || (widget.client != null && editMode == true)) ...[ - const SizedBox(width: 20), - TextButton( - onPressed: checkValidValues() == true - ? () { - createClient(); - Navigator.pop(context); - } - : null, - child: Text( - widget.client != null && editMode == true - ? AppLocalizations.of(context)!.save - : AppLocalizations.of(context)!.confirm, - style: TextStyle( - color: checkValidValues() == true - ? Theme.of(context).primaryColor - : Colors.grey - ), - ) - ), - ] - ], - ) - ], - ), - ), - ], - ), - ), - ); - } -} \ No newline at end of file diff --git a/lib/screens/clients/client_screen.dart b/lib/screens/clients/client_screen.dart new file mode 100644 index 0000000..8979dc5 --- /dev/null +++ b/lib/screens/clients/client_screen.dart @@ -0,0 +1,661 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:uuid/uuid.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +import 'package:adguard_home_manager/screens/clients/remove_client_modal.dart'; +import 'package:adguard_home_manager/screens/clients/services_modal.dart'; +import 'package:adguard_home_manager/screens/clients/tags_modal.dart'; + +import 'package:adguard_home_manager/providers/servers_provider.dart'; +import 'package:adguard_home_manager/models/clients.dart'; + +class ClientScreen extends StatefulWidget { + final Client? client; + final void Function(Client) onConfirm; + final void Function(Client)? onDelete; + + const ClientScreen({ + Key? key, + this.client, + required this.onConfirm, + this.onDelete, + }) : super(key: key); + + @override + State createState() => _ClientScreenState(); +} + +class _ClientScreenState extends State { + final Uuid uuid = const Uuid(); + bool editMode = true; + + TextEditingController nameController = TextEditingController(); + + List selectedTags = []; + + List> identifiersControllers = [ + { + 'id': 0, + 'controller': TextEditingController() + } + ]; + + bool useGlobalSettingsFiltering = true; + bool? enableFiltering; + bool? enableSafeBrowsing; + bool? enableParentalControl; + bool? enableSafeSearch; + + bool useGlobalSettingsServices = true; + List blockedServices = []; + + List> upstreamServers = []; + + + bool checkValidValues() { + if ( + nameController.text != '' && + identifiersControllers.isNotEmpty && + identifiersControllers[0]['controller'].text != '' + ) { + return true; + } + else { + return false; + } + } + + @override + void initState() { + if (widget.client != null) { + editMode = false; + + nameController.text = widget.client!.name; + selectedTags = widget.client!.tags; + identifiersControllers = widget.client!.ids.map((e) => { + 'id': uuid.v4(), + 'controller': TextEditingController(text: e) + }).toList(); + useGlobalSettingsFiltering = widget.client!.useGlobalSettings; + enableFiltering = widget.client!.filteringEnabled; + enableParentalControl = widget.client!.parentalEnabled; + enableSafeBrowsing = widget.client!.safebrowsingEnabled; + enableSafeSearch = widget.client!.safesearchEnabled; + useGlobalSettingsServices = widget.client!.useGlobalBlockedServices; + blockedServices = widget.client!.blockedServices; + upstreamServers = widget.client!.upstreams.map((e) => { + 'id': uuid.v4(), + 'controller': TextEditingController(text: e) + }).toList(); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { + final serversProvider = Provider.of(context); + + void createClient() { + final Client client = Client( + name: nameController.text, + ids: List.from(identifiersControllers.map((e) => e['controller'].text)), + useGlobalSettings: useGlobalSettingsFiltering, + filteringEnabled: enableFiltering ?? false, + parentalEnabled: enableParentalControl ?? false, + safebrowsingEnabled: enableSafeBrowsing ?? false, + safesearchEnabled: enableSafeSearch ?? false, + useGlobalBlockedServices: useGlobalSettingsServices, + blockedServices: blockedServices, + upstreams: List.from(upstreamServers.map((e) => e['controller'].text)), + tags: selectedTags + ); + widget.onConfirm(client); + } + + Widget sectionLabel(String label) { + return Padding( + padding: const EdgeInsets.symmetric( + vertical: 24, + horizontal: 24 + ), + child: Text( + label, + style: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 16, + color: Theme.of(context).primaryColor + ), + ), + ); + } + + void enableDisableGlobalSettingsFiltering() { + if (useGlobalSettingsFiltering == true) { + setState(() { + useGlobalSettingsFiltering = false; + + enableFiltering = false; + enableSafeBrowsing = false; + enableParentalControl = false; + enableSafeSearch = false; + }); + } + else if (useGlobalSettingsFiltering == false) { + setState(() { + useGlobalSettingsFiltering = true; + + enableFiltering = null; + enableSafeBrowsing = null; + enableParentalControl = null; + enableSafeSearch = null; + }); + } + } + + void openTagsModal() { + showDialog( + context: context, + builder: (context) => TagsModal( + selectedTags: selectedTags, + tags: serversProvider.clients.data!.supportedTags, + onConfirm: (selected) => setState(() => selectedTags = selected), + ) + ); + } + + void openServicesModal() { + showDialog( + context: context, + builder: (context) => ServicesModal( + blockedServices: blockedServices, + onConfirm: (values) => setState(() => blockedServices = values), + ) + ); + } + + void updateServicesGlobalSettings(bool value) { + if (value == true) { + setState(() { + blockedServices = []; + useGlobalSettingsServices = true; + }); + } + else if (value == false) { + setState(() { + useGlobalSettingsServices = false; + }); + } + } + + void openDeleteClientScreen() { + showDialog( + context: context, + builder: (ctx) => RemoveClientModal( + onConfirm: () { + Navigator.pop(context); + widget.onDelete!(widget.client!); + } + ) + ); + } + + Widget settignsTile({ + required String label, + required bool? value, + void Function(bool)? onChange + }) { + return Material( + color: Colors.transparent, + child: InkWell( + onTap: onChange != null + ? value != null ? () => onChange(!value) : null + : null, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 42, + vertical: 5 + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + label, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface, + ), + ), + useGlobalSettingsFiltering == false + ? Switch( + value: value!, + onChanged: onChange, + activeColor: Theme.of(context).primaryColor, + ) + : Padding( + padding: const EdgeInsets.symmetric(vertical: 14), + child: Text( + "Global", + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + ), + ), + ) + ], + ), + ), + ), + ); + } + + return Scaffold( + appBar: AppBar( + leading: IconButton( + onPressed: () => Navigator.pop(context), + icon: const Icon(Icons.close) + ), + title: Text( + widget.client != null + ? AppLocalizations.of(context)!.client + : AppLocalizations.of(context)!.addClient + ), + actions: [ + if (widget.client == null || (widget.client != null && editMode == true)) IconButton( + onPressed: checkValidValues() == true + ? () { + createClient(); + Navigator.pop(context); + } + : null, + icon: Icon( + widget.client != null && editMode == true + ? Icons.save_rounded + : Icons.check_rounded + ), + tooltip: widget.client != null && editMode == true + ? AppLocalizations.of(context)!.save + : AppLocalizations.of(context)!.confirm, + ), + if (widget.client != null && editMode == false) IconButton( + onPressed: () => setState(() => editMode = true), + icon: const Icon(Icons.edit_rounded), + tooltip: AppLocalizations.of(context)!.edit, + ), + if (widget.client != null) IconButton( + onPressed: openDeleteClientScreen, + icon: const Icon(Icons.delete_rounded), + tooltip: AppLocalizations.of(context)!.delete, + ), + const SizedBox(width: 10), + ], + ), + body: ListView( + children: [ + const SizedBox(height: 24), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: TextFormField( + enabled: widget.client != null ? false : true, + controller: nameController, + onChanged: (_) => checkValidValues(), + decoration: InputDecoration( + prefixIcon: const Icon(Icons.badge_rounded), + border: const OutlineInputBorder( + borderRadius: BorderRadius.all( + Radius.circular(10) + ) + ), + labelText: AppLocalizations.of(context)!.name, + ), + ), + ), + sectionLabel(AppLocalizations.of(context)!.tags), + Material( + color: Colors.transparent, + child: InkWell( + onTap: editMode == true ? () => openTagsModal() : null, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 0, horizontal: 24 + ), + child: Row( + children: [ + Icon( + Icons.label_rounded, + color: Theme.of(context).listTileTheme.iconColor + ), + const SizedBox(width: 16), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + AppLocalizations.of(context)!.selectTags, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface + ), + ), + const SizedBox(height: 3), + Text( + selectedTags.isNotEmpty + ? "${selectedTags.length} ${AppLocalizations.of(context)!.tagsSelected}" + : AppLocalizations.of(context)!.noTagsSelected, + style: TextStyle( + color: Theme.of(context).listTileTheme.iconColor + ), + ) + ], + ) + ], + ), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + sectionLabel(AppLocalizations.of(context)!.identifiers), + if (editMode == true) Padding( + padding: const EdgeInsets.only(right: 20), + child: IconButton( + onPressed: () => setState(() => identifiersControllers.add({ + 'id': uuid.v4(), + 'controller': TextEditingController() + })), + icon: const Icon(Icons.add) + ), + ) + ], + ), + if (identifiersControllers.isNotEmpty) ...identifiersControllers.map((controller) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: TextFormField( + enabled: editMode, + controller: controller['controller'], + onChanged: (_) => checkValidValues(), + decoration: InputDecoration( + prefixIcon: const Icon(Icons.tag), + border: const OutlineInputBorder( + borderRadius: BorderRadius.all( + Radius.circular(10) + ) + ), + helperText: AppLocalizations.of(context)!.identifierHelper, + labelText: AppLocalizations.of(context)!.identifier, + ), + ), + ), + if (editMode == true) ...[ + const SizedBox(width: 20), + Padding( + padding: const EdgeInsets.only(bottom: 25), + child: IconButton( + onPressed: () => setState( + () => identifiersControllers = identifiersControllers.where((e) => e['id'] != controller['id']).toList() + ), + icon: const Icon(Icons.remove_circle_outline_outlined) + ), + ) + ] + ], + ), + )).toList(), + if (identifiersControllers.isEmpty) Container( + padding: const EdgeInsets.only(top: 10), + child: Text( + AppLocalizations.of(context)!.noIdentifiers, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 18, + color: Colors.grey + ), + ), + ), + sectionLabel(AppLocalizations.of(context)!.settings), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Material( + color: Theme.of(context).primaryColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(28), + child: InkWell( + onTap: editMode + ? () => enableDisableGlobalSettingsFiltering() + : null, + borderRadius: BorderRadius.circular(28), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 5 + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + AppLocalizations.of(context)!.useGlobalSettings, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface + ), + ), + Switch( + value: useGlobalSettingsFiltering, + onChanged: editMode == true + ? (value) => enableDisableGlobalSettingsFiltering() + : null, + activeColor: Theme.of(context).primaryColor, + ) + ], + ), + ), + ), + ), + ), + const SizedBox(height: 10), + settignsTile( + label: AppLocalizations.of(context)!.enableFiltering, + value: enableFiltering, + onChange: editMode == true + ? (value) => setState(() => enableFiltering = value) + : null + ), + settignsTile( + label: AppLocalizations.of(context)!.enableSafeBrowsing, + value: enableSafeBrowsing, + onChange: editMode == true + ? (value) => setState(() => enableSafeBrowsing = value) + : null + ), + settignsTile( + label: AppLocalizations.of(context)!.enableParentalControl, + value: enableParentalControl, + onChange: editMode == true + ? (value) => setState(() => enableParentalControl = value) + : null + ), + settignsTile( + label: AppLocalizations.of(context)!.enableSafeSearch, + value: enableSafeSearch, + onChange: editMode == true + ? (value) => setState(() => enableSafeSearch = value) + : null + ), + sectionLabel(AppLocalizations.of(context)!.blockedServices), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Material( + color: Theme.of(context).primaryColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(28), + child: InkWell( + onTap: editMode == true + ? () => updateServicesGlobalSettings(!useGlobalSettingsServices) + : null, + borderRadius: BorderRadius.circular(28), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20, + vertical: 5 + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + AppLocalizations.of(context)!.useGlobalSettings, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface + ), + ), + Switch( + value: useGlobalSettingsServices, + onChanged: editMode == true + ? (value) => updateServicesGlobalSettings(value) + : null, + activeColor: Theme.of(context).primaryColor, + ) + ], + ), + ), + ), + ), + ), + const SizedBox(height: 10), + Material( + color: Colors.transparent, + child: InkWell( + onTap: editMode == true + ? useGlobalSettingsServices == false + ? openServicesModal + : null + : null, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 24 + ), + child: Row( + children: [ + Icon( + Icons.public, + color: useGlobalSettingsServices == false + ? Theme.of(context).listTileTheme.iconColor + : 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), + Text( + blockedServices.isNotEmpty + ? "${blockedServices.length} ${AppLocalizations.of(context)!.servicesBlocked}" + : AppLocalizations.of(context)!.noBlockedServicesSelected, + style: TextStyle( + color: Theme.of(context).listTileTheme.iconColor + ), + ) + ] + ], + ) + ], + ), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + sectionLabel(AppLocalizations.of(context)!.upstreamServers), + if (editMode == true) Padding( + padding: const EdgeInsets.only(right: 20), + child: IconButton( + onPressed: () => setState(() => upstreamServers.add({ + 'id': uuid.v4(), + 'controller': TextEditingController() + })), + icon: const Icon(Icons.add) + ), + ) + ], + ), + if (upstreamServers.isNotEmpty) ...upstreamServers.map((controller) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Padding( + padding: const EdgeInsets.only(bottom: 20), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + width: editMode == true + ? MediaQuery.of(context).size.width - 108 + : MediaQuery.of(context).size.width - 40, + child: TextFormField( + enabled: editMode, + controller: controller['controller'], + onChanged: (_) => checkValidValues(), + decoration: InputDecoration( + prefixIcon: const Icon(Icons.dns_rounded), + border: const OutlineInputBorder( + borderRadius: BorderRadius.all( + Radius.circular(10) + ) + ), + labelText: AppLocalizations.of(context)!.serverAddress, + ), + ), + ), + if (editMode == true) ...[ + const SizedBox(width: 20), + IconButton( + onPressed: () => setState( + () => upstreamServers = upstreamServers.where((e) => e['id'] != controller['id']).toList() + ), + icon: const Icon(Icons.remove_circle_outline_outlined) + ) + ] + ], + ), + ), + )).toList(), + if (upstreamServers.isEmpty) Container( + padding: const EdgeInsets.only(top: 10), + child: Column( + children: [ + Text( + AppLocalizations.of(context)!.noUpstreamServers, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 18, + color: Colors.grey + ), + ), + const SizedBox(height: 10), + Text( + AppLocalizations.of(context)!.willBeUsedGeneralServers, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 15, + color: Colors.grey + ), + ), + ], + ), + ), + const SizedBox(height: 20) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/clients/clients.dart b/lib/screens/clients/clients.dart index 97074d7..f411da9 100644 --- a/lib/screens/clients/clients.dart +++ b/lib/screens/clients/clients.dart @@ -121,26 +121,15 @@ class _ClientsWidgetState extends State with TickerProviderStateM ], bottom: TabBar( controller: tabController, + unselectedLabelColor: Theme.of(context).colorScheme.onSurfaceVariant, tabs: [ Tab( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.devices), - const SizedBox(width: 20), - Text(AppLocalizations.of(context)!.activeClients) - ], - ), + icon: const Icon(Icons.devices), + text: AppLocalizations.of(context)!.activeClients, ), Tab( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.add), - const SizedBox(width: 20), - Text(AppLocalizations.of(context)!.added) - ], - ), + icon: const Icon(Icons.add_rounded), + text: AppLocalizations.of(context)!.added, ), ] ) @@ -154,9 +143,7 @@ class _ClientsWidgetState extends State with TickerProviderStateM color: Theme.of(context).scaffoldBackgroundColor, border: Border( top: BorderSide( - color: Theme.of(context).brightness == Brightness.light - ? const Color.fromRGBO(220, 220, 220, 1) - : const Color.fromRGBO(50, 50, 50, 1) + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.1) ) ) ), diff --git a/lib/screens/clients/clients_list.dart b/lib/screens/clients/clients_list.dart index 76cd386..c15464b 100644 --- a/lib/screens/clients/clients_list.dart +++ b/lib/screens/clients/clients_list.dart @@ -56,7 +56,12 @@ class ClientsList extends StatelessWidget { subtitle: data[index].name != '' ? data[index].ip : null, - trailing: Text(data[index].source), + trailing: Text( + data[index].source, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ), ) ); } diff --git a/lib/screens/clients/fab.dart b/lib/screens/clients/fab.dart index b39b2fa..97ae592 100644 --- a/lib/screens/clients/fab.dart +++ b/lib/screens/clients/fab.dart @@ -2,15 +2,13 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:bottom_sheet/bottom_sheet.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:adguard_home_manager/screens/clients/client_modal.dart'; +import 'package:adguard_home_manager/screens/clients/client_screen.dart'; import 'package:adguard_home_manager/functions/snackbar.dart'; import 'package:adguard_home_manager/models/clients.dart'; import 'package:adguard_home_manager/services/http_requests.dart'; -import 'package:adguard_home_manager/models/clients_allowed_blocked.dart'; import 'package:adguard_home_manager/classes/process_modal.dart'; import 'package:adguard_home_manager/providers/servers_provider.dart'; import 'package:adguard_home_manager/providers/app_config_provider.dart'; @@ -61,28 +59,20 @@ class ClientsFab extends StatelessWidget { } void openAddClient() { - ScaffoldMessenger.of(context).clearSnackBars(); - showFlexibleBottomSheet( - minHeight: 0.6, - initHeight: 0.6, - maxHeight: 0.95, - isCollapsible: true, - duration: const Duration(milliseconds: 250), - anchors: [0.95], - context: context, - builder: (ctx, controller, offset) => ClientModal( - scrollController: controller, - onConfirm: confirmAddClient - ), - bottomSheetColor: Colors.transparent - ); + Navigator.push(context, MaterialPageRoute( + fullscreenDialog: true, + builder: (BuildContext context) => ClientScreen( + onConfirm: confirmAddClient, + ) + )); } return FloatingActionButton( onPressed: () => openAddClient(), + backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, child: Icon( Icons.add, - color: Theme.of(context).primaryColor.computeLuminance() > 0.5 ? Colors.black : Colors.white, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, ), ); } diff --git a/lib/screens/clients/options_modal.dart b/lib/screens/clients/options_modal.dart index dc22d76..eed56fa 100644 --- a/lib/screens/clients/options_modal.dart +++ b/lib/screens/clients/options_modal.dart @@ -14,51 +14,64 @@ class OptionsModal extends StatelessWidget { @override Widget build(BuildContext context) { return AlertDialog( - contentPadding: const EdgeInsets.all(0), + contentPadding: const EdgeInsets.symmetric( + horizontal: 0, + vertical: 16 + ), title: Column( children: [ - const Icon(Icons.more_horiz), - const SizedBox(height: 20), - Text(AppLocalizations.of(context)!.options) + Icon( + Icons.more_horiz, + color: Theme.of(context).listTileTheme.iconColor + ), + const SizedBox(height: 16), + Text( + AppLocalizations.of(context)!.options, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ) ], ), - content: SizedBox( - height: 150, - width: double.minPositive, - child: ListView( - physics: const NeverScrollableScrollPhysics(), - children: [ - const SizedBox(height: 25), - ListTile( - onTap: () { - Navigator.pop(context); - onEdit(); - }, - title: Padding( - padding: const EdgeInsets.all(10.0), - child: Text(AppLocalizations.of(context)!.edit), - ), - leading: const Padding( - padding: EdgeInsets.only(left: 10), - child: Icon(Icons.edit), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 24), + ListTile( + onTap: () { + Navigator.pop(context); + onEdit(); + }, + title: Text( + AppLocalizations.of(context)!.edit, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + fontWeight: FontWeight.normal ), ), - ListTile( - onTap: () { - Navigator.pop(context); - onDelete(); - }, - title: Padding( - padding: const EdgeInsets.all(10.0), - child: Text(AppLocalizations.of(context)!.delete), - ), - leading: const Padding( - padding: EdgeInsets.only(left: 10), - child: Icon(Icons.delete), + leading: Icon( + Icons.edit, + color: Theme.of(context).listTileTheme.iconColor, + ), + ), + ListTile( + onTap: () { + Navigator.pop(context); + onDelete(); + }, + title: Text( + AppLocalizations.of(context)!.delete, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + fontWeight: FontWeight.normal ), ), - ], - ), + leading: Icon( + Icons.delete, + color: Theme.of(context).listTileTheme.iconColor, + ), + ), + ], ), actions: [ TextButton( diff --git a/lib/screens/clients/remove_client_modal.dart b/lib/screens/clients/remove_client_modal.dart index a32b06e..4427d22 100644 --- a/lib/screens/clients/remove_client_modal.dart +++ b/lib/screens/clients/remove_client_modal.dart @@ -14,15 +14,26 @@ class RemoveClientModal extends StatelessWidget { return AlertDialog( title: Column( children: [ - const Icon( + Icon( Icons.delete_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), - const SizedBox(height: 20), - Text(AppLocalizations.of(context)!.removeClient) + const SizedBox(height: 16), + Text( + AppLocalizations.of(context)!.removeClient, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ) ], ), - content: Text(AppLocalizations.of(context)!.removeClientMessage), + content: Text( + AppLocalizations.of(context)!.removeClientMessage, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), actions: [ TextButton( onPressed: () => Navigator.pop(context), diff --git a/lib/screens/clients/search_clients.dart b/lib/screens/clients/search_clients.dart index d762f03..0a4b9a1 100644 --- a/lib/screens/clients/search_clients.dart +++ b/lib/screens/clients/search_clients.dart @@ -2,12 +2,11 @@ import 'package:flutter/material.dart'; import 'package:animations/animations.dart'; -import 'package:bottom_sheet/bottom_sheet.dart'; import 'package:provider/provider.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:adguard_home_manager/screens/clients/client_modal.dart'; import 'package:adguard_home_manager/screens/clients/remove_client_modal.dart'; +import 'package:adguard_home_manager/screens/clients/client_screen.dart'; import 'package:adguard_home_manager/screens/clients/options_modal.dart'; import 'package:adguard_home_manager/widgets/custom_list_tile.dart'; @@ -59,10 +58,18 @@ class _SearchClientsWidgetState extends State { bool showDivider = true; void search(String value) { - setState(() { - clientsScreen = clients.where((client) => client.name.contains(value) || client.ids.where((e) => e.contains(value)).isNotEmpty).toList(); - autoClientsScreen = autoClients.where((client) => (client.name != null ? client.name!.contains(value) : true) || client.ip.contains(value)).toList(); - }); + if (value == '') { + setState(() { + clientsScreen = []; + autoClientsScreen = []; + }); + } + else { + setState(() { + clientsScreen = clients.where((client) => client.name.contains(value) || client.ids.where((e) => e.contains(value)).isNotEmpty).toList(); + autoClientsScreen = autoClients.where((client) => (client.name != null ? client.name!.contains(value) : true) || client.ip.contains(value)).toList(); + }); + } } void scrollListener() { @@ -81,9 +88,6 @@ class _SearchClientsWidgetState extends State { setState(() { clients = widget.serversProvider.clients.data!.clients; autoClients = widget.serversProvider.clients.data!.autoClientsData; - - clientsScreen = widget.serversProvider.clients.data!.clients; - autoClientsScreen = widget.serversProvider.clients.data!.autoClientsData; }); super.initState(); @@ -178,23 +182,14 @@ class _SearchClientsWidgetState extends State { } void openClientModal(Client client) { - ScaffoldMessenger.of(context).clearSnackBars(); - showFlexibleBottomSheet( - minHeight: 0.6, - initHeight: 0.6, - maxHeight: 0.95, - isCollapsible: true, - duration: const Duration(milliseconds: 250), - anchors: [0.95], - context: context, - builder: (ctx, controller, offset) => ClientModal( - scrollController: controller, - client: client, + Navigator.push(context, MaterialPageRoute( + fullscreenDialog: true, + builder: (BuildContext context) => ClientScreen( onConfirm: confirmEditClient, onDelete: deleteClient, - ), - bottomSheetColor: Colors.transparent - ); + client: client, + ) + )); } void openDeleteModal(Client client) { @@ -387,7 +382,9 @@ class _SearchClientsWidgetState extends State { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Text( - AppLocalizations.of(context)!.noClientsSearch, + searchController.text == '' + ? AppLocalizations.of(context)!.inputSearchTerm + : AppLocalizations.of(context)!.noClientsSearch, textAlign: TextAlign.center, style: const TextStyle( color: Colors.grey, diff --git a/lib/screens/clients/services_modal.dart b/lib/screens/clients/services_modal.dart index f49d93d..974c565 100644 --- a/lib/screens/clients/services_modal.dart +++ b/lib/screens/clients/services_modal.dart @@ -45,13 +45,21 @@ class _ServicesModalState extends State { scrollable: true, contentPadding: const EdgeInsets.symmetric( horizontal: 0, - vertical: 20 + vertical: 16 ), title: Column( children: [ - const Icon(Icons.public), - const SizedBox(height: 20), - Text(AppLocalizations.of(context)!.services) + Icon( + Icons.public, + color: Theme.of(context).listTileTheme.iconColor + ), + const SizedBox(height: 16), + Text( + AppLocalizations.of(context)!.services, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + ), + ) ], ), content: SizedBox( @@ -65,8 +73,9 @@ class _ServicesModalState extends State { padding: const EdgeInsets.only(left: 10), child: Text( services[index]['label']!, - style: const TextStyle( - fontWeight: FontWeight.normal + style: TextStyle( + fontWeight: FontWeight.normal, + color: Theme.of(context).colorScheme.onSurface ), ), ), @@ -95,7 +104,7 @@ class _ServicesModalState extends State { style: TextStyle( color: blockedServices.isNotEmpty ? Theme.of(context).primaryColor - : Colors.grey + : Theme.of(context).colorScheme.onSurface.withOpacity(0.38) ), ) ), diff --git a/lib/screens/clients/tags_modal.dart b/lib/screens/clients/tags_modal.dart index 0232de7..fbc1c1b 100644 --- a/lib/screens/clients/tags_modal.dart +++ b/lib/screens/clients/tags_modal.dart @@ -45,13 +45,21 @@ class _TagsModalState extends State { scrollable: true, contentPadding: const EdgeInsets.symmetric( horizontal: 0, - vertical: 20 + vertical: 16 ), title: Column( children: [ - const Icon(Icons.label_rounded), - const SizedBox(height: 20), - Text(AppLocalizations.of(context)!.tags) + Icon( + Icons.label_rounded, + color: Theme.of(context).listTileTheme.iconColor + ), + const SizedBox(height: 16), + Text( + AppLocalizations.of(context)!.tags, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ) ], ), content: SizedBox( @@ -63,8 +71,9 @@ class _TagsModalState extends State { itemBuilder: (context, index) => CheckboxListTile( title: Text( widget.tags[index], - style: const TextStyle( - fontWeight: FontWeight.normal + style: TextStyle( + fontWeight: FontWeight.normal, + color: Theme.of(context).colorScheme.onSurface ), ), value: selectedTags.contains(widget.tags[index]), @@ -92,7 +101,7 @@ class _TagsModalState extends State { style: TextStyle( color: selectedTags.isNotEmpty ? Theme.of(context).primaryColor - : Colors.grey + : Theme.of(context).colorScheme.onSurface.withOpacity(0.38) ), ) ), diff --git a/lib/screens/connect/fab.dart b/lib/screens/connect/fab.dart index c83f94f..61b1144 100644 --- a/lib/screens/connect/fab.dart +++ b/lib/screens/connect/fab.dart @@ -17,9 +17,10 @@ class FabConnect extends StatelessWidget { return FloatingActionButton( onPressed: openAddServerModal, + backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, child: Icon( Icons.add_rounded, - color: Theme.of(context).primaryColor.computeLuminance() > 0.5 ? Colors.black : Colors.white, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, ), ); } diff --git a/lib/screens/filters/add_custom_rule.dart b/lib/screens/filters/add_custom_rule.dart index d7b660c..a3b70b1 100644 --- a/lib/screens/filters/add_custom_rule.dart +++ b/lib/screens/filters/add_custom_rule.dart @@ -1,18 +1,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:provider/provider.dart'; +import 'package:material_segmented_control/material_segmented_control.dart'; import 'package:flutter_web_browser/flutter_web_browser.dart'; -import 'package:adguard_home_manager/widgets/custom_radio_toggle.dart'; - import 'package:adguard_home_manager/constants/urls.dart'; +import 'package:adguard_home_manager/providers/app_config_provider.dart'; class AddCustomRule extends StatefulWidget { - final ScrollController scrollController; final void Function(String) onConfirm; const AddCustomRule({ Key? key, - required this.scrollController, required this.onConfirm }) : super(key: key); @@ -24,19 +23,14 @@ class _AddCustomRuleState extends State { final TextEditingController domainController = TextEditingController(); String? domainError; - String preset = "block"; + int preset = 0; bool addImportant = false; bool checkValidValues() { if ( domainController.text != '' && - domainError == null && - ( - preset == 'block' || - preset == 'unblock' || - preset == 'custom' - ) + domainError == null ) { return true; } @@ -61,10 +55,10 @@ class _AddCustomRuleState extends State { String fieldValue = value ?? domainController.text; - if (preset == 'block') { + if (preset == 0) { rule = "||${fieldValue.trim()}^"; } - else if (preset == 'unblock') { + else if (preset == 1) { rule = "@@||${fieldValue.trim()}^"; } else { @@ -96,318 +90,325 @@ class _AddCustomRuleState extends State { @override Widget build(BuildContext context) { - return Padding( - padding: MediaQuery.of(context).viewInsets, - child: Container( - decoration: BoxDecoration( - color: Theme.of(context).dialogBackgroundColor, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(28), - topRight: Radius.circular(28) - ) + final appConfigProvider = Provider.of(context); + + Map presets = { + 0: Text( + AppLocalizations.of(context)!.block, + style: TextStyle( + color: appConfigProvider.useDynamicColor == true + ? Theme.of(context).floatingActionButtonTheme.foregroundColor! + : preset == 0 + ? Colors.white + : Theme.of(context).primaryColor, + fontSize: 14, + fontWeight: FontWeight.w500 ), - child: Column( - children: [ - Expanded( - child: ListView( - controller: widget.scrollController, - children: [ - const Padding( - padding: EdgeInsets.only(top: 28), - child: Icon( - Icons.shield_rounded, - size: 26, - ), + ), + 1: Text( + AppLocalizations.of(context)!.unblock, + style: TextStyle( + color: appConfigProvider.useDynamicColor == true + ? Theme.of(context).floatingActionButtonTheme.foregroundColor! + : preset == 1 + ? Colors.white + : Theme.of(context).primaryColor, + fontSize: 14, + fontWeight: FontWeight.w500 + ), + ), + 2: Text( + AppLocalizations.of(context)!.custom, + style: TextStyle( + color: appConfigProvider.useDynamicColor == true + ? Theme.of(context).floatingActionButtonTheme.foregroundColor! + : preset == 2 + ? Colors.white + : Theme.of(context).primaryColor, + fontSize: 14, + fontWeight: FontWeight.w500 + ), + ), + }; + + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.addCustomRule), + ), + body: ListView( + children: [ + const SizedBox(height: 24), + Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 5 + ), + decoration: BoxDecoration( + color: Theme.of(context).primaryColor.withOpacity(0.1), + borderRadius: BorderRadius.circular(30), + border: Border.all( + color: Theme.of(context).primaryColor + ) + ), + child: Text( + buildRule(), + textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of(context).primaryColor, + fontWeight: FontWeight.w500 ), - const SizedBox(height: 20), - Text( - AppLocalizations.of(context)!.addCustomRule, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 - ), - ), - const SizedBox(height: 30), - Row( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Container( - padding: const EdgeInsets.symmetric( - horizontal: 10, - vertical: 5 - ), - decoration: BoxDecoration( - color: Theme.of(context).primaryColor.withOpacity(0.1), - borderRadius: BorderRadius.circular(30), - border: Border.all( - color: Theme.of(context).primaryColor - ) - ), - child: Text( - buildRule(), - textAlign: TextAlign.center, - style: TextStyle( - color: Theme.of(context).primaryColor, - fontWeight: FontWeight.w500 - ), - ) - ), - ], - ), - const SizedBox(height: 30), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 28), - child: TextFormField( - controller: domainController, - onChanged: (value) => setState(() => {}), - decoration: InputDecoration( - prefixIcon: const Icon(Icons.link_rounded), - border: const OutlineInputBorder( - borderRadius: BorderRadius.all( - Radius.circular(10) - ) - ), - errorText: domainError, - labelText: AppLocalizations.of(context)!.domain, - ), - ), - ), - const SizedBox(height: 30), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - CustomRadioToggle( - groupSelected: preset, - value: 'block', - label: AppLocalizations.of(context)!.block, - onTap: (value) => setState(() => preset = value) - ), - CustomRadioToggle( - groupSelected: preset, - value: 'unblock', - label: AppLocalizations.of(context)!.unblock, - onTap: (value) => setState(() => preset = value) - ), - CustomRadioToggle( - groupSelected: preset, - value: 'custom', - label: AppLocalizations.of(context)!.custom, - onTap: (value) => setState(() => preset = value) - ), - ], - ), - const SizedBox(height: 20), - Material( - color: Colors.transparent, - child: InkWell( - onTap: () => setState(() => addImportant = !addImportant), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 28), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.only(left: 10), - child: Text( - AppLocalizations.of(context)!.addImportant, - style: const TextStyle( - fontSize: 16 - ), - ), - ), - Switch( - value: addImportant, - onChanged: (value) => setState(() => addImportant = value), - activeColor: Theme.of(context).primaryColor, - ) - ], - ), - ), - ), - ), - const SizedBox(height: 20), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Card( - child: Padding( - padding: const EdgeInsets.all(20), - child: Column( - children: [ - Row( - children: [ - const Icon(Icons.info), - const SizedBox(width: 20), - Text( - AppLocalizations.of(context)!.examples, - style: const TextStyle( - fontSize: 18 - ), - ) - ], - ), - const SizedBox(height: 20), - SizedBox( - width: double.maxFinite, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "||example.org^", - textAlign: TextAlign.left, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - const SizedBox(height: 5), - Text( - AppLocalizations.of(context)!.example1, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).primaryColor - ), - ), - const SizedBox(height: 20), - Text( - "@@||example.org^", - textAlign: TextAlign.left, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - const SizedBox(height: 5), - Text( - AppLocalizations.of(context)!.example2, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).primaryColor - ), - ), - const SizedBox(height: 20), - Text( - "! Here goes a comment", - textAlign: TextAlign.left, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - Text( - "# Also a comment", - textAlign: TextAlign.left, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - const SizedBox(height: 5), - Text( - AppLocalizations.of(context)!.example3, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).primaryColor - ), - ), - const SizedBox(height: 20), - Text( - "/REGEX/", - textAlign: TextAlign.left, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - const SizedBox(height: 5), - Text( - AppLocalizations.of(context)!.example4, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).primaryColor - ), - ), - ], - ), - ) - ], - ), - ), - ), - ), - const SizedBox(height: 20), - Material( - color: Colors.transparent, - child: InkWell( - onTap: openDocsPage, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.only(left: 10), - child: Text( - AppLocalizations.of(context)!.moreInformation, - style: const TextStyle( - fontSize: 16 - ), - ), - ), - const Padding( - padding: EdgeInsets.only(right: 15), - child: Icon(Icons.open_in_new), - ) - ], - ), - ), - ), - ), - ], + ) + ), + ], + ), + const SizedBox(height: 30), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: TextFormField( + controller: domainController, + onChanged: (value) => setState(() => {}), + decoration: InputDecoration( + prefixIcon: const Icon(Icons.link_rounded), + border: const OutlineInputBorder( + borderRadius: BorderRadius.all( + Radius.circular(10) + ) + ), + errorText: domainError, + labelText: AppLocalizations.of(context)!.domain, ), ), - Padding( - padding: const EdgeInsets.only( - left: 28, - right: 28, - top: 20, - bottom: 28 + ), + const SizedBox(height: 30), + MaterialSegmentedControl( + children: presets, + selectionIndex: preset, + onSegmentChosen: (value) => setState(() => preset = value), + selectedColor: Theme.of(context).floatingActionButtonTheme.backgroundColor!, + unselectedColor: Colors.transparent, + borderColor: Theme.of(context).colorScheme.onSurface, + ), + const SizedBox(height: 20), + Material( + color: Colors.transparent, + child: InkWell( + onTap: () => setState(() => addImportant = !addImportant), + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 28), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 10), + child: Text( + AppLocalizations.of(context)!.addImportant, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface + ), + ), + ), + Switch( + value: addImportant, + onChanged: (value) => setState(() => addImportant = value), + activeColor: Theme.of(context).primaryColor, + ) + ], + ), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: Text(AppLocalizations.of(context)!.cancel) - ), - const SizedBox(width: 20), - TextButton( - onPressed: checkValidValues() == true - ? () { - Navigator.pop(context); - widget.onConfirm(buildRule()); - } - : null, - child: Text( - AppLocalizations.of(context)!.confirm, - style: TextStyle( - color: checkValidValues() == true - ? Theme.of(context).primaryColor - : Colors.grey + ), + ), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Card( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + children: [ + Row( + children: [ + Icon( + Icons.info, + color: Theme.of(context).colorScheme.onSurface + ), + const SizedBox(width: 20), + Text( + AppLocalizations.of(context)!.examples, + style: TextStyle( + fontSize: 18, + color: Theme.of(context).colorScheme.onSurface + ), + ) + ], + ), + const SizedBox(height: 20), + SizedBox( + width: double.maxFinite, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "||example.org^", + textAlign: TextAlign.left, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + const SizedBox(height: 5), + Text( + AppLocalizations.of(context)!.example1, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).primaryColor + ), + ), + const SizedBox(height: 20), + Text( + "@@||example.org^", + textAlign: TextAlign.left, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + const SizedBox(height: 5), + Text( + AppLocalizations.of(context)!.example2, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).primaryColor + ), + ), + const SizedBox(height: 20), + Text( + "! Here goes a comment", + textAlign: TextAlign.left, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + Text( + "# Also a comment", + textAlign: TextAlign.left, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + const SizedBox(height: 5), + Text( + AppLocalizations.of(context)!.example3, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).primaryColor + ), + ), + const SizedBox(height: 20), + Text( + "/REGEX/", + textAlign: TextAlign.left, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + const SizedBox(height: 5), + Text( + AppLocalizations.of(context)!.example4, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).primaryColor + ), + ), + ], ), ) - ), - ], + ], + ), ), - ) - ], - ), + ), + ), + const SizedBox(height: 20), + Material( + color: Colors.transparent, + child: InkWell( + onTap: openDocsPage, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 10), + child: Text( + AppLocalizations.of(context)!.moreInformation, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface + ), + ), + ), + Padding( + padding: const EdgeInsets.only(right: 15), + child: Icon( + Icons.open_in_new, + color: Theme.of(context).colorScheme.onSurface + ), + ) + ], + ), + ), + ), + ), + const SizedBox(height: 20) + ], ), ); } -} \ No newline at end of file +} + // Padding( + // padding: const EdgeInsets.only( + // left: 28, + // right: 28, + // top: 20, + // bottom: 28 + // ), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.end, + // children: [ + // TextButton( + // onPressed: () => Navigator.pop(context), + // child: Text(AppLocalizations.of(context)!.cancel) + // ), + // const SizedBox(width: 20), + // TextButton( + // onPressed: checkValidValues() == true + // ? () { + // Navigator.pop(context); + // widget.onConfirm(buildRule()); + // } + // : null, + // child: Text( + // AppLocalizations.of(context)!.confirm, + // style: TextStyle( + // color: checkValidValues() == true + // ? Theme.of(context).primaryColor + // : Colors.grey + // ), + // ) + // ), + // ], + // ), + // ) \ No newline at end of file diff --git a/lib/screens/filters/add_list_modal.dart b/lib/screens/filters/add_list_modal.dart index 618e1e3..d76d55b 100644 --- a/lib/screens/filters/add_list_modal.dart +++ b/lib/screens/filters/add_list_modal.dart @@ -69,7 +69,7 @@ class _AddListModalState extends State { return Padding( padding: MediaQuery.of(context).viewInsets, child: Container( - height: 410, + height: 370, decoration: BoxDecoration( borderRadius: const BorderRadius.only( topLeft: Radius.circular(28), @@ -86,15 +86,16 @@ class _AddListModalState extends State { : null, children: [ Padding( - padding: const EdgeInsets.only(top: 28), + padding: const EdgeInsets.only(top: 24), child: Icon( widget.type == 'whitelist' ? Icons.verified_user_rounded : Icons.gpp_bad_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( widget.list != null ? widget.type == 'whitelist' @@ -104,13 +105,14 @@ class _AddListModalState extends State { ? AppLocalizations.of(context)!.addWhitelist : AppLocalizations.of(context)!.addBlacklist, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 30), + const SizedBox(height: 16), Padding( - padding: const EdgeInsets.symmetric(horizontal: 28), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: nameController, onChanged: (_) => checkValidValues(), @@ -127,7 +129,7 @@ class _AddListModalState extends State { ), const SizedBox(height: 30), Padding( - padding: const EdgeInsets.symmetric(horizontal: 28), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: urlController, onChanged: validateUrl, @@ -148,7 +150,7 @@ class _AddListModalState extends State { ), ), Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(24), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ diff --git a/lib/screens/filters/blocked_services_modal.dart b/lib/screens/filters/blocked_services_modal.dart index 86dad49..e724295 100644 --- a/lib/screens/filters/blocked_services_modal.dart +++ b/lib/screens/filters/blocked_services_modal.dart @@ -71,19 +71,21 @@ class _BlockedServicesModalState extends State { child: ListView( controller: widget.scrollController, children: [ - const Padding( - padding: EdgeInsets.only(top: 28), + Padding( + padding: const EdgeInsets.only(top: 24), child: Icon( Icons.block, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.blockedServices, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ), const SizedBox(height: 20), @@ -102,8 +104,9 @@ class _BlockedServicesModalState extends State { children: [ Text( services[index]['label']!, - style: const TextStyle( - fontSize: 16 + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface ), ), Checkbox( diff --git a/lib/screens/filters/check_host_modal.dart b/lib/screens/filters/check_host_modal.dart index 06f22d8..6e8e3b9 100644 --- a/lib/screens/filters/check_host_modal.dart +++ b/lib/screens/filters/check_host_modal.dart @@ -120,7 +120,7 @@ class _CheckHostModalState extends State { return Padding( padding: MediaQuery.of(context).viewInsets, child: Container( - height: 350, + height: 330, width: double.maxFinite, decoration: BoxDecoration( borderRadius: const BorderRadius.only( @@ -138,24 +138,26 @@ class _CheckHostModalState extends State { ? const NeverScrollableScrollPhysics() : null, children: [ - const Padding( - padding: EdgeInsets.only(top: 24), + Padding( + padding: const EdgeInsets.only(top: 24), child: Icon( Icons.shield_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.checkHostFiltered, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 30), + const SizedBox(height: 16), Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: domainController, onChanged: validateDomain, @@ -202,8 +204,8 @@ class _CheckHostModalState extends State { children: [ Padding( padding: const EdgeInsets.only( - bottom: 20, - right: 20 + bottom: 24, + right: 24 ), child: Row( mainAxisAlignment: MainAxisAlignment.end, diff --git a/lib/screens/filters/custom_rules_list.dart b/lib/screens/filters/custom_rules_list.dart index 03bccf3..b40ebb7 100644 --- a/lib/screens/filters/custom_rules_list.dart +++ b/lib/screens/filters/custom_rules_list.dart @@ -148,10 +148,8 @@ class _CustomRulesListState extends State { widget.data[index], style: TextStyle( color: checkIfComment(widget.data[index]) == true - ? Theme.of(context).brightness == Brightness.light - ? const Color.fromRGBO(100, 100, 100, 1) - : const Color.fromRGBO(200, 200, 200, 1) - : null, + ? Theme.of(context).colorScheme.onSurface.withOpacity(0.6) + : Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.normal, ), ), diff --git a/lib/screens/filters/delete_list_modal.dart b/lib/screens/filters/delete_list_modal.dart index e286326..5d751e4 100644 --- a/lib/screens/filters/delete_list_modal.dart +++ b/lib/screens/filters/delete_list_modal.dart @@ -14,15 +14,27 @@ class DeleteListModal extends StatelessWidget { return AlertDialog( title: Column( children: [ - const Icon( + Icon( Icons.delete_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), - const SizedBox(height: 20), - Text(AppLocalizations.of(context)!.deleteList) + const SizedBox(height: 16), + Text( + AppLocalizations.of(context)!.deleteList, + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface + ), + ) ], ), - content: Text(AppLocalizations.of(context)!.deleteListMessage), + content: Text( + AppLocalizations.of(context)!.deleteListMessage, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ), actions: [ TextButton( onPressed: () => Navigator.pop(context), diff --git a/lib/screens/filters/fab.dart b/lib/screens/filters/fab.dart index 479ea04..ee6b121 100644 --- a/lib/screens/filters/fab.dart +++ b/lib/screens/filters/fab.dart @@ -64,20 +64,12 @@ class FiltersFab extends StatelessWidget { } void openAddCustomRule() { - ScaffoldMessenger.of(context).clearSnackBars(); - showFlexibleBottomSheet( - minHeight: 0.7, - initHeight: 0.7, - maxHeight: 0.95, - isCollapsible: true, - duration: const Duration(milliseconds: 250), - anchors: [0.7, 0.95], - context: context, - builder: (ctx, controller, offset) => AddCustomRule( - scrollController: controller, - onConfirm: confirmAddRule - ), - bottomSheetColor: Colors.transparent + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => AddCustomRule( + onConfirm: confirmAddRule + ), + ) ); } @@ -176,9 +168,10 @@ class FiltersFab extends StatelessWidget { onPressed: type == 'blacklist' || type == 'whitelist' ? () => openAddWhitelistBlacklist() : () => openAddCustomRule(), + backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, child: Icon( Icons.add, - color: Theme.of(context).primaryColor.computeLuminance() > 0.5 ? Colors.black : Colors.white, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, ), ); } diff --git a/lib/screens/filters/filter_list_tile.dart b/lib/screens/filters/filter_list_tile.dart index 808ccaa..1782d62 100644 --- a/lib/screens/filters/filter_list_tile.dart +++ b/lib/screens/filters/filter_list_tile.dart @@ -19,31 +19,35 @@ class FilterListTile extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Icon( icon, + size: 24, + color: Theme.of(context).listTileTheme.iconColor, ), - const SizedBox(width: 20), + const SizedBox(width: 16), Flexible( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, - style: const TextStyle( - fontSize: 18, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 5), + const SizedBox(height: 3), Text( subtitle, style: TextStyle( fontSize: 14, - color: color ?? Theme.of(context).listTileTheme.iconColor, - fontWeight: bold == true ? FontWeight.bold : null + color: color ?? Theme.of(context).listTileTheme.textColor, + fontWeight: bold == true ? FontWeight.bold : FontWeight.w400 ), ), ], diff --git a/lib/screens/filters/filters.dart b/lib/screens/filters/filters.dart index 610b721..de0d3d5 100644 --- a/lib/screens/filters/filters.dart +++ b/lib/screens/filters/filters.dart @@ -367,36 +367,19 @@ class _FiltersWidgetState extends State with TickerProviderStateM bottom: TabBar( controller: tabController, isScrollable: true, + unselectedLabelColor: Theme.of(context).colorScheme.onSurfaceVariant, tabs: [ Tab( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.verified_user_rounded), - const SizedBox(width: 20), - Text(AppLocalizations.of(context)!.whitelists), - ], - ), + icon: const Icon(Icons.verified_user_rounded), + text: AppLocalizations.of(context)!.whitelists, ), Tab( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.gpp_bad_rounded), - const SizedBox(width: 20), - Text(AppLocalizations.of(context)!.blacklist), - ], - ), + icon: const Icon(Icons.gpp_bad_rounded), + text: AppLocalizations.of(context)!.blacklist, ), Tab( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.shield_rounded), - const SizedBox(width: 20), - Text(AppLocalizations.of(context)!.customRules), - ], - ), + icon: const Icon(Icons.shield_rounded), + text: AppLocalizations.of(context)!.customRules, ), ] ) @@ -410,9 +393,7 @@ class _FiltersWidgetState extends State with TickerProviderStateM color: Theme.of(context).scaffoldBackgroundColor, border: Border( top: BorderSide( - color: Theme.of(context).brightness == Brightness.light - ? const Color.fromRGBO(220, 220, 220, 1) - : const Color.fromRGBO(50, 50, 50, 1) + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.1) ) ) ), diff --git a/lib/screens/filters/filters_list.dart b/lib/screens/filters/filters_list.dart index f6d7255..1467404 100644 --- a/lib/screens/filters/filters_list.dart +++ b/lib/screens/filters/filters_list.dart @@ -3,21 +3,14 @@ import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:bottom_sheet/bottom_sheet.dart'; import 'package:provider/provider.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:adguard_home_manager/screens/filters/fab.dart'; -import 'package:adguard_home_manager/screens/filters/list_details_modal.dart'; -import 'package:adguard_home_manager/screens/filters/add_list_modal.dart'; -import 'package:adguard_home_manager/screens/filters/delete_list_modal.dart'; +import 'package:adguard_home_manager/screens/filters/list_details_screen.dart'; import 'package:adguard_home_manager/widgets/custom_list_tile.dart'; -import 'package:adguard_home_manager/services/http_requests.dart'; -import 'package:adguard_home_manager/functions/snackbar.dart'; -import 'package:adguard_home_manager/classes/process_modal.dart'; -import 'package:adguard_home_manager/providers/servers_provider.dart'; import 'package:adguard_home_manager/providers/app_config_provider.dart'; import 'package:adguard_home_manager/functions/number_format.dart'; import 'package:adguard_home_manager/models/filtering.dart'; @@ -68,196 +61,16 @@ class _FiltersListState extends State { @override Widget build(BuildContext context) { - final serversProvider = Provider.of(context); final appConfigProvider = Provider.of(context); - - void enableDisableList(Filter list, bool enabled) async { - ProcessModal processModal = ProcessModal(context: context); - processModal.open( - enabled == true - ? AppLocalizations.of(context)!.enablingList - : AppLocalizations.of(context)!.disablingList, - ); - - final result = await updateFilterList(server: serversProvider.selectedServer!, data: { - "data": { - "enabled": enabled, - "name": list.name, - "url": list.url - }, - "url": list.url, - "whitelist": widget.type == 'whitelist' ? true : false - }); - - processModal.close(); - - if (result['result'] == 'success') { - final result2 = await getFiltering(server: serversProvider.selectedServer!); - - if (result2['result'] == 'success') { - serversProvider.setFilteringData(result2['data']); - serversProvider.setFilteringLoadStatus(1, true); - } - else { - appConfigProvider.addLog(result2['log']); - serversProvider.setFilteringLoadStatus(2, true); - } - - showSnacbkar( - context: context, - appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.listDataUpdated, - color: Colors.green - ); - } - else { - appConfigProvider.addLog(result['log']); - - showSnacbkar( - context: context, - appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.listDataNotUpdated, - color: Colors.red - ); - } - } - - void confirmEditList({required Filter list, required String type}) async { - ProcessModal processModal = ProcessModal(context: context); - processModal.open(AppLocalizations.of(context)!.updatingListData); - - final result1 = await updateFilterList(server: serversProvider.selectedServer!, data: { - "data": { - "enabled": list.enabled, - "name": list.name, - "url": list.url - }, - "url": list.url, - "whitelist": type == 'whitelist' ? true : false - }); - - if (result1['result'] == 'success') { - final result2 = await getFiltering(server: serversProvider.selectedServer!); - - if (result2['result'] == 'success') { - serversProvider.setFilteringData(result2['data']); - serversProvider.setFilteringLoadStatus(1, true); - } - else { - appConfigProvider.addLog(result2['log']); - serversProvider.setFilteringLoadStatus(2, true); - } - - processModal.close(); - - showSnacbkar( - context: context, - appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.listDataUpdated, - color: Colors.green - ); - } - else { - processModal.close(); - appConfigProvider.addLog(result1['log']); - - showSnacbkar( - context: context, - appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.listDataNotUpdated, - color: Colors.red - ); - } - } - - void deleteList(Filter list, String type) async { - ProcessModal processModal = ProcessModal(context: context); - processModal.open(AppLocalizations.of(context)!.deletingList); - - final result1 = await deleteFilterList(server: serversProvider.selectedServer!, data: { - "url": list.url, - "whitelist": type == 'whitelist' ? true : false - }); - - if (result1['result'] == 'success') { - final result2 = await getFiltering(server: serversProvider.selectedServer!); - - if (result2['result'] == 'success') { - serversProvider.setFilteringData(result2['data']); - serversProvider.setFilteringLoadStatus(1, true); - } - else { - appConfigProvider.addLog(result2['log']); - serversProvider.setFilteringLoadStatus(2, true); - } - - processModal.close(); - - showSnacbkar( - context: context, - appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.listDeleted, - color: Colors.green - ); - } - else { - processModal.close(); - appConfigProvider.addLog(result1['log']); - - showSnacbkar( - context: context, - appConfigProvider: appConfigProvider, - label: AppLocalizations.of(context)!.listNotDeleted, - color: Colors.red - ); - } - } - + void openDetailsModal(Filter filter) { - final height = (filter.enabled == true ? 774 : 755)/MediaQuery.of(context).size.height < 1 - ? (filter.enabled == true ? 774 : 755)/MediaQuery.of(context).size.height - : 0.95; - - ScaffoldMessenger.of(context).clearSnackBars(); - - showFlexibleBottomSheet( - minHeight: 0.6, - initHeight: 0.6, - maxHeight: height, - isCollapsible: true, - duration: const Duration(milliseconds: 250), - anchors: [height], - context: context, - builder: (ctx, controller, offset) => ListDetailsModal( - scrollController: controller, - list: filter, - type: widget.type, - onDelete: (Filter list, String type) { - showDialog( - context: context, - builder: (context) => DeleteListModal( - onConfirm: () { - Navigator.pop(context); - deleteList(list, type); - }, - ) - ); - }, - edit: (type) => { - showModalBottomSheet( - context: context, - builder: (ctx) => AddListModal( - list: filter, - type: type, - onEdit: confirmEditList - ), - isScrollControlled: true, - backgroundColor: Colors.transparent - ) - }, - onEnableDisable: enableDisableList, - ), - bottomSheetColor: Colors.transparent + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => ListDetailsScreen( + list: filter, + type: widget.type, + ) + ) ); } diff --git a/lib/screens/filters/list_details_modal.dart b/lib/screens/filters/list_details_modal.dart deleted file mode 100644 index eb9109b..0000000 --- a/lib/screens/filters/list_details_modal.dart +++ /dev/null @@ -1,176 +0,0 @@ -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/filters/filter_list_tile.dart'; - -import 'package:adguard_home_manager/functions/format_time.dart'; -import 'package:adguard_home_manager/providers/app_config_provider.dart'; -import 'package:adguard_home_manager/models/filtering.dart'; - -class ListDetailsModal extends StatelessWidget { - final ScrollController scrollController; - final Filter list; - final String type; - final void Function(Filter, String) onDelete; - final void Function(String) edit; - final void Function(Filter, bool) onEnableDisable; - - const ListDetailsModal({ - Key? key, - required this.scrollController, - required this.list, - required this.type, - required this.onDelete, - required this.edit, - required this.onEnableDisable, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - final appConfigProvider = Provider.of(context); - - return Container( - decoration: BoxDecoration( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(28), - topRight: Radius.circular(28) - ), - color: Theme.of(context).dialogBackgroundColor - ), - child: Column( - children: [ - Expanded( - child: NotificationListener( - onNotification: (overscroll) { - overscroll.disallowIndicator(); - return false; - }, - child: ListView( - controller: scrollController, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Padding( - padding: const EdgeInsets.only(top: 24), - child: Icon( - type == 'whitelist' - ? Icons.verified_user_rounded - : Icons.gpp_bad_rounded, - size: 26, - ), - ), - ), - const SizedBox(height: 20), - Text( - AppLocalizations.of(context)!.listDetails, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24, - ), - ), - const SizedBox(height: 30), - Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton.icon( - onPressed: () { - Navigator.pop(context); - onEnableDisable(list, !list.enabled); - }, - label: Text( - list.enabled == true - ? AppLocalizations.of(context)!.disable - : AppLocalizations.of(context)!.enable - ), - icon: Icon( - list.enabled == true - ? Icons.gpp_bad_rounded - : Icons.verified_user_rounded - ), - ), - ], - ), - const SizedBox(height: 30), - FilterListTile( - icon: Icons.shield_rounded, - title: AppLocalizations.of(context)!.currentStatus, - subtitle: list.enabled == true - ? AppLocalizations.of(context)!.enabled - : AppLocalizations.of(context)!.disabled, - color: list.enabled == true - ? appConfigProvider.useThemeColorForStatus == true - ? Theme.of(context).primaryColor - : Colors.green - : appConfigProvider.useThemeColorForStatus == true - ? Colors.grey - : Colors.red, - bold: true, - ), - FilterListTile( - icon: Icons.badge_rounded, - title: AppLocalizations.of(context)!.name, - subtitle: list.name - ), - FilterListTile( - icon: Icons.link_rounded, - title: "URL", - subtitle: list.url - ), - FilterListTile( - icon: Icons.list_rounded, - title: AppLocalizations.of(context)!.rules, - subtitle: list.rulesCount.toString() - ), - FilterListTile( - icon: Icons.shield_rounded, - title: AppLocalizations.of(context)!.listType, - subtitle: type == 'whitelist' - ? AppLocalizations.of(context)!.whitelist - : AppLocalizations.of(context)!.blacklist, - ), - if (list.lastUpdated != null) FilterListTile( - icon: Icons.schedule_rounded, - title: AppLocalizations.of(context)!.latestUpdate, - subtitle: formatTimestampUTC(list.lastUpdated!, 'dd-MM-yyyy HH:mm'), - ), - ], - ), - ) - ), - Padding( - padding: const EdgeInsets.all(20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - IconButton( - onPressed: () { - Navigator.pop(context); - edit(type); - }, - icon: const Icon(Icons.edit) - ), - const SizedBox(width: 10), - IconButton( - onPressed: () { - onDelete(list, type); - }, - icon: const Icon(Icons.delete) - ), - ], - ), - TextButton( - onPressed: () => Navigator.pop(context), - child: Text(AppLocalizations.of(context)!.close) - ) - ], - ), - ), - ], - ), - ); - } -} \ No newline at end of file diff --git a/lib/screens/filters/list_details_screen.dart b/lib/screens/filters/list_details_screen.dart new file mode 100644 index 0000000..95c26fb --- /dev/null +++ b/lib/screens/filters/list_details_screen.dart @@ -0,0 +1,322 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:provider/provider.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +import 'package:adguard_home_manager/screens/filters/filter_list_tile.dart'; +import 'package:adguard_home_manager/screens/filters/add_list_modal.dart'; +import 'package:adguard_home_manager/screens/filters/delete_list_modal.dart'; + +import 'package:adguard_home_manager/functions/format_time.dart'; +import 'package:adguard_home_manager/providers/app_config_provider.dart'; +import 'package:adguard_home_manager/functions/snackbar.dart'; +import 'package:adguard_home_manager/classes/process_modal.dart'; +import 'package:adguard_home_manager/providers/servers_provider.dart'; +import 'package:adguard_home_manager/services/http_requests.dart'; +import 'package:adguard_home_manager/models/filtering.dart'; + +class ListDetailsScreen extends StatefulWidget { + final Filter list; + final String type; + + const ListDetailsScreen({ + Key? key, + required this.list, + required this.type, + }) : super(key: key); + + @override + State createState() => _ListDetailsScreenState(); +} + +class _ListDetailsScreenState extends State { + final ScrollController scrollController = ScrollController(); + String name = ""; + bool enabled = true; + bool fabVisible = true; + + @override + void initState() { + name = widget.list.name; + enabled = widget.list.enabled; + + scrollController.addListener(() { + if (scrollController.position.userScrollDirection == ScrollDirection.reverse) { + if (mounted && fabVisible == true) { + setState(() => fabVisible = false); + } + } + else { + if (scrollController.position.userScrollDirection == ScrollDirection.forward) { + if (mounted && fabVisible == false) { + setState(() => fabVisible = true); + } + } + } + }); + + super.initState(); + } + + @override + Widget build(BuildContext context) { + final serversProvider = Provider.of(context); + final appConfigProvider = Provider.of(context); + + void enableDisableList(Filter list, bool newStatus) async { + ProcessModal processModal = ProcessModal(context: context); + processModal.open( + enabled == true + ? AppLocalizations.of(context)!.disablingList + : AppLocalizations.of(context)!.enablingList, + ); + + final result = await updateFilterList(server: serversProvider.selectedServer!, data: { + "data": { + "enabled": newStatus, + "name": list.name, + "url": list.url + }, + "url": list.url, + "whitelist": widget.type == 'whitelist' ? true : false + }); + + processModal.close(); + + if (result['result'] == 'success') { + final result2 = await getFiltering(server: serversProvider.selectedServer!); + + if (result2['result'] == 'success') { + serversProvider.setFilteringData(result2['data']); + serversProvider.setFilteringLoadStatus(1, true); + } + else { + appConfigProvider.addLog(result2['log']); + serversProvider.setFilteringLoadStatus(2, true); + } + + setState(() => enabled = newStatus); + + showSnacbkar( + context: context, + appConfigProvider: appConfigProvider, + label: AppLocalizations.of(context)!.listDataUpdated, + color: Colors.green + ); + } + else { + appConfigProvider.addLog(result['log']); + + showSnacbkar( + context: context, + appConfigProvider: appConfigProvider, + label: AppLocalizations.of(context)!.listDataNotUpdated, + color: Colors.red + ); + } + } + + void confirmEditList({required Filter list, required String type}) async { + ProcessModal processModal = ProcessModal(context: context); + processModal.open(AppLocalizations.of(context)!.updatingListData); + + final result1 = await updateFilterList(server: serversProvider.selectedServer!, data: { + "data": { + "enabled": list.enabled, + "name": list.name, + "url": list.url + }, + "url": list.url, + "whitelist": type == 'whitelist' ? true : false + }); + + if (result1['result'] == 'success') { + final result2 = await getFiltering(server: serversProvider.selectedServer!); + + if (result2['result'] == 'success') { + serversProvider.setFilteringData(result2['data']); + serversProvider.setFilteringLoadStatus(1, true); + } + else { + appConfigProvider.addLog(result2['log']); + serversProvider.setFilteringLoadStatus(2, true); + } + + processModal.close(); + + setState(() => name = list.name); + + showSnacbkar( + context: context, + appConfigProvider: appConfigProvider, + label: AppLocalizations.of(context)!.listDataUpdated, + color: Colors.green + ); + } + else { + processModal.close(); + appConfigProvider.addLog(result1['log']); + + showSnacbkar( + context: context, + appConfigProvider: appConfigProvider, + label: AppLocalizations.of(context)!.listDataNotUpdated, + color: Colors.red + ); + } + } + + void deleteList(Filter list, String type) async { + ProcessModal processModal = ProcessModal(context: context); + processModal.open(AppLocalizations.of(context)!.deletingList); + + final result1 = await deleteFilterList(server: serversProvider.selectedServer!, data: { + "url": list.url, + "whitelist": type == 'whitelist' ? true : false + }); + + if (result1['result'] == 'success') { + final result2 = await getFiltering(server: serversProvider.selectedServer!); + + if (result2['result'] == 'success') { + serversProvider.setFilteringData(result2['data']); + serversProvider.setFilteringLoadStatus(1, true); + } + else { + appConfigProvider.addLog(result2['log']); + serversProvider.setFilteringLoadStatus(2, true); + } + + processModal.close(); + + Navigator.pop(context); // Closes the screen + + showSnacbkar( + context: context, + appConfigProvider: appConfigProvider, + label: AppLocalizations.of(context)!.listDeleted, + color: Colors.green + ); + } + else { + processModal.close(); + appConfigProvider.addLog(result1['log']); + + showSnacbkar( + context: context, + appConfigProvider: appConfigProvider, + label: AppLocalizations.of(context)!.listNotDeleted, + color: Colors.red + ); + } + } + + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.listDetails), + actions: [ + IconButton( + onPressed: () => { + showModalBottomSheet( + context: context, + builder: (ctx) => AddListModal( + list: widget.list, + type: widget.type, + onEdit: confirmEditList + ), + isScrollControlled: true, + backgroundColor: Colors.transparent + ) + }, + icon: const Icon(Icons.edit), + tooltip: AppLocalizations.of(context)!.edit, + ), + IconButton( + onPressed: () { + showDialog( + context: context, + builder: (context) => DeleteListModal( + onConfirm: () => deleteList(widget.list, widget.type), + ) + ); + }, + icon: const Icon(Icons.delete), + tooltip: AppLocalizations.of(context)!.delete, + ), + const SizedBox(width: 10), + ], + ), + body: Stack( + children: [ + ListView( + children: [ + FilterListTile( + icon: Icons.shield_rounded, + title: AppLocalizations.of(context)!.currentStatus, + subtitle: enabled == true + ? AppLocalizations.of(context)!.enabled + : AppLocalizations.of(context)!.disabled, + color: enabled == true + ? appConfigProvider.useThemeColorForStatus == true + ? Theme.of(context).primaryColor + : Colors.green + : appConfigProvider.useThemeColorForStatus == true + ? Colors.grey + : Colors.red, + bold: true, + ), + FilterListTile( + icon: Icons.badge_rounded, + title: AppLocalizations.of(context)!.name, + subtitle: name + ), + FilterListTile( + icon: Icons.link_rounded, + title: "URL", + subtitle: widget.list.url + ), + FilterListTile( + icon: Icons.list_rounded, + title: AppLocalizations.of(context)!.rules, + subtitle: widget.list.rulesCount.toString() + ), + FilterListTile( + icon: Icons.shield_rounded, + title: AppLocalizations.of(context)!.listType, + subtitle: widget.type == 'whitelist' + ? AppLocalizations.of(context)!.whitelist + : AppLocalizations.of(context)!.blacklist, + ), + if (widget.list.lastUpdated != null) FilterListTile( + icon: Icons.schedule_rounded, + title: AppLocalizations.of(context)!.latestUpdate, + subtitle: formatTimestampUTC(widget.list.lastUpdated!, 'dd-MM-yyyy HH:mm'), + ), + ], + ), + AnimatedPositioned( + duration: const Duration(milliseconds: 100), + curve: Curves.easeInOut, + bottom: fabVisible ? + appConfigProvider.showingSnackbar + ? 70 : 20 + : -70, + right: 20, + child: FloatingActionButton( + onPressed: () => enableDisableList(widget.list, !enabled), + backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, + child: Icon( + enabled == true + ? Icons.gpp_bad_rounded + : Icons.verified_user_rounded, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, + ), + ), + ) + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/filters/remove_custom_rule_modal.dart b/lib/screens/filters/remove_custom_rule_modal.dart index de25f4b..f1c4352 100644 --- a/lib/screens/filters/remove_custom_rule_modal.dart +++ b/lib/screens/filters/remove_custom_rule_modal.dart @@ -14,18 +14,27 @@ class RemoveCustomRule extends StatelessWidget { return AlertDialog( title: Column( children: [ - const Icon( + Icon( Icons.shield_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.removeCustomRule, textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), ) ], ), - content: Text(AppLocalizations.of(context)!.removeCustomRuleMessage), + content: Text( + AppLocalizations.of(context)!.removeCustomRuleMessage, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ), actions: [ TextButton( onPressed: () => Navigator.pop(context), diff --git a/lib/screens/filters/update_interval_lists_modal.dart b/lib/screens/filters/update_interval_lists_modal.dart index b55c006..cc7d8f9 100644 --- a/lib/screens/filters/update_interval_lists_modal.dart +++ b/lib/screens/filters/update_interval_lists_modal.dart @@ -42,7 +42,7 @@ class _UpdateIntervalListsModalState extends State { return Padding( padding: mediaQueryData.viewInsets, child: Container( - height: 410, + height: 390, decoration: BoxDecoration( color: Theme.of(context).dialogBackgroundColor, borderRadius: const BorderRadius.only( @@ -59,211 +59,216 @@ class _UpdateIntervalListsModalState extends State { ? const NeverScrollableScrollPhysics() : null, children: [ - const Padding( - padding: EdgeInsets.only(top: 24), - child: Icon( - Icons.update_rounded, - size: 26, - ), - ), - Container( - padding: const EdgeInsets.all(24), - width: double.maxFinite, - child: Text( - AppLocalizations.of(context)!.updateFrequency, - textAlign: TextAlign.center, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: 24, + Padding( + padding: const EdgeInsets.only(top: 24), + child: Icon( + Icons.update_rounded, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), - ), - SizedBox( - width: double.maxFinite, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Container( - width: (mediaQueryData.size.width-70)/2, - margin: const EdgeInsets.only( - top: 10, - right: 5, - bottom: 5 - ), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 0, - onTap: _updateRadioValue, - child: Center( - child: AnimatedDefaultTextStyle( - duration: const Duration(milliseconds: 250), - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: selectedOption == 0 - ? Theme.of(context).primaryColor - : Theme.of(context).textTheme.bodyText1!.color - ), - child: Text(AppLocalizations.of(context)!.never), - ), - ), - ), - ), - Container( - width: (mediaQueryData.size.width-70)/2, - margin: const EdgeInsets.only( - top: 10, - left: 5, - bottom: 5 - ), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 1, - onTap: _updateRadioValue, - child: Center( - child: AnimatedDefaultTextStyle( - duration: const Duration(milliseconds: 250), - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: selectedOption == 1 - ? Theme.of(context).primaryColor - : Theme.of(context).textTheme.bodyText1!.color - ), - child: Text(AppLocalizations.of(context)!.hour1), - ), - ), - ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Container( - width: (mediaQueryData.size.width-70)/2, - margin: const EdgeInsets.only( - top: 5, - right: 5, - bottom: 5 - ), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 12, - onTap: _updateRadioValue, - child: Center( - child: AnimatedDefaultTextStyle( - duration: const Duration(milliseconds: 250), - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: selectedOption == 12 - ? Theme.of(context).primaryColor - : Theme.of(context).textTheme.bodyText1!.color - ), - child: Text(AppLocalizations.of(context)!.hours12), - ), - ), - ), - ), - Container( - width: (mediaQueryData.size.width-70)/2, - margin: const EdgeInsets.only( - top: 5, - left: 5, - bottom: 5 - ), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 24, - onTap: _updateRadioValue, - child: Center( - child: AnimatedDefaultTextStyle( - duration: const Duration(milliseconds: 250), - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: selectedOption == 24 - ? Theme.of(context).primaryColor - : Theme.of(context).textTheme.bodyText1!.color - ), - child: Text(AppLocalizations.of(context)!.hours24), - ), - ), - ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Container( - width: (mediaQueryData.size.width-70)/2, - margin: const EdgeInsets.only( - top: 5, - right: 5, - bottom: 10 - ), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 72, - onTap: _updateRadioValue, - child: Center( - child: AnimatedDefaultTextStyle( - duration: const Duration(milliseconds: 250), - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: selectedOption == 72 - ? Theme.of(context).primaryColor - : Theme.of(context).textTheme.bodyText1!.color - ), - child: Text(AppLocalizations.of(context)!.days3), - ), - ), - ), - ), - Container( - width: (mediaQueryData.size.width-70)/2, - margin: const EdgeInsets.only( - top: 5, - left: 5, - bottom: 10 - ), - child: OptionBox( - optionsValue: selectedOption, - itemValue: 168, - onTap: _updateRadioValue, - child: Center( - child: AnimatedDefaultTextStyle( - duration: const Duration(milliseconds: 250), - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 14, - color: selectedOption == 168 - ? Theme.of(context).primaryColor - : Theme.of(context).textTheme.bodyText1!.color - ), - child: Text(AppLocalizations.of(context)!.days7), - ), - ), - ), - ), - ], - ), - ], + Container( + padding: const EdgeInsets.symmetric( + horizontal: 24, + vertical: 16 + ), + width: double.maxFinite, + child: Text( + AppLocalizations.of(context)!.updateFrequency, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface + ), + ), + ), + SizedBox( + width: double.maxFinite, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + width: (mediaQueryData.size.width-70)/2, + margin: const EdgeInsets.only( + top: 10, + right: 5, + bottom: 5 + ), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 0, + onTap: _updateRadioValue, + child: Center( + child: AnimatedDefaultTextStyle( + duration: const Duration(milliseconds: 250), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: selectedOption == 0 + ? Theme.of(context).primaryColor + : Theme.of(context).textTheme.bodyText1!.color + ), + child: Text(AppLocalizations.of(context)!.never), + ), + ), + ), + ), + Container( + width: (mediaQueryData.size.width-70)/2, + margin: const EdgeInsets.only( + top: 10, + left: 5, + bottom: 5 + ), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 1, + onTap: _updateRadioValue, + child: Center( + child: AnimatedDefaultTextStyle( + duration: const Duration(milliseconds: 250), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: selectedOption == 1 + ? Theme.of(context).primaryColor + : Theme.of(context).textTheme.bodyText1!.color + ), + child: Text(AppLocalizations.of(context)!.hour1), + ), + ), + ), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + width: (mediaQueryData.size.width-70)/2, + margin: const EdgeInsets.only( + top: 5, + right: 5, + bottom: 5 + ), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 12, + onTap: _updateRadioValue, + child: Center( + child: AnimatedDefaultTextStyle( + duration: const Duration(milliseconds: 250), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: selectedOption == 12 + ? Theme.of(context).primaryColor + : Theme.of(context).textTheme.bodyText1!.color + ), + child: Text(AppLocalizations.of(context)!.hours12), + ), + ), + ), + ), + Container( + width: (mediaQueryData.size.width-70)/2, + margin: const EdgeInsets.only( + top: 5, + left: 5, + bottom: 5 + ), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 24, + onTap: _updateRadioValue, + child: Center( + child: AnimatedDefaultTextStyle( + duration: const Duration(milliseconds: 250), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: selectedOption == 24 + ? Theme.of(context).primaryColor + : Theme.of(context).textTheme.bodyText1!.color + ), + child: Text(AppLocalizations.of(context)!.hours24), + ), + ), + ), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + width: (mediaQueryData.size.width-70)/2, + margin: const EdgeInsets.only( + top: 5, + right: 5, + bottom: 10 + ), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 72, + onTap: _updateRadioValue, + child: Center( + child: AnimatedDefaultTextStyle( + duration: const Duration(milliseconds: 250), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: selectedOption == 72 + ? Theme.of(context).primaryColor + : Theme.of(context).textTheme.bodyText1!.color + ), + child: Text(AppLocalizations.of(context)!.days3), + ), + ), + ), + ), + Container( + width: (mediaQueryData.size.width-70)/2, + margin: const EdgeInsets.only( + top: 5, + left: 5, + bottom: 10 + ), + child: OptionBox( + optionsValue: selectedOption, + itemValue: 168, + onTap: _updateRadioValue, + child: Center( + child: AnimatedDefaultTextStyle( + duration: const Duration(milliseconds: 250), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 14, + color: selectedOption == 168 + ? Theme.of(context).primaryColor + : Theme.of(context).textTheme.bodyText1!.color + ), + child: Text(AppLocalizations.of(context)!.days7), + ), + ), + ), + ), + ], + ), + ], + ), ), ), - ), ], ), ), Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(24), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ diff --git a/lib/screens/home/appbar.dart b/lib/screens/home/appbar.dart index 45157f2..b4ceb71 100644 --- a/lib/screens/home/appbar.dart +++ b/lib/screens/home/appbar.dart @@ -66,9 +66,9 @@ class HomeAppBar extends StatelessWidget with PreferredSizeWidget { ? Theme.of(context).primaryColor : Colors.green : appConfigProvider.useThemeColorForStatus == true - ? Colors.grey + ? Theme.of(context).colorScheme.onSurface.withOpacity(0.38) : Colors.red - : Colors.grey, + : Theme.of(context).colorScheme.onSurface.withOpacity(0.38) ), const SizedBox(width: 20), Column( @@ -84,9 +84,9 @@ class HomeAppBar extends StatelessWidget with PreferredSizeWidget { const SizedBox(height: 5), Text( "${server.connectionMethod}://${server.domain}${server.path ?? ""}${server.port != null ? ':${server.port}' : ""}", - style: const TextStyle( + style: TextStyle( fontSize: 14, - color: Color.fromRGBO(140, 140, 140, 1) + color: Theme.of(context).listTileTheme.textColor ), ) ], diff --git a/lib/screens/home/chart.dart b/lib/screens/home/chart.dart index 829de1f..315d421 100644 --- a/lib/screens/home/chart.dart +++ b/lib/screens/home/chart.dart @@ -50,9 +50,10 @@ class HomeChart extends StatelessWidget { children: [ Text( label, - style: const TextStyle( + style: TextStyle( fontSize: 18, - fontWeight: FontWeight.w500 + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.onSurface ), ), !isEmpty @@ -110,10 +111,11 @@ class HomeChart extends StatelessWidget { ], ), ), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), child: Divider( thickness: 1, + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.2), ), ), const SizedBox(height: 20), diff --git a/lib/screens/home/fab.dart b/lib/screens/home/fab.dart index bfa266f..d976168 100644 --- a/lib/screens/home/fab.dart +++ b/lib/screens/home/fab.dart @@ -24,9 +24,10 @@ class HomeFab extends StatelessWidget { return serversProvider.serverStatus.loadStatus == 1 ? FloatingActionButton( onPressed: openManagementBottomSheet, + backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, child: Icon( Icons.shield_rounded, - color: Theme.of(context).primaryColor.computeLuminance() > 0.5 ? Colors.black : Colors.white, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, ), ) : const SizedBox(); diff --git a/lib/screens/home/home.dart b/lib/screens/home/home.dart index b23c083..21cff4f 100644 --- a/lib/screens/home/home.dart +++ b/lib/screens/home/home.dart @@ -83,10 +83,11 @@ class _HomeState extends State { controller: scrollController, children: [ ServerStatus(serverStatus: serversProvider.serverStatus.data!), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), child: Divider( thickness: 1, + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.2), ), ), const SizedBox(height: 20), @@ -128,10 +129,11 @@ class _HomeState extends State { data: serversProvider.serverStatus.data!.stats.topQueriedDomains, type: 'topQueriedDomains', ), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), child: Divider( thickness: 1, + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.2), ), ), const SizedBox(height: 20), @@ -141,10 +143,11 @@ class _HomeState extends State { data: serversProvider.serverStatus.data!.stats.topBlockedDomains, type: 'topBlockedDomains', ), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), child: Divider( thickness: 1, + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.2), ), ), const SizedBox(height: 20), diff --git a/lib/screens/home/management_modal.dart b/lib/screens/home/management_modal.dart index 76fe208..6b77a22 100644 --- a/lib/screens/home/management_modal.dart +++ b/lib/screens/home/management_modal.dart @@ -36,7 +36,7 @@ class ManagementModal extends StatelessWidget { Widget mainSwitch() { return Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), + padding: const EdgeInsets.symmetric(horizontal: 24), child: Material( color: Theme.of(context).primaryColor.withOpacity(0.1), borderRadius: BorderRadius.circular(28), @@ -84,7 +84,7 @@ class ManagementModal extends StatelessWidget { child: Padding( padding: const EdgeInsets.symmetric( horizontal: 35, - vertical: 5 + vertical: 8 ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -94,12 +94,15 @@ class ManagementModal extends StatelessWidget { Icon( icon, size: 24, + color: Theme.of(context).listTileTheme.iconColor, ), - const SizedBox(width: 20), + const SizedBox(width: 16), Text( label, - style: const TextStyle( - fontSize: 15, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface, ), ), ], @@ -136,53 +139,55 @@ class ManagementModal extends StatelessWidget { ? const NeverScrollableScrollPhysics() : null, children: [ - const Padding( - padding: EdgeInsets.only(top: 24), - child: Icon( - Icons.shield_rounded, - size: 26, - ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 24), - child: Text( - AppLocalizations.of(context)!.manageServer, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 22 + Padding( + padding: const EdgeInsets.only(top: 24), + child: Icon( + Icons.shield_rounded, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), - ), - mainSwitch(), - const SizedBox(height: 10), - smallSwitch( - AppLocalizations.of(context)!.ruleFiltering, - Icons.filter_list_rounded, - serversProvider.serverStatus.data!.filteringEnabled, - (value) => updateBlocking(value, 'filtering'), - serversProvider.protectionsManagementProcess.contains('filtering') - ), - smallSwitch( - AppLocalizations.of(context)!.safeBrowsing, - Icons.vpn_lock_rounded, - serversProvider.serverStatus.data!.safeBrowsingEnabled, - (value) => updateBlocking(value, 'safeBrowsing'), - serversProvider.protectionsManagementProcess.contains('safeBrowsing') - ), - smallSwitch( - AppLocalizations.of(context)!.parentalFiltering, - Icons.block, - serversProvider.serverStatus.data!.parentalControlEnabled, - (value) => updateBlocking(value, 'parentalControl'), - serversProvider.protectionsManagementProcess.contains('parentalControl') - ), - smallSwitch( - AppLocalizations.of(context)!.safeSearch, - Icons.search_rounded, - serversProvider.serverStatus.data!.safeSearchEnabled, - (value) => updateBlocking(value, 'safeSearch'), - serversProvider.protectionsManagementProcess.contains('safeSearch') - ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: Text( + AppLocalizations.of(context)!.manageServer, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface, + ), + ), + ), + mainSwitch(), + const SizedBox(height: 10), + smallSwitch( + AppLocalizations.of(context)!.ruleFiltering, + Icons.filter_list_rounded, + serversProvider.serverStatus.data!.filteringEnabled, + (value) => updateBlocking(value, 'filtering'), + serversProvider.protectionsManagementProcess.contains('filtering') + ), + smallSwitch( + AppLocalizations.of(context)!.safeBrowsing, + Icons.vpn_lock_rounded, + serversProvider.serverStatus.data!.safeBrowsingEnabled, + (value) => updateBlocking(value, 'safeBrowsing'), + serversProvider.protectionsManagementProcess.contains('safeBrowsing') + ), + smallSwitch( + AppLocalizations.of(context)!.parentalFiltering, + Icons.block, + serversProvider.serverStatus.data!.parentalControlEnabled, + (value) => updateBlocking(value, 'parentalControl'), + serversProvider.protectionsManagementProcess.contains('parentalControl') + ), + smallSwitch( + AppLocalizations.of(context)!.safeSearch, + Icons.search_rounded, + serversProvider.serverStatus.data!.safeSearchEnabled, + (value) => updateBlocking(value, 'safeSearch'), + serversProvider.protectionsManagementProcess.contains('safeSearch') + ), ], ), ), diff --git a/lib/screens/home/server_status.dart b/lib/screens/home/server_status.dart index 0540c47..c4d8d97 100644 --- a/lib/screens/home/server_status.dart +++ b/lib/screens/home/server_status.dart @@ -21,9 +21,10 @@ class ServerStatus extends StatelessWidget { children: [ Text( AppLocalizations.of(context)!.serverStatus, - style: const TextStyle( + style: TextStyle( fontSize: 18, - fontWeight: FontWeight.w500 + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.onSurface ), ), const SizedBox(height: 20), diff --git a/lib/screens/home/top_items.dart b/lib/screens/home/top_items.dart index 5eee31f..e738147 100644 --- a/lib/screens/home/top_items.dart +++ b/lib/screens/home/top_items.dart @@ -48,8 +48,9 @@ class TopItems extends StatelessWidget { Text( item.keys.toList()[0], overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: 16 + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface ), ), if (name != null) ...[ @@ -59,14 +60,19 @@ class TopItems extends StatelessWidget { overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 14, - color: Theme.of(context).listTileTheme.iconColor + color: Theme.of(context).colorScheme.onSurfaceVariant ), ), ] ], ), ), - Text(item.values.toList()[0].toString()) + Text( + item.values.toList()[0].toString(), + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ) ], ), ); @@ -93,9 +99,10 @@ class TopItems extends StatelessWidget { children: [ Text( label, - style: const TextStyle( + style: TextStyle( fontSize: 18, - fontWeight: FontWeight.w500 + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.onSurface ), ), const SizedBox(height: 20), diff --git a/lib/screens/logs/filter_status_modal.dart b/lib/screens/logs/filter_status_modal.dart index 178dbdf..371f3ab 100644 --- a/lib/screens/logs/filter_status_modal.dart +++ b/lib/screens/logs/filter_status_modal.dart @@ -48,7 +48,7 @@ class _FilterStatusModalState extends State { child: InkWell( onTap: () => onChanged(id), child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 5), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -57,12 +57,14 @@ class _FilterStatusModalState extends State { Icon( icon, size: 24, + color: Theme.of(context).listTileTheme.iconColor ), - const SizedBox(width: 20), + const SizedBox(width: 16), Text( label, - style: const TextStyle( + style: TextStyle( fontSize: 16, + color: Theme.of(context).colorScheme.onSurface ), ) ], @@ -80,8 +82,8 @@ class _FilterStatusModalState extends State { } return Container( - height: height >= 680 == true - ? 680 + height: height >= 720 == true + ? 720 : height-25, decoration: BoxDecoration( borderRadius: const BorderRadius.only( @@ -92,26 +94,29 @@ class _FilterStatusModalState extends State { ), child: Column( children: [ - const Padding( - padding: EdgeInsets.only( + Padding( + padding: const EdgeInsets.only( top: 24, - bottom: 20, + bottom: 16, ), child: Icon( Icons.shield_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), Text( AppLocalizations.of(context)!.responseStatus, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Expanded( child: ListView( - physics: height >= 680 == true + physics: height >= 720 == true ? const NeverScrollableScrollPhysics() : null, children: [ @@ -168,7 +173,7 @@ class _FilterStatusModalState extends State { ), ), Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(24), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ diff --git a/lib/screens/logs/log_details_modal.dart b/lib/screens/logs/log_details_modal.dart deleted file mode 100644 index 6a02943..0000000 --- a/lib/screens/logs/log_details_modal.dart +++ /dev/null @@ -1,276 +0,0 @@ -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/logs/log_list_tile.dart'; - -import 'package:adguard_home_manager/functions/get_filtered_status.dart'; -import 'package:adguard_home_manager/functions/format_time.dart'; -import 'package:adguard_home_manager/models/filtering_status.dart'; -import 'package:adguard_home_manager/providers/servers_provider.dart'; -import 'package:adguard_home_manager/providers/app_config_provider.dart'; -import 'package:adguard_home_manager/models/logs.dart'; - -class LogDetailsModal extends StatelessWidget { - final ScrollController scrollController; - final Log log; - final void Function(Log, String) blockUnblock; - - const LogDetailsModal({ - Key? key, - required this.scrollController, - required this.log, - required this.blockUnblock - }) : super(key: key); - - @override - Widget build(BuildContext context) { - final serversProvider = Provider.of(context); - final appConfigProvider = Provider.of(context); - - Filter getList(int id) { - return serversProvider.filteringStatus!.filters.firstWhere((filter) => filter.id == id, orElse: () { - return serversProvider.filteringStatus!.whitelistFilters.firstWhere((filter) => filter.id == id); - }); - } - - Widget getResult() { - final filter = getFilteredStatus(context, appConfigProvider, log.reason, true); - return Text( - filter['label'], - style: TextStyle( - color: filter['color'], - fontWeight: FontWeight.w500 - ), - ); - } - - return Container( - decoration: BoxDecoration( - color: Theme.of(context).dialogBackgroundColor, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(28), - topRight: Radius.circular(28), - ) - ), - child: Column( - children: [ - Expanded( - child: ListView( - controller: scrollController, - children: [ - const Padding( - padding: EdgeInsets.only( - top: 28, - bottom: 20, - ), - child: Icon( - Icons.list_rounded, - size: 26, - ), - ), - Text( - AppLocalizations.of(context)!.logDetails, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 - ), - ), - Padding( - padding: const EdgeInsets.all(20), - child: Text( - AppLocalizations.of(context)!.status, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - ), - LogListTile( - icon: Icons.shield_rounded, - title: AppLocalizations.of(context)!.result, - subtitleWidget: getResult(), - trailing: log.cached == true - ? Container( - padding: const EdgeInsets.all(5), - decoration: BoxDecoration( - color: Theme.of(context).listTileTheme.iconColor, - borderRadius: BorderRadius.circular(10) - ), - child: const Text( - "CACHE", - style: TextStyle( - fontSize: 12, - color: Colors.white, - fontWeight: FontWeight.w500 - ), - ), - ) - : null, - ), - if (log.rule != null) LogListTile( - icon: Icons.block, - title: AppLocalizations.of(context)!.blockingRule, - subtitle: log.rule - ), - LogListTile( - icon: Icons.schedule, - title: AppLocalizations.of(context)!.time, - subtitle: formatTimestampUTCFromAPI(log.time, 'HH:mm:ss') - ), - Padding( - padding: const EdgeInsets.all(20), - child: Text( - AppLocalizations.of(context)!.request, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - ), - LogListTile( - icon: Icons.domain_rounded, - title: AppLocalizations.of(context)!.domain, - subtitle: log.question.name - ), - LogListTile( - icon: Icons.category_rounded, - title: AppLocalizations.of(context)!.type, - subtitle: log.question.type - ), - LogListTile( - icon: Icons.class_rounded, - title: AppLocalizations.of(context)!.clas, - subtitle: log.question.questionClass - ), - Padding( - padding: const EdgeInsets.all(20), - child: Text( - AppLocalizations.of(context)!.response, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - ), - if (log.upstream != '') LogListTile( - icon: Icons.dns_rounded, - title: AppLocalizations.of(context)!.dnsServer, - subtitle: log.upstream - ), - LogListTile( - icon: Icons.timer_rounded, - title: AppLocalizations.of(context)!.elapsedTime, - subtitle: "${double.parse(log.elapsedMs).toStringAsFixed(2)} ms" - ), - LogListTile( - icon: Icons.system_update_alt_rounded, - title: AppLocalizations.of(context)!.responseCode, - subtitle: log.status - ), - Padding( - padding: const EdgeInsets.all(20), - child: Text( - AppLocalizations.of(context)!.client, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - ), - LogListTile( - icon: Icons.smartphone_rounded, - title: AppLocalizations.of(context)!.deviceIp, - subtitle: log.client - ), - if (log.clientInfo != null && log.clientInfo!.name != '') LogListTile( - icon: Icons.abc_rounded, - title: AppLocalizations.of(context)!.deviceName, - subtitle: log.clientInfo!.name - ), - if (log.rules.isNotEmpty) ...[ - Padding( - padding: const EdgeInsets.all(20), - child: Text( - AppLocalizations.of(context)!.rules, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - ), - ...log.rules.map((rule) => LogListTile( - icon: Icons.rule_rounded, - title: rule.text, - subtitle: getList(rule.filterListId).name, - )).toList() - ], - if (log.answer.isNotEmpty) ...[ - Padding( - padding: const EdgeInsets.all(20), - child: Text( - AppLocalizations.of(context)!.answer, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w500, - color: Theme.of(context).primaryColor - ), - ), - ), - ...log.answer.map((a) => LogListTile( - icon: Icons.download_rounded, - title: a.value, - subtitle: "TTL: ${a.ttl.toString()}", - trailing: Container( - padding: const EdgeInsets.all(5), - decoration: BoxDecoration( - color: Theme.of(context).listTileTheme.iconColor, - borderRadius: BorderRadius.circular(10) - ), - child: Text( - a.type, - style: const TextStyle( - fontSize: 12, - color: Colors.white, - fontWeight: FontWeight.w500 - ), - ), - ) - )).toList() - ] - ], - ), - ), - Padding( - padding: const EdgeInsets.all(20), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - TextButton( - onPressed: () { - blockUnblock(log, getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true ? 'unblock' : 'block'); - Navigator.pop(context); - }, - child: Text( - getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true - ? AppLocalizations.of(context)!.unblockDomain - : AppLocalizations.of(context)!.blockDomain - ) - ), - TextButton( - onPressed: () => Navigator.pop(context), - child: Text(AppLocalizations.of(context)!.close) - ), - ], - ), - ) - ], - ), - ); - } -} \ No newline at end of file diff --git a/lib/screens/logs/log_details_screen.dart b/lib/screens/logs/log_details_screen.dart new file mode 100644 index 0000000..f197795 --- /dev/null +++ b/lib/screens/logs/log_details_screen.dart @@ -0,0 +1,299 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +import 'package:adguard_home_manager/screens/logs/log_list_tile.dart'; + +import 'package:adguard_home_manager/classes/process_modal.dart'; +import 'package:adguard_home_manager/functions/get_filtered_status.dart'; +import 'package:adguard_home_manager/models/logs.dart'; +import 'package:adguard_home_manager/services/http_requests.dart'; +import 'package:adguard_home_manager/functions/format_time.dart'; +import 'package:adguard_home_manager/models/filtering_status.dart'; +import 'package:adguard_home_manager/providers/servers_provider.dart'; +import 'package:adguard_home_manager/providers/app_config_provider.dart'; + +class LogDetailsScreen extends StatelessWidget { + final Log log; + + const LogDetailsScreen({ + Key? key, + required this.log + }) : super(key: key); + + @override + Widget build(BuildContext context) { + final serversProvider = Provider.of(context); + final appConfigProvider = Provider.of(context); + + Filter getList(int id) { + return serversProvider.filteringStatus!.filters.firstWhere((filter) => filter.id == id, orElse: () { + return serversProvider.filteringStatus!.whitelistFilters.firstWhere((filter) => filter.id == id); + }); + } + + Widget getResult() { + final filter = getFilteredStatus(context, appConfigProvider, log.reason, true); + return Text( + filter['label'], + style: TextStyle( + color: filter['color'], + fontWeight: FontWeight.w500 + ), + ); + } + + void blockUnblock(Log log, String newStatus) async { + final ProcessModal processModal = ProcessModal(context: context); + processModal.open(AppLocalizations.of(context)!.savingUserFilters); + + final rules = await getFilteringRules(server: serversProvider.selectedServer!); + + if (rules['result'] == 'success') { + FilteringStatus oldStatus = serversProvider.filteringStatus!; + + List newRules = rules['data'].userRules.where((domain) => !domain.contains(log.question.name)).toList(); + if (newStatus == 'block') { + newRules.add("||${log.question.name}^"); + } + else if (newStatus == 'unblock') { + newRules.add("@@||${log.question.name}^"); + } + FilteringStatus newObj = serversProvider.filteringStatus!; + newObj.userRules = newRules; + serversProvider.setFilteringStatus(newObj); + + final result = await postFilteringRules(server: serversProvider.selectedServer!, data: {'rules': newRules}); + + processModal.close(); + + if (result['result'] == 'success') { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(AppLocalizations.of(context)!.userFilteringRulesUpdated), + backgroundColor: Colors.green, + ) + ); + } + else { + appConfigProvider.addLog(result['log']); + serversProvider.setFilteringStatus(oldStatus); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(AppLocalizations.of(context)!.userFilteringRulesNotUpdated), + backgroundColor: Colors.red, + ) + ); + } + } + else { + appConfigProvider.addLog(rules['log']); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(AppLocalizations.of(context)!.userFilteringRulesNotUpdated), + backgroundColor: Colors.red, + ) + ); + } + } + + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.logDetails), + actions: [ + IconButton( + onPressed: () => blockUnblock(log, getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true ? 'unblock' : 'block'), + icon: Icon( + getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true + ? Icons.check_circle_rounded + : Icons.block + ), + tooltip: getFilteredStatus(context, appConfigProvider, log.reason, true)['filtered'] == true + ? AppLocalizations.of(context)!.unblockDomain + : AppLocalizations.of(context)!.blockDomain, + ), + const SizedBox(width: 10) + ], + ), + body: ListView( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), + child: Text( + AppLocalizations.of(context)!.status, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + ), + LogListTile( + icon: Icons.shield_rounded, + title: AppLocalizations.of(context)!.result, + subtitleWidget: getResult(), + trailing: log.cached == true + ? Container( + padding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 5 + ), + decoration: BoxDecoration( + color: Theme.of(context).floatingActionButtonTheme.backgroundColor, + borderRadius: BorderRadius.circular(30) + ), + child: Text( + "CACHE", + style: TextStyle( + fontSize: 12, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, + fontWeight: FontWeight.w500 + ), + ), + ) + : null, + ), + if (log.rule != null) LogListTile( + icon: Icons.block, + title: AppLocalizations.of(context)!.blockingRule, + subtitle: log.rule + ), + LogListTile( + icon: Icons.schedule, + title: AppLocalizations.of(context)!.time, + subtitle: formatTimestampUTCFromAPI(log.time, 'HH:mm:ss') + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), + child: Text( + AppLocalizations.of(context)!.request, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + ), + LogListTile( + icon: Icons.domain_rounded, + title: AppLocalizations.of(context)!.domain, + subtitle: log.question.name + ), + LogListTile( + icon: Icons.category_rounded, + title: AppLocalizations.of(context)!.type, + subtitle: log.question.type + ), + LogListTile( + icon: Icons.class_rounded, + title: AppLocalizations.of(context)!.clas, + subtitle: log.question.questionClass + ), + Padding( + padding: const EdgeInsets.all(20), + child: Text( + AppLocalizations.of(context)!.response, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + ), + if (log.upstream != '') LogListTile( + icon: Icons.dns_rounded, + title: AppLocalizations.of(context)!.dnsServer, + subtitle: log.upstream + ), + LogListTile( + icon: Icons.timer_rounded, + title: AppLocalizations.of(context)!.elapsedTime, + subtitle: "${double.parse(log.elapsedMs).toStringAsFixed(2)} ms" + ), + LogListTile( + icon: Icons.system_update_alt_rounded, + title: AppLocalizations.of(context)!.responseCode, + subtitle: log.status + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), + child: Text( + AppLocalizations.of(context)!.client, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + ), + LogListTile( + icon: Icons.smartphone_rounded, + title: AppLocalizations.of(context)!.deviceIp, + subtitle: log.client + ), + if (log.clientInfo != null && log.clientInfo!.name != '') LogListTile( + icon: Icons.abc_rounded, + title: AppLocalizations.of(context)!.deviceName, + subtitle: log.clientInfo!.name + ), + if (log.rules.isNotEmpty) ...[ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10), + child: Text( + AppLocalizations.of(context)!.rules, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + ), + ...log.rules.map((rule) => LogListTile( + icon: Icons.rule_rounded, + title: rule.text, + subtitle: getList(rule.filterListId).name, + )).toList() + ], + if (log.answer.isNotEmpty) ...[ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), + child: Text( + AppLocalizations.of(context)!.answer, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context).primaryColor + ), + ), + ), + ...log.answer.map((a) => LogListTile( + icon: Icons.download_rounded, + title: a.value, + subtitle: "TTL: ${a.ttl.toString()}", + trailing: Container( + padding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 5 + ), + decoration: BoxDecoration( + color: Theme.of(context).floatingActionButtonTheme.backgroundColor, + borderRadius: BorderRadius.circular(30) + ), + child: Text( + a.type, + style: TextStyle( + fontSize: 12, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, + fontWeight: FontWeight.w500 + ), + ), + ) + )).toList() + ] + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/logs/log_list_tile.dart b/lib/screens/logs/log_list_tile.dart index d5e011f..df57550 100644 --- a/lib/screens/logs/log_list_tile.dart +++ b/lib/screens/logs/log_list_tile.dart @@ -19,7 +19,7 @@ class LogListTile extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -29,8 +29,9 @@ class LogListTile extends StatelessWidget { Icon( icon, size: 24, + color: Theme.of(context).listTileTheme.iconColor, ), - const SizedBox(width: 20), + const SizedBox(width: 16), Flexible( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -38,15 +39,16 @@ class LogListTile extends StatelessWidget { Text( title, style: const TextStyle( - fontSize: 18, + fontSize: 16, + fontWeight: FontWeight.w400 ), ), - const SizedBox(height: 5), + const SizedBox(height: 3), subtitleWidget ?? Text( subtitle!, style: TextStyle( fontSize: 14, - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, ), ) ], @@ -56,7 +58,7 @@ class LogListTile extends StatelessWidget { ), ), if (trailing != null) ...[ - const SizedBox(width: 10), + const SizedBox(width: 16), trailing! ] ], diff --git a/lib/screens/logs/log_tile.dart b/lib/screens/logs/log_tile.dart index 50d44c4..8f3ea9d 100644 --- a/lib/screens/logs/log_tile.dart +++ b/lib/screens/logs/log_tile.dart @@ -2,17 +2,11 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:bottom_sheet/bottom_sheet.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:adguard_home_manager/screens/logs/log_details_modal.dart'; +import 'package:adguard_home_manager/screens/logs/log_details_screen.dart'; import 'package:adguard_home_manager/providers/app_config_provider.dart'; import 'package:adguard_home_manager/functions/get_filtered_status.dart'; -import 'package:adguard_home_manager/models/filtering_status.dart'; -import 'package:adguard_home_manager/classes/process_modal.dart'; -import 'package:adguard_home_manager/providers/servers_provider.dart'; -import 'package:adguard_home_manager/services/http_requests.dart'; import 'package:adguard_home_manager/models/logs.dart'; import 'package:adguard_home_manager/functions/format_time.dart'; @@ -30,7 +24,6 @@ class LogTile extends StatelessWidget { @override Widget build(BuildContext context) { - final serversProvider = Provider.of(context); final appConfigProvider = Provider.of(context); final width = MediaQuery.of(context).size.width; @@ -70,87 +63,16 @@ class LogTile extends StatelessWidget { text: filter['label'], ); } - - void blockUnblock(Log log, String newStatus) async { - final ProcessModal processModal = ProcessModal(context: context); - processModal.open(AppLocalizations.of(context)!.savingUserFilters); - - final rules = await getFilteringRules(server: serversProvider.selectedServer!); - - if (rules['result'] == 'success') { - FilteringStatus oldStatus = serversProvider.filteringStatus!; - - List newRules = rules['data'].userRules.where((domain) => !domain.contains(log.question.name)).toList(); - if (newStatus == 'block') { - newRules.add("||${log.question.name}^"); - } - else if (newStatus == 'unblock') { - newRules.add("@@||${log.question.name}^"); - } - FilteringStatus newObj = serversProvider.filteringStatus!; - newObj.userRules = newRules; - serversProvider.setFilteringStatus(newObj); - - final result = await postFilteringRules(server: serversProvider.selectedServer!, data: {'rules': newRules}); - - processModal.close(); - - if (result['result'] == 'success') { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(AppLocalizations.of(context)!.userFilteringRulesUpdated), - backgroundColor: Colors.green, - ) - ); - } - else { - appConfigProvider.addLog(result['log']); - serversProvider.setFilteringStatus(oldStatus); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(AppLocalizations.of(context)!.userFilteringRulesNotUpdated), - backgroundColor: Colors.red, - ) - ); - } - } - else { - appConfigProvider.addLog(rules['log']); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(AppLocalizations.of(context)!.userFilteringRulesNotUpdated), - backgroundColor: Colors.red, - ) - ); - } - } - - void openLogDetailsModal() { - ScaffoldMessenger.of(context).clearSnackBars(); - showFlexibleBottomSheet( - minHeight: 0.6, - initHeight: 0.6, - maxHeight: 0.95, - isCollapsible: true, - duration: const Duration(milliseconds: 250), - anchors: [0.95], - context: context, - builder: (ctx, controller, offset) => LogDetailsModal( - scrollController: controller, - log: log, - blockUnblock: blockUnblock, - ), - bottomSheetColor: Colors.transparent, - ); - } - + return Material( color: Colors.transparent, child: InkWell( - onTap: openLogDetailsModal, + onTap: () => Navigator.push(context, MaterialPageRoute( + builder: (context) => LogDetailsScreen(log: log) + )), child: Container( width: double.maxFinite, - padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -161,19 +83,21 @@ class LogTile extends StatelessWidget { children: [ Text( log.question.name, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: 18 + style: TextStyle( + fontSize: 16, + height: 1.5, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 10), + const SizedBox(height: 5), if (log.client.length <= 15 && appConfigProvider.showNameTimeLogs == false) Row( children: [ ...[ Icon( Icons.smartphone_rounded, size: 16, - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, ), const SizedBox(width: 5), SizedBox( @@ -181,8 +105,10 @@ class LogTile extends StatelessWidget { log.client, overflow: TextOverflow.ellipsis, style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor, - fontSize: 13 + color: Theme.of(context).listTileTheme.textColor, + fontSize: 14, + height: 1.4, + fontWeight: FontWeight.w400, ), ), ) @@ -192,7 +118,7 @@ class LogTile extends StatelessWidget { Icon( Icons.schedule_rounded, size: 16, - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, ), const SizedBox(width: 5), SizedBox( @@ -200,7 +126,7 @@ class LogTile extends StatelessWidget { formatTimestampUTCFromAPI(log.time, 'HH:mm:ss'), overflow: TextOverflow.ellipsis, style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, fontSize: 13 ), ), @@ -215,7 +141,7 @@ class LogTile extends StatelessWidget { Icon( Icons.smartphone_rounded, size: 16, - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, ), const SizedBox(width: 15), SizedBox( @@ -223,7 +149,7 @@ class LogTile extends StatelessWidget { log.client, overflow: TextOverflow.ellipsis, style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, fontSize: 13 ), ), @@ -237,7 +163,7 @@ class LogTile extends StatelessWidget { Icon( Icons.badge_rounded, size: 16, - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), const SizedBox(width: 15), SizedBox( @@ -245,7 +171,7 @@ class LogTile extends StatelessWidget { log.clientInfo!.name, overflow: TextOverflow.ellipsis, style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, fontSize: 13 ), ), @@ -259,7 +185,7 @@ class LogTile extends StatelessWidget { Icon( Icons.schedule_rounded, size: 16, - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, ), const SizedBox(width: 15), SizedBox( @@ -267,7 +193,7 @@ class LogTile extends StatelessWidget { formatTimestampUTCFromAPI(log.time, 'HH:mm:ss'), overflow: TextOverflow.ellipsis, style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, fontSize: 13 ), ), @@ -281,7 +207,7 @@ class LogTile extends StatelessWidget { Icon( Icons.timer, size: 16, - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, ), const SizedBox(width: 15), SizedBox( @@ -289,7 +215,7 @@ class LogTile extends StatelessWidget { "${double.parse(log.elapsedMs).toStringAsFixed(2)} ms", overflow: TextOverflow.ellipsis, style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, fontSize: 13 ), ), diff --git a/lib/screens/logs/logs.dart b/lib/screens/logs/logs.dart index 6b84058..84bf377 100644 --- a/lib/screens/logs/logs.dart +++ b/lib/screens/logs/logs.dart @@ -224,11 +224,11 @@ class _LogsWidgetState extends State { final Map translatedString = { "all": AppLocalizations.of(context)!.all, "filtered": AppLocalizations.of(context)!.filtered, - "processed": AppLocalizations.of(context)!.processed, - "whitelisted": AppLocalizations.of(context)!.processedWhitelist, + "processed": AppLocalizations.of(context)!.processedRow, + "whitelisted": AppLocalizations.of(context)!.processedWhitelistRow, "blocked": AppLocalizations.of(context)!.blocked, - "blocked_safebrowsing": AppLocalizations.of(context)!.blockedSafeBrowsing, - "blocked_parental": AppLocalizations.of(context)!.blockedParental, + "blocked_safebrowsing": AppLocalizations.of(context)!.blockedSafeBrowsingRow, + "blocked_parental": AppLocalizations.of(context)!.blockedParentalRow, "safe_search": AppLocalizations.of(context)!.safeSearch, }; @@ -392,17 +392,26 @@ class _LogsWidgetState extends State { if (logsProvider.appliedFilters.searchText != null) ...[ const SizedBox(width: 15), Chip( + avatar: Icon( + Icons.search, + size: 24, + color: Theme.of(context).primaryColor, + ), label: Row( children: [ - const Icon(Icons.search), - const SizedBox(width: 10), - Text(logsProvider.appliedFilters.searchText!), - const SizedBox(width: 10), + Text( + logsProvider.appliedFilters.searchText!, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500 + ), + ), ], ), - deleteIcon: const Icon( + deleteIcon: Icon( Icons.cancel_rounded, - size: 20, + size: 18, + color: Theme.of(context).colorScheme.onSurfaceVariant ), onDeleted: () { logsProvider.setAppliedFilters( @@ -417,22 +426,38 @@ class _LogsWidgetState extends State { searchText: '' ); }, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: BorderSide( + color: Theme.of(context).colorScheme.onSurfaceVariant + ) + ), + backgroundColor: Theme.of(context).dialogBackgroundColor, ), ], if (logsProvider.appliedFilters.selectedResultStatus != 'all') ...[ const SizedBox(width: 15), Chip( + avatar: Icon( + Icons.shield_rounded, + size: 24, + color: Theme.of(context).primaryColor, + ), label: Row( children: [ - const Icon(Icons.shield_rounded), - const SizedBox(width: 10), - Text(translatedString[logsProvider.appliedFilters.selectedResultStatus]!), - const SizedBox(width: 10), + Text( + translatedString[logsProvider.appliedFilters.selectedResultStatus]!, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.w500 + ), + ), ], ), - deleteIcon: const Icon( + deleteIcon: Icon( Icons.cancel_rounded, - size: 20, + size: 18, + color: Theme.of(context).colorScheme.onSurfaceVariant ), onDeleted: () { logsProvider.setAppliedFilters( @@ -447,6 +472,13 @@ class _LogsWidgetState extends State { responseStatus: 'all' ); }, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: BorderSide( + color: Theme.of(context).colorScheme.onSurfaceVariant + ) + ), + backgroundColor: Theme.of(context).dialogBackgroundColor, ), ], const SizedBox(width: 15), diff --git a/lib/screens/logs/logs_config_modal.dart b/lib/screens/logs/logs_config_modal.dart index 15ea2dd..ebd594e 100644 --- a/lib/screens/logs/logs_config_modal.dart +++ b/lib/screens/logs/logs_config_modal.dart @@ -122,28 +122,30 @@ class _LogsConfigModalWidgetState extends State { children: [ Expanded( child: ListView( - physics: 450 < MediaQuery.of(context).size.height + physics: 420 < MediaQuery.of(context).size.height ? const NeverScrollableScrollPhysics() : null, children: [ - const Padding( - padding: EdgeInsets.only(top: 28), + Padding( + padding: const EdgeInsets.only(top: 24), child: Icon( Icons.settings, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.logsSettings, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 30), + const SizedBox(height: 16), Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), + padding: const EdgeInsets.symmetric(horizontal: 24), child: Material( color: Theme.of(context).primaryColor.withOpacity(0.1), borderRadius: BorderRadius.circular(28), @@ -175,7 +177,7 @@ class _LogsConfigModalWidgetState extends State { ), ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Material( color: Colors.transparent, child: InkWell( @@ -201,9 +203,9 @@ class _LogsConfigModalWidgetState extends State { ), ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Padding( - padding: const EdgeInsets.symmetric(horizontal: 28), + padding: const EdgeInsets.symmetric(horizontal: 24), child: DropdownButtonFormField( items: retentionItems.map>((Map item) { return DropdownMenuItem( @@ -228,7 +230,7 @@ class _LogsConfigModalWidgetState extends State { ), ), Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(24), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -308,7 +310,7 @@ class _LogsConfigModalWidgetState extends State { } return Container( - height: 450, + height: 420, decoration: BoxDecoration( borderRadius: const BorderRadius.only( topLeft: Radius.circular(28), diff --git a/lib/screens/logs/logs_filters_modal.dart b/lib/screens/logs/logs_filters_modal.dart index 9e5bb08..7cd72e6 100644 --- a/lib/screens/logs/logs_filters_modal.dart +++ b/lib/screens/logs/logs_filters_modal.dart @@ -171,7 +171,7 @@ class _LogsFiltersModalWidgetState extends State { return Padding( padding: MediaQuery.of(context).viewInsets, child: Container( - height: 400, + height: 360, decoration: BoxDecoration( color: Theme.of(context).dialogBackgroundColor, borderRadius: const BorderRadius.only( @@ -187,30 +187,33 @@ class _LogsFiltersModalWidgetState extends State { ? const NeverScrollableScrollPhysics() : null, children: [ - const Padding( - padding: EdgeInsets.only( + Padding( + padding: const EdgeInsets.only( top: 24, - bottom: 20, + bottom: 16, ), child: Icon( Icons.filter_list_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), Text( AppLocalizations.of(context)!.filters, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w400, + height: 1.3, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Padding( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: Row( children: [ - SizedBox( - width: MediaQuery.of(context).size.width - 108, + Expanded( child: TextFormField( controller: searchController, onChanged: (value) => logsProvider.setSearchText(value), @@ -222,22 +225,22 @@ class _LogsFiltersModalWidgetState extends State { ) ), labelText: AppLocalizations.of(context)!.search, + suffixIcon: IconButton( + onPressed: () { + setState(() { + searchController.text = ''; + }); + logsProvider.setSearchText(null); + }, + icon: const Icon(Icons.clear) + ) ), ), - ), - const SizedBox(width: 20), - IconButton( - onPressed: () { - setState(() { - searchController.text = ''; - }); - logsProvider.setSearchText(null); - }, - icon: const Icon(Icons.clear) ) ], ), ), + const SizedBox(height: 16), // Material( // color: Colors.transparent, // child: InkWell( @@ -284,12 +287,13 @@ class _LogsFiltersModalWidgetState extends State { subtitle: "${translatedString[logsProvider.selectedResultStatus]}", onTap: openSelectFilterStatus, icon: Icons.shield_rounded, + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), ), ], ), ), Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(24), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/screens/servers/servers.dart b/lib/screens/servers/servers.dart index 20f365a..89fd1ec 100644 --- a/lib/screens/servers/servers.dart +++ b/lib/screens/servers/servers.dart @@ -88,9 +88,10 @@ class _ServersState extends State { right: 20, child: FloatingActionButton( onPressed: openAddServerModal, + backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, child: Icon( Icons.add, - color: Theme.of(context).primaryColor.computeLuminance() > 0.5 ? Colors.black : Colors.white, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, ), ), ), diff --git a/lib/screens/settings/access_settings/access_settings.dart b/lib/screens/settings/access_settings/access_settings.dart index e2c8bad..f6db465 100644 --- a/lib/screens/settings/access_settings/access_settings.dart +++ b/lib/screens/settings/access_settings/access_settings.dart @@ -91,36 +91,19 @@ class _AccessSettingsWidgetState extends State with Ticker bottom: TabBar( controller: tabController, isScrollable: true, + unselectedLabelColor: Theme.of(context).colorScheme.onSurfaceVariant, tabs: [ Tab( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.check), - const SizedBox(width: 20), - Text(AppLocalizations.of(context)!.allowedClients) - ], - ), + icon: const Icon(Icons.check), + text: AppLocalizations.of(context)!.allowedClients, ), Tab( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.block), - const SizedBox(width: 20), - Text(AppLocalizations.of(context)!.disallowedClients) - ], - ), + icon: const Icon(Icons.block), + text: AppLocalizations.of(context)!.disallowedClients, ), Tab( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon(Icons.link_rounded), - const SizedBox(width: 20), - Text(AppLocalizations.of(context)!.disallowedDomains) - ], - ), + icon: const Icon(Icons.link_rounded), + text: AppLocalizations.of(context)!.disallowedDomains, ), ] ) @@ -134,9 +117,7 @@ class _AccessSettingsWidgetState extends State with Ticker color: Theme.of(context).scaffoldBackgroundColor, border: Border( top: BorderSide( - color: Theme.of(context).brightness == Brightness.light - ? const Color.fromRGBO(220, 220, 220, 1) - : const Color.fromRGBO(50, 50, 50, 1) + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.1) ) ) ), diff --git a/lib/screens/settings/access_settings/add_client_modal.dart b/lib/screens/settings/access_settings/add_client_modal.dart index 69cf96f..6e0105c 100644 --- a/lib/screens/settings/access_settings/add_client_modal.dart +++ b/lib/screens/settings/access_settings/add_client_modal.dart @@ -66,8 +66,8 @@ class _AddClientModalState extends State { return Padding( padding: MediaQuery.of(context).viewInsets, child: Container( - height: 322, - padding: const EdgeInsets.all(28), + height: 305, + padding: const EdgeInsets.all(24), decoration: BoxDecoration( color: Theme.of(context).dialogBackgroundColor, borderRadius: const BorderRadius.only( @@ -85,17 +85,19 @@ class _AddClientModalState extends State { children: [ Icon( icon(), - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( title(), textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 30), + const SizedBox(height: 16), TextFormField( controller: fieldController, onChanged: (_) => checkValidValues(), @@ -117,7 +119,7 @@ class _AddClientModalState extends State { ), ), Padding( - padding: const EdgeInsets.only(top: 20), + padding: const EdgeInsets.only(top: 24), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ diff --git a/lib/screens/settings/access_settings/clients_list.dart b/lib/screens/settings/access_settings/clients_list.dart index db71b2d..1f8fa85 100644 --- a/lib/screens/settings/access_settings/clients_list.dart +++ b/lib/screens/settings/access_settings/clients_list.dart @@ -244,11 +244,18 @@ class _ClientsListState extends State { padding: const EdgeInsets.all(20), child: Row( children: [ - const Icon(Icons.info_rounded), + Icon( + Icons.info_rounded, + color: Theme.of(context).listTileTheme.iconColor, + ), const SizedBox(width: 20), - SizedBox( - width: MediaQuery.of(context).size.width-112, - child: Text(description()), + Flexible( + child: Text( + description(), + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + ), + ), ) ], ), @@ -260,7 +267,13 @@ class _ClientsListState extends State { padding: const EdgeInsets.only(top: 0), itemCount: widget.data.length, itemBuilder: (context, index) => ListTile( - title: Text(widget.data[index]), + title: Text( + widget.data[index], + style: TextStyle( + fontWeight: FontWeight.normal, + color: Theme.of(context).colorScheme.onSurface + ), + ), trailing: IconButton( onPressed: () => { showDialog( @@ -308,6 +321,7 @@ class _ClientsListState extends State { : -70, right: 20, child: FloatingActionButton( + backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, onPressed: () { showModalBottomSheet( context: context, @@ -321,7 +335,7 @@ class _ClientsListState extends State { }, child: Icon( Icons.add, - color: Theme.of(context).primaryColor.computeLuminance() > 0.5 ? Colors.black : Colors.white, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, ), ), ) diff --git a/lib/screens/settings/dhcp/add_static_lease_modal.dart b/lib/screens/settings/dhcp/add_static_lease_modal.dart index 54fc3ec..3091b40 100644 --- a/lib/screens/settings/dhcp/add_static_lease_modal.dart +++ b/lib/screens/settings/dhcp/add_static_lease_modal.dart @@ -68,7 +68,7 @@ class _AddStaticLeaseModalState extends State { return Padding( padding: MediaQuery.of(context).viewInsets, child: Container( - height: 550, + height: 510, decoration: BoxDecoration( color: Theme.of(context).dialogBackgroundColor, borderRadius: const BorderRadius.only( @@ -84,22 +84,24 @@ class _AddStaticLeaseModalState extends State { ? const NeverScrollableScrollPhysics() : null, children: [ - const Padding( - padding: EdgeInsets.only(top: 28), + Padding( + padding: const EdgeInsets.only(top: 24), child: Icon( Icons.add, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.addStaticLease, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 30), + const SizedBox(height: 16), Padding( padding: const EdgeInsets.symmetric(horizontal: 28), child: TextFormField( diff --git a/lib/screens/settings/dhcp/delete_static_lease_modal.dart b/lib/screens/settings/dhcp/delete_static_lease_modal.dart index 630079b..77ad241 100644 --- a/lib/screens/settings/dhcp/delete_static_lease_modal.dart +++ b/lib/screens/settings/dhcp/delete_static_lease_modal.dart @@ -14,18 +14,27 @@ class DeleteStaticLeaseModal extends StatelessWidget { return AlertDialog( title: Column( children: [ - const Icon( + Icon( Icons.delete_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.deleteStaticLease, textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), ) ], ), - content: Text(AppLocalizations.of(context)!.deleteStaticLeaseDescription), + content: Text( + AppLocalizations.of(context)!.deleteStaticLeaseDescription, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), actions: [ TextButton( onPressed: () => Navigator.pop(context), diff --git a/lib/screens/settings/dhcp/dhcp.dart b/lib/screens/settings/dhcp/dhcp.dart index 04c368c..85e3796 100644 --- a/lib/screens/settings/dhcp/dhcp.dart +++ b/lib/screens/settings/dhcp/dhcp.dart @@ -375,8 +375,8 @@ class _DhcpWidgetState extends State { Padding( padding: const EdgeInsets.only( top: 10, - left: 12, - right: 12 + left: 24, + right: 24 ), child: Material( color: Theme.of(context).primaryColor.withOpacity(0.1), @@ -399,8 +399,9 @@ class _DhcpWidgetState extends State { children: [ Text( AppLocalizations.of(context)!.enableDhcpServer, - style: const TextStyle( - fontSize: 18, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface ), ), if (selectedInterface != null) ...[ @@ -408,7 +409,7 @@ class _DhcpWidgetState extends State { selectedInterface!.name, style: TextStyle( fontSize: 14, - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor ), ) ] @@ -432,7 +433,7 @@ class _DhcpWidgetState extends State { label: AppLocalizations.of(context)!.ipv4settings, ), Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: ipv4StartRangeController, onChanged: (value) => validateIpV4(value, 'ipv4StartRangeError', AppLocalizations.of(context)!.ipNotValid), @@ -451,7 +452,7 @@ class _DhcpWidgetState extends State { ), const SizedBox(height: 30), Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: ipv4EndRangeController, onChanged: (value) => validateIpV4(value, 'ipv4EndRangeError', AppLocalizations.of(context)!.ipNotValid), @@ -470,7 +471,7 @@ class _DhcpWidgetState extends State { ), const SizedBox(height: 30), Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: ipv4SubnetMaskController, onChanged: (value) => validateIpV4(value, 'ipv4SubnetMaskError', AppLocalizations.of(context)!.subnetMaskNotValid), @@ -489,7 +490,7 @@ class _DhcpWidgetState extends State { ), const SizedBox(height: 30), Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: ipv4GatewayController, onChanged: (value) => validateIpV4(value, 'ipv4GatewayError', AppLocalizations.of(context)!.gatewayNotValid), @@ -508,7 +509,7 @@ class _DhcpWidgetState extends State { ), const SizedBox(height: 30), Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: ipv4LeaseTimeController, onChanged: (value) { @@ -538,7 +539,7 @@ class _DhcpWidgetState extends State { label: AppLocalizations.of(context)!.ipv6settings, ), Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: ipv6StartRangeController, onChanged: (value) => validateIpV4(value, 'ipv6StartRangeError', AppLocalizations.of(context)!.ipNotValid), @@ -557,7 +558,7 @@ class _DhcpWidgetState extends State { ), const SizedBox(height: 30), Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: ipv6EndRangeController, onChanged: (value) => validateIpV4(value, 'ipv6EndRangeError', AppLocalizations.of(context)!.ipNotValid), @@ -576,7 +577,7 @@ class _DhcpWidgetState extends State { ), const SizedBox(height: 30), Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: ipv6LeaseTimeController, onChanged: (value) { @@ -617,18 +618,22 @@ class _DhcpWidgetState extends State { )); }, child: Container( - padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 20), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 20), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( AppLocalizations.of(context)!.dhcpLeases, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 16 + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface, ), ), - const Icon(Icons.arrow_forward_rounded) + Icon( + Icons.arrow_forward_rounded, + color: Theme.of(context).colorScheme.onSurface, + ) ], ), ), @@ -646,18 +651,22 @@ class _DhcpWidgetState extends State { )); }, child: Container( - padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 20), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 20), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( AppLocalizations.of(context)!.dhcpStatic, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 16 + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface, ), ), - const Icon(Icons.arrow_forward_rounded) + Icon( + Icons.arrow_forward_rounded, + color: Theme.of(context).colorScheme.onSurface, + ) ], ), ), @@ -678,9 +687,9 @@ class _DhcpWidgetState extends State { child: Text( AppLocalizations.of(context)!.neededSelectInterface, textAlign: TextAlign.center, - style: const TextStyle( + style: TextStyle( fontSize: 22, - color: Colors.grey + color: Theme.of(context).colorScheme.onSurface.withOpacity(0.5) ), ), ), diff --git a/lib/screens/settings/dhcp/dhcp_leases.dart b/lib/screens/settings/dhcp/dhcp_leases.dart index f1033d6..4f10b77 100644 --- a/lib/screens/settings/dhcp/dhcp_leases.dart +++ b/lib/screens/settings/dhcp/dhcp_leases.dart @@ -184,9 +184,10 @@ class DhcpLeases extends StatelessWidget { floatingActionButton: staticLeases == true ? FloatingActionButton( onPressed: openAddStaticLease, + backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, child: Icon( Icons.add, - color: Theme.of(context).primaryColor.computeLuminance() > 0.5 ? Colors.black : Colors.white, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, ), ) : null, diff --git a/lib/screens/settings/dhcp/select_interface_modal.dart b/lib/screens/settings/dhcp/select_interface_modal.dart index b223122..49b5957 100644 --- a/lib/screens/settings/dhcp/select_interface_modal.dart +++ b/lib/screens/settings/dhcp/select_interface_modal.dart @@ -31,22 +31,24 @@ class SelectInterfaceModal extends StatelessWidget { child: ListView( controller: scrollController, children: [ - const Padding( - padding: EdgeInsets.only(top: 28), + Padding( + padding: const EdgeInsets.only(top: 24), child: Icon( Icons.settings_ethernet_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.selectInterface, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), ListView.builder( primary: false, shrinkWrap: true, @@ -59,38 +61,54 @@ class SelectInterfaceModal extends StatelessWidget { onSelect(interfaces[index]); }, child: Container( - padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 10), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( interfaces[index].name, - style: const TextStyle( - fontSize: 18 + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface ), ), Row( children: [ Text( "${AppLocalizations.of(context)!.hardwareAddress}: ", - style: const TextStyle( - fontWeight: FontWeight.w500 + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), + Text( + interfaces[index].hardwareAddress, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant ), ), - Text(interfaces[index].hardwareAddress), ], ), const SizedBox(height: 5), if (interfaces[index].flags.isNotEmpty) ...[ Row( children: [ - const Text( + Text( "Flags: ", style: TextStyle( - fontWeight: FontWeight.w500 + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), + Text( + interfaces[index].flags.join(', '), + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant ), ), - Text(interfaces[index].flags.join(', ')), ], ), const SizedBox(height: 5), @@ -100,11 +118,18 @@ class SelectInterfaceModal extends StatelessWidget { children: [ Text( "${AppLocalizations.of(context)!.gatewayIp}: ", - style: const TextStyle( - fontWeight: FontWeight.w500 + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), + Text( + interfaces[index].gatewayIp, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant ), ), - Text(interfaces[index].gatewayIp), ], ), const SizedBox(height: 5), @@ -114,11 +139,18 @@ class SelectInterfaceModal extends StatelessWidget { children: [ Text( "${AppLocalizations.of(context)!.ipv4addresses}: ", - style: const TextStyle( - fontWeight: FontWeight.w500 + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), + Text( + interfaces[index].ipv4Addresses.join(', '), + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant ), ), - Text(interfaces[index].ipv4Addresses.join(', ')), ], ), const SizedBox(height: 5), @@ -128,11 +160,18 @@ class SelectInterfaceModal extends StatelessWidget { children: [ Text( "${AppLocalizations.of(context)!.ipv4addresses}: ", - style: const TextStyle( - fontWeight: FontWeight.w500 + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), + Text( + interfaces[index].ipv6Addresses.join(', '), + style: TextStyle( + fontSize: 14, + color: Theme.of(context).colorScheme.onSurfaceVariant ), ), - Text(interfaces[index].ipv6Addresses.join(', ')), ], ), ] diff --git a/lib/screens/settings/dns/bootstrap_dns.dart b/lib/screens/settings/dns/bootstrap_dns.dart index 5187177..394ea7f 100644 --- a/lib/screens/settings/dns/bootstrap_dns.dart +++ b/lib/screens/settings/dns/bootstrap_dns.dart @@ -140,11 +140,18 @@ class _BootstrapDnsScreenState extends State { padding: const EdgeInsets.all(20), child: Row( children: [ - const Icon(Icons.info_rounded), + Icon( + Icons.info_rounded, + color: Theme.of(context).listTileTheme.iconColor, + ), const SizedBox(width: 20), - SizedBox( - width: MediaQuery.of(context).size.width-132, - child: Text(AppLocalizations.of(context)!.bootstrapDnsServersInfo) + Flexible( + child: Text( + AppLocalizations.of(context)!.bootstrapDnsServersInfo, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ) ) ], ), diff --git a/lib/screens/settings/dns/comment_modal.dart b/lib/screens/settings/dns/comment_modal.dart index 0eb2694..9e927f7 100644 --- a/lib/screens/settings/dns/comment_modal.dart +++ b/lib/screens/settings/dns/comment_modal.dart @@ -33,7 +33,7 @@ class _CommentModalState extends State { return Padding( padding: MediaQuery.of(context).viewInsets, child: Container( - height: 330, + height: 310, decoration: BoxDecoration( borderRadius: const BorderRadius.only( topLeft: Radius.circular(28), @@ -49,24 +49,26 @@ class _CommentModalState extends State { ? const NeverScrollableScrollPhysics() : null, children: [ - const Padding( - padding: EdgeInsets.only(top: 28), + Padding( + padding: const EdgeInsets.only(top: 24), child: Icon( Icons.comment_rounded, - size: 26, + size: 24, + color: Theme.of(context).colorScheme.secondary, ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.comment, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 30), + const SizedBox(height: 16), Padding( - padding: const EdgeInsets.symmetric(horizontal: 28), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: commentController, onChanged: (value) { @@ -94,7 +96,7 @@ class _CommentModalState extends State { ), ), Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.all(24), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ diff --git a/lib/screens/settings/dns/private_reverse_servers.dart b/lib/screens/settings/dns/private_reverse_servers.dart index 28965e3..381e495 100644 --- a/lib/screens/settings/dns/private_reverse_servers.dart +++ b/lib/screens/settings/dns/private_reverse_servers.dart @@ -173,11 +173,18 @@ class _PrivateReverseDnsServersScreenState extends State { return Padding( padding: MediaQuery.of(context).viewInsets, child: Container( - height: 410, + height: 400, decoration: BoxDecoration( borderRadius: const BorderRadius.only( topLeft: Radius.circular(28), @@ -67,24 +67,26 @@ class _AddDnsRewriteModalState extends State { ? const NeverScrollableScrollPhysics() : null, children: [ - const Padding( - padding: EdgeInsets.only(top: 28), + Padding( + padding: const EdgeInsets.only(top: 24), child: Icon( Icons.add, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.addDnsRewrite, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ), - const SizedBox(height: 30), + const SizedBox(height: 16), Padding( - padding: const EdgeInsets.symmetric(horizontal: 28), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: domainController, onChanged: validateDomain, @@ -102,7 +104,7 @@ class _AddDnsRewriteModalState extends State { ), const SizedBox(height: 30), Padding( - padding: const EdgeInsets.symmetric(horizontal: 28), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: answerController, onChanged: (_) => checkValidValues(), @@ -121,11 +123,7 @@ class _AddDnsRewriteModalState extends State { ), ), Padding( - padding: const EdgeInsets.only( - top: 20, - bottom: 20, - right: 28 - ), + padding: const EdgeInsets.all(24), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ @@ -151,7 +149,7 @@ class _AddDnsRewriteModalState extends State { style: TextStyle( color: validData == true ? Theme.of(context).primaryColor - : Colors.grey + : Theme.of(context).colorScheme.onSurface.withOpacity(0.38) ), ), ), diff --git a/lib/screens/settings/dns_rewrites/delete_dns_rewrite.dart b/lib/screens/settings/dns_rewrites/delete_dns_rewrite.dart index 3f7ed3b..7419b2c 100644 --- a/lib/screens/settings/dns_rewrites/delete_dns_rewrite.dart +++ b/lib/screens/settings/dns_rewrites/delete_dns_rewrite.dart @@ -14,18 +14,27 @@ class DeleteDnsRewrite extends StatelessWidget { return AlertDialog( title: Column( children: [ - const Icon( + Icon( Icons.delete_rounded, - size: 26, + size: 24, + color: Theme.of(context).colorScheme.secondary, ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.deleteDnsRewrite, textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), ) ], ), - content: Text(AppLocalizations.of(context)!.deleteDnsRewriteMessage), + content: Text( + AppLocalizations.of(context)!.deleteDnsRewriteMessage, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), actions: [ TextButton( onPressed: () => Navigator.pop(context), diff --git a/lib/screens/settings/dns_rewrites/dns_rewrites.dart b/lib/screens/settings/dns_rewrites/dns_rewrites.dart index 0ad4fbb..3d2e77a 100644 --- a/lib/screens/settings/dns_rewrites/dns_rewrites.dart +++ b/lib/screens/settings/dns_rewrites/dns_rewrites.dart @@ -170,11 +170,12 @@ class _DnsRewritesWidgetState extends State { padding: const EdgeInsets.only(top: 0), itemCount: serversProvider.rewriteRules.data!.length, itemBuilder: (context, index) => Container( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 10), decoration: BoxDecoration( border: Border( bottom: BorderSide( - color: Colors.grey.shade200 + width: 1, + color: Theme.of(context).colorScheme.outline.withOpacity(0.5) ) ) ), @@ -188,12 +189,16 @@ class _DnsRewritesWidgetState extends State { children: [ Text( "${AppLocalizations.of(context)!.domain}: ", - style: const TextStyle( - fontWeight: FontWeight.w500 + style: TextStyle( + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.onSurface ), ), Text( serversProvider.rewriteRules.data![index].domain, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), ), ], ), @@ -202,12 +207,16 @@ class _DnsRewritesWidgetState extends State { children: [ Text( "${AppLocalizations.of(context)!.answer}: ", - style: const TextStyle( - fontWeight: FontWeight.w500 + style: TextStyle( + fontWeight: FontWeight.w500, + color: Theme.of(context).colorScheme.onSurface ), ), Text( serversProvider.rewriteRules.data![index].answer, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), ), ], ), @@ -277,6 +286,7 @@ class _DnsRewritesWidgetState extends State { ), body: generateBody(), floatingActionButton: FloatingActionButton( + backgroundColor: Theme.of(context).floatingActionButtonTheme.backgroundColor, onPressed: () => { showModalBottomSheet( context: context, @@ -289,7 +299,7 @@ class _DnsRewritesWidgetState extends State { }, child: Icon( Icons.add, - color: Theme.of(context).primaryColor.computeLuminance() > 0.5 ? Colors.black : Colors.white, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, ), ), ); diff --git a/lib/screens/settings/encryption/config_error_modal.dart b/lib/screens/settings/encryption/config_error_modal.dart index 80aa0bc..1e2cfd0 100644 --- a/lib/screens/settings/encryption/config_error_modal.dart +++ b/lib/screens/settings/encryption/config_error_modal.dart @@ -12,8 +12,18 @@ class EncryptionErrorModal extends StatelessWidget { @override Widget build(BuildContext context) { return AlertDialog( - title: Text(AppLocalizations.of(context)!.configError), - content: Text(error), + title: Text( + AppLocalizations.of(context)!.configError, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ), + content: Text( + error, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), actions: [ TextButton( onPressed: () => Navigator.pop(context), diff --git a/lib/screens/settings/encryption/custom_text_field.dart b/lib/screens/settings/encryption/custom_text_field.dart index 3b1cf79..f068152 100644 --- a/lib/screens/settings/encryption/custom_text_field.dart +++ b/lib/screens/settings/encryption/custom_text_field.dart @@ -27,7 +27,7 @@ class EncryptionTextField extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: ConstrainedBox( constraints: const BoxConstraints( maxHeight: 200 diff --git a/lib/screens/settings/encryption/encryption.dart b/lib/screens/settings/encryption/encryption.dart index 02867ef..d57c5a8 100644 --- a/lib/screens/settings/encryption/encryption.dart +++ b/lib/screens/settings/encryption/encryption.dart @@ -369,15 +369,23 @@ class _EncryptionSettingsWidgetState extends State { ), SectionLabel(label: AppLocalizations.of(context)!.certificates), Card( - margin: const EdgeInsets.symmetric(horizontal: 20), + margin: const EdgeInsets.symmetric(horizontal: 24), child: Padding( padding: const EdgeInsets.all(20), child: Row( children: [ - const Icon(Icons.info_rounded), + Icon( + Icons.info_rounded, + color: Theme.of(context).listTileTheme.iconColor, + ), const SizedBox(width: 20), Flexible( - child: Text(AppLocalizations.of(context)!.certificatesDescription) + child: Text( + AppLocalizations.of(context)!.certificatesDescription, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface, + ), + ) ) ], ), diff --git a/lib/screens/settings/encryption/master_switch.dart b/lib/screens/settings/encryption/master_switch.dart index d7e9d90..61c1f14 100644 --- a/lib/screens/settings/encryption/master_switch.dart +++ b/lib/screens/settings/encryption/master_switch.dart @@ -16,8 +16,8 @@ class EncryptionMasterSwitch extends StatelessWidget { return Padding( padding: const EdgeInsets.only( top: 10, - left: 12, - right: 12 + left: 24, + right: 24 ), child: Material( color: Theme.of(context).primaryColor.withOpacity(0.1), @@ -39,8 +39,9 @@ class EncryptionMasterSwitch extends StatelessWidget { children: [ Text( AppLocalizations.of(context)!.enableEncryption, - style: const TextStyle( - fontSize: 18, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface ), ), const SizedBox(height: 3), @@ -48,7 +49,7 @@ class EncryptionMasterSwitch extends StatelessWidget { AppLocalizations.of(context)!.enableEncryptionTypes, style: TextStyle( fontSize: 14, - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor ), ) ], diff --git a/lib/screens/settings/server_info/dns_addresses_modal.dart b/lib/screens/settings/server_info/dns_addresses_modal.dart index 3fbee4c..2a6fa2f 100644 --- a/lib/screens/settings/server_info/dns_addresses_modal.dart +++ b/lib/screens/settings/server_info/dns_addresses_modal.dart @@ -14,9 +14,17 @@ class DnsAddressesModal extends StatelessWidget { return AlertDialog( title: Column( children: [ - const Icon(Icons.route_rounded), - const SizedBox(height: 20), - Text(AppLocalizations.of(context)!.dnsAddresses) + Icon( + Icons.route_rounded, + color: Theme.of(context).listTileTheme.iconColor + ), + const SizedBox(height: 16), + Text( + AppLocalizations.of(context)!.dnsAddresses, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ) ], ), content: SizedBox( @@ -27,8 +35,9 @@ class DnsAddressesModal extends StatelessWidget { children: dnsAddresses.map((address) => ListTile( title: Text( address, - style: const TextStyle( - fontWeight: FontWeight.normal + style: TextStyle( + fontWeight: FontWeight.normal, + color: Theme.of(context).listTileTheme.textColor ), ), )).toList(), diff --git a/lib/screens/settings/settings.dart b/lib/screens/settings/settings.dart index 95bea38..0031768 100644 --- a/lib/screens/settings/settings.dart +++ b/lib/screens/settings/settings.dart @@ -196,7 +196,7 @@ class Settings extends StatelessWidget { onPressed: () => openWeb(Urls.playStore), icon: SvgPicture.asset( 'assets/resources/google-play.svg', - color: Theme.of(context).textTheme.bodyText2!.color, + color: Theme.of(context).colorScheme.onSurfaceVariant, width: 30, height: 30, ), @@ -206,7 +206,7 @@ class Settings extends StatelessWidget { onPressed: () => openWeb(Urls.gitHub), icon: SvgPicture.asset( 'assets/resources/github.svg', - color: Theme.of(context).textTheme.bodyText2!.color, + color: Theme.of(context).colorScheme.onSurfaceVariant, width: 30, height: 30, ), diff --git a/lib/screens/top_items/top_items.dart b/lib/screens/top_items/top_items.dart index baa032c..734b640 100644 --- a/lib/screens/top_items/top_items.dart +++ b/lib/screens/top_items/top_items.dart @@ -154,7 +154,12 @@ class _TopItemsScreenState extends State { return CustomListTile( title: screenData[index].keys.toList()[0], - trailing: Text(screenData[index].values.toList()[0].toString()), + trailing: Text( + screenData[index].values.toList()[0].toString(), + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), subtitleWidget: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -163,9 +168,7 @@ class _TopItemsScreenState extends State { name, style: TextStyle( fontSize: 14, - color: Theme.of(context).brightness == Brightness.light - ? Colors.black - : Colors.white + color: Theme.of(context).colorScheme.onSurface ), ), const SizedBox(height: 5), @@ -177,7 +180,7 @@ class _TopItemsScreenState extends State { child: Text( "${doubleFormat((screenData[index].values.toList()[0]/total*100), Platform.localeName)}%", style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor + color: Theme.of(context).listTileTheme.textColor ), ), ), @@ -191,7 +194,7 @@ class _TopItemsScreenState extends State { percent: screenData[index].values.toList()[0]/total, barRadius: const Radius.circular(5), progressColor: Theme.of(context).primaryColor, - backgroundColor: Theme.of(context).primaryColor.withOpacity(0.15), + backgroundColor: Theme.of(context).primaryColor.withOpacity(0.15), ), ), const SizedBox(width: 10), diff --git a/lib/widgets/add_server_modal.dart b/lib/widgets/add_server_modal.dart index 6d4663b..3c19202 100644 --- a/lib/widgets/add_server_modal.dart +++ b/lib/widgets/add_server_modal.dart @@ -3,10 +3,9 @@ import 'package:provider/provider.dart'; import 'package:flutter/material.dart'; import 'package:uuid/uuid.dart'; +import 'package:material_segmented_control/material_segmented_control.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:adguard_home_manager/widgets/custom_radio_toggle.dart'; - import 'package:adguard_home_manager/providers/app_config_provider.dart'; import 'package:adguard_home_manager/functions/encode_base64.dart'; import 'package:adguard_home_manager/services/http_requests.dart'; @@ -61,8 +60,8 @@ class _AddServerModalState extends State { Widget sectionLabel(String label) { return Padding( padding: const EdgeInsets.symmetric( - horizontal: 20, - vertical: 30 + horizontal: 24, + vertical: 24 ), child: Text( label, @@ -87,7 +86,7 @@ class _AddServerModalState extends State { String? helperText }) { return Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: TextFormField( controller: controller, onChanged: onChanged, @@ -249,6 +248,33 @@ class _AddServerModalState extends State { final mediaQuery = MediaQuery.of(context); + Map connectionTypes = { + 0: Text( + 'HTTP', + style: TextStyle( + color: appConfigProvider.useDynamicColor == true + ? Theme.of(context).floatingActionButtonTheme.foregroundColor! + : connectionType == 'http' + ? Colors.white + : Theme.of(context).primaryColor, + fontSize: 14, + fontWeight: FontWeight.w500 + ), + ), + 1: Text( + 'HTTPS', + style: TextStyle( + color: appConfigProvider.useDynamicColor == true + ? Theme.of(context).floatingActionButtonTheme.foregroundColor! + : connectionType == 'https' + ? Colors.white + : Theme.of(context).primaryColor, + fontSize: 14, + fontWeight: FontWeight.w500 + ), + ) + }; + void connect() async { Server serverObj = Server( id: uuid.v4(), @@ -461,11 +487,8 @@ class _AddServerModalState extends State { return Stack( children: [ Scaffold( - backgroundColor: Theme.of(context).dialogBackgroundColor, - appBar: AppBar( - systemOverlayStyle: systemUiOverlayStyleConfig(context), + appBar: AppBar( title: Text(AppLocalizations.of(context)!.createConnection), - elevation: 5, actions: [ Padding( padding: const EdgeInsets.only(right: 10), @@ -493,9 +516,9 @@ class _AddServerModalState extends State { Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), margin: const EdgeInsets.only( - top: 30, - left: 20, - right: 20 + top: 24, + left: 24, + right: 24 ), decoration: BoxDecoration( color: Theme.of(context).primaryColor.withOpacity(0.05), @@ -530,22 +553,23 @@ class _AddServerModalState extends State { } ), sectionLabel(AppLocalizations.of(context)!.connection), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - CustomRadioToggle( - groupSelected: connectionType, - value: 'http', - label: 'HTTP', - onTap: (value) => setState(() => connectionType = value) - ), - CustomRadioToggle( - groupSelected: connectionType, - value: 'https', - label: 'HTTPS', - onTap: (value) => setState(() => connectionType = value) - ), - ], + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: MaterialSegmentedControl( + children: connectionTypes, + selectionIndex: connectionType == 'http' ? 0 : 1, + onSegmentChosen: (value) => setState(() { + if (value == 0) { + connectionType = 'http'; + } + else if (value == 1) { + connectionType = 'https'; + } + }), + selectedColor: Theme.of(context).floatingActionButtonTheme.backgroundColor!, + unselectedColor: Colors.transparent, + borderColor: Theme.of(context).colorScheme.onSurface, + ), ), const SizedBox(height: 20), textField( @@ -601,7 +625,7 @@ class _AddServerModalState extends State { ? () => setState(() => defaultServer = !defaultServer) : null, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -629,7 +653,7 @@ class _AddServerModalState extends State { child: InkWell( onTap: () => setState(() => homeAssistant = !homeAssistant), child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: 24), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/widgets/bottom_nav_bar.dart b/lib/widgets/bottom_nav_bar.dart index 204c1c0..dabc657 100644 --- a/lib/widgets/bottom_nav_bar.dart +++ b/lib/widgets/bottom_nav_bar.dart @@ -52,13 +52,9 @@ class BottomNavBar extends StatelessWidget { destinations: screens.map((screen) => NavigationDestination( icon: Icon( screen.icon, - color: screens.indexOf(screen) == appConfigProvider.selectedScreen - ? Theme.of(context).navigationBarTheme.indicatorColor!.computeLuminance() > 0.5 ? - appConfigProvider.useDynamicColor == true - ? Theme.of(context).primaryColor - : Colors.black - : Colors.white - : null, + color: screens[appConfigProvider.selectedScreen] == screen + ? Theme.of(context).colorScheme.onSecondaryContainer + : Theme.of(context).colorScheme.onSurfaceVariant, ), label: translatedName(screen.name) )).toList(), diff --git a/lib/widgets/custom_list_tile.dart b/lib/widgets/custom_list_tile.dart index 89b01a8..194c6a7 100644 --- a/lib/widgets/custom_list_tile.dart +++ b/lib/widgets/custom_list_tile.dart @@ -27,7 +27,7 @@ class CustomListTile extends StatelessWidget { child: InkWell( onTap: onTap, child: Padding( - padding: padding ?? const EdgeInsets.symmetric(horizontal: 20, vertical: 15), + padding: padding ?? const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -38,8 +38,10 @@ class CustomListTile extends StatelessWidget { if (icon != null) ...[ Icon( icon, + size: 24, + color: Theme.of(context).listTileTheme.iconColor, ), - const SizedBox(width: 20), + const SizedBox(width: 16), ], Flexible( child: Column( @@ -47,9 +49,10 @@ class CustomListTile extends StatelessWidget { children: [ Text( title, - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.normal + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface, ), ), if (subtitle != null || subtitleWidget != null) ...[ @@ -58,8 +61,9 @@ class CustomListTile extends StatelessWidget { if (subtitle != null && subtitleWidget == null) Text( subtitle!, style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor, - fontSize: 14 + color: Theme.of(context).listTileTheme.textColor, + fontSize: 14, + fontWeight: FontWeight.w400 ), ), ] diff --git a/lib/widgets/custom_radio_list_tile.dart b/lib/widgets/custom_radio_list_tile.dart index b66ef61..802431e 100644 --- a/lib/widgets/custom_radio_list_tile.dart +++ b/lib/widgets/custom_radio_list_tile.dart @@ -27,16 +27,18 @@ class CustomRadioListTile extends StatelessWidget { child: InkWell( onTap: () => onChanged(value), child: Padding( - padding: const EdgeInsets.all(20), + padding: const EdgeInsets.symmetric( + horizontal: 24, + vertical: 12 + ), child: Row( children: [ - const SizedBox(width: 10), CustomRadio( value: value, groupValue: groupValue, backgroundColor: radioBackgroundColor, ), - const SizedBox(width: 30), + const SizedBox(width: 24), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -44,8 +46,9 @@ class CustomRadioListTile extends StatelessWidget { width: MediaQuery.of(context).size.width-110, child: Text( title, - style: const TextStyle( - fontSize: 16 + style: TextStyle( + fontSize: 16, + color: Theme.of(context).colorScheme.onSurface ), ), ), @@ -56,7 +59,7 @@ class CustomRadioListTile extends StatelessWidget { child: Text( subtitle!, style: TextStyle( - color: Theme.of(context).listTileTheme.iconColor, + color: Theme.of(context).listTileTheme.textColor, fontSize: 14 ), ), diff --git a/lib/widgets/custom_switch_list_tile.dart b/lib/widgets/custom_switch_list_tile.dart index d612af3..cc46a8f 100644 --- a/lib/widgets/custom_switch_list_tile.dart +++ b/lib/widgets/custom_switch_list_tile.dart @@ -26,7 +26,7 @@ class CustomSwitchListTile extends StatelessWidget { : () => onChanged(!value), child: Padding( padding: const EdgeInsets.only( - top: 15, left: 24, right: 15, bottom: 15 + top: 12, left: 24, right: 12, bottom: 12 ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -41,8 +41,8 @@ class CustomSwitchListTile extends StatelessWidget { style: TextStyle( fontSize: 16, color: disabled != null && disabled == true - ? Colors.grey - : null, + ? Theme.of(context).colorScheme.onSurface.withOpacity(0.38) + : Theme.of(context).colorScheme.onSurface, ), ), ), @@ -55,8 +55,8 @@ class CustomSwitchListTile extends StatelessWidget { style: TextStyle( fontSize: 14, color: disabled != null && disabled == true - ? Colors.grey - : Theme.of(context).listTileTheme.iconColor, + ? Theme.of(context).listTileTheme.textColor!.withOpacity(0.38) + : Theme.of(context).listTileTheme.textColor ), ), ), diff --git a/lib/widgets/process_dialog.dart b/lib/widgets/process_dialog.dart index 49fa16b..84c1185 100644 --- a/lib/widgets/process_dialog.dart +++ b/lib/widgets/process_dialog.dart @@ -23,7 +23,12 @@ class ProcessDialog extends StatelessWidget { children: [ const CircularProgressIndicator(), const SizedBox(width: 40), - Text(message) + Text( + message, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurface + ), + ) ], ), ), diff --git a/lib/widgets/section_label.dart b/lib/widgets/section_label.dart index ef2127e..93c9572 100644 --- a/lib/widgets/section_label.dart +++ b/lib/widgets/section_label.dart @@ -16,7 +16,7 @@ class SectionLabel extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, children: [ Padding( - padding: padding ?? const EdgeInsets.all(25), + padding: padding ?? const EdgeInsets.all(24), child: Text( label, style: TextStyle( diff --git a/lib/widgets/servers_list/delete_modal.dart b/lib/widgets/servers_list/delete_modal.dart index 2ba22bf..2cc9809 100644 --- a/lib/widgets/servers_list/delete_modal.dart +++ b/lib/widgets/servers_list/delete_modal.dart @@ -46,16 +46,19 @@ class DeleteModal extends StatelessWidget { return AlertDialog( title: Column( children: [ - const Icon( + Icon( Icons.delete, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor ), Padding( - padding: const EdgeInsets.only(top: 20), + padding: const EdgeInsets.only(top: 16), child: Text( AppLocalizations.of(context)!.remove, - style: const TextStyle( - fontSize: 24 + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface ), ), ), @@ -70,13 +73,17 @@ class DeleteModal extends StatelessWidget { Text( AppLocalizations.of(context)!.removeWarning, textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), ), const SizedBox(height: 10), Center( child: Text( "${serverToDelete.connectionMethod}://${serverToDelete.domain}${serverToDelete.path ?? ""}${serverToDelete.port != null ? ':${serverToDelete.port}' : ""}", - style: const TextStyle( - fontStyle: FontStyle.italic + style: TextStyle( + fontStyle: FontStyle.italic, + color: Theme.of(context).colorScheme.onSurfaceVariant ), ), ), diff --git a/lib/widgets/servers_list/servers_list.dart b/lib/widgets/servers_list/servers_list.dart index 6f1b291..1ba3d1e 100644 --- a/lib/widgets/servers_list/servers_list.dart +++ b/lib/widgets/servers_list/servers_list.dart @@ -187,12 +187,12 @@ class _ServersListState extends State with SingleTickerProviderStat Container( padding: const EdgeInsets.all(1), decoration: BoxDecoration( - color: Theme.of(context).primaryColor, + color: Theme.of(context).floatingActionButtonTheme.backgroundColor, borderRadius: BorderRadius.circular(20) ), - child: const Icon( + child: Icon( Icons.star, - color: Colors.white, + color: Theme.of(context).floatingActionButtonTheme.foregroundColor, size: 10, ), ), @@ -218,44 +218,49 @@ class _ServersListState extends State with SingleTickerProviderStat return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Container( - width: 48, - margin: const EdgeInsets.only(right: 12), - child: leadingIcon(servers[index]), - ), Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + child: Row( children: [ - Text( - "${server.connectionMethod}://${server.domain}${server.path ?? ""}${server.port != null ? ':${server.port}' : ""}", - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 18, + Container( + margin: const EdgeInsets.only(right: 16), + child: leadingIcon(servers[index]), + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "${server.connectionMethod}://${server.domain}${server.path ?? ""}${server.port != null ? ':${server.port}' : ""}", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurface + ), + ), + Column( + children: [ + const SizedBox(height: 3), + Text( + servers[index].name, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w400, + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ) + ], + ) + ], ), ), - Column( - children: [ - const SizedBox(height: 5), - Text( - servers[index].name, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).listTileTheme.iconColor - ), - ) - ], - ) ], ), ), - Padding( - padding: const EdgeInsets.only(right: 10), - child: RotationTransition( - turns: animation, - child: const Icon(Icons.keyboard_arrow_down_rounded), - ), + RotationTransition( + turns: animation, + child: const Icon(Icons.keyboard_arrow_down_rounded), ), ], ); @@ -383,7 +388,7 @@ class _ServersListState extends State with SingleTickerProviderStat child: InkWell( onTap: () => widget.onChange(index), child: Padding( - padding: const EdgeInsets.all(10), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: topRow(servers[index], index), ), ), @@ -393,7 +398,7 @@ class _ServersListState extends State with SingleTickerProviderStat child: InkWell( onTap: () => widget.onChange(index), child: Padding( - padding: const EdgeInsets.all(10), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), child: Column( children: [ topRow(servers[index], index), diff --git a/lib/widgets/update_modal.dart b/lib/widgets/update_modal.dart index 3cebe79..b3acc8d 100644 --- a/lib/widgets/update_modal.dart +++ b/lib/widgets/update_modal.dart @@ -34,16 +34,18 @@ class _UpdateModalState extends State { scrollable: true, title: Column( children: [ - const Icon( + Icon( Icons.system_update_rounded, - size: 26, + size: 24, + color: Theme.of(context).listTileTheme.iconColor, ), - const SizedBox(height: 20), + const SizedBox(height: 16), Text( AppLocalizations.of(context)!.updateAvailable, textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 26 + style: TextStyle( + fontSize: 24, + color: Theme.of(context).colorScheme.onSurface ), ) ], @@ -51,11 +53,26 @@ class _UpdateModalState extends State { content: Column( children: [ const SizedBox(height: 10), - Text("${AppLocalizations.of(context)!.installedVersion}: ${appConfigProvider.getAppInfo!.version}"), + Text( + "${AppLocalizations.of(context)!.installedVersion}: ${appConfigProvider.getAppInfo!.version}", + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), const SizedBox(height: 10), - Text("${AppLocalizations.of(context)!.newVersion}: ${widget.gitHubRelease.tagName}"), + Text( + "${AppLocalizations.of(context)!.newVersion}: ${widget.gitHubRelease.tagName}", + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), const SizedBox(height: 10), - Text("${AppLocalizations.of(context)!.source}: GitHub"), + Text( + "${AppLocalizations.of(context)!.source}: GitHub", + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ), const SizedBox(height: 20), GestureDetector( onTap: () => setState(() => doNotRemember = !doNotRemember), @@ -70,7 +87,14 @@ class _UpdateModalState extends State { ), ), const SizedBox(width: 10), - Flexible(child: Text(AppLocalizations.of(context)!.doNotRememberAgainUpdate)) + Flexible( + child: Text( + AppLocalizations.of(context)!.doNotRememberAgainUpdate, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant + ), + ) + ) ], ), ) diff --git a/pubspec.lock b/pubspec.lock index 310551d..74fa225 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -329,6 +329,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.5" + material_segmented_control: + dependency: "direct main" + description: + name: material_segmented_control + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" meta: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 5281506..674d4aa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -50,6 +50,7 @@ dependencies: bottom_sheet: ^3.1.2 percent_indicator: ^4.2.2 store_checker: ^1.1.0 + material_segmented_control: ^4.0.0 dev_dependencies: flutter_test: