mirror of
https://github.com/JGeek00/adguard-home-manager.git
synced 2025-06-05 22:30:15 +00:00
Added sorting options custom rules
This commit is contained in:
parent
47b5313bf3
commit
10ff5183f1
5 changed files with 161 additions and 8 deletions
|
@ -1,2 +1,3 @@
|
||||||
enum LoadStatus { loading, loaded, error }
|
enum LoadStatus { loading, loaded, error }
|
||||||
enum HomeTopItems { queriedDomains, blockedDomains, recurrentClients, topUpstreams, avgUpstreamResponseTime }
|
enum HomeTopItems { queriedDomains, blockedDomains, recurrentClients, topUpstreams, avgUpstreamResponseTime }
|
||||||
|
enum CustomRulesSorting { topBottom, bottomTop }
|
|
@ -801,5 +801,7 @@
|
||||||
"applicationDetails": "Application details",
|
"applicationDetails": "Application details",
|
||||||
"applicationDetailsDescription": "App repository, stores where it's available, and more",
|
"applicationDetailsDescription": "App repository, stores where it's available, and more",
|
||||||
"myOtherApps": "Check my other apps",
|
"myOtherApps": "Check my other apps",
|
||||||
"myOtherAppsDescription": "Created by JGeek00"
|
"myOtherAppsDescription": "Created by JGeek00",
|
||||||
|
"topToBottom": "From top to bottom",
|
||||||
|
"bottomToTop": "From bottom to top"
|
||||||
}
|
}
|
|
@ -801,5 +801,7 @@
|
||||||
"applicationDetails": "Detalles de la aplicación",
|
"applicationDetails": "Detalles de la aplicación",
|
||||||
"applicationDetailsDescription": "Repositorio de la app, tiendas donde está disponible, y más",
|
"applicationDetailsDescription": "Repositorio de la app, tiendas donde está disponible, y más",
|
||||||
"myOtherApps": "Comprueba mis otras apps",
|
"myOtherApps": "Comprueba mis otras apps",
|
||||||
"myOtherAppsDescription": "Creadas por JGeek00"
|
"myOtherAppsDescription": "Creadas por JGeek00",
|
||||||
|
"topToBottom": "Desde arriba hacia abajo",
|
||||||
|
"bottomToTop": "Desde abajo hacia arriba"
|
||||||
}
|
}
|
|
@ -6,6 +6,7 @@ import 'package:provider/provider.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/screens/filters/add_button.dart';
|
import 'package:adguard_home_manager/screens/filters/add_button.dart';
|
||||||
|
import 'package:adguard_home_manager/screens/filters/modals/custom_rules/sort_rules.dart';
|
||||||
import 'package:adguard_home_manager/widgets/tab_content_list.dart';
|
import 'package:adguard_home_manager/widgets/tab_content_list.dart';
|
||||||
|
|
||||||
import 'package:adguard_home_manager/functions/snackbar.dart';
|
import 'package:adguard_home_manager/functions/snackbar.dart';
|
||||||
|
@ -34,6 +35,8 @@ class CustomRulesList extends StatefulWidget {
|
||||||
class _CustomRulesListState extends State<CustomRulesList> {
|
class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
late bool isVisible;
|
late bool isVisible;
|
||||||
|
|
||||||
|
CustomRulesSorting _sortingMethod = CustomRulesSorting.topBottom;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
initState(){
|
initState(){
|
||||||
super.initState();
|
super.initState();
|
||||||
|
@ -60,6 +63,8 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
final filteringProvider = Provider.of<FilteringProvider>(context);
|
final filteringProvider = Provider.of<FilteringProvider>(context);
|
||||||
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
final appConfigProvider = Provider.of<AppConfigProvider>(context);
|
||||||
|
|
||||||
|
final renderData = _sortingMethod == CustomRulesSorting.bottomTop ? widget.data.reversed.toList() : widget.data.toList();
|
||||||
|
|
||||||
bool checkIfComment(String value) {
|
bool checkIfComment(String value) {
|
||||||
final regex = RegExp(r'^(!|#).*$');
|
final regex = RegExp(r'^(!|#).*$');
|
||||||
if (regex.hasMatch(value)) {
|
if (regex.hasMatch(value)) {
|
||||||
|
@ -104,6 +109,16 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showSortingMethodModal() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (ctx) => SortCustomRulesModal(
|
||||||
|
sortingMethod: _sortingMethod,
|
||||||
|
onSelect: (value) => setState(() => _sortingMethod = value),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return CustomTabContentList(
|
return CustomTabContentList(
|
||||||
loadingGenerator: () => SizedBox(
|
loadingGenerator: () => SizedBox(
|
||||||
width: double.maxFinite,
|
width: double.maxFinite,
|
||||||
|
@ -124,10 +139,10 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
itemsCount: widget.data.length,
|
itemsCount: renderData.length,
|
||||||
contentWidget: (index) => ListTile(
|
contentWidget: (index) => ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
widget.data[index],
|
renderData[index],
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: checkIfComment(widget.data[index]) == true
|
color: checkIfComment(widget.data[index]) == true
|
||||||
? Theme.of(context).colorScheme.onSurface.withOpacity(0.6)
|
? Theme.of(context).colorScheme.onSurface.withOpacity(0.6)
|
||||||
|
@ -135,9 +150,9 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
fontWeight: FontWeight.normal,
|
fontWeight: FontWeight.normal,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: generateSubtitle(widget.data[index]),
|
subtitle: generateSubtitle(renderData[index]),
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
onPressed: () => widget.onRemoveCustomRule(widget.data[index]),
|
onPressed: () => widget.onRemoveCustomRule(renderData[index]),
|
||||||
icon: const Icon(Icons.delete)
|
icon: const Icon(Icons.delete)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -212,6 +227,11 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
},
|
},
|
||||||
fab: Column(
|
fab: Column(
|
||||||
children: [
|
children: [
|
||||||
|
FloatingActionButton.small(
|
||||||
|
onPressed: showSortingMethodModal,
|
||||||
|
child: Icon(Icons.sort_rounded),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
AddFiltersButton(
|
AddFiltersButton(
|
||||||
type: 'edit_custom_rule',
|
type: 'edit_custom_rule',
|
||||||
widget: (fn) => FloatingActionButton.small(
|
widget: (fn) => FloatingActionButton.small(
|
||||||
|
@ -229,7 +249,7 @@ class _CustomRulesListState extends State<CustomRulesList> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
heightFabHidden: -120,
|
heightFabHidden: -180,
|
||||||
fabVisible: isVisible,
|
fabVisible: isVisible,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
128
lib/screens/filters/modals/custom_rules/sort_rules.dart
Normal file
128
lib/screens/filters/modals/custom_rules/sort_rules.dart
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
import 'package:adguard_home_manager/constants/enums.dart';
|
||||||
|
|
||||||
|
class SortCustomRulesModal extends StatelessWidget {
|
||||||
|
final CustomRulesSorting sortingMethod;
|
||||||
|
final void Function(CustomRulesSorting) onSelect;
|
||||||
|
|
||||||
|
const SortCustomRulesModal({
|
||||||
|
super.key,
|
||||||
|
required this.sortingMethod,
|
||||||
|
required this.onSelect,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
|
scrollable: true,
|
||||||
|
title: Column(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.sort_rounded,
|
||||||
|
size: 24,
|
||||||
|
color: Theme.of(context).listTileTheme.iconColor
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
AppLocalizations.of(context)!.sortingOptions,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.onSurface
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
content: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxWidth: 500
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_CustomListTileDialog(
|
||||||
|
title: AppLocalizations.of(context)!.topToBottom,
|
||||||
|
icon: Icons.arrow_downward_rounded,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
onSelect(CustomRulesSorting.topBottom);
|
||||||
|
},
|
||||||
|
isSelected: sortingMethod == CustomRulesSorting.topBottom
|
||||||
|
),
|
||||||
|
_CustomListTileDialog(
|
||||||
|
title: AppLocalizations.of(context)!.bottomToTop,
|
||||||
|
icon: Icons.arrow_upward_rounded,
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
onSelect(CustomRulesSorting.bottomTop);
|
||||||
|
},
|
||||||
|
isSelected: sortingMethod == CustomRulesSorting.bottomTop
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(AppLocalizations.of(context)!.close)
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CustomListTileDialog extends StatelessWidget {
|
||||||
|
final String title;
|
||||||
|
final IconData? icon;
|
||||||
|
final void Function()? onTap;
|
||||||
|
final bool isSelected;
|
||||||
|
|
||||||
|
const _CustomListTileDialog({
|
||||||
|
required this.title,
|
||||||
|
required this.icon,
|
||||||
|
required this.onTap,
|
||||||
|
required this.isSelected,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Material(
|
||||||
|
color: Colors.transparent,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
icon,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 24),
|
||||||
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 24),
|
||||||
|
Icon(
|
||||||
|
isSelected == true ? Icons.radio_button_checked_rounded : Icons.radio_button_unchecked_rounded,
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue