feat: add date input fields to settings_page
This commit is contained in:
@ -166,12 +166,61 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||
final TextEditingController _urlController = TextEditingController();
|
||||
final TextEditingController _usernameController = TextEditingController();
|
||||
final TextEditingController _passwordController = TextEditingController();
|
||||
final TextEditingController _historyDaysController = TextEditingController();
|
||||
final TextEditingController _historyHoursController = TextEditingController();
|
||||
|
||||
void _syncHistoryControllers(Duration duration) {
|
||||
_historyDaysController.text = duration.inDays.toString();
|
||||
_historyHoursController.text = (duration.inHours % 24).toString();
|
||||
}
|
||||
|
||||
void _showSnackBar(BuildContext context, String message) {
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context)
|
||||
.showSnackBar(SnackBar(content: Text(message)));
|
||||
}
|
||||
|
||||
void _maybeWarnLongDuration(BuildContext context, Duration duration) {
|
||||
if (duration.inDays > 4) {
|
||||
_showSnackBar(context,
|
||||
'Warning:\nLong durations might cause slowdowns and high data usage!');
|
||||
}
|
||||
}
|
||||
|
||||
void _applyDuration(BuildContext context, Duration duration) {
|
||||
if (duration.inHours < 1) {
|
||||
_showSnackBar(
|
||||
context, 'Please pick a duration of at least 1 hour (>= 1h)!');
|
||||
return;
|
||||
}
|
||||
|
||||
context.read<SettingsCubit>().updateSettings(historyTime: duration);
|
||||
_maybeWarnLongDuration(context, duration);
|
||||
}
|
||||
|
||||
void _applyManualDuration(BuildContext context) {
|
||||
final daysText = _historyDaysController.text.trim();
|
||||
final hoursText = _historyHoursController.text.trim();
|
||||
|
||||
final days = int.tryParse(daysText.isEmpty ? '0' : daysText);
|
||||
final hours = int.tryParse(hoursText.isEmpty ? '0' : hoursText);
|
||||
|
||||
if (days == null || hours == null) {
|
||||
_showSnackBar(context, 'Days and hours must be whole numbers.');
|
||||
return;
|
||||
}
|
||||
|
||||
final duration = Duration(days: days, hours: hours);
|
||||
_applyDuration(context, duration);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_urlController.dispose();
|
||||
_usernameController.dispose();
|
||||
_passwordController.dispose();
|
||||
_historyDaysController.dispose();
|
||||
_historyHoursController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -184,11 +233,13 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||
_urlController.text = state.url;
|
||||
_usernameController.text = state.username;
|
||||
_passwordController.text = state.password;
|
||||
_syncHistoryControllers(state.historyTime);
|
||||
},
|
||||
builder: (context, state) {
|
||||
_urlController.text = state.url;
|
||||
_usernameController.text = state.username;
|
||||
_passwordController.text = state.password;
|
||||
_syncHistoryControllers(state.historyTime);
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
@ -279,37 +330,68 @@ class _SettingsPageState extends State<SettingsPage> {
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
final settingsCubit = context.read<SettingsCubit>();
|
||||
var resultingDuration = await showDurationPicker(
|
||||
context: context,
|
||||
initialTime: state.historyTime,
|
||||
baseUnit: BaseUnit.hour,
|
||||
);
|
||||
if (resultingDuration != null) {
|
||||
if (resultingDuration.inHours == 0) {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Please pick a duration of 1h or more!')));
|
||||
}
|
||||
} else {
|
||||
settingsCubit.updateSettings(
|
||||
historyTime: resultingDuration);
|
||||
}
|
||||
|
||||
if (resultingDuration.inDays > 4) {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Warning:\nLong durations might cause slowdowns and high data usage!')));
|
||||
}
|
||||
}
|
||||
_applyDuration(context, resultingDuration);
|
||||
}
|
||||
},
|
||||
child: Text(
|
||||
'Set Time to Load Points (current: ${formatDuration(state.historyTime)})')),
|
||||
const SizedBox(height: 12),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'Or enter duration manually:',
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _historyDaysController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Days',
|
||||
border: OutlineInputBorder(),
|
||||
suffixText: 'd',
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _historyHoursController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Hours',
|
||||
border: OutlineInputBorder(),
|
||||
suffixText: 'h',
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: () => _applyManualDuration(context),
|
||||
icon: const Icon(Icons.edit_calendar),
|
||||
label: const Text('Apply Duration'),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
|
||||
Reference in New Issue
Block a user