Changed system navigation bar color

This commit is contained in:
Juan Gilsanz Polo 2023-12-09 04:04:14 +01:00
parent 83ea589187
commit b164d520db
47 changed files with 3370 additions and 3207 deletions

View file

@ -2,6 +2,7 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:provider/provider.dart';
import 'package:flutter_displaymode/flutter_displaymode.dart';
@ -35,6 +36,7 @@ import 'package:adguard_home_manager/services/db/database.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
setWindowMinSize(const Size(500, 500));

View file

@ -185,7 +185,8 @@ class _ClientScreenState extends State<ClientScreen> {
),
actions: actions(),
),
body: ClientForm(
body: SafeArea(
child: ClientForm(
isFullScreen: true,
client: widget.client,
nameController: nameController,
@ -215,6 +216,7 @@ class _ClientScreenState extends State<ClientScreen> {
updateUseGlobalSettingsServices: (v) => setState(() => useGlobalSettingsServices = v),
),
),
),
);
}
else {

View file

@ -149,7 +149,8 @@ class _LogsListClientState extends State<LogsListClient> {
]
],
),
body: Builder(
body: SafeArea(
child: Builder(
builder: (context) {
switch (loadStatus) {
case 0:
@ -268,6 +269,7 @@ class _LogsListClientState extends State<LogsListClient> {
return const SizedBox();
}
},
),
)
);
}

View file

@ -11,7 +11,7 @@ import 'package:adguard_home_manager/providers/servers_provider.dart';
import 'package:adguard_home_manager/providers/app_config_provider.dart';
class Connect extends StatefulWidget {
const Connect({Key? key}) : super(key: key);
const Connect({super.key});
@override
State<Connect> createState() => _ConnectState();
@ -61,7 +61,8 @@ class _ConnectState extends State<Connect> {
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.connect),
),
body: Stack(
body: SafeArea(
child: Stack(
children: [
ServersList(
context: context,
@ -75,13 +76,14 @@ class _ConnectState extends State<Connect> {
curve: Curves.easeInOut,
bottom: isVisible ?
appConfigProvider.showingSnackbar
? 70 : 20
: -70,
? 90 : 20
: -90,
right: 20,
child: const FabConnect()
)
],
),
),
);
}
}

View file

