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

View file

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

View file

@ -149,7 +149,8 @@ class _LogsListClientState extends State<LogsListClient> {
] ]
], ],
), ),
body: Builder( body: SafeArea(
child: Builder(
builder: (context) { builder: (context) {
switch (loadStatus) { switch (loadStatus) {
case 0: case 0:
@ -268,6 +269,7 @@ class _LogsListClientState extends State<LogsListClient> {
return const SizedBox(); 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'; import 'package:adguard_home_manager/providers/app_config_provider.dart';
class Connect extends StatefulWidget { class Connect extends StatefulWidget {
const Connect({Key? key}) : super(key: key); const Connect({super.key});
@override @override
State<Connect> createState() => _ConnectState(); State<Connect> createState() => _ConnectState();
@ -61,7 +61,8 @@ class _ConnectState extends State<Connect> {
appBar: AppBar( appBar: AppBar(
title: Text(AppLocalizations.of(context)!.connect), title: Text(AppLocalizations.of(context)!.connect),
), ),
body: Stack( body: SafeArea(
child: Stack(
children: [ children: [
ServersList( ServersList(
context: context, context: context,
@ -75,13 +76,14 @@ class _ConnectState extends State<Connect> {
curve: Curves.easeInOut, curve: Curves.easeInOut,
bottom: isVisible ? bottom: isVisible ?
appConfigProvider.showingSnackbar appConfigProvider.showingSnackbar
? 70 : 20 ? 90 : 20
: -70, : -90,
right: 20, right: 20,
child: const FabConnect() 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'; import 'package:adguard_home_manager/models/filtering.dart';
class AddListModal extends StatefulWidget { class AddListModal extends StatelessWidget {
final String type; final String type;
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;
@ -13,19 +13,74 @@ class AddListModal extends StatefulWidget {
final bool dialog; final bool dialog;
const AddListModal({ const AddListModal({
Key? key, super.key,
required this.type, required this.type,
this.list, this.list,
this.onConfirm, this.onConfirm,
this.onEdit, this.onEdit,
required this.dialog required this.dialog
}) : super(key: key); });
@override @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 nameController = TextEditingController();
final TextEditingController urlController = TextEditingController(); final TextEditingController urlController = TextEditingController();
String? urlError; String? urlError;
@ -70,7 +125,6 @@ class _AddListModalState extends State<AddListModal> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget content() {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ 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/functions/get_filtered_status.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 StatelessWidget {
final bool dialog; final bool dialog;
const CheckHostModal({ const CheckHostModal({
Key? key, super.key,
required this.dialog required this.dialog
}) : super(key: key); });
@override @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(); final TextEditingController domainController = TextEditingController();
String? domainError; String? domainError;
@ -59,8 +95,8 @@ class _CheckHostModalState extends State<CheckHostModal> {
setState(() => resultWidget = checking()); setState(() => resultWidget = checking());
final result = await serversProvider.apiClient2!.checkHostFiltered(host: domainController.text); final result = await serversProvider.apiClient2!.checkHostFiltered(host: domainController.text);
if (!mounted) return;
if (mounted) {
if (result.successful == true) { if (result.successful == true) {
final status = getFilteredStatus(context, appConfigProvider, result.content['reason'], true); final status = getFilteredStatus(context, appConfigProvider, result.content['reason'], true);
if (mounted) { if (mounted) {
@ -117,9 +153,7 @@ class _CheckHostModalState extends State<CheckHostModal> {
)); ));
} }
} }
}
Widget content() {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ 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; final bool dialog;
const ListDetailsScreen({ const ListDetailsScreen({
Key? key, super.key,
required this.listId, required this.listId,
required this.type, required this.type,
required this.dialog required this.dialog
}) : super(key: key); });
@override @override
State<ListDetailsScreen> createState() => _ListDetailsScreenState(); State<ListDetailsScreen> createState() => _ListDetailsScreenState();
@ -367,7 +367,8 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
title: Text(AppLocalizations.of(context)!.listDetails), title: Text(AppLocalizations.of(context)!.listDetails),
actions: list != null ? actions() : null, actions: list != null ? actions() : null,
), ),
body: Stack( body: SafeArea(
child: Stack(
children: [ children: [
if (list != null) ListView( if (list != null) ListView(
children: content(), children: content(),
@ -405,6 +406,7 @@ class _ListDetailsScreenState extends State<ListDetailsScreen> {
], ],
), ),
), ),
),
); );
} }
} }

View file

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

View file

@ -17,9 +17,9 @@ class BlockedServicesScreen extends StatefulWidget {
final bool fullScreen; final bool fullScreen;
const BlockedServicesScreen({ const BlockedServicesScreen({
Key? key, super.key,
required this.fullScreen required this.fullScreen
}) : super(key: key); });
@override @override
State<BlockedServicesScreen> createState() => _BlockedServicesScreenStateWidget(); 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) { switch (filteringProvider.blockedServicesLoadStatus) {
case LoadStatus.loading: case LoadStatus.loading:
return Container( return Container(
@ -181,89 +285,6 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreen> {
return const SizedBox(); 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({ void openBlockedServicesModal({

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -16,9 +16,9 @@ class Servers extends StatefulWidget {
final double? breakingWidth; final double? breakingWidth;
const Servers({ const Servers({
Key? key, super.key,
this.breakingWidth this.breakingWidth
}) : super(key: key); });
@override @override
State<Servers> createState() => _ServersState(); State<Servers> createState() => _ServersState();
@ -77,7 +77,8 @@ class _ServersState extends State<Servers> {
title: Text(AppLocalizations.of(context)!.servers), title: Text(AppLocalizations.of(context)!.servers),
centerTitle: false, centerTitle: false,
), ),
body: Stack( body: SafeArea(
child: Stack(
children: [ children: [
ServersList( ServersList(
context: context, 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) topRight: Radius.circular(28)
) )
), ),
child: SafeArea(
child: _Content( child: _Content(
type: type, type: type,
onConfirm: onConfirm, 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'; import 'package:adguard_home_manager/providers/app_config_provider.dart';
class AdvancedSettings extends StatelessWidget { class AdvancedSettings extends StatelessWidget {
const AdvancedSettings({Key? key}) : super(key: key); const AdvancedSettings({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -46,7 +46,8 @@ class AdvancedSettings extends StatelessWidget {
title: Text(AppLocalizations.of(context)!.advancedSettings), title: Text(AppLocalizations.of(context)!.advancedSettings),
surfaceTintColor: isDesktop(width) ? Colors.transparent : null, surfaceTintColor: isDesktop(width) ? Colors.transparent : null,
), ),
body: ListView( body: SafeArea(
child: ListView(
children: [ children: [
CustomListTile( CustomListTile(
icon: Icons.lock, 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'; import 'package:adguard_home_manager/constants/colors.dart';
class Customization extends StatelessWidget { class Customization extends StatelessWidget {
const Customization({Key? key}) : super(key: key); const Customization({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -65,7 +65,8 @@ class _CustomizationWidgetState extends State<CustomizationWidget> {
centerTitle: false, centerTitle: false,
surfaceTintColor: isDesktop(width) ? Colors.transparent : null, surfaceTintColor: isDesktop(width) ? Colors.transparent : null,
), ),
body: ListView( body: SafeArea(
child: ListView(
children: [ children: [
SectionLabel( SectionLabel(
label: AppLocalizations.of(context)!.theme, 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'; import 'package:adguard_home_manager/models/dhcp.dart';
class AddStaticLeaseModal extends StatefulWidget { class AddStaticLeaseModal extends StatelessWidget {
final void Function(Lease) onConfirm; final void Function(Lease) onConfirm;
final bool dialog; final bool dialog;
@ -14,10 +14,49 @@ class AddStaticLeaseModal extends StatefulWidget {
}); });
@override @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(); final TextEditingController macController = TextEditingController();
String? macError; String? macError;
final TextEditingController ipController = TextEditingController(); final TextEditingController ipController = TextEditingController();
@ -67,7 +106,6 @@ class _AddStaticLeaseModalState extends State<AddStaticLeaseModal> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget content() {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ 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) const SizedBox(width: 10)
] : null, ] : null,
), ),
body: Builder( body: SafeArea(
child: Builder(
builder: (context) { builder: (context) {
switch (dhcpProvider.loadStatus) { switch (dhcpProvider.loadStatus) {
case LoadStatus.loading: case LoadStatus.loading:
@ -733,6 +734,7 @@ class _DhcpScreenState extends State<DhcpScreen> {
return const SizedBox(); return const SizedBox();
} }
}, },
),
) )
); );
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -1,23 +1,70 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class CommentModal extends StatefulWidget { class CommentModal extends StatelessWidget {
final String? comment; final String? comment;
final void Function(String) onConfirm; final void Function(String) onConfirm;
final bool dialog; final bool dialog;
const CommentModal({ const CommentModal({
Key? key, super.key,
this.comment, this.comment,
required this.onConfirm, required this.onConfirm,
required this.dialog required this.dialog
}) : super(key: key); });
@override @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(); final TextEditingController commentController = TextEditingController();
bool validData = false; bool validData = false;
@ -32,7 +79,6 @@ class _CommentModalState extends State<CommentModal> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget content() {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ 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; final bool splitView;
const DnsSettings({ const DnsSettings({
Key? key, super.key,
required this.splitView, required this.splitView,
}) : super(key: key); });
@override @override
State<DnsSettings> createState() => _DnsSettingsState(); State<DnsSettings> createState() => _DnsSettingsState();
@ -118,7 +118,8 @@ class _DnsSettingsState extends State<DnsSettings> {
const SizedBox(width: 10) const SizedBox(width: 10)
], ],
), ),
body: Builder( body: SafeArea(
child: Builder(
builder: (context) { builder: (context) {
switch (dnsProvider.loadStatus) { switch (dnsProvider.loadStatus) {
case LoadStatus.loading: case LoadStatus.loading:
@ -207,6 +208,7 @@ class _DnsSettingsState extends State<DnsSettings> {
return const SizedBox(); return const SizedBox();
} }
}, },
),
) )
); );
} }

View file

@ -167,7 +167,8 @@ class _DnsServerSettingsScreenState extends State<DnsServerSettingsScreen> {
const SizedBox(width: 10) const SizedBox(width: 10)
], ],
), ),
body: ListView( body: SafeArea(
child: ListView(
padding: const EdgeInsets.only(top: 10), padding: const EdgeInsets.only(top: 10),
children: [ children: [
Padding( 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'; import 'package:adguard_home_manager/providers/app_config_provider.dart';
class PrivateReverseDnsServersScreen extends StatefulWidget { class PrivateReverseDnsServersScreen extends StatefulWidget {
const PrivateReverseDnsServersScreen({Key? key}) : super(key: key); const PrivateReverseDnsServersScreen({super.key});
@override @override
State<PrivateReverseDnsServersScreen> createState() => _PrivateReverseDnsServersScreenState(); State<PrivateReverseDnsServersScreen> createState() => _PrivateReverseDnsServersScreenState();
@ -149,7 +149,8 @@ class _PrivateReverseDnsServersScreenState extends State<PrivateReverseDnsServer
const SizedBox(width: 10) const SizedBox(width: 10)
], ],
), ),
body: ListView( body: SafeArea(
child: ListView(
padding: const EdgeInsets.only(top: 10), padding: const EdgeInsets.only(top: 10),
children: [ children: [
Card( 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) const SizedBox(width: 10)
], ],
), ),
body: ListView( body: SafeArea(
child: ListView(
padding: const EdgeInsets.only(top: 10), padding: const EdgeInsets.only(top: 10),
children: [ children: [
if (dnsServers.isEmpty) Column( 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, color: Theme.of(context).dialogBackgroundColor,
), ),
child: SafeArea(
child: _Content( child: _Content(
onConfirm: onConfirm, onConfirm: onConfirm,
onDelete: onDelete, onDelete: onDelete,
rule: rule, rule: rule,
),
) )
), ),
); );

View file

@ -136,7 +136,8 @@ class _DnsRewritesScreenState extends State<DnsRewritesScreen> {
surfaceTintColor: isDesktop(width) ? Colors.transparent : null, surfaceTintColor: isDesktop(width) ? Colors.transparent : null,
centerTitle: false, centerTitle: false,
), ),
body: Stack( body: SafeArea(
child: Stack(
children: [ children: [
Builder( Builder(
builder: (context) { 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 { class ServerVersionNeeded extends StatelessWidget {
final String version; final String version;
// ignore: use_super_parameters
const ServerVersionNeeded({ const ServerVersionNeeded({
Key? key, Key? key,
required this.version required this.version

View file

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

View file

@ -124,7 +124,8 @@ class _GeneralSettingsState extends State<GeneralSettings> {
title: Text(AppLocalizations.of(context)!.generalSettings), title: Text(AppLocalizations.of(context)!.generalSettings),
surfaceTintColor: isDesktop(width) ? Colors.transparent : null, surfaceTintColor: isDesktop(width) ? Colors.transparent : null,
), ),
body: ListView( body: SafeArea(
child: ListView(
children: [ children: [
SectionLabel(label: AppLocalizations.of(context)!.home), SectionLabel(label: AppLocalizations.of(context)!.home),
CustomListTile( 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'; import 'package:adguard_home_manager/providers/app_config_provider.dart';
class SafeSearchSettingsScreen extends StatefulWidget { class SafeSearchSettingsScreen extends StatefulWidget {
const SafeSearchSettingsScreen({Key? key}) : super(key: key); const SafeSearchSettingsScreen({super.key});
@override @override
State<SafeSearchSettingsScreen> createState() => _SafeSearchSettingsScreenState(); State<SafeSearchSettingsScreen> createState() => _SafeSearchSettingsScreenState();
@ -123,7 +123,8 @@ class _SafeSearchSettingsScreenState extends State<SafeSearchSettingsScreen> {
const SizedBox(width: 8) const SizedBox(width: 8)
], ],
), ),
body: Builder( body: SafeArea(
child: Builder(
builder: (context) { builder: (context) {
switch (statusProvider.loadStatus) { switch (statusProvider.loadStatus) {
case LoadStatus.loading: case LoadStatus.loading:
@ -283,6 +284,7 @@ class _SafeSearchSettingsScreenState extends State<SafeSearchSettingsScreen> {
return const SizedBox(); return const SizedBox();
} }
}, },
),
) )
); );
} }

View file

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

View file

@ -14,10 +14,10 @@ class ThemeModal extends StatefulWidget {
final int selectedTheme; final int selectedTheme;
const ThemeModal({ const ThemeModal({
Key? key, super.key,
required this.statusBarHeight, required this.statusBarHeight,
required this.selectedTheme, required this.selectedTheme,
}) : super(key: key); });
@override @override
State<ThemeModal> createState() => _ThemeModalState(); 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'; import 'package:adguard_home_manager/providers/servers_provider.dart';
class UpdateScreen extends StatelessWidget { class UpdateScreen extends StatelessWidget {
const UpdateScreen({Key? key}) : super(key: key); const UpdateScreen({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -166,8 +166,10 @@ class UpdateScreen extends StatelessWidget {
); );
} }
final changelog = serversProvider.updateAvailable.loadStatus == LoadStatus.loaded && serversProvider.updateAvailable.data!.changelog != null final SafeArea? changelog;
? ListView( if (serversProvider.updateAvailable.loadStatus == LoadStatus.loaded && serversProvider.updateAvailable.data!.changelog != null) {
changelog = SafeArea(
child: ListView(
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
@ -191,8 +193,11 @@ class UpdateScreen extends StatelessWidget {
) )
) )
], ],
) ),
: null; );
} else {
changelog = null;
}
return Scaffold( return Scaffold(
body: Column( body: Column(

View file

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

View file

@ -5,12 +5,14 @@ class OverlayStyle extends StatelessWidget {
final Widget child; final Widget child;
const OverlayStyle({ const OverlayStyle({
Key? key, super.key,
required this.child required this.child
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final systemGestureInsets = MediaQuery.of(context).systemGestureInsets;
return AnnotatedRegion<SystemUiOverlayStyle>( return AnnotatedRegion<SystemUiOverlayStyle>(
value: SystemUiOverlayStyle( value: SystemUiOverlayStyle(
statusBarColor: Colors.transparent, statusBarColor: Colors.transparent,
@ -20,7 +22,13 @@ class OverlayStyle extends StatelessWidget {
statusBarIconBrightness: Theme.of(context).brightness == Brightness.light statusBarIconBrightness: Theme.of(context).brightness == Brightness.light
? Brightness.dark ? Brightness.dark
: Brightness.light, : 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 systemNavigationBarIconBrightness: Theme.of(context).brightness == Brightness.light
? Brightness.dark ? Brightness.dark
: Brightness.light, : Brightness.light,

View file

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