Added sliverappbar to more screens

This commit is contained in:
Juan Gilsanz Polo 2024-03-10 14:51:35 +01:00
parent a3c63ffd9a
commit b270ca2b8c
4 changed files with 331 additions and 210 deletions

View file

@ -85,38 +85,130 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreen> {
if (widget.fullScreen == true) { if (widget.fullScreen == true) {
return Dialog.fullscreen( return Dialog.fullscreen(
child: Scaffold( child: Material(
appBar: AppBar( child: NestedScrollView(
leading: CloseButton(onPressed: () => Navigator.pop(context)), headerSliverBuilder: (context, innerBoxIsScrolled) => [
title: Text(AppLocalizations.of(context)!.blockedServices), SliverOverlapAbsorber(
actions: [ handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
IconButton( sliver: SliverAppBar.large(
onPressed: updateBlockedServices, pinned: true,
icon: const Icon( floating: true,
Icons.save_rounded centerTitle: false,
), forceElevated: innerBoxIsScrolled,
tooltip: AppLocalizations.of(context)!.save, leading: CloseButton(onPressed: () => Navigator.pop(context)),
), title: Text(AppLocalizations.of(context)!.blockedServices),
const SizedBox(width: 10) actions: [
], IconButton(
), onPressed: updateBlockedServices,
body: SafeArea( icon: const Icon(
child: RefreshIndicator( Icons.save_rounded
onRefresh: () async { ),
final result = await filteringProvider.loadBlockedServices(); tooltip: AppLocalizations.of(context)!.save,
if (result == false) { ),
showSnacbkar( const SizedBox(width: 10)
appConfigProvider: appConfigProvider, ],
label: AppLocalizations.of(context)!.blockedServicesListNotLoaded, )
color: Colors.red
);
}
},
child: _Content(
values: values,
updateValues: updateValues,
) )
), ],
body: SafeArea(
top: false,
bottom: true,
child: Builder(
builder: (context) => CustomScrollView(
slivers: [
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
),
if (filteringProvider.blockedServicesLoadStatus == LoadStatus.loading) Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
width: double.maxFinite,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const CircularProgressIndicator(),
const SizedBox(height: 30),
Text(
AppLocalizations.of(context)!.loadingBlockedServicesList,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
)
],
),
),
if (filteringProvider.blockedServicesLoadStatus == LoadStatus.loaded) SliverList.builder(
itemCount: filteringProvider.blockedServices!.services.length,
itemBuilder: (context, index) => Material(
color: Colors.transparent,
child: InkWell(
onTap: () => updateValues(
values.contains(filteringProvider.blockedServices!.services[index].id),
filteringProvider.blockedServices!.services[index]
),
child: Padding(
padding: const EdgeInsets.only(
top: 6,
bottom: 6,
right: 12,
left: 24
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
filteringProvider.blockedServices!.services[index].name,
style: TextStyle(
fontSize: 16,
color: Theme.of(context).colorScheme.onSurface
),
),
Checkbox(
value: values.contains(filteringProvider.blockedServices!.services[index].id),
onChanged: (value) => updateValues(
value!,
filteringProvider.blockedServices!.services[index]
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)
),
)
],
),
),
),
)
),
if (filteringProvider.blockedServicesLoadStatus == LoadStatus.error) Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
width: double.maxFinite,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(
Icons.error,
color: Colors.red,
size: 50,
),
const SizedBox(height: 30),
Text(
AppLocalizations.of(context)!.blockedServicesListNotLoaded,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
)
],
),
)
],
),
)
)
), ),
), ),
); );
@ -162,9 +254,105 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreen> {
), ),
), ),
Expanded( Expanded(
child: _Content( child: Builder(
values: values, builder: (ctx) {
updateValues: updateValues, switch (filteringProvider.blockedServicesLoadStatus) {
case LoadStatus.loading:
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
width: double.maxFinite,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const CircularProgressIndicator(),
const SizedBox(height: 30),
Text(
AppLocalizations.of(context)!.loadingBlockedServicesList,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
)
],
),
);
case LoadStatus.loaded:
return ListView.builder(
itemCount: filteringProvider.blockedServices!.services.length,
itemBuilder: (context, index) => Material(
color: Colors.transparent,
child: InkWell(
onTap: () => updateValues(
values.contains(filteringProvider.blockedServices!.services[index].id),
filteringProvider.blockedServices!.services[index]
),
child: Padding(
padding: const EdgeInsets.only(
top: 6,
bottom: 6,
right: 12,
left: 24
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
filteringProvider.blockedServices!.services[index].name,
style: TextStyle(
fontSize: 16,
color: Theme.of(context).colorScheme.onSurface
),
),
Checkbox(
value: values.contains(filteringProvider.blockedServices!.services[index].id),
onChanged: (value) => updateValues(
value!,
filteringProvider.blockedServices!.services[index]
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)
),
)
],
),
),
),
)
);
case LoadStatus.error:
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
width: double.maxFinite,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(
Icons.error,
color: Colors.red,
size: 50,
),
const SizedBox(height: 30),
Text(
AppLocalizations.of(context)!.blockedServicesListNotLoaded,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
)
],
),
);
default:
return const SizedBox();
}
},
) )
), ),
], ],
@ -175,117 +363,6 @@ class _BlockedServicesScreenStateWidget extends State<BlockedServicesScreen> {
} }
} }
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(
padding: const EdgeInsets.symmetric(horizontal: 16),
width: double.maxFinite,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const CircularProgressIndicator(),
const SizedBox(height: 30),
Text(
AppLocalizations.of(context)!.loadingBlockedServicesList,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
)
],
),
);
case LoadStatus.loaded:
return ListView.builder(
itemCount: filteringProvider.blockedServices!.services.length,
itemBuilder: (context, index) => Material(
color: Colors.transparent,
child: InkWell(
onTap: () => updateValues(
values.contains(filteringProvider.blockedServices!.services[index].id),
filteringProvider.blockedServices!.services[index]
),
child: Padding(
padding: const EdgeInsets.only(
top: 6,
bottom: 6,
right: 12,
left: 24
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
filteringProvider.blockedServices!.services[index].name,
style: TextStyle(
fontSize: 16,
color: Theme.of(context).colorScheme.onSurface
),
),
Checkbox(
value: values.contains(filteringProvider.blockedServices!.services[index].id),
onChanged: (value) => updateValues(
value!,
filteringProvider.blockedServices!.services[index]
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)
),
)
],
),
),
),
)
);
case LoadStatus.error:
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
width: double.maxFinite,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(
Icons.error,
color: Colors.red,
size: 50,
),
const SizedBox(height: 30),
Text(
AppLocalizations.of(context)!.blockedServicesListNotLoaded,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 22,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
)
],
),
);
default:
return const SizedBox();
}
}
}
void openBlockedServicesModal({ void openBlockedServicesModal({
required BuildContext context, required BuildContext context,

View file

@ -55,44 +55,66 @@ class _AddCustomRuleState extends State<AddCustomRule> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (widget.fullScreen == true) { if (widget.fullScreen == true) {
return Dialog.fullscreen( return Dialog.fullscreen(
child: Scaffold( child: Material(
appBar: AppBar( child: NestedScrollView(
leading: CloseButton(onPressed: () => Navigator.pop(context)), headerSliverBuilder: (context, innerBoxIsScrolled) => [
title: Text(AppLocalizations.of(context)!.addCustomRule), SliverOverlapAbsorber(
actions: [ handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
IconButton( sliver: SliverAppBar.large(
onPressed: _checkValidValues() == true pinned: true,
? () { floating: true,
Navigator.pop(context); centerTitle: false,
widget.onConfirm( forceElevated: innerBoxIsScrolled,
_buildRule( leading: CloseButton(onPressed: () => Navigator.pop(context)),
domainController: _domainController, title: Text(AppLocalizations.of(context)!.addCustomRule),
important: _addImportant, actions: [
preset: _preset IconButton(
) onPressed: _checkValidValues() == true
); ? () {
} Navigator.pop(context);
: null, widget.onConfirm(
icon: const Icon(Icons.check) _buildRule(
), domainController: _domainController,
const SizedBox(width: 10) important: _addImportant,
], preset: _preset
), )
body: SafeArea( );
child: ListView( }
children: [ : null,
_CustomRuleEditor( icon: const Icon(Icons.check)
domainController: _domainController, ),
domainError: _domainError, const SizedBox(width: 10)
important: _addImportant, ],
preset: _preset, )
setImportant: (v) => setState(() => _addImportant = v),
setPreset: (v) => setState(() => _preset = v),
validateDomain: validateDomain
) )
] ],
body: SafeArea(
top: false,
bottom: true,
child: Builder(
builder: (context) => CustomScrollView(
slivers: [
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
),
SliverList.list(
children: [
_CustomRuleEditor(
domainController: _domainController,
domainError: _domainError,
important: _addImportant,
preset: _preset,
setImportant: (v) => setState(() => _addImportant = v),
setPreset: (v) => setState(() => _preset = v),
validateDomain: validateDomain
)
]
)
],
),
)
)
), ),
)
), ),
); );
} }

View file

@ -37,29 +37,51 @@ class _EditCustomRulesState extends State<EditCustomRules> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (widget.fullScreen == true) { if (widget.fullScreen == true) {
return Dialog.fullscreen( return Dialog.fullscreen(
child: Scaffold( child: Material(
appBar: AppBar( child: NestedScrollView(
leading: CloseButton(onPressed: () => Navigator.pop(context)), headerSliverBuilder: (context, innerBoxIsScrolled) => [
title: Text(AppLocalizations.of(context)!.editCustomRules), SliverOverlapAbsorber(
actions: [ handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
IconButton( sliver: SliverAppBar.large(
onPressed: () { pinned: true,
Navigator.pop(context); floating: true,
widget.onConfirm(_fieldController.text.split("\n")); centerTitle: false,
}, forceElevated: innerBoxIsScrolled,
icon: const Icon(Icons.save_rounded), leading: CloseButton(onPressed: () => Navigator.pop(context)),
tooltip: AppLocalizations.of(context)!.save, title: Text(AppLocalizations.of(context)!.editCustomRules),
), actions: [
const SizedBox(width: 10) IconButton(
], onPressed: () {
Navigator.pop(context);
widget.onConfirm(_fieldController.text.split("\n"));
},
icon: const Icon(Icons.save_rounded),
tooltip: AppLocalizations.of(context)!.save,
),
const SizedBox(width: 10)
],
)
)
],
body: SafeArea(
top: false,
bottom: true,
child: Builder(
builder: (context) => CustomScrollView(
slivers: [
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
),
SliverList.list(
children: [
_CustomRulesRawEditor(fieldController: _fieldController)
]
)
],
),
)
)
), ),
body: SafeArea(
child: ListView(
children: [
_CustomRulesRawEditor(fieldController: _fieldController)
]
),
)
), ),
); );
} }

View file

@ -6,13 +6,13 @@ PODS:
- FlutterMacOS (1.0.0) - FlutterMacOS (1.0.0)
- package_info_plus (0.0.1): - package_info_plus (0.0.1):
- FlutterMacOS - FlutterMacOS
- Sentry/HybridSDK (8.20.0): - Sentry/HybridSDK (8.21.0):
- SentryPrivate (= 8.20.0) - SentryPrivate (= 8.21.0)
- sentry_flutter (0.0.1): - sentry_flutter (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
- Sentry/HybridSDK (= 8.20.0) - Sentry/HybridSDK (= 8.21.0)
- SentryPrivate (8.20.0) - SentryPrivate (8.21.0)
- shared_preferences_foundation (0.0.1): - shared_preferences_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
@ -84,9 +84,9 @@ SPEC CHECKSUMS:
dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f dynamic_color: 2eaa27267de1ca20d879fbd6e01259773fb1670f
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
Sentry: a8d7b373b9f9868442b02a0c425192f693103cbf Sentry: ebc12276bd17613a114ab359074096b6b3725203
sentry_flutter: 03e7660857a8cdb236e71456a7e8447b65c8a788 sentry_flutter: dff1df05dc39c83d04f9330b36360fc374574c5e
SentryPrivate: 006b24af16828441f70e2ab6adf241bd0a8ad130 SentryPrivate: d651efb234cf385ec9a1cdd3eff94b5e78a0e0fe
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
sqlite3: 73b7fc691fdc43277614250e04d183740cb15078 sqlite3: 73b7fc691fdc43277614250e04d183740cb15078