@ -5,7 +5,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/models/filtering.dart';
class AddListModal extends StatefulWidget {
class AddListModal extends StatelessWidget {
final String type;
final Filter? list;
final void Function({required String name, required String url, required String type})? onConfirm;
@ -13,19 +13,74 @@ class AddListModal extends StatefulWidget {
final bool dialog;
const AddListModal({
Key? key,
super.key,
required this.type,
this.list,
this.onConfirm,
this.onEdit,
required this.dialog
}) : super(key: key);
});
@override
State<AddListModal> createState() => _AddListModalState();
Widget build(BuildContext context) {
if (dialog == true) {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 400
),
child: _Content(
list: list,
onConfirm: onConfirm,
onEdit: onEdit,
type: type,
)
),
);
}
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: SafeArea(
child: _Content(
list: list,
onConfirm: onConfirm,
onEdit: onEdit,
type: type,
),
)
),
);
}
}
}
class _AddListModalState extends State<AddListModal> {
class _Content extends StatefulWidget {
final String type;
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;
const _Content({
required this.type,
required this.list,
required this.onConfirm,
required this.onEdit,
});
@override
State<_Content> createState() => _ContentState();
}
class _ContentState extends State<_Content> {
final TextEditingController nameController = TextEditingController();
final TextEditingController urlController = TextEditingController();
String? urlError;
@ -70,7 +125,6 @@ class _AddListModalState extends State<AddListModal> {
@override
Widget build(BuildContext context) {
Widget content() {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
@ -200,31 +254,4 @@ class _AddListModalState extends State<AddListModal> {
],
);
}
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

@ -8,19 +8,55 @@ import 'package:adguard_home_manager/providers/app_config_provider.dart';
import 'package:adguard_home_manager/functions/get_filtered_status.dart';
import 'package:adguard_home_manager/providers/servers_provider.dart';
class CheckHostModal extends StatefulWidget {
class CheckHostModal extends StatelessWidget {
final bool dialog;
const CheckHostModal({
Key? key,
super.key,
required this.dialog
}) : super(key: key);
});
@override
State<CheckHostModal> createState() => _CheckHostModalState();
Widget build(BuildContext context) {
if (dialog == true) {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 400
),
child: const _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: const SafeArea(
child: _Content()
)
),
);
}
}
}
class _CheckHostModalState extends State<CheckHostModal> {
class _Content extends StatefulWidget {
const _Content();
@override
State<_Content> createState() => _ContentState();
}
class _ContentState extends State<_Content> {
final TextEditingController domainController = TextEditingController();
String? domainError;
@ -59,8 +95,8 @@ class _CheckHostModalState extends State<CheckHostModal> {
setState(() => resultWidget = checking());
final result = await serversProvider.apiClient2!.checkHostFiltered(host: domainController.text);
if (!mounted) return;
if (mounted) {
if (result.successful == true) {
final status = getFilteredStatus(context, appConfigProvider, result.content['reason'], true);
if (mounted) {
@ -117,9 +153,7 @@ class _CheckHostModalState extends State<CheckHostModal> {
));
}
}
}
Widget content() {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
@ -228,32 +262,4 @@ 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

@ -25,11 +25,11 @@ class ListDetailsScreen extends StatefulWidget {
final bool dialog;
const ListDetailsScreen({
Key? key,
super.key,
required this.listId,
required this.type,
required this.dialog
}) : super(key: key);
});
@override
State<ListDetailsScreen> createState() => _ListDetailsScreenState();
@ -367,7 +367,8 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
title: Text(AppLocalizations.of(context)!.listDetails),
actions: list != null ? actions() : null,
),
body: Stack(
body: SafeArea(
child: Stack(
children: [
if (list != null) ListView(
children: content(),
@ -405,6 +406,7 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
],
),
),
),
);
}
}

View file

@ -10,10 +10,10 @@ class AddCustomRule extends StatefulWidget {
final bool fullScreen;
const AddCustomRule({
Key? key,
super.key,
required this.onConfirm,
required this.fullScreen
}) : super(key: key);
});
@override
State<AddCustomRule> createState() => _AddCustomRuleState();
@ -349,8 +349,10 @@ class _AddCustomRuleState extends State<AddCustomRule> {
const SizedBox(width: 10)
],
),
body: ListView(
body: SafeArea(
child: ListView(
children: content(),
),
)
),
);

View file

@ -17,9 +17,9 @@ class BlockedServicesScreen extends StatefulWidget {
final bool fullScreen;
const BlockedServicesScreen({
Key? key,
super.key,
required this.fullScreen
}) : super(key: key);
});
@override
State<BlockedServicesScreen> createState() => _BlockedServicesScreenStateWidget();
@ -83,7 +83,111 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreen> {
}
}
Widget body() {
if (widget.fullScreen == true) {
return Dialog.fullscreen(
child: Scaffold(
appBar: AppBar(
leading: CloseButton(onPressed: () => Navigator.pop(context)),
title: Text(AppLocalizations.of(context)!.blockedServices),
actions: [
IconButton(
onPressed: updateBlockedServices,
icon: const Icon(
Icons.save_rounded
),
tooltip: AppLocalizations.of(context)!.save,
),
const SizedBox(width: 10)
],
),
body: SafeArea(
child: RefreshIndicator(
onRefresh: () async {
final result = await filteringProvider.loadBlockedServices();
if (result == false) {
showSnacbkar(
appConfigProvider: appConfigProvider,
label: AppLocalizations.of(context)!.blockedServicesListNotLoaded,
color: Colors.red
);
}
},
child: _Content(
values: values,
updateValues: updateValues,
)
),
),
),
);
}
else {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 400
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
IconButton(
onPressed: () => Navigator.pop(context),
icon: const Icon(Icons.clear_rounded),
tooltip: AppLocalizations.of(context)!.close,
),
const SizedBox(width: 8),
Text(
AppLocalizations.of(context)!.blockedServices,
style: const TextStyle(
fontSize: 22
),
)
],
),
IconButton(
onPressed: updateBlockedServices,
icon: const Icon(
Icons.save_rounded
),
tooltip: AppLocalizations.of(context)!.save,
),
],
),
),
Expanded(
child: _Content(
values: values,
updateValues: updateValues,
)
),
],
)
),
);
}
}
}
class _Content extends StatelessWidget {
final List<String> values;
final void Function(bool value, BlockedService item) updateValues;
const _Content({
required this.values,
required this.updateValues,
});
@override
Widget build(BuildContext context) {
final filteringProvider = Provider.of<FilteringProvider>(context);
switch (filteringProvider.blockedServicesLoadStatus) {
case LoadStatus.loading:
return Container(
@ -181,89 +285,6 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreen> {
return const SizedBox();
}
}
if (widget.fullScreen == true) {
return Dialog.fullscreen(
child: Scaffold(
appBar: AppBar(
leading: CloseButton(onPressed: () => Navigator.pop(context)),
title: Text(AppLocalizations.of(context)!.blockedServices),
actions: [
IconButton(
onPressed: updateBlockedServices,
icon: const Icon(
Icons.save_rounded
),
tooltip: AppLocalizations.of(context)!.save,
),
const SizedBox(width: 10)
],
),
body: RefreshIndicator(
onRefresh: () async {
final result = await filteringProvider.loadBlockedServices();
if (result == false) {
showSnacbkar(
appConfigProvider: appConfigProvider,
label: AppLocalizations.of(context)!.blockedServicesListNotLoaded,
color: Colors.red
);
}
},
child: body()
),
),
);
}
else {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 400
),
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
IconButton(
onPressed: () => Navigator.pop(context),
icon: const Icon(Icons.clear_rounded),
tooltip: AppLocalizations.of(context)!.close,
),
const SizedBox(width: 8),
Text(
AppLocalizations.of(context)!.blockedServices,
style: const TextStyle(
fontSize: 22
),
)
],
),
IconButton(
onPressed: updateBlockedServices,
icon: const Icon(
Icons.save_rounded
),
tooltip: AppLocalizations.of(context)!.save,
),
],
),
),
Expanded(
child: body()
),
],
)
),
);
}
}
}
void openBlockedServicesModal({

View file

@ -5,9 +5,9 @@ class DeleteListModal extends StatelessWidget {
final void Function() onConfirm;
const DeleteListModal({
Key? key,
super.key,
required this.onConfirm
}) : super(key: key);
});
@override
Widget build(BuildContext context) {

View file

@ -66,10 +66,12 @@ class _UpdateIntervalListsModalState extends State<UpdateIntervalListsModal> {
topRight: Radius.circular(28)
),
),
child: SafeArea(
child: _Content(
selectedOption: selectedOption,
onUpdateValue: _updateRadioValue,
onConfirm: () => widget.onChange(selectedOption!),
),
)
),
);

View file

@ -72,19 +72,18 @@ class SelectionSliverList extends StatelessWidget {
final void Function() unselectAll;
const SelectionSliverList({
Key? key,
super.key,
required this.lists,
required this.selectedLists,
required this.onSelect,
required this.selectAll,
required this.unselectAll,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
return SafeArea(
top: false,
bottom: false,
child: Builder(
builder: (BuildContext context) {
return CustomScrollView(

View file

@ -19,9 +19,9 @@ class ManagementModal extends StatefulWidget {
final bool dialog;
const ManagementModal({
Key? key,
super.key,
required this.dialog
}) : super(key: key);
});
@override
State<ManagementModal> createState() => _ManagementModalState();
@ -141,6 +141,7 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
topRight: Radius.circular(28)
)
),
child: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
@ -169,6 +170,7 @@ class _ManagementModalState extends State<ManagementModal> with SingleTickerProv
if (Platform.isIOS) const SizedBox(height: 16)
],
),
),
);
}
}

View file

@ -122,7 +122,8 @@ class _TopItemsScreenState extends State<TopItemsScreen> {
const SizedBox(width: 8)
],
),
body: _Content(
body: SafeArea(
child: _Content(
buildValue: widget.buildValue,
isClient: widget.isClient,
onTapEntry: widget.onTapEntry,
@ -132,6 +133,7 @@ class _TopItemsScreenState extends State<TopItemsScreen> {
withProgressBar: widget.withProgressBar,
),
),
),
);
}
else {

View file

@ -148,6 +148,7 @@ class _LogsConfigModalState extends State<LogsConfigModal> {
),
color: Theme.of(context).dialogBackgroundColor
),
child: SafeArea(
child: Builder(
builder: (context) {
switch (loadStatus) {
@ -178,6 +179,7 @@ class _LogsConfigModalState extends State<LogsConfigModal> {
return const SizedBox();
}
},
),
)
);
}

View file

@ -25,10 +25,10 @@ class LogDetailsScreen extends StatelessWidget {
final bool dialog;
const LogDetailsScreen({
Key? key,
super.key,
required this.log,
required this.dialog
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@ -322,7 +322,6 @@ class LogDetailsScreen extends StatelessWidget {
],
body: SafeArea(
top: false,
bottom: false,
child: Builder(
builder: (context) => CustomScrollView(
slivers: [

View file

@ -60,9 +60,11 @@ class _ClientsModalState extends State<ClientsModal> {
),
color: Theme.of(context).dialogBackgroundColor
),
child: SafeArea(
child: _ModalContent(
selectedClients: selectedClients,
onClientsSelected: (v) => setState(() => selectedClients = v),
),
)
),
);

View file

@ -62,10 +62,12 @@ class _FilterStatusModalState extends State<FilterStatusModal> {
),
color: Theme.of(context).dialogBackgroundColor
),
child: SafeArea(
child: _Content(
onApply: apply,
updateSelectedResultStatus: (v) => setState(() => selectedResultStatus = v),
selectedResultStatus: selectedResultStatus,
),
)
);
}

View file

@ -19,9 +19,9 @@ class LogsFiltersModal extends StatefulWidget {
final bool dialog;
const LogsFiltersModal({
Key? key,
super.key,
required this.dialog
}) : super(key: key);
});
@override
State<LogsFiltersModal> createState() => _LogsFiltersModalState();
@ -65,9 +65,11 @@ class _LogsFiltersModalState extends State<LogsFiltersModal> {
topRight: Radius.circular(28)
)
),
child: SafeArea(
child: _FiltersList(
searchController: searchController,
onClearSearch: () => setState(() => searchController.text = "")
),
)
),
);

View file

@ -16,9 +16,9 @@ class Servers extends StatefulWidget {
final double? breakingWidth;
const Servers({
Key? key,
super.key,
this.breakingWidth
}) : super(key: key);
});
@override
State<Servers> createState() => _ServersState();
@ -77,7 +77,8 @@ class _ServersState extends State<Servers> {
title: Text(AppLocalizations.of(context)!.servers),
centerTitle: false,
),
body: Stack(
body: SafeArea(
child: Stack(
children: [
ServersList(
context: context,
@ -101,6 +102,7 @@ class _ServersState extends State<Servers> {
),
],
),
),
);
}
}

View file

@ -44,9 +44,11 @@ class AddClientModal extends StatelessWidget {
topRight: Radius.circular(28)
)
),
child: SafeArea(
child: _Content(
type: type,
onConfirm: onConfirm,
),
)
),
);

View file

