Adapted modals filters

This commit is contained in:
Juan Gilsanz Polo 2023-05-02 18:03:16 +02:00
parent 9b2f5f7aba
commit 2afbaf1f93
6 changed files with 616 additions and 494 deletions

View file

@ -10,6 +10,7 @@ class AddListModal extends StatefulWidget {
final Filter? list; final Filter? list;
final void Function({required String name, required String url, required String type})? onConfirm; final void Function({required String name, required String url, required String type})? onConfirm;
final void Function({required Filter list, required String type})? onEdit; final void Function({required Filter list, required String type})? onEdit;
final bool dialog;
const AddListModal({ const AddListModal({
Key? key, Key? key,
@ -17,6 +18,7 @@ class AddListModal extends StatefulWidget {
this.list, this.list,
this.onConfirm, this.onConfirm,
this.onEdit, this.onEdit,
required this.dialog
}) : super(key: key); }) : super(key: key);
@override @override
@ -68,24 +70,18 @@ class _AddListModalState extends State<AddListModal> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Padding( Widget content() {
padding: MediaQuery.of(context).viewInsets, return Column(
child: Container( mainAxisSize: MainAxisSize.min,
height: Platform.isIOS ? 386 : 370,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28)
),
color: Theme.of(context).dialogBackgroundColor
),
child: Column(
children: [ children: [
Expanded( Flexible(
child: ListView( child: SingleChildScrollView(
physics: (Platform.isIOS ? 426 : 410) < MediaQuery.of(context).size.height child: Wrap(
? const NeverScrollableScrollPhysics() children: [
: null, Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.only(top: 24), padding: const EdgeInsets.only(top: 24),
@ -113,6 +109,10 @@ class _AddListModalState extends State<AddListModal> {
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
],
),
],
),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 24), padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField( child: TextFormField(
@ -129,7 +129,7 @@ class _AddListModalState extends State<AddListModal> {
), ),
), ),
), ),
const SizedBox(height: 30), Container(height: 30),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 24), padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField( child: TextFormField(
@ -151,6 +151,7 @@ class _AddListModalState extends State<AddListModal> {
], ],
), ),
), ),
),
Padding( Padding(
padding: const EdgeInsets.all(24), padding: const EdgeInsets.all(24),
child: Row( child: Row(
@ -197,8 +198,33 @@ class _AddListModalState extends State<AddListModal> {
), ),
if (Platform.isIOS) const SizedBox(height: 16) if (Platform.isIOS) const SizedBox(height: 16)
], ],
);
}
if (widget.dialog == true) {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 400
), ),
child: content()
),
);
}
else {
return Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28)
),
color: Theme.of(context).dialogBackgroundColor
),
child: content()
), ),
); );
} }
} }
}

View file

@ -10,7 +10,12 @@ import 'package:adguard_home_manager/services/http_requests.dart';
import 'package:adguard_home_manager/providers/servers_provider.dart'; import 'package:adguard_home_manager/providers/servers_provider.dart';
class CheckHostModal extends StatefulWidget { class CheckHostModal extends StatefulWidget {
const CheckHostModal({Key? key}) : super(key: key); final bool dialog;
const CheckHostModal({
Key? key,
required this.dialog
}) : super(key: key);
@override @override
State<CheckHostModal> createState() => _CheckHostModalState(); State<CheckHostModal> createState() => _CheckHostModalState();
@ -117,26 +122,18 @@ class _CheckHostModalState extends State<CheckHostModal> {
} }
} }
return Padding( Widget content() {
padding: MediaQuery.of(context).viewInsets, return Column(
child: Container( mainAxisSize: MainAxisSize.min,
height: 330,
width: double.maxFinite,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28),
),
color: Theme.of(context).dialogBackgroundColor
),
child: Center(
child: Column(
children: [ children: [
Expanded( Flexible(
child: ListView( child: SingleChildScrollView(
physics: 350 < MediaQuery.of(context).size.height child: Wrap(
? const NeverScrollableScrollPhysics() children: [
: null, Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.only(top: 24), padding: const EdgeInsets.only(top: 24),
@ -156,6 +153,10 @@ class _CheckHostModalState extends State<CheckHostModal> {
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
],
),
],
),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 24), padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField( child: TextFormField(
@ -174,22 +175,15 @@ class _CheckHostModalState extends State<CheckHostModal> {
), ),
), ),
if (resultWidget != null) Padding( if (resultWidget != null) Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.all(24),
top: 20,
left: 20,
right: 20
),
child: resultWidget, child: resultWidget,
), ),
if (resultWidget == null) Padding( if (resultWidget == null) Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.all(24),
top: 20,
left: 20,
right: 20
),
child: Center( child: Center(
child: Text( child: Text(
AppLocalizations.of(context)!.insertDomain, AppLocalizations.of(context)!.insertDomain,
textAlign: TextAlign.center,
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
), ),
@ -199,6 +193,7 @@ class _CheckHostModalState extends State<CheckHostModal> {
], ],
), ),
), ),
),
Column( Column(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
@ -234,9 +229,34 @@ class _CheckHostModalState extends State<CheckHostModal> {
], ],
) )
], ],
);
}
if (widget.dialog == true) {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 400
), ),
child: content()
), ),
);
}
else {
return Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
width: double.maxFinite,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28),
),
color: Theme.of(context).dialogBackgroundColor
),
child: content()
), ),
); );
} }
} }
}

