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 void Function({required String name, required String url, required String type})? onConfirm;
final void Function({required Filter list, required String type})? onEdit;
final bool dialog;
const AddListModal({
Key? key,
@ -17,6 +18,7 @@ class AddListModal extends StatefulWidget {
this.list,
this.onConfirm,
this.onEdit,
required this.dialog
}) : super(key: key);
@override
@ -68,51 +70,49 @@ class _AddListModalState extends State<AddListModal> {
@override
Widget build(BuildContext context) {
return Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
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: [
Expanded(
child: ListView(
physics: (Platform.isIOS ? 426 : 410) < MediaQuery.of(context).size.height
? const NeverScrollableScrollPhysics()
: null,
Widget content() {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: SingleChildScrollView(
child: Wrap(
children: [
Padding(
padding: const EdgeInsets.only(top: 24),
child: Icon(
widget.type == 'whitelist'
? Icons.verified_user_rounded
: Icons.gpp_bad_rounded,
size: 24,
color: Theme.of(context).listTileTheme.iconColor
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 24),
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: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
@ -129,7 +129,7 @@ class _AddListModalState extends State<AddListModal> {
),
),
),
const SizedBox(height: 30),
Container(height: 30),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: TextFormField(
@ -151,54 +151,80 @@ class _AddListModalState extends State<AddListModal> {
],
),
),
Padding(
padding: const EdgeInsets.all(24),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(AppLocalizations.of(context)!.cancel)
),
const SizedBox(width: 20),
TextButton(
onPressed: () {
Navigator.pop(context);
if (widget.list != null) {
final Filter newList = Filter(
url: urlController.text,
name: nameController.text,
lastUpdated: widget.list!.lastUpdated,
id: widget.list!.id,
rulesCount: widget.list!.rulesCount,
enabled: widget.list!.enabled
);
widget.onEdit!(
list: newList,
type: widget.type
);
}
else {
widget.onConfirm!(
name: nameController.text,
url: urlController.text,
type: widget.type
);
}
},
child: Text(
widget.list != null
? AppLocalizations.of(context)!.save
: AppLocalizations.of(context)!.confirm
)
),
],
),
),
Padding(
padding: const EdgeInsets.all(24),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(AppLocalizations.of(context)!.cancel)
),
const SizedBox(width: 20),
TextButton(
onPressed: () {
Navigator.pop(context);
if (widget.list != null) {
final Filter newList = Filter(
url: urlController.text,
name: nameController.text,
lastUpdated: widget.list!.lastUpdated,
id: widget.list!.id,
rulesCount: widget.list!.rulesCount,
enabled: widget.list!.enabled
);
widget.onEdit!(
list: newList,
type: widget.type
);
}
else {
widget.onConfirm!(
name: nameController.text,
url: urlController.text,
type: widget.type
);
}
},
child: Text(
widget.list != null
? 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';
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
State<CheckHostModal> createState() => _CheckHostModalState();
@ -117,126 +122,141 @@ class _CheckHostModalState extends State<CheckHostModal> {
}
}
return Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
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: [
Expanded(
child: ListView(
physics: 350 < MediaQuery.of(context).size.height
? const NeverScrollableScrollPhysics()
: 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)
)
Widget content() {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: SingleChildScrollView(
child: Wrap(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 24),
child: Icon(
Icons.shield_rounded,
size: 24,
color: Theme.of(context).listTileTheme.iconColor
),
),
errorText: domainError,
labelText: AppLocalizations.of(context)!.domain,
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,
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
),
child: resultWidget,
),
],
),
),
),
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),
),
if (resultWidget == null) Padding(
padding: const EdgeInsets.only(
top: 20,
left: 20,
right: 20
),
child: Center(
child: Text(
AppLocalizations.of(context)!.insertDomain,
style: const TextStyle(
fontSize: 16,
),
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
),
),
),
],
),
),
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
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.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 appConfigProvider = Provider.of<AppConfigProvider>(context);
final width = MediaQuery.of(context).size.width;
void confirmAddRule(String rule) async {
ProcessModal processModal = ProcessModal(context: context);
processModal.open(AppLocalizations.of(context)!.addingRule);
@ -154,15 +158,28 @@ class FiltersFab extends StatelessWidget {
}
void openAddWhitelistBlacklist() {
showModalBottomSheet(
context: context,
builder: (ctx) => AddListModal(
type: type,
onConfirm: confirmAddList,
),
isScrollControlled: true,
backgroundColor: Colors.transparent
);
if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
showDialog(
context: context,
builder: (ctx) => AddListModal(
type: type,
onConfirm: confirmAddList,
dialog: true,
),
);
}
else {
showModalBottomSheet(
context: context,
builder: (ctx) => AddListModal(
type: type,
onConfirm: confirmAddList,
dialog: false,
),
isScrollControlled: true,
backgroundColor: Colors.transparent
);
}
}
return FloatingActionButton(

View file

@ -1,5 +1,7 @@
// ignore_for_file: use_build_context_synchronously
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.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 appConfigProvider = Provider.of<AppConfigProvider>(context);
final width = MediaQuery.of(context).size.width;
void fetchUpdateLists() async {
ProcessModal processModal = ProcessModal(context: context);
processModal.open(AppLocalizations.of(context)!.updatingLists);
@ -139,12 +143,24 @@ class _FiltersWidgetState extends State<FiltersWidget> with TickerProviderStateM
void showCheckHostModal() {
Future.delayed(const Duration(seconds: 0), () {
showModalBottomSheet(
context: context,
builder: (context) => const CheckHostModal(),
backgroundColor: Colors.transparent,
isScrollControlled: true,
);
if (width > 700 || !(Platform.isAndroid || Platform.isIOS)) {
showDialog(
context: context,
builder: (context) => const CheckHostModal(
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(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) => UpdateIntervalListsModal(
interval: serversProvider.filtering.data!.interval,
onChange: setUpdateFrequency
),
backgroundColor: Colors.transparent,
isScrollControlled: true
);
if (width > 900 || !(Platform.isAndroid || Platform.isIOS)) {
showDialog(
context: context,
builder: (context) => UpdateIntervalListsModal(
interval: serversProvider.filtering.data!.interval,
onChange: setUpdateFrequency,
dialog: 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)
),
@ -329,20 +358,38 @@ class _FiltersWidgetState extends State<FiltersWidget> with TickerProviderStateM
] : [],
bottom: TabBar(
controller: tabController,
isScrollable: false,
isScrollable: true,
unselectedLabelColor: Theme.of(context).colorScheme.onSurfaceVariant,
tabs: [
Tab(
icon: const Icon(Icons.verified_user_rounded),
text: AppLocalizations.of(context)!.whitelists,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.verified_user_rounded),
const SizedBox(width: 8),
Text(AppLocalizations.of(context)!.whitelists,)
],
),
),
Tab(
icon: const Icon(Icons.gpp_bad_rounded),
text: AppLocalizations.of(context)!.blacklist,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.gpp_bad_rounded),
const SizedBox(width: 8),
Text(AppLocalizations.of(context)!.blacklists)
],
),
),
Tab(
icon: const Icon(Icons.shield_rounded),
text: AppLocalizations.of(context)!.customRules,
child: Row(
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 appConfigProvider = Provider.of<AppConfigProvider>(context);
final width = MediaQuery.of(context).size.width;
void enableDisableList(Filter list, bool newStatus) async {
ProcessModal processModal = ProcessModal(context: context);
processModal.open(
@ -222,16 +224,30 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
actions: [
IconButton(
onPressed: () => {
showModalBottomSheet(
context: context,
builder: (ctx) => AddListModal(
list: widget.list,
type: widget.type,
onEdit: confirmEditList
),
isScrollControlled: true,
backgroundColor: Colors.transparent
)
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(
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),
tooltip: AppLocalizations.of(context)!.edit,

View file

@ -9,11 +9,13 @@ import 'package:adguard_home_manager/widgets/option_box.dart';
class UpdateIntervalListsModal extends StatefulWidget {
final int interval;
final void Function(int) onChange;
final bool dialog;
const UpdateIntervalListsModal({
Key? key,
required this.interval,
required this.onChange,
required this.dialog
}) : super(key: key);
@override
@ -37,272 +39,266 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
@override
Widget build(BuildContext context) {
final MediaQueryData mediaQueryData = MediaQuery.of(context);
final MediaQueryData mediaQueryData = MediaQuery.of(context);
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: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: ListView(
physics: (Platform.isIOS ? 426 : 410) < MediaQuery.of(context).size.height
? const NeverScrollableScrollPhysics()
: null,
Widget content() {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: SingleChildScrollView(
child: Wrap(
children: [
Padding(
padding: const EdgeInsets.only(top: 24),
child: Icon(
Icons.update_rounded,
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(
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: (mediaQueryData.size.width-70)/2,
margin: const EdgeInsets.only(
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),
),
),
),
),
],
Padding(
padding: const EdgeInsets.only(top: 24),
child: Icon(
Icons.update_rounded,
size: 24,
color: Theme.of(context).listTileTheme.iconColor
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: (mediaQueryData.size.width-70)/2,
margin: const EdgeInsets.only(
top: 5,
right: 5,
bottom: 5
),
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),
),
),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 24,
vertical: 16
),
child: Text(
AppLocalizations.of(context)!.updateFrequency,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 24,
color: Theme.of(context).colorScheme.onSurface
),
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),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(AppLocalizations.of(context)!.cancel),
),
const SizedBox(width: 20),
TextButton(
onPressed: selectedOption != null
? () {
Navigator.pop(context);
widget.onChange(selectedOption!);
}
: null,
style: ButtonStyle(
overlayColor: MaterialStateProperty.all(
Theme.of(context).colorScheme.primary.withOpacity(0.1)
),
foregroundColor: MaterialStateProperty.all(
selectedOption != null
? Theme.of(context).colorScheme.primary
: Colors.grey,
),
),
child: Text(AppLocalizations.of(context)!.confirm),
),
],
),
),
Padding(
padding: const EdgeInsets.all(24),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text(AppLocalizations.of(context)!.cancel),
),
const SizedBox(width: 20),
TextButton(
onPressed: selectedOption != null
? () {
Navigator.pop(context);
widget.onChange(selectedOption!);
}
: null,
style: ButtonStyle(
overlayColor: MaterialStateProperty.all(
Theme.of(context).colorScheme.primary.withOpacity(0.1)
),
foregroundColor: MaterialStateProperty.all(
selectedOption != null
? Theme.of(context).colorScheme.primary
: Colors.grey,
),
),
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()
),
);
}
}
}