@ -11,7 +11,7 @@ import 'package:adguard_home_manager/functions/snackbar.dart';
import 'package:adguard_home_manager/providers/app_config_provider.dart';
class AdvancedSettings extends StatelessWidget {
const AdvancedSettings({Key? key}) : super(key: key);
const AdvancedSettings({super.key});
@override
Widget build(BuildContext context) {
@ -46,7 +46,8 @@ class AdvancedSettings extends StatelessWidget {
title: Text(AppLocalizations.of(context)!.advancedSettings),
surfaceTintColor: isDesktop(width) ? Colors.transparent : null,
),
body: ListView(
body: SafeArea(
child: ListView(
children: [
CustomListTile(
icon: Icons.lock,
@ -71,6 +72,7 @@ class AdvancedSettings extends StatelessWidget {
)
),
],
),
)
);
}

View file

@ -14,7 +14,7 @@ import 'package:adguard_home_manager/providers/app_config_provider.dart';
import 'package:adguard_home_manager/constants/colors.dart';
class Customization extends StatelessWidget {
const Customization({Key? key}) : super(key: key);
const Customization({super.key});
@override
Widget build(BuildContext context) {
@ -65,7 +65,8 @@ class _CustomizationWidgetState extends State<CustomizationWidget> {
centerTitle: false,
surfaceTintColor: isDesktop(width) ? Colors.transparent : null,
),
body: ListView(
body: SafeArea(
child: ListView(
children: [
SectionLabel(
label: AppLocalizations.of(context)!.theme,
@ -212,6 +213,7 @@ class _CustomizationWidgetState extends State<CustomizationWidget> {
)
],
),
),
);
}
}

View file

@ -3,7 +3,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:adguard_home_manager/models/dhcp.dart';
class AddStaticLeaseModal extends StatefulWidget {
class AddStaticLeaseModal extends StatelessWidget {
final void Function(Lease) onConfirm;
final bool dialog;
@ -14,10 +14,49 @@ class AddStaticLeaseModal extends StatefulWidget {
});
@override
State<AddStaticLeaseModal> createState() => _AddStaticLeaseModalState();
Widget build(BuildContext context) {
if (dialog == true) {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 400
),
child: _Content(onConfirm: onConfirm)
),
);
}
else {
return Padding(
padding: MediaQuery.of(context).viewInsets,
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).dialogBackgroundColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28)
)
),
child: SafeArea(
child: _Content(onConfirm: onConfirm)
)
),
);
}
}
}
class _AddStaticLeaseModalState extends State<AddStaticLeaseModal> {
class _Content extends StatefulWidget {
final void Function(Lease) onConfirm;
const _Content({
required this.onConfirm
});
@override
State<_Content> createState() => __ContentState();
}
class __ContentState extends State<_Content> {
final TextEditingController macController = TextEditingController();
String? macError;
final TextEditingController ipController = TextEditingController();
@ -67,7 +106,6 @@ class _AddStaticLeaseModalState extends State<AddStaticLeaseModal> {
@override
Widget build(BuildContext context) {
Widget content() {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
@ -211,31 +249,4 @@ class _AddStaticLeaseModalState extends State<AddStaticLeaseModal> {
],
);
}
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(
color: Theme.of(context).dialogBackgroundColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(28),
topRight: Radius.circular(28)
)
),
child: content()
),
);
}
}
}

View file

@ -411,7 +411,8 @@ class _DhcpScreenState extends State<DhcpScreen> {
const SizedBox(width: 10)
] : null,
),
body: Builder(
body: SafeArea(
child: Builder(
builder: (context) {
switch (dhcpProvider.loadStatus) {
case LoadStatus.loading:
@ -733,6 +734,7 @@ class _DhcpScreenState extends State<DhcpScreen> {
return const SizedBox();
}
},
),
)
);
}

View file

@ -22,10 +22,10 @@ class DhcpLeases extends StatelessWidget {
final bool staticLeases;
const DhcpLeases({
Key? key,
super.key,
required this.items,
required this.staticLeases,
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@ -130,7 +130,8 @@ class DhcpLeases extends StatelessWidget {
),
),
body: items.isNotEmpty
? ListView.builder(
? SafeArea(
child: ListView.builder(
padding: const EdgeInsets.only(top: 0),
itemCount: items.length,
itemBuilder: (context, index) => ListTile(
@ -157,6 +158,7 @@ class DhcpLeases extends StatelessWidget {
)
: null,
),
),
)
: Center(
child: Padding(

View file

@ -137,6 +137,7 @@ class SelectInterfaceModal extends StatelessWidget {
),
),
Expanded(
child: SafeArea(
child: ListView.builder(
controller: controller,
itemCount: interfaces.length,
@ -144,9 +145,9 @@ class SelectInterfaceModal extends StatelessWidget {
networkInterface: interfaces[index],
onSelect: onSelect
)
),
)
),
const SizedBox(height: 16)
],
),
);

View file

@ -117,7 +117,8 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
const SizedBox(width: 10)
],
),
body: ListView(
body: SafeArea(
child: ListView(
padding: const EdgeInsets.only(top: 10),
children: [
Card(
@ -217,6 +218,7 @@ class _BootstrapDnsScreenState extends State<BootstrapDnsScreen> {
const SizedBox(height: 20)
],
),
),
);
}
}

