mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-05-04 20:30:35 +00:00
Added modal to select clients on logs
This commit is contained in:
parent
f10ba33222
commit
a4a7840e55
10 changed files with 291 additions and 13 deletions
|
@ -143,7 +143,8 @@ class TopItems extends StatelessWidget {
|
|||
logsProvider.setAppliedFilters(
|
||||
AppliedFiters(
|
||||
selectedResultStatus: 'all',
|
||||
searchText: item.keys.toList()[0]
|
||||
searchText: item.keys.toList()[0],
|
||||
clients: null
|
||||
)
|
||||
);
|
||||
appConfigProvider.setSelectedScreen(2);
|
||||
|
|
172
lib/screens/logs/clients_modal.dart
Normal file
172
lib/screens/logs/clients_modal.dart
Normal file
|
@ -0,0 +1,172 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
import 'package:adguard_home_manager/providers/logs_provider.dart';
|
||||
|
||||
class ClientsModal extends StatefulWidget {
|
||||
final List<String>? value;
|
||||
|
||||
const ClientsModal({
|
||||
Key? key,
|
||||
required this.value
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<ClientsModal> createState() => _ClientsModalState();
|
||||
}
|
||||
|
||||
class _ClientsModalState extends State<ClientsModal> {
|
||||
List<String> selectedClients = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
setState(() => selectedClients = widget.value ?? []);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final logsProvider = Provider.of<LogsProvider>(context);
|
||||
|
||||
final height = MediaQuery.of(context).size.height;
|
||||
|
||||
void apply() async {
|
||||
logsProvider.setSelectedClients(
|
||||
selectedClients.isNotEmpty ? selectedClients : null
|
||||
);
|
||||
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
Widget listItem({
|
||||
required String label,
|
||||
required void Function() onChanged
|
||||
}) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () => onChanged(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
color: Theme.of(context).colorScheme.onSurface
|
||||
),
|
||||
),
|
||||
Checkbox(
|
||||
value: selectedClients.contains(label),
|
||||
onChanged: (_) => onChanged(),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5)
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void selectAll() {
|
||||
setState(() {
|
||||
selectedClients = logsProvider.clients!.map((item) => item.ip).toList();
|
||||
});
|
||||
}
|
||||
|
||||
void unselectAll() {
|
||||
setState(() {
|
||||
selectedClients = [];
|
||||
});
|
||||
}
|
||||
|
||||
return Container(
|
||||
height: height >= (logsProvider.clients!.length*64) == true
|
||||
? logsProvider.clients!.length*64
|
||||
: height-25,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(28),
|
||||
topRight: Radius.circular(28)
|
||||
),
|
||||
color: Theme.of(context).dialogBackgroundColor
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 24,
|
||||
bottom: 16,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.smartphone_rounded,
|
||||
size: 24,
|
||||
color: Theme.of(context).listTileTheme.iconColor
|
||||
),
|
||||
),
|
||||
Text(
|
||||
AppLocalizations.of(context)!.clients,
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context).colorScheme.onSurface
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
physics: height >= (logsProvider.clients!.length*64) == true
|
||||
? const NeverScrollableScrollPhysics()
|
||||
: null,
|
||||
itemCount: logsProvider.clients!.length,
|
||||
itemBuilder: (context, index) => listItem(
|
||||
label: logsProvider.clients![index].ip,
|
||||
onChanged: () {
|
||||
if (selectedClients.contains(logsProvider.clients![index].ip)) {
|
||||
setState(() {
|
||||
selectedClients = selectedClients.where(
|
||||
(item) => item != logsProvider.clients![index].ip
|
||||
).toList();
|
||||
});
|
||||
}
|
||||
else {
|
||||
setState(() {
|
||||
selectedClients.add(logsProvider.clients![index].ip);
|
||||
});
|
||||
}
|
||||
}
|
||||
)
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: selectedClients.length == logsProvider.clients!.length
|
||||
? () => unselectAll()
|
||||
: () => selectAll(),
|
||||
child: Text(
|
||||
selectedClients.length == logsProvider.clients!.length
|
||||
? AppLocalizations.of(context)!.unselectAll
|
||||
: AppLocalizations.of(context)!.selectAll
|
||||
)
|
||||
),
|
||||
TextButton(
|
||||
onPressed: apply,
|
||||
child: Text(AppLocalizations.of(context)!.apply)
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -129,6 +129,26 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
}
|
||||
}
|
||||
|
||||
Future fetchClients() async {
|
||||
final result = await getClients(widget.serversProvider.selectedServer!);
|
||||
if (mounted) {
|
||||
if (result['result'] == 'success') {
|
||||
widget.logsProvider.setClientsLoadStatus(1);
|
||||
widget.logsProvider.setClients(result['data'].autoClientsData);
|
||||
}
|
||||
else {
|
||||
widget.logsProvider.setClientsLoadStatus(2);
|
||||
widget.appConfigProvider.addLog(result['log']);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.couldntGetFilteringStatus),
|
||||
backgroundColor: Colors.red,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scrollListener() {
|
||||
if (scrollController.position.extentAfter < 500 && isLoadingMore == false) {
|
||||
fetchLogs(loadingMore: true);
|
||||
|
@ -146,6 +166,7 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
scrollController = ScrollController()..addListener(scrollListener);
|
||||
fetchLogs(inOffset: 0);
|
||||
fetchFilteringRules();
|
||||
fetchClients();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
@ -417,7 +438,8 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
logsProvider.setAppliedFilters(
|
||||
AppliedFiters(
|
||||
selectedResultStatus: logsProvider.appliedFilters.selectedResultStatus,
|
||||
searchText: null
|
||||
searchText: null,
|
||||
clients: null
|
||||
)
|
||||
);
|
||||
logsProvider.setSearchText(null);
|
||||
|
@ -463,7 +485,8 @@ class _LogsWidgetState extends State<LogsWidget> {
|
|||
logsProvider.setAppliedFilters(
|
||||
AppliedFiters(
|
||||
selectedResultStatus: 'all',
|
||||
searchText: logsProvider.appliedFilters.searchText
|
||||
searchText: logsProvider.appliedFilters.searchText,
|
||||
clients: null
|
||||
)
|
||||
);
|
||||
logsProvider.setSelectedResultStatus('all');
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// ignore_for_file: use_build_context_synchronously
|
||||
|
||||
import 'package:adguard_home_manager/screens/logs/clients_modal.dart';
|
||||
import 'package:adguard_home_manager/widgets/custom_list_tile.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
@ -111,7 +112,8 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
logsProvider.setAppliedFilters(
|
||||
AppliedFiters(
|
||||
selectedResultStatus: 'all',
|
||||
searchText: null
|
||||
searchText: null,
|
||||
clients: null
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -136,6 +138,17 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
);
|
||||
}
|
||||
|
||||
void openSelectClients() {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => ClientsModal(
|
||||
value: logsProvider.selectedClients,
|
||||
),
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent
|
||||
);
|
||||
}
|
||||
|
||||
void filterLogs() async {
|
||||
Navigator.pop(context);
|
||||
|
||||
|
@ -155,6 +168,7 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
AppliedFiters(
|
||||
selectedResultStatus: logsProvider.selectedResultStatus,
|
||||
searchText: logsProvider.searchText,
|
||||
clients: logsProvider.selectedClients
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -171,7 +185,7 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
return Padding(
|
||||
padding: MediaQuery.of(context).viewInsets,
|
||||
child: Container(
|
||||
height: 360,
|
||||
height: 430,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).dialogBackgroundColor,
|
||||
borderRadius: const BorderRadius.only(
|
||||
|
@ -282,6 +296,31 @@ class _LogsFiltersModalWidgetState extends State<LogsFiltersModalWidget> {
|
|||
// ),
|
||||
// ),
|
||||
// ),
|
||||
CustomListTile(
|
||||
title: AppLocalizations.of(context)!.client,
|
||||
subtitle: logsProvider.selectedClients != null
|
||||
? "${logsProvider.selectedClients!.length} ${AppLocalizations.of(context)!.clientsSelected}"
|
||||
: AppLocalizations.of(context)!.all,
|
||||
onTap: logsProvider.clientsLoadStatus == 1
|
||||
? openSelectClients
|
||||
: null,
|
||||
icon: Icons.smartphone_rounded,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
trailing: logsProvider.clientsLoadStatus == 0
|
||||
? const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
),
|
||||
)
|
||||
: logsProvider.clientsLoadStatus == 2
|
||||
? const Icon(
|
||||
Icons.error_rounded,
|
||||
color: Colors.red,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
CustomListTile(
|
||||
title: AppLocalizations.of(context)!.responseStatus,
|
||||
subtitle: "${translatedString[logsProvider.selectedResultStatus]}",
|
||||
|
|
|
@ -203,7 +203,8 @@ class _TopItemsScreenState extends State<TopItemsScreen> {
|
|||
logsProvider.setAppliedFilters(
|
||||
AppliedFiters(
|
||||
selectedResultStatus: 'all',
|
||||
searchText: screenData[index].keys.toList()[0]
|
||||
searchText: screenData[index].keys.toList()[0],
|
||||
clients: null
|
||||
)
|
||||
);
|
||||
Navigator.pop(context);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue