diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index c6f9d42..13f6e05 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -242,5 +242,10 @@ "listDataNotUpdated": "Couldn't update list data", "updatingListData": "Updating list data...", "editWhitelist": "Edit white list", - "editBlacklist": "Edit black list" + "editBlacklist": "Edit black list", + "deletingList": "Deleting list...", + "listDeleted": "List deleted successfully", + "listNotDeleted": "The list couldn't be deleted", + "deleteList": "Delete list", + "deleteListMessage": "Are you sure you want to delete this list? This action can't be reverted." } \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index efeba52..779859a 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -242,5 +242,10 @@ "listDataNotUpdated": "No se han podido actualizar los datos de la lista", "updatingListData": "Actualizando datos de lista...", "editWhitelist": "Editar lista blanca", - "editBlacklist": "Editar lista negra" + "editBlacklist": "Editar lista negra", + "deletingList": "Eliminando lista...", + "listDeleted": "Lista eliminada correctamente", + "listNotDeleted": "La lista no pudo ser eliminada", + "deleteList": "Eliminar lista", + "deleteListMessage": "¿Estás seguro que deseas eliminar esta lista? Esta acción no se puede revertir." } \ No newline at end of file diff --git a/lib/screens/clients/added_list.dart b/lib/screens/clients/added_list.dart index aa7bdac..8e27123 100644 --- a/lib/screens/clients/added_list.dart +++ b/lib/screens/clients/added_list.dart @@ -6,7 +6,7 @@ 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/remove_domain_modal.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'; @@ -154,7 +154,7 @@ class _AddedListState extends State { void openDeleteModal(Client client) { showModal( context: context, - builder: (ctx) => RemoveDomainModal( + builder: (ctx) => RemoveClientModal( onConfirm: () => deleteClient(client) ) ); diff --git a/lib/screens/clients/blocked_list.dart b/lib/screens/clients/blocked_list.dart index fae1691..addd70d 100644 --- a/lib/screens/clients/blocked_list.dart +++ b/lib/screens/clients/blocked_list.dart @@ -5,7 +5,7 @@ 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/remove_domain_modal.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/providers/app_config_provider.dart'; @@ -138,7 +138,7 @@ class _BlockedListState extends State { onPressed: () => { showDialog( context: context, - builder: (context) => RemoveDomainModal( + builder: (context) => RemoveClientModal( onConfirm: () => confirmRemoveDomain(widget.data[index]), ) ) diff --git a/lib/screens/clients/client_modal.dart b/lib/screens/clients/client_modal.dart index 70bc078..f6c78ad 100644 --- a/lib/screens/clients/client_modal.dart +++ b/lib/screens/clients/client_modal.dart @@ -3,7 +3,7 @@ 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_domain_modal.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'; @@ -191,7 +191,7 @@ class _ClientModalState extends State { void openDeleteClientModal() { showDialog( context: context, - builder: (ctx) => RemoveDomainModal( + builder: (ctx) => RemoveClientModal( onConfirm: () { Navigator.pop(context); widget.onDelete!(widget.client!); diff --git a/lib/screens/clients/remove_domain_modal.dart b/lib/screens/clients/remove_client_modal.dart similarity index 92% rename from lib/screens/clients/remove_domain_modal.dart rename to lib/screens/clients/remove_client_modal.dart index 31373a5..a32b06e 100644 --- a/lib/screens/clients/remove_domain_modal.dart +++ b/lib/screens/clients/remove_client_modal.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -class RemoveDomainModal extends StatelessWidget { +class RemoveClientModal extends StatelessWidget { final void Function() onConfirm; - const RemoveDomainModal({ + const RemoveClientModal({ Key? key, required this.onConfirm }) : super(key: key); diff --git a/lib/screens/filters/add_list_modal.dart b/lib/screens/filters/add_list_modal.dart index b0621dc..24fca97 100644 --- a/lib/screens/filters/add_list_modal.dart +++ b/lib/screens/filters/add_list_modal.dart @@ -6,7 +6,7 @@ import 'package:adguard_home_manager/models/filtering.dart'; class AddListModal extends StatefulWidget { final String type; final Filter? list; - final void Function({required String name, required String url})? onConfirm; + final void Function({required String name, required String url, required String type})? onConfirm; final void Function({required Filter list, required String type})? onEdit; const AddListModal({ @@ -163,6 +163,7 @@ class _AddListModalState extends State { widget.onConfirm!( name: nameController.text, url: urlController.text, + type: widget.type ); } }, diff --git a/lib/screens/filters/delete_list_modal.dart b/lib/screens/filters/delete_list_modal.dart new file mode 100644 index 0000000..e286326 --- /dev/null +++ b/lib/screens/filters/delete_list_modal.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class DeleteListModal extends StatelessWidget { + final void Function() onConfirm; + + const DeleteListModal({ + Key? key, + required this.onConfirm + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: Column( + children: [ + const Icon( + Icons.delete_rounded, + size: 26, + ), + const SizedBox(height: 20), + Text(AppLocalizations.of(context)!.deleteList) + ], + ), + content: Text(AppLocalizations.of(context)!.deleteListMessage), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context), + child: Text(AppLocalizations.of(context)!.cancel) + ), + TextButton( + onPressed: () { + onConfirm(); + Navigator.pop(context); + }, + child: Text(AppLocalizations.of(context)!.confirm) + ), + ], + ); + } +} \ No newline at end of file diff --git a/lib/screens/filters/fab.dart b/lib/screens/filters/fab.dart index f6c2aa8..6e5e485 100644 --- a/lib/screens/filters/fab.dart +++ b/lib/screens/filters/fab.dart @@ -72,7 +72,7 @@ class FiltersFab extends StatelessWidget { ); } - void confirmAddList({required String name, required String url, String? type}) async { + void confirmAddList({required String name, required String url, required String type}) async { ProcessModal processModal = ProcessModal(context: context); processModal.open(AppLocalizations.of(context)!.addingList); diff --git a/lib/screens/filters/filters_list.dart b/lib/screens/filters/filters_list.dart index 06d4ec0..81cbfb4 100644 --- a/lib/screens/filters/filters_list.dart +++ b/lib/screens/filters/filters_list.dart @@ -2,6 +2,7 @@ import 'dart:io'; +import 'package:adguard_home_manager/screens/filters/delete_list_modal.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:flutter/rendering.dart'; @@ -119,7 +120,7 @@ class _FiltersListState extends State { void confirmEditList({required Filter list, required String type}) async { ProcessModal processModal = ProcessModal(context: context); - processModal.open(AppLocalizations.of(context)!.addingList); + processModal.open(AppLocalizations.of(context)!.updatingListData); final result1 = await updateFilterList(server: serversProvider.selectedServer!, data: { "data": { @@ -166,13 +167,67 @@ class _FiltersListState extends State { } } + 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(); + + appConfigProvider.setShowingSnackbar(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(AppLocalizations.of(context)!.listDeleted), + backgroundColor: Colors.green, + ) + ); + } + else { + processModal.close(); + appConfigProvider.addLog(result1['log']); + appConfigProvider.setShowingSnackbar(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(AppLocalizations.of(context)!.listNotDeleted), + backgroundColor: Colors.red, + ) + ); + } + } + void openDetailsModal(Filter filter) { showModalBottomSheet( context: context, builder: (ctx) => ListDetailsModal( list: filter, type: widget.type, - onDelete: () => {}, + onDelete: (Filter list, String type) { + showDialog( + context: context, + builder: (context) => DeleteListModal( + onConfirm: () { + Navigator.pop(context); + deleteList(list, type); + }, + ) + ); + }, edit: (type) => { showModalBottomSheet( context: context, diff --git a/lib/screens/filters/list_details_modal.dart b/lib/screens/filters/list_details_modal.dart index 012a59f..6da00c4 100644 --- a/lib/screens/filters/list_details_modal.dart +++ b/lib/screens/filters/list_details_modal.dart @@ -9,7 +9,7 @@ import 'package:adguard_home_manager/models/filtering.dart'; class ListDetailsModal extends StatelessWidget { final Filter list; final String type; - final void Function() onDelete; + final void Function(Filter, String) onDelete; final void Function(String) edit; final void Function(Filter, bool) onEnableDisable; @@ -133,12 +133,23 @@ class ListDetailsModal extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - IconButton( - onPressed: () { - Navigator.pop(context); - edit(type); - }, - icon: const Icon(Icons.edit) + 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), diff --git a/lib/services/http_requests.dart b/lib/services/http_requests.dart index 0b98d18..a20338b 100644 --- a/lib/services/http_requests.dart +++ b/lib/services/http_requests.dart @@ -845,4 +845,38 @@ Future updateFilterList({ else { return result; } +} + +Future deleteFilterList({ + required Server server, + required Map data, +}) async { + final result = await apiRequest( + urlPath: '/filtering/remove_url', + method: 'post', + server: server, + body: data, + type: 'delete_filter_list' + ); + + if (result['hasResponse'] == true) { + if (result['statusCode'] == 200) { + return {'result': 'success'}; + } + else { + return { + 'result': 'error', + 'log': AppLog( + type: 'delete_filter_list', + dateTime: DateTime.now(), + message: 'error_code_not_expected', + statusCode: result['statusCode'].toString(), + resBody: result['body'] + ) + }; + } + } + else { + return result; + } } \ No newline at end of file