View file

@ -169,7 +169,8 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
const SizedBox(width: 10)
],
),
body: ListView(
body: SafeArea(
child: ListView(
padding: const EdgeInsets.only(top: 10),
children: [
numericField(
@ -245,6 +246,7 @@ class _CacheConfigDnsScreenState extends State<CacheConfigDnsScreen> {
const SizedBox(height: 16)
],
),
),
);
}
}

View file

@ -1,23 +1,70 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class CommentModal extends StatefulWidget {
class CommentModal extends StatelessWidget {
final String? comment;
final void Function(String) onConfirm;
final bool dialog;
const CommentModal({
Key? key,
super.key,
this.comment,
required this.onConfirm,
required this.dialog
}) : super(key: key);
});
@override
State<CommentModal> createState() => _CommentModalState();
Widget build(BuildContext context) {
if (dialog == true) {
return Dialog(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 400
),
child: _Content(
comment: comment,
onConfirm: onConfirm,
)
),
);
}
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: SafeArea(
child: _Content(
comment: comment,
onConfirm: onConfirm,
),
)
),
);
}
}
}
class _CommentModalState extends State<CommentModal> {
class _Content extends StatefulWidget {
final String? comment;
final void Function(String) onConfirm;
const _Content({
required this.comment,
required this.onConfirm
});
@override
State<_Content> createState() => __ContentState();
}
class __ContentState extends State<_Content> {
final TextEditingController commentController = TextEditingController();
bool validData = false;
@ -32,7 +79,6 @@ class _CommentModalState extends State<CommentModal> {
@override
Widget build(BuildContext context) {
Widget content() {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
@ -128,31 +174,4 @@ class _CommentModalState extends State<CommentModal> {
],
);
}
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

@ -25,9 +25,9 @@ class DnsSettings extends StatefulWidget {
final bool splitView;
const DnsSettings({
Key? key,
super.key,
required this.splitView,
}) : super(key: key);
});
@override
State<DnsSettings> createState() => _DnsSettingsState();
@ -118,7 +118,8 @@ class _DnsSettingsState extends State<DnsSettings> {
const SizedBox(width: 10)
],
),
body: Builder(
body: SafeArea(
child: Builder(
builder: (context) {
switch (dnsProvider.loadStatus) {
case LoadStatus.loading:
@ -207,6 +208,7 @@ class _DnsSettingsState extends State<DnsSettings> {
return const SizedBox();
}
},
),
)
);
}

View file

@ -167,7 +167,8 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
const SizedBox(width: 10)
],
),
body: ListView(
body: SafeArea(
child: ListView(
padding: const EdgeInsets.only(top: 10),
children: [
Padding(
@ -303,6 +304,7 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
]
],
),
),
);
}
}

View file

@ -13,7 +13,7 @@ import 'package:adguard_home_manager/functions/snackbar.dart';
import 'package:adguard_home_manager/providers/app_config_provider.dart';
class PrivateReverseDnsServersScreen extends StatefulWidget {
const PrivateReverseDnsServersScreen({Key? key}) : super(key: key);
const PrivateReverseDnsServersScreen({super.key});
@override
State<PrivateReverseDnsServersScreen> createState() => _PrivateReverseDnsServersScreenState();
@ -149,7 +149,8 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
const SizedBox(width: 10)
],
),
body: ListView(
body: SafeArea(
child: ListView(
padding: const EdgeInsets.only(top: 10),
children: [
Card(
@ -293,6 +294,7 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
),
],
),
),
);
}
}

View file