View file

@ -1,5 +1,7 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -28,6 +30,8 @@ class FiltersFab extends StatelessWidget {
final serversProvider = Provider.of<ServersProvider>(context); final serversProvider = Provider.of<ServersProvider>(context);
final appConfigProvider = Provider.of<AppConfigProvider>(context); final appConfigProvider = Provider.of<AppConfigProvider>(context);
final width = MediaQuery.of(context).size.width;
void confirmAddRule(String rule) async { void confirmAddRule(String rule) async {
ProcessModal processModal = ProcessModal(context: context); ProcessModal processModal = ProcessModal(context: context);
processModal.open(AppLocalizations.of(context)!.addingRule); processModal.open(AppLocalizations.of(context)!.addingRule);
@ -154,16 +158,29 @@ class FiltersFab extends StatelessWidget {
} }
void openAddWhitelistBlacklist() { void openAddWhitelistBlacklist() {
if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
showDialog(
context: context,
builder: (ctx) => AddListModal(
type: type,
onConfirm: confirmAddList,
dialog: true,
),
);
}
else {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
builder: (ctx) => AddListModal( builder: (ctx) => AddListModal(
type: type, type: type,
onConfirm: confirmAddList, onConfirm: confirmAddList,
dialog: false,
), ),
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Colors.transparent backgroundColor: Colors.transparent
); );
} }
}
return FloatingActionButton( return FloatingActionButton(
onPressed: type == 'blacklist' || type == 'whitelist' onPressed: type == 'blacklist' || type == 'whitelist'

View file

@ -1,5 +1,7 @@
// ignore_for_file: use_build_context_synchronously // ignore_for_file: use_build_context_synchronously
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -89,6 +91,8 @@ class _FiltersWidgetState extends State<FiltersWidget> with TickerProviderStateM
final serversProvider = Provider.of<ServersProvider>(context); final serversProvider = Provider.of<ServersProvider>(context);
final appConfigProvider = Provider.of<AppConfigProvider>(context); final appConfigProvider = Provider.of<AppConfigProvider>(context);
final width = MediaQuery.of(context).size.width;
void fetchUpdateLists() async { void fetchUpdateLists() async {
ProcessModal processModal = ProcessModal(context: context); ProcessModal processModal = ProcessModal(context: context);
processModal.open(AppLocalizations.of(context)!.updatingLists); processModal.open(AppLocalizations.of(context)!.updatingLists);
@ -139,12 +143,24 @@ class _FiltersWidgetState extends State<FiltersWidget> with TickerProviderStateM
void showCheckHostModal() { void showCheckHostModal() {
Future.delayed(const Duration(seconds: 0), () { Future.delayed(const Duration(seconds: 0), () {
if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
showDialog(
context: context,
builder: (context) => const CheckHostModal(
dialog: true,
),
);
}
else {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
builder: (context) => const CheckHostModal(), builder: (context) => const CheckHostModal(
dialog: false,
),
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
isScrollControlled: true, isScrollControlled: true,
); );
}
}); });
} }
@ -279,15 +295,28 @@ class _FiltersWidgetState extends State<FiltersWidget> with TickerProviderStateM
), ),
IconButton( IconButton(
onPressed: () { onPressed: () {
if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
showDialog(
context: context,
builder: (context) => UpdateIntervalListsModal(
interval: serversProvider.filtering.data!.interval,
onChange: setUpdateFrequency,
dialog: true,
),
);
}
else {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
builder: (context) => UpdateIntervalListsModal( builder: (context) => UpdateIntervalListsModal(
interval: serversProvider.filtering.data!.interval, interval: serversProvider.filtering.data!.interval,
onChange: setUpdateFrequency onChange: setUpdateFrequency,
dialog: false,
), ),
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
isScrollControlled: true isScrollControlled: true
); );
}
}, },
icon: const Icon(Icons.update_rounded) icon: const Icon(Icons.update_rounded)
), ),
@ -329,20 +358,38 @@ class _FiltersWidgetState extends State<FiltersWidget> with TickerProviderStateM
] : [], ] : [],
bottom: TabBar( bottom: TabBar(
controller: tabController, controller: tabController,
isScrollable: false, isScrollable: true,
unselectedLabelColor: Theme.of(context).colorScheme.onSurfaceVariant, unselectedLabelColor: Theme.of(context).colorScheme.onSurfaceVariant,
tabs: [ tabs: [
Tab( Tab(
icon: const Icon(Icons.verified_user_rounded), child: Row(
text: AppLocalizations.of(context)!.whitelists, mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.verified_user_rounded),
const SizedBox(width: 8),
Text(AppLocalizations.of(context)!.whitelists,)
],
),
), ),
Tab( Tab(
icon: const Icon(Icons.gpp_bad_rounded), child: Row(
text: AppLocalizations.of(context)!.blacklist, mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.gpp_bad_rounded),
const SizedBox(width: 8),
Text(AppLocalizations.of(context)!.blacklists)
],
),
), ),
Tab( Tab(
icon: const Icon(Icons.shield_rounded), child: Row(
text: AppLocalizations.of(context)!.customRules, mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.shield_rounded),
const SizedBox(width: 8),
Text(AppLocalizations.of(context)!.customRules)
],
),
), ),
] ]
) )

