pass suggestions

This commit is contained in:
davmar
2026-09-17 15:45:11 +02:00
parent bd3bc5357e
commit 22a535a6fd
2 changed files with 83 additions and 59 deletions
+71 -59
View File
@@ -2,6 +2,7 @@
library;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pocketbase/pocketbase.dart';
import 'package:provider/provider.dart';
@@ -46,6 +47,8 @@ class _LoginScreenState extends State<LoginScreen> {
email: _emailController.text,
password: _passwordController.text,
);
// Lets iOS/Android password managers offer to save / confirm the login.
TextInput.finishAutofillContext();
if (!mounted) return;
if (!widget.asRoot) {
Navigator.of(context).pop(true);
@@ -96,68 +99,77 @@ class _LoginScreenState extends State<LoginScreen> {
),
),
const SizedBox(height: 24),
Form(
key: _formKey,
child: Column(
children: [
AppTextField(
controller: _emailController,
label: 'Email',
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
autofocus: true,
validator: (value) {
final text = value?.trim() ?? '';
if (text.isEmpty) return 'Enter your email';
if (!text.contains('@')) return 'Enter a valid email';
return null;
},
),
const SizedBox(height: 16),
TextFormField(
controller: _passwordController,
obscureText: _obscurePassword,
textInputAction: TextInputAction.done,
onFieldSubmitted: (_) => _submit(),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Enter your password';
}
return null;
},
decoration: InputDecoration(
labelText: 'Password',
suffixIcon: IconButton(
tooltip: _obscurePassword
? 'Show password'
: 'Hide password',
onPressed: () => setState(
() => _obscurePassword = !_obscurePassword,
),
icon: Icon(
_obscurePassword
? Icons.visibility_outlined
: Icons.visibility_off_outlined,
AutofillGroup(
child: Form(
key: _formKey,
child: Column(
children: [
AppTextField(
controller: _emailController,
label: 'Email',
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
autofocus: true,
autofillHints: const [
AutofillHints.email,
AutofillHints.username,
],
validator: (value) {
final text = value?.trim() ?? '';
if (text.isEmpty) return 'Enter your email';
if (!text.contains('@')) return 'Enter a valid email';
return null;
},
),
const SizedBox(height: 16),
TextFormField(
controller: _passwordController,
obscureText: _obscurePassword,
textInputAction: TextInputAction.done,
autofillHints: const [AutofillHints.password],
enableSuggestions: false,
autocorrect: false,
onFieldSubmitted: (_) => _submit(),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Enter your password';
}
return null;
},
decoration: InputDecoration(
labelText: 'Password',
suffixIcon: IconButton(
tooltip: _obscurePassword
? 'Show password'
: 'Hide password',
onPressed: () => setState(
() => _obscurePassword = !_obscurePassword,
),
icon: Icon(
_obscurePassword
? Icons.visibility_outlined
: Icons.visibility_off_outlined,
),
),
),
),
),
const SizedBox(height: 24),
FilledButton.icon(
onPressed: _busy ? null : _submit,
icon: _busy
? SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(
strokeWidth: 2,
color: theme.colorScheme.onPrimary,
),
)
: const Icon(Icons.login),
label: Text(_busy ? 'Signing in…' : 'Sign in'),
),
],
const SizedBox(height: 24),
FilledButton.icon(
onPressed: _busy ? null : _submit,
icon: _busy
? SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(
strokeWidth: 2,
color: theme.colorScheme.onPrimary,
),
)
: const Icon(Icons.login),
label: Text(_busy ? 'Signing in…' : 'Sign in'),
),
],
),
),
),
],