@ -189,7 +189,8 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
const SizedBox(width: 10)
],
),
body: ListView(
body: SafeArea(
child: ListView(
padding: const EdgeInsets.only(top: 10),
children: [
if (dnsServers.isEmpty) Column(
@ -313,6 +314,7 @@ class _UpstreamDnsScreenState extends State<UpstreamDnsScreen> {
),
],
),
),
);
}
}

View file

@ -46,10 +46,12 @@ class DnsRewriteModal extends StatelessWidget {
),
color: Theme.of(context).dialogBackgroundColor,
),
child: SafeArea(
child: _Content(
onConfirm: onConfirm,
onDelete: onDelete,
rule: rule,
),
)
),
);

View file

@ -136,7 +136,8 @@ class _DnsRewritesScreenState extends State<DnsRewritesScreen> {
surfaceTintColor: isDesktop(width) ? Colors.transparent : null,
centerTitle: false,
),
body: Stack(
body: SafeArea(
child: Stack(
children: [
Builder(
builder: (context) {
@ -370,6 +371,7 @@ class _DnsRewritesScreenState extends State<DnsRewritesScreen> {
)
],
),
),
);
}
}

View file

@ -4,6 +4,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class ServerVersionNeeded extends StatelessWidget {
final String version;
// ignore: use_super_parameters
const ServerVersionNeeded({
Key? key,
required this.version

View file

@ -283,7 +283,8 @@ class _EncryptionSettingsState extends State<EncryptionSettings> {
const SizedBox(width: 10),
],
),
body: Builder(
body: SafeArea(
child: Builder(
builder: (context) {
switch (loadStatus) {
case LoadStatus.loading:
@ -653,6 +654,7 @@ class _EncryptionSettingsState extends State<EncryptionSettings> {
return const SizedBox();
}
},
),
)
);
}

View file

@ -124,7 +124,8 @@ class _GeneralSettingsState extends State<GeneralSettings> {
title: Text(AppLocalizations.of(context)!.generalSettings),
surfaceTintColor: isDesktop(width) ? Colors.transparent : null,
),
body: ListView(
body: SafeArea(
child: ListView(
children: [
SectionLabel(label: AppLocalizations.of(context)!.home),
CustomListTile(
@ -291,6 +292,7 @@ class _GeneralSettingsState extends State<GeneralSettings> {
)
]
],
),
)
);
}

View file

@ -14,7 +14,7 @@ import 'package:adguard_home_manager/functions/snackbar.dart';
import 'package:adguard_home_manager/providers/app_config_provider.dart';
class SafeSearchSettingsScreen extends StatefulWidget {
const SafeSearchSettingsScreen({Key? key}) : super(key: key);
const SafeSearchSettingsScreen({super.key});
@override
State<SafeSearchSettingsScreen> createState() => _SafeSearchSettingsScreenState();
@ -123,7 +123,8 @@ class _SafeSearchSettingsScreenState extends State<SafeSearchSettingsScreen> {
const SizedBox(width: 8)
],
),
body: Builder(
body: SafeArea(
child: Builder(
builder: (context) {
switch (statusProvider.loadStatus) {
case LoadStatus.loading:
@ -283,6 +284,7 @@ class _SafeSearchSettingsScreenState extends State<SafeSearchSettingsScreen> {
return const SizedBox();
}
},
),
)
);
}

View file

@ -51,7 +51,8 @@ class _ServerInformationState extends State<ServerInformation> {
surfaceTintColor: isDesktop(width) ? Colors.transparent : null,
centerTitle: false,
),
body: Builder(
body: SafeArea(
child: Builder(
builder: (context) {
switch (serverInfo.loadStatus) {
case LoadStatus.loading:
@ -159,6 +160,7 @@ class _ServerInformationState extends State<ServerInformation> {
return const SizedBox();
}
},
),
)
);
}

View file

@ -14,10 +14,10 @@ class ThemeModal extends StatefulWidget {
final int selectedTheme;
const ThemeModal({
Key? key,
super.key,
required this.statusBarHeight,
required this.selectedTheme,
}) : super(key: key);
});
@override
State<ThemeModal> createState() => _ThemeModalState();

View file