View file

@ -68,6 +68,8 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
final serversProvider = Provider.of<ServersProvider>(context); final serversProvider = Provider.of<ServersProvider>(context);
final appConfigProvider = Provider.of<AppConfigProvider>(context); final appConfigProvider = Provider.of<AppConfigProvider>(context);
final width = MediaQuery.of(context).size.width;
void enableDisableList(Filter list, bool newStatus) async { void enableDisableList(Filter list, bool newStatus) async {
ProcessModal processModal = ProcessModal(context: context); ProcessModal processModal = ProcessModal(context: context);
processModal.open( processModal.open(
@ -222,16 +224,30 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
actions: [ actions: [
IconButton( IconButton(
onPressed: () => { onPressed: () => {
if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
showDialog(
context: context,
builder: (ctx) => AddListModal(
list: widget.list,
type: widget.type,
onEdit: confirmEditList,
dialog: true,
),
)
}
else {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
builder: (ctx) => AddListModal( builder: (ctx) => AddListModal(
list: widget.list, list: widget.list,
type: widget.type, type: widget.type,
onEdit: confirmEditList onEdit: confirmEditList,
dialog: false,
), ),
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Colors.transparent backgroundColor: Colors.transparent
) )
}
}, },
icon: const Icon(Icons.edit), icon: const Icon(Icons.edit),
tooltip: AppLocalizations.of(context)!.edit, tooltip: AppLocalizations.of(context)!.edit,

View file

@ -9,11 +9,13 @@ import 'package:adguard_home_manager/widgets/option_box.dart';
class UpdateIntervalListsModal extends StatefulWidget { class UpdateIntervalListsModal extends StatefulWidget {
final int interval; final int interval;
final void Function(int) onChange; final void Function(int) onChange;
final bool dialog;
const UpdateIntervalListsModal({ const UpdateIntervalListsModal({
Key? key, Key? key,
required this.interval, required this.interval,
required this.onChange, required this.onChange,
required this.dialog
}) : super(key: key); }) : super(key: key);
@override @override
@ -39,25 +41,18 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final MediaQueryData mediaQueryData = MediaQuery.of(context); final MediaQueryData mediaQueryData = MediaQuery.of(context);
return Padding( Widget content() {
padding: mediaQueryData.viewInsets, return Column(
child: Container(
height: Platform.isIOS ? 406 : 390,
decoration: BoxDecoration(
color: Theme.of(context).dialogBackgroundColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28)
),
),
child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Expanded( Flexible(
child: ListView( child: SingleChildScrollView(
physics: (Platform.isIOS ? 426 : 410) < MediaQuery.of(context).size.height child: Wrap(
? const NeverScrollableScrollPhysics() children: [
: null, Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.only(top: 24), padding: const EdgeInsets.only(top: 24),
@ -72,7 +67,6 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
horizontal: 24, horizontal: 24,
vertical: 16 vertical: 16
), ),
width: double.maxFinite,
child: Text( child: Text(
AppLocalizations.of(context)!.updateFrequency, AppLocalizations.of(context)!.updateFrequency,
textAlign: TextAlign.center, textAlign: TextAlign.center,
@ -83,22 +77,19 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
), ),
), ),
), ),
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
), ),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Wrap(
runSpacing: 16,
children: [
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(right: 6),
child: OptionBox( child: OptionBox(
optionsValue: selectedOption, optionsValue: selectedOption,
itemValue: 0, itemValue: 0,
@ -118,13 +109,11 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
), ),
), ),
), ),
Container(
width: (mediaQueryData.size.width-70)/2,
margin: const EdgeInsets.only(
top: 10,
left: 5,
bottom: 5
), ),
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(left: 6),
child: OptionBox( child: OptionBox(
optionsValue: selectedOption, optionsValue: selectedOption,
itemValue: 1, itemValue: 1,
@ -144,18 +133,11 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
), ),
), ),
), ),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: (mediaQueryData.size.width-70)/2,
margin: const EdgeInsets.only(
top: 5,
right: 5,
bottom: 5
), ),
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(right: 6),
child: OptionBox( child: OptionBox(
optionsValue: selectedOption, optionsValue: selectedOption,
itemValue: 12, itemValue: 12,
@ -175,13 +157,11 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
), ),
), ),
), ),
Container(
width: (mediaQueryData.size.width-70)/2,
margin: const EdgeInsets.only(
top: 5,
left: 5,
bottom: 5
), ),
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(left: 6),
child: OptionBox( child: OptionBox(
optionsValue: selectedOption, optionsValue: selectedOption,
itemValue: 24, itemValue: 24,
@ -201,18 +181,11 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
), ),
), ),
), ),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: (mediaQueryData.size.width-70)/2,
margin: const EdgeInsets.only(
top: 5,
right: 5,
bottom: 10
), ),
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(right: 6),
child: OptionBox( child: OptionBox(
optionsValue: selectedOption, optionsValue: selectedOption,
itemValue: 72, itemValue: 72,
@ -232,13 +205,11 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
), ),
), ),
), ),
Container(
width: (mediaQueryData.size.width-70)/2,
margin: const EdgeInsets.only(
top: 5,
left: 5,
bottom: 10
), ),
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(left: 6),
child: OptionBox( child: OptionBox(
optionsValue: selectedOption, optionsValue: selectedOption,
itemValue: 168, itemValue: 168,
@ -258,15 +229,14 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
), ),
), ),
), ),
],
), ),
], ],
), ),
), )
),
], ],
), ),
), ),
),
Padding( Padding(
padding: const EdgeInsets.all(24), padding: const EdgeInsets.all(24),
child: Row( child: Row(
@ -301,8 +271,34 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
), ),
if (Platform.isIOS) const SizedBox(height: 16) if (Platform.isIOS) const SizedBox(height: 16)
], ],
);
}
if (widget.dialog == true) {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 500
), ),
child: content()
),
);
}
else {
return Padding(
padding: mediaQueryData.viewInsets,
child: Container(
height: Platform.isIOS ? 406 : 390,
decoration: BoxDecoration(
color: Theme.of(context).dialogBackgroundColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28)
),
),
child: content()
), ),
); );
} }
} }
}