Fix bugs
This commit is contained in:
@@ -86,158 +86,161 @@ class ProfileDetailsPage extends HookConsumerWidget with PresLogger {
|
||||
return Stack(
|
||||
children: [
|
||||
Scaffold(
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
title: Text(t.profile.detailsPageTitle),
|
||||
pinned: true,
|
||||
actions: [
|
||||
if (state.isEditing)
|
||||
PopupMenuButton(
|
||||
itemBuilder: (context) {
|
||||
return [
|
||||
if (state.profile case RemoteProfileEntity())
|
||||
body: SafeArea(
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
title: Text(t.profile.detailsPageTitle),
|
||||
pinned: true,
|
||||
actions: [
|
||||
if (state.isEditing)
|
||||
PopupMenuButton(
|
||||
itemBuilder: (context) {
|
||||
return [
|
||||
if (state.profile case RemoteProfileEntity())
|
||||
PopupMenuItem(
|
||||
child: Text(t.profile.update.buttonTxt),
|
||||
onTap: () async {
|
||||
await notifier.updateProfile();
|
||||
},
|
||||
),
|
||||
PopupMenuItem(
|
||||
child: Text(t.profile.update.buttonTxt),
|
||||
child: Text(t.profile.delete.buttonTxt),
|
||||
onTap: () async {
|
||||
await notifier.updateProfile();
|
||||
final deleteConfirmed =
|
||||
await showConfirmationDialog(
|
||||
context,
|
||||
title: t.profile.delete.buttonTxt,
|
||||
message: t.profile.delete.confirmationMsg,
|
||||
);
|
||||
if (deleteConfirmed) {
|
||||
await notifier.delete();
|
||||
}
|
||||
},
|
||||
),
|
||||
PopupMenuItem(
|
||||
child: Text(t.profile.delete.buttonTxt),
|
||||
onTap: () async {
|
||||
final deleteConfirmed =
|
||||
await showConfirmationDialog(
|
||||
context,
|
||||
title: t.profile.delete.buttonTxt,
|
||||
message: t.profile.delete.confirmationMsg,
|
||||
);
|
||||
if (deleteConfirmed) {
|
||||
await notifier.delete();
|
||||
}
|
||||
},
|
||||
),
|
||||
];
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
Form(
|
||||
autovalidateMode: state.showErrorMessages
|
||||
? AutovalidateMode.always
|
||||
: AutovalidateMode.disabled,
|
||||
child: SliverList.list(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
];
|
||||
},
|
||||
),
|
||||
child: CustomTextFormField(
|
||||
initialValue: state.profile.name,
|
||||
onChanged: (value) =>
|
||||
notifier.setField(name: value),
|
||||
validator: (value) => (value?.isEmpty ?? true)
|
||||
? t.profile.detailsForm.emptyNameMsg
|
||||
: null,
|
||||
label: t.profile.detailsForm.nameLabel,
|
||||
hint: t.profile.detailsForm.nameHint,
|
||||
),
|
||||
),
|
||||
if (state.profile
|
||||
case RemoteProfileEntity(
|
||||
:final url,
|
||||
:final options
|
||||
)) ...[
|
||||
],
|
||||
),
|
||||
Form(
|
||||
autovalidateMode: state.showErrorMessages
|
||||
? AutovalidateMode.always
|
||||
: AutovalidateMode.disabled,
|
||||
child: SliverList.list(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
child: CustomTextFormField(
|
||||
initialValue: url,
|
||||
initialValue: state.profile.name,
|
||||
onChanged: (value) =>
|
||||
notifier.setField(url: value),
|
||||
validator: (value) =>
|
||||
(value != null && !isUrl(value))
|
||||
? t.profile.detailsForm.invalidUrlMsg
|
||||
: null,
|
||||
label: t.profile.detailsForm.urlLabel,
|
||||
hint: t.profile.detailsForm.urlHint,
|
||||
notifier.setField(name: value),
|
||||
validator: (value) => (value?.isEmpty ?? true)
|
||||
? t.profile.detailsForm.emptyNameMsg
|
||||
: null,
|
||||
label: t.profile.detailsForm.nameLabel,
|
||||
hint: t.profile.detailsForm.nameHint,
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(t.profile.detailsForm.updateInterval),
|
||||
subtitle: Text(
|
||||
options?.updateInterval.toApproximateTime(
|
||||
isRelativeToNow: false,
|
||||
) ??
|
||||
t.general.toggle.disabled,
|
||||
if (state.profile
|
||||
case RemoteProfileEntity(
|
||||
:final url,
|
||||
:final options
|
||||
)) ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
child: CustomTextFormField(
|
||||
initialValue: url,
|
||||
onChanged: (value) =>
|
||||
notifier.setField(url: value),
|
||||
validator: (value) =>
|
||||
(value != null && !isUrl(value))
|
||||
? t.profile.detailsForm.invalidUrlMsg
|
||||
: null,
|
||||
label: t.profile.detailsForm.urlLabel,
|
||||
hint: t.profile.detailsForm.urlHint,
|
||||
),
|
||||
),
|
||||
leading: const Icon(Icons.update),
|
||||
onTap: () async {
|
||||
final intervalInHours = await SettingsInputDialog(
|
||||
title: t.profile.detailsForm
|
||||
.updateIntervalDialogTitle,
|
||||
initialValue: options?.updateInterval.inHours,
|
||||
optionalAction: (
|
||||
t.general.state.disable,
|
||||
() =>
|
||||
notifier.setField(updateInterval: none()),
|
||||
),
|
||||
validator: isPort,
|
||||
mapTo: int.tryParse,
|
||||
digitsOnly: true,
|
||||
).show(context);
|
||||
if (intervalInHours == null) return;
|
||||
notifier.setField(
|
||||
updateInterval: optionOf(intervalInHours),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
if (state.isEditing)
|
||||
ListTile(
|
||||
title: Text(t.profile.detailsForm.lastUpdate),
|
||||
subtitle: Text(state.profile.lastUpdate.format()),
|
||||
dense: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SliverFillRemaining(
|
||||
hasScrollBody: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 16,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
OverflowBar(
|
||||
spacing: 12,
|
||||
overflowAlignment: OverflowBarAlignment.end,
|
||||
children: [
|
||||
OutlinedButton(
|
||||
onPressed: context.pop,
|
||||
child: Text(
|
||||
MaterialLocalizations.of(context)
|
||||
.cancelButtonLabel,
|
||||
),
|
||||
ListTile(
|
||||
title: Text(t.profile.detailsForm.updateInterval),
|
||||
subtitle: Text(
|
||||
options?.updateInterval.toApproximateTime(
|
||||
isRelativeToNow: false,
|
||||
) ??
|
||||
t.general.toggle.disabled,
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: notifier.save,
|
||||
child: Text(t.profile.save.buttonText),
|
||||
),
|
||||
],
|
||||
),
|
||||
leading: const Icon(Icons.update),
|
||||
onTap: () async {
|
||||
final intervalInHours =
|
||||
await SettingsInputDialog(
|
||||
title: t.profile.detailsForm
|
||||
.updateIntervalDialogTitle,
|
||||
initialValue: options?.updateInterval.inHours,
|
||||
optionalAction: (
|
||||
t.general.state.disable,
|
||||
() => notifier.setField(
|
||||
updateInterval: none()),
|
||||
),
|
||||
validator: isPort,
|
||||
mapTo: int.tryParse,
|
||||
digitsOnly: true,
|
||||
).show(context);
|
||||
if (intervalInHours == null) return;
|
||||
notifier.setField(
|
||||
updateInterval: optionOf(intervalInHours),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
if (state.isEditing)
|
||||
ListTile(
|
||||
title: Text(t.profile.detailsForm.lastUpdate),
|
||||
subtitle: Text(state.profile.lastUpdate.format()),
|
||||
dense: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
SliverFillRemaining(
|
||||
hasScrollBody: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 16,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
OverflowBar(
|
||||
spacing: 12,
|
||||
overflowAlignment: OverflowBarAlignment.end,
|
||||
children: [
|
||||
OutlinedButton(
|
||||
onPressed: context.pop,
|
||||
child: Text(
|
||||
MaterialLocalizations.of(context)
|
||||
.cancelButtonLabel,
|
||||
),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: notifier.save,
|
||||
child: Text(t.profile.save.buttonText),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (showLoadingOverlay)
|
||||
|
||||
Reference in New Issue
Block a user