@ -17,7 +17,7 @@ import 'package:adguard_home_manager/constants/enums.dart';
import 'package:adguard_home_manager/providers/servers_provider.dart';
class UpdateScreen extends StatelessWidget {
const UpdateScreen({Key? key}) : super(key: key);
const UpdateScreen({super.key});
@override
Widget build(BuildContext context) {
@ -166,8 +166,10 @@ class UpdateScreen extends StatelessWidget {
);
}
final changelog = serversProvider.updateAvailable.loadStatus == LoadStatus.loaded && serversProvider.updateAvailable.data!.changelog != null
? ListView(
final SafeArea? changelog;
if (serversProvider.updateAvailable.loadStatus == LoadStatus.loaded && serversProvider.updateAvailable.data!.changelog != null) {
changelog = SafeArea(
child: ListView(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
@ -191,8 +193,11 @@ class UpdateScreen extends StatelessWidget {
)
)
],
)
: null;
),
);
} else {
changelog = null;
}
return Scaffold(
body: Column(

View file

@ -550,10 +550,12 @@ class _AddServerModalState extends State<AddServerModal> {
const SizedBox(width: 8)
],
),
body: ListView(
body: SafeArea(
child: ListView(
children: form()
),
),
),
);
}
else {

View file

@ -5,12 +5,14 @@ class OverlayStyle extends StatelessWidget {
final Widget child;
const OverlayStyle({
Key? key,
super.key,
required this.child
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
final systemGestureInsets = MediaQuery.of(context).systemGestureInsets;
return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
@ -20,7 +22,13 @@ class OverlayStyle extends StatelessWidget {
statusBarIconBrightness: Theme.of(context).brightness == Brightness.light
? Brightness.dark
: Brightness.light,
systemNavigationBarColor: Theme.of(context).colorScheme.background,
systemNavigationBarColor: systemGestureInsets.left > 0 // If true gestures navigation
? Colors.transparent
: ElevationOverlay.applySurfaceTint(
Theme.of(context).colorScheme.surface,
Theme.of(context).colorScheme.surfaceTint,
3
),
systemNavigationBarIconBrightness: Theme.of(context).brightness == Brightness.light
? Brightness.dark
: Brightness.light,

View file

@ -19,7 +19,7 @@ class CustomTabContentList extends StatelessWidget {
final EdgeInsets? listPadding;
const CustomTabContentList({
Key? key,
super.key,
required this.loadingGenerator,
required this.itemsCount,
required this.contentWidget,
@ -32,7 +32,7 @@ class CustomTabContentList extends StatelessWidget {
this.fabVisible,
this.noSliver,
this.listPadding
}) : super(key: key);
});
@override
Widget build(BuildContext context) {
@ -49,7 +49,6 @@ class CustomTabContentList extends StatelessWidget {
else {
return SafeArea(
top: false,
bottom: false,
child: Builder(
builder: (BuildContext context) => CustomScrollView(
slivers: [
@ -72,7 +71,8 @@ class CustomTabContentList extends StatelessWidget {
case LoadStatus.loaded:
if (noSliver == true) {
if (itemsCount > 0) {
return Stack(
return SafeArea(
child: Stack(
children: [
ListView.builder(
padding: listPadding,
@ -90,10 +90,12 @@ class CustomTabContentList extends StatelessWidget {
child: fab!
),
],
),
);
}
else {
return Stack(
return SafeArea(
child: Stack(
children: [
noData,
if (fab != null) AnimatedPositioned(
@ -107,6 +109,7 @@ class CustomTabContentList extends StatelessWidget {
child: fab!
),
],
),
);
}
}
@ -146,10 +149,10 @@ class CustomTabContentList extends StatelessWidget {
curve: Curves.easeInOut,
bottom: fabVisible != null && fabVisible == true ?
appConfigProvider.showingSnackbar
? 70 : 20
: -70,
? 90 : 20
: -90,
right: 20,
child: fab!
child: SafeArea(child: fab!)
),
],
);
@ -169,7 +172,6 @@ class CustomTabContentList extends StatelessWidget {
else {
return SafeArea(
top: false,
bottom: false,
child: Builder(
builder: (BuildContext context) => CustomScrollView(
slivers: [