fix: convert HomeScreen to StatefulWidget with mounted checks
Prevents Duplicate GlobalKeys / wrong build scope crashes when opening dialogs from async scanner and DB operations. The scan button is also disabled while a query is in flight to prevent double-taps.
This commit is contained in:
parent
bbcacc0664
commit
16d1145efd
1 changed files with 23 additions and 17 deletions
|
|
@ -339,9 +339,16 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Home Screen ───────────────────────────────────────────────────────
|
// ── Home Screen ───────────────────────────────────────────────────────
|
||||||
class HomeScreen extends StatelessWidget {
|
class HomeScreen extends StatefulWidget {
|
||||||
const HomeScreen({super.key});
|
const HomeScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<HomeScreen> createState() => _HomeScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HomeScreenState extends State<HomeScreen> {
|
||||||
|
bool _isBusy = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final user = supabase.auth.currentUser;
|
final user = supabase.auth.currentUser;
|
||||||
|
|
@ -379,18 +386,20 @@ class HomeScreen extends StatelessWidget {
|
||||||
floatingActionButton: FloatingActionButton.extended(
|
floatingActionButton: FloatingActionButton.extended(
|
||||||
icon: const Icon(Icons.camera_alt),
|
icon: const Icon(Icons.camera_alt),
|
||||||
label: const Text('Scan'),
|
label: const Text('Scan'),
|
||||||
onPressed: () => _openScanner(context),
|
onPressed: _isBusy ? null : _openScanner,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens the scanner, gets the hw_id, then queries the DB.
|
/// Opens the scanner, gets the hw_id, then queries the DB.
|
||||||
Future<void> _openScanner(BuildContext context) async {
|
Future<void> _openScanner() async {
|
||||||
final hwId = await Navigator.of(context).push<String>(
|
final hwId = await Navigator.of(context).push<String>(
|
||||||
MaterialPageRoute(builder: (_) => const ScannerScreen()),
|
MaterialPageRoute(builder: (_) => const ScannerScreen()),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (hwId == null || !context.mounted) return;
|
if (hwId == null || !mounted) return;
|
||||||
|
|
||||||
|
setState(() => _isBusy = true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final data = await supabase
|
final data = await supabase
|
||||||
|
|
@ -399,21 +408,18 @@ class HomeScreen extends StatelessWidget {
|
||||||
.eq('hw_id', hwId)
|
.eq('hw_id', hwId)
|
||||||
.maybeSingle();
|
.maybeSingle();
|
||||||
|
|
||||||
if (!context.mounted) return;
|
if (!mounted) return;
|
||||||
|
setState(() => _isBusy = false);
|
||||||
|
|
||||||
if (data != null) {
|
await showDialog<void>(
|
||||||
showDialog<void>(
|
context: context,
|
||||||
context: context,
|
builder: (_) => data != null
|
||||||
builder: (_) => _AlreadyExistsDialog(hwId: hwId),
|
? _AlreadyExistsDialog(hwId: hwId)
|
||||||
);
|
: _AddCarDialog(hwId: hwId),
|
||||||
} else {
|
);
|
||||||
showDialog<void>(
|
|
||||||
context: context,
|
|
||||||
builder: (_) => _AddCarDialog(hwId: hwId),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!context.mounted) return;
|
if (!mounted) return;
|
||||||
|
setState(() => _isBusy = false);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('DB error: $e'), backgroundColor: Colors.red),
|
SnackBar(content: Text('DB error: $e'), backgroundColor: Colors.red),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue