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,51 +70,49 @@ 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, children: [
decoration: BoxDecoration( Flexible(
borderRadius: const BorderRadius.only( child: SingleChildScrollView(
topLeft: Radius.circular(28), child: Wrap(
topRight: Radius.circular(28)
),
color: Theme.of(context).dialogBackgroundColor
),
child: Column(
children: [
Expanded(
child: ListView(
physics: (Platform.isIOS ? 426 : 410) < MediaQuery.of(context).size.height
? const NeverScrollableScrollPhysics()
: null,
children: [ children: [
Padding( Row(
padding: const EdgeInsets.only(top: 24), mainAxisAlignment: MainAxisAlignment.center,
child: Icon( children: [
widget.type == 'whitelist' Column(
? Icons.verified_user_rounded children: [
: Icons.gpp_bad_rounded, Padding(
size: 24, padding: const EdgeInsets.only(top: 24),
color: Theme.of(context).listTileTheme.iconColor child: Icon(
), widget.type == 'whitelist'
? Icons.verified_user_rounded
: Icons.gpp_bad_rounded,
size: 24,
color: Theme.of(context).listTileTheme.iconColor
),
),
const SizedBox(height: 16),
Text(
widget.list != null
? widget.type == 'whitelist'
? AppLocalizations.of(context)!.editWhitelist
: AppLocalizations.of(context)!.editBlacklist
: widget.type == 'whitelist'
? AppLocalizations.of(context)!.addWhitelist
: AppLocalizations.of(context)!.addBlacklist,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24,
color: Theme.of(context).colorScheme.onSurface
),
),
const SizedBox(height: 16),
],
),
],
), ),
const SizedBox(height: 16),
Text(
widget.list != null
? widget.type == 'whitelist'
? AppLocalizations.of(context)!.editWhitelist
: AppLocalizations.of(context)!.editBlacklist
: widget.type == 'whitelist'
? AppLocalizations.of(context)!.addWhitelist
: AppLocalizations.of(context)!.addBlacklist,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24,
color: Theme.of(context).colorScheme.onSurface
),
),
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,54 +151,80 @@ class _AddListModalState extends State<AddListModal> {
], ],
), ),
), ),
Padding( ),
padding: const EdgeInsets.all(24), Padding(
child: Row( padding: const EdgeInsets.all(24),
mainAxisAlignment: MainAxisAlignment.end, child: Row(
children: [ mainAxisAlignment: MainAxisAlignment.end,
TextButton( children: [
onPressed: () => Navigator.pop(context), TextButton(
child: Text(AppLocalizations.of(context)!.cancel) onPressed: () => Navigator.pop(context),
), child: Text(AppLocalizations.of(context)!.cancel)
const SizedBox(width: 20), ),
TextButton( const SizedBox(width: 20),
onPressed: () { TextButton(
Navigator.pop(context); onPressed: () {
if (widget.list != null) { Navigator.pop(context);
final Filter newList = Filter( if (widget.list != null) {
url: urlController.text, final Filter newList = Filter(
name: nameController.text, url: urlController.text,
lastUpdated: widget.list!.lastUpdated, name: nameController.text,
id: widget.list!.id, lastUpdated: widget.list!.lastUpdated,
rulesCount: widget.list!.rulesCount, id: widget.list!.id,
enabled: widget.list!.enabled rulesCount: widget.list!.rulesCount,
); enabled: widget.list!.enabled
widget.onEdit!( );
list: newList, widget.onEdit!(
type: widget.type list: newList,
); type: widget.type
} );
else { }
widget.onConfirm!( else {
name: nameController.text, widget.onConfirm!(
url: urlController.text, name: nameController.text,
type: widget.type url: urlController.text,
); type: widget.type
} );
}, }
child: Text( },
widget.list != null child: Text(
? AppLocalizations.of(context)!.save widget.list != null
: AppLocalizations.of(context)!.confirm ? AppLocalizations.of(context)!.save
) : AppLocalizations.of(context)!.confirm
), )
], ),
), ],
), ),
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,126 +122,141 @@ class _CheckHostModalState extends State<CheckHostModal> {
} }
} }
return Padding( Widget content() {
padding: MediaQuery.of(context).viewInsets, return Column(
child: Container( mainAxisSize: MainAxisSize.min,
height: 330, children: [
width: double.maxFinite, Flexible(
decoration: BoxDecoration( child: SingleChildScrollView(
borderRadius: const BorderRadius.only( child: Wrap(
topLeft: Radius.circular(28), children: [
topRight: Radius.circular(28), Row(
), mainAxisAlignment: MainAxisAlignment.center,
color: Theme.of(context).dialogBackgroundColor children: [
), Column(
child: Center( children: [
child: Column( Padding(
children: [ padding: const EdgeInsets.only(top: 24),
Expanded( child: Icon(
child: ListView( Icons.shield_rounded,
physics: 350 < MediaQuery.of(context).size.height size: 24,
? const NeverScrollableScrollPhysics() color: Theme.of(context).listTileTheme.iconColor
: null, ),
children: [
Padding(
padding: const EdgeInsets.only(top: 24),
child: Icon(
Icons.shield_rounded,
size: 24,
color: Theme.of(context).listTileTheme.iconColor
),
),
const SizedBox(height: 16),
Text(
AppLocalizations.of(context)!.checkHostFiltered,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24,
color: Theme.of(context).colorScheme.onSurface
),
),
const SizedBox(height: 16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: domainController,
onChanged: validateDomain,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.link_rounded),
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(10)
)
), ),
errorText: domainError, const SizedBox(height: 16),
labelText: AppLocalizations.of(context)!.domain, Text(
AppLocalizations.of(context)!.checkHostFiltered,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24,
color: Theme.of(context).colorScheme.onSurface
),
),
const SizedBox(height: 16),
],
),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
controller: domainController,
onChanged: validateDomain,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.link_rounded),
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(10)
)
),
errorText: domainError,
labelText: AppLocalizations.of(context)!.domain,
),
),
),
if (resultWidget != null) Padding(
padding: const EdgeInsets.all(24),
child: resultWidget,
),
if (resultWidget == null) Padding(
padding: const EdgeInsets.all(24),
child: Center(
child: Text(
AppLocalizations.of(context)!.insertDomain,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 16,
), ),
), ),
), ),
if (resultWidget != null) Padding( ),
padding: const EdgeInsets.only( ],
top: 20, ),
left: 20, ),
right: 20 ),
), Column(
child: resultWidget, mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.only(
bottom: 24,
right: 24
),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(AppLocalizations.of(context)!.close),
), ),
if (resultWidget == null) Padding( const SizedBox(width: 20),
padding: const EdgeInsets.only( TextButton(
top: 20, onPressed: domainController.text != '' && domainError == null
left: 20, ? () => checkHost()
right: 20 : null,
), child: Text(
child: Center( AppLocalizations.of(context)!.check,
child: Text( style: TextStyle(
AppLocalizations.of(context)!.insertDomain, color: domainController.text != '' && domainError == null
style: const TextStyle( ? Theme.of(context).colorScheme.primary
fontSize: 16, : Colors.grey
),
), ),
), ),
), ),
], ],
), ),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.only(
bottom: 24,
right: 24
),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(AppLocalizations.of(context)!.close),
),
const SizedBox(width: 20),
TextButton(
onPressed: domainController.text != '' && domainError == null
? () => checkHost()
: null,
child: Text(
AppLocalizations.of(context)!.check,
style: TextStyle(
color: domainController.text != '' && domainError == null
? Theme.of(context).colorScheme.primary
: Colors.grey
),
),
),
],
),
)
],
) )
], ],
)
],
);
}
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,15 +158,28 @@ class FiltersFab extends StatelessWidget {
} }
void openAddWhitelistBlacklist() { void openAddWhitelistBlacklist() {
showModalBottomSheet( if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
context: context, showDialog(
builder: (ctx) => AddListModal( context: context,
type: type, builder: (ctx) => AddListModal(
onConfirm: confirmAddList, type: type,
), onConfirm: confirmAddList,
isScrollControlled: true, dialog: true,
backgroundColor: Colors.transparent ),
); );
}
else {
showModalBottomSheet(
context: context,
builder: (ctx) => AddListModal(
type: type,
onConfirm: confirmAddList,
dialog: false,
),
isScrollControlled: true,
backgroundColor: Colors.transparent
);
}
} }
return FloatingActionButton( return FloatingActionButton(

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), () {
showModalBottomSheet( if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
context: context, showDialog(
builder: (context) => const CheckHostModal(), context: context,
backgroundColor: Colors.transparent, builder: (context) => const CheckHostModal(
isScrollControlled: true, dialog: true,
); ),
);
}
else {
showModalBottomSheet(
context: context,
builder: (context) => const CheckHostModal(
dialog: false,
),
backgroundColor: Colors.transparent,
isScrollControlled: true,
);
}
}); });
} }
@ -279,15 +295,28 @@ class _FiltersWidgetState extends State<FiltersWidget> with TickerProviderStateM
), ),
IconButton( IconButton(
onPressed: () { onPressed: () {
showModalBottomSheet( if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
context: context, showDialog(
builder: (context) => UpdateIntervalListsModal( context: context,
interval: serversProvider.filtering.data!.interval, builder: (context) => UpdateIntervalListsModal(
onChange: setUpdateFrequency interval: serversProvider.filtering.data!.interval,
), onChange: setUpdateFrequency,
backgroundColor: Colors.transparent, dialog: true,
isScrollControlled: true ),
); );
}
else {
showModalBottomSheet(
context: context,
builder: (context) => UpdateIntervalListsModal(
interval: serversProvider.filtering.data!.interval,
onChange: setUpdateFrequency,
dialog: false,
),
backgroundColor: Colors.transparent,
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: () => {
showModalBottomSheet( if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
context: context, showDialog(
builder: (ctx) => AddListModal( context: context,
list: widget.list, builder: (ctx) => AddListModal(
type: widget.type, list: widget.list,
onEdit: confirmEditList type: widget.type,
), onEdit: confirmEditList,
isScrollControlled: true, dialog: true,
backgroundColor: Colors.transparent ),
) )
}
else {
showModalBottomSheet(
context: context,
builder: (ctx) => AddListModal(
list: widget.list,
type: widget.type,
onEdit: confirmEditList,
dialog: false,
),
isScrollControlled: true,
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
@ -37,272 +39,266 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
@override @override
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( mainAxisSize: MainAxisSize.min,
height: Platform.isIOS ? 406 : 390, children: [
decoration: BoxDecoration( Flexible(
color: Theme.of(context).dialogBackgroundColor, child: SingleChildScrollView(
borderRadius: const BorderRadius.only( child: Wrap(
topLeft: Radius.circular(28),
topRight: Radius.circular(28)
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ListView(
physics: (Platform.isIOS ? 426 : 410) < MediaQuery.of(context).size.height
? const NeverScrollableScrollPhysics()
: null,
children: [ children: [
Padding( Row(
padding: const EdgeInsets.only(top: 24), mainAxisAlignment: MainAxisAlignment.center,
child: Icon( children: [
Icons.update_rounded, Column(
size: 24,
color: Theme.of(context).listTileTheme.iconColor
),
),
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: [ children: [
Row( Padding(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, padding: const EdgeInsets.only(top: 24),
children: [ child: Icon(
Container( Icons.update_rounded,
width: (mediaQueryData.size.width-70)/2, size: 24,
margin: const EdgeInsets.only( color: Theme.of(context).listTileTheme.iconColor
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
child: Text(AppLocalizations.of(context)!.hour1),
),
),
),
),
],
), ),
Row( Container(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, padding: const EdgeInsets.symmetric(
children: [ horizontal: 24,
Container( vertical: 16
width: (mediaQueryData.size.width-70)/2, ),
margin: const EdgeInsets.only( child: Text(
top: 5, AppLocalizations.of(context)!.updateFrequency,
right: 5, textAlign: TextAlign.center,
bottom: 5 overflow: TextOverflow.ellipsis,
), style: TextStyle(
child: OptionBox( fontSize: 24,
optionsValue: selectedOption, color: Theme.of(context).colorScheme.onSurface
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
child: Text(AppLocalizations.of(context)!.days7),
),
),
),
),
],
), ),
], ],
), )
],
),
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(
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
child: Text(AppLocalizations.of(context)!.never),
),
),
),
),
),
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(left: 6),
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
child: Text(AppLocalizations.of(context)!.hour1),
),
),
),
),
),
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(right: 6),
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
child: Text(AppLocalizations.of(context)!.hours12),
),
),
),
),
),
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(left: 6),
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
child: Text(AppLocalizations.of(context)!.hours24),
),
),
),
),
),
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(right: 6),
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
child: Text(AppLocalizations.of(context)!.days3),
),
),
),
),
),
FractionallySizedBox(
widthFactor: 0.5,
child: Padding(
padding: const EdgeInsets.only(left: 6),
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).colorScheme.onInverseSurface
: Theme.of(context).colorScheme.onSurface
),
child: Text(AppLocalizations.of(context)!.days7),
),
),
),
),
),
],
), ),
), )
], ],
), ),
), ),
Padding( ),
padding: const EdgeInsets.all(24), Padding(
child: Row( padding: const EdgeInsets.all(24),
mainAxisAlignment: MainAxisAlignment.end, child: Row(
children: [ mainAxisAlignment: MainAxisAlignment.end,
TextButton( children: [
onPressed: () => Navigator.pop(context), TextButton(
child: Text(AppLocalizations.of(context)!.cancel), onPressed: () => Navigator.pop(context),
), child: Text(AppLocalizations.of(context)!.cancel),
const SizedBox(width: 20), ),
TextButton( const SizedBox(width: 20),
onPressed: selectedOption != null TextButton(
? () { onPressed: selectedOption != null
Navigator.pop(context); ? () {
widget.onChange(selectedOption!); Navigator.pop(context);
} widget.onChange(selectedOption!);
: null, }
style: ButtonStyle( : null,
overlayColor: MaterialStateProperty.all( style: ButtonStyle(
Theme.of(context).colorScheme.primary.withOpacity(0.1) overlayColor: MaterialStateProperty.all(
), Theme.of(context).colorScheme.primary.withOpacity(0.1)
foregroundColor: MaterialStateProperty.all( ),
selectedOption != null foregroundColor: MaterialStateProperty.all(
? Theme.of(context).colorScheme.primary selectedOption != null
: Colors.grey, ? Theme.of(context).colorScheme.primary
), : Colors.grey,
), ),
child: Text(AppLocalizations.of(context)!.confirm), ),
), child: Text(AppLocalizations.of(context)!.confirm),
], ),
), ],
), ),
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()
),
);
}
} }
} }