fix(app): a phrase field keeps its focus as the app goes and comes back

SecretScreen built its child alone, and a stack around it with the cover
while the app was away (iOS), so each switch of apps built the child anew:
a phrase field lost its focus, its caret and what the keyboard was
composing (the short reading's L4). It always builds the stack now, laid
out as the child alone (StackFit.passthrough), the cover in it only while
away.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-21 18:02:35 +02:00
commit 1ca4e083bb
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -46,6 +46,39 @@ void main() {
expect(find.byKey(SecretScreen.coverKey), findsNothing);
});
testWidgets('a field under the cover keeps its text, focus and place as '
'the app goes and comes back (the short reading, L4)', (tester) async {
final typed = TextEditingController();
addTearDown(typed.dispose);
await pump(
tester,
SecretScreen(
guard: FakeScreenGuard(),
coversWhenAway: true,
child: TextField(controller: typed),
),
);
await tester.tap(find.byType(TextField));
await tester.enterText(find.byType(TextField), 'abandon abil');
await tester.pump();
final field = tester.state<EditableTextState>(find.byType(EditableText));
expect(field.widget.focusNode.hasFocus, isTrue);
tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.inactive);
await tester.pump();
expect(find.byKey(SecretScreen.coverKey), findsOneWidget);
tester.binding.handleAppLifecycleStateChanged(AppLifecycleState.resumed);
await tester.pump();
expect(find.byKey(SecretScreen.coverKey), findsNothing);
expect(
tester.state<EditableTextState>(find.byType(EditableText)),
same(field),
);
expect(field.widget.focusNode.hasFocus, isTrue);
expect(typed.text, 'abandon abil');
});
testWidgets('the phrase, shown or typed back, the recovery codes and an '
'authenticator are each shown as a secret (typed back: the reading of '
'the fixes)', (tester) async {