fix: pincode functionality

This commit is contained in:
2026-07-29 22:43:38 +02:00
parent 3cf4787e8c
commit a732e2d07f
8 changed files with 112 additions and 56 deletions
+10 -8
View File
@@ -62,14 +62,16 @@ class _BarScreenViewState extends State<BarScreenView> {
onPressed: () => context.go('/settings'),
icon: const Icon(Icons.settings),
),
const SizedBox(width: 6),
IconButton(
tooltip: 'logout',
onPressed: () {
Provider.of<PinLockViewModel>(context, listen: false).lock();
},
icon: const Icon(Icons.logout),
),
if (context.watch<PinLockViewModel>().isPinSet) ...[
const SizedBox(width: 6),
IconButton(
tooltip: 'Logout',
onPressed: () {
Provider.of<PinLockViewModel>(context, listen: false).lock();
},
icon: const Icon(Icons.logout),
),
],
],
actionsPadding: const EdgeInsets.symmetric(horizontal: 8),
),
+10 -8
View File
@@ -242,30 +242,32 @@ class _PinKeypad extends StatelessWidget {
children: [
for (final row in _rows)
Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
spacing: 16,
mainAxisAlignment: MainAxisAlignment.center,
children: [
for (final digit in row)
for (final digit in row) ...[
_KeypadButton(
label: digit,
onTap: enabled ? () => onDigit(digit) : null,
),
const SizedBox(width: 20),
],
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
spacing: 16,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const _KeypadButton(isSpacer: true, onTap: null),
const SizedBox(width: 20),
_KeypadButton(
label: '0',
onTap: enabled ? () => onDigit('0') : null,
),
const SizedBox(width: 20),
_KeypadButton(
icon: Icons.backspace_outlined,
onTap: enabled ? onBackspace : null,
@@ -294,14 +296,14 @@ class _KeypadButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
if (isSpacer) {
return const SizedBox(width: 72, height: 72);
return const SizedBox(width: 80, height: 80);
}
final scheme = Theme.of(context).colorScheme;
return SizedBox(
width: 72,
height: 72,
width: 80,
height: 80,
child: Material(
color: scheme.onSurface.withValues(alpha: 0.04),
shape: const CircleBorder(),
+40 -29
View File
@@ -1,3 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:package_info_plus/package_info_plus.dart';
@@ -55,32 +57,37 @@ class _SettingsScreenViewState extends State<SettingsScreenView> {
});
}
Future<String?> _promptPin(String title, {String hint = 'Enter PIN'}) {
Future<String?> _promptPin(String title, {String hint = 'Enter PIN (4 digits)'}) {
final controller = TextEditingController();
return showDialog<String>(
context: context,
builder: (context) => AlertDialog(
title: Text(title),
content: TextField(
controller: controller,
autofocus: true,
obscureText: true,
keyboardType: TextInputType.number,
maxLength: 6,
decoration: InputDecoration(hintText: hint),
contentPadding: const EdgeInsets.fromLTRB(24, 20, 24, 0),
content: SizedBox(
width: 320,
child: TextField(
controller: controller,
autofocus: true,
obscureText: true,
keyboardType: TextInputType.number,
maxLength: 4,
decoration: InputDecoration(hintText: hint),
),
),
actionsPadding: const EdgeInsets.fromLTRB(16, 8, 16, 12),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
const SizedBox(width: 12),
FilledButton(
onPressed: () => Navigator.pop(context, controller.text),
child: const Text('Confirm'),
),
],
actionsPadding: const EdgeInsets.symmetric(horizontal: 8),
),
);
}
@@ -93,11 +100,11 @@ class _SettingsScreenViewState extends State<SettingsScreenView> {
}
Future<void> _enablePin() async {
final pin = await _promptPin('Set PIN Code', hint: '46 digits');
final pin = await _promptPin('Set PIN Code', hint: '4 digits');
if (pin == null) return;
if (pin.length < 4) {
_showError('PIN must be at least 4 digits');
if (pin.length != 4) {
_showError('PIN must be exactly 4 digits');
return;
}
@@ -109,6 +116,7 @@ class _SettingsScreenViewState extends State<SettingsScreenView> {
return;
}
pinLockViewModel.setPinRequired(true);
await context.read<SettingsViewModel>().updatePinRequired(true);
}
@@ -116,11 +124,11 @@ class _SettingsScreenViewState extends State<SettingsScreenView> {
final current = await _promptPin('Enter Current PIN');
if (current == null) return;
final newPin = await _promptPin('Enter New PIN', hint: '46 digits');
final newPin = await _promptPin('Enter New PIN', hint: '4 digits');
if (newPin == null) return;
if (newPin.length < 4) {
_showError('PIN must be at least 4 digits');
if (newPin.length != 4) {
_showError('PIN must be exactly 4 digits');
return;
}
@@ -147,6 +155,7 @@ class _SettingsScreenViewState extends State<SettingsScreenView> {
return;
}
pinLockViewModel.setPinRequired(false);
await context.read<SettingsViewModel>().updatePinRequired(false);
}
@@ -252,20 +261,21 @@ class _SettingsScreenViewState extends State<SettingsScreenView> {
),
],
),
_SettingsSection(
title: 'Updates',
children: [
_SettingsTile(
icon: Icons.system_update_alt_rounded,
title: settingsViewModel.checkingForUpdates
? 'Checking for updates...'
: 'Check for updates',
onTap: settingsViewModel.checkingForUpdates
? null
: _checkForUpdates,
),
],
),
if (Platform.isAndroid)
_SettingsSection(
title: 'Updates',
children: [
_SettingsTile(
icon: Icons.system_update_alt_rounded,
title: settingsViewModel.checkingForUpdates
? 'Checking for updates...'
: 'Check for updates',
onTap: settingsViewModel.checkingForUpdates
? null
: _checkForUpdates,
),
],
),
const SizedBox(height: 40),
GestureDetector(
onTap: _onVersionTap,
@@ -289,6 +299,7 @@ class _SettingsScreenViewState extends State<SettingsScreenView> {
}
Future<void> _checkForUpdates() async {
if (!Platform.isAndroid) return;
final vm = context.read<SettingsViewModel>();
try {