Security locks work independently; other-account avatars flush right in the avatar menu

Login lock, lock account switching and lock hidden files no longer depend on
each other: passGate prompts on its own flag, the two sub-locks can be set
with login lock off, and disabling login lock leaves them alone. Turning any
lock on or off asks for device auth (on also checks the device can). The iOS
Share Extension's unlock rules follow. The avatar dropdown's additional
accounts lose the 44px spacer so their avatars sit at the right edge.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Ayushya Amitabh
2026-10-06 20:07:28 -04:00
co-authored by Claude Sonnet 5.5
parent 27c8ac12f2
commit 22a6602f08
10 changed files with 323 additions and 55 deletions
+10
View File
@@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:local_auth/local_auth.dart';
/// Thin wrapper around `local_auth`. Deliberately doesn't implement its own
@@ -8,9 +9,17 @@ import 'package:local_auth/local_auth.dart';
class AppLockService {
static final LocalAuthentication _auth = LocalAuthentication();
/// Replace the platform prompt in tests (null = the real one).
@visibleForTesting
static Future<bool> Function(String reason)? debugAuthenticate;
@visibleForTesting
static Future<bool> Function()? debugIsDeviceSupported;
/// Whether this device can do *some* form of local auth - biometric
/// enrolled, or at minimum a device PIN/pattern/password set up.
static Future<bool> isDeviceSupported() async {
if (debugIsDeviceSupported != null) return debugIsDeviceSupported!();
try {
final canCheckBiometrics = await _auth.canCheckBiometrics;
if (canCheckBiometrics) return true;
@@ -24,6 +33,7 @@ class AppLockService {
/// throws) on cancellation, failure, or any platform error, so callers
/// can treat every non-true result the same way: stay locked/blocked.
static Future<bool> authenticate(String reason) async {
if (debugAuthenticate != null) return debugAuthenticate!(reason);
try {
return await _auth.authenticate(
localizedReason: reason,