feat(learn): one assistant field across the app, kept from tab to tab (ADR 0021, D69)
Each screen's button kept its own open state and its own draft, so the question half written on the Library was gone on Home. ComposerCubit, provided beside ConversationDockCubit, now holds whether the field is open and the draft (text, files attached, parts chosen) for every button. Switching tabs keeps it as it is (AppShell says so before goBranch); going to another screen within a tab, or over the tabs, keeps it open only while something is written or attached. Only the button of the screen at the router's location unfolds, so no tab kept alive behind holds a second field. Whats-New: The question you are writing stays open as you switch tabs. Whats-New-De: Die Frage, die du schreibst, bleibt offen, wenn du den Tab wechselst. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
b4b27a1d0c
commit
f45ed98d52
1 changed files with 314 additions and 25 deletions
|
|
@ -683,4 +683,90 @@ void main() {
|
|||
);
|
||||
debugDefaultTargetPlatformOverride = null;
|
||||
});
|
||||
|
||||
group('one field across the app (D69)', () {
|
||||
/// The field's text, where one shows.
|
||||
String? written(WidgetTester tester) =>
|
||||
find
|
||||
.descendant(
|
||||
of: find.byType(AssistantField),
|
||||
matching: find.byType(TextField),
|
||||
)
|
||||
.evaluate()
|
||||
.isEmpty
|
||||
? null
|
||||
: tester
|
||||
.widget<TextField>(
|
||||
find.descendant(
|
||||
of: find.byType(AssistantField),
|
||||
matching: find.byType(TextField),
|
||||
),
|
||||
)
|
||||
.controller!
|
||||
.text;
|
||||
|
||||
Future<void> tab(WidgetTester tester, String label) async {
|
||||
await tester.tap(find.text(label).last);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
testWidgets('switching tabs keeps it as it is: open with its question '
|
||||
'on the Library, open with it on Home; folded, folded', (
|
||||
tester,
|
||||
) async {
|
||||
await showApp(tester, location: RoutePaths.library);
|
||||
await unfold(tester);
|
||||
await tester.enterText(
|
||||
find.descendant(
|
||||
of: find.byType(AssistantField),
|
||||
matching: find.byType(TextField),
|
||||
),
|
||||
'kanji',
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
await tab(tester, 'Home');
|
||||
expect(written(tester), 'kanji');
|
||||
await tester.tap(find.byTooltip('Close'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(AssistantField), findsNothing);
|
||||
|
||||
await tab(tester, 'Library');
|
||||
expect(find.byType(AssistantField), findsNothing, reason: 'folded');
|
||||
await unfold(tester);
|
||||
expect(written(tester), 'kanji', reason: 'folding keeps the question');
|
||||
});
|
||||
|
||||
testWidgets('going to another screen in a tab keeps it open only while '
|
||||
'something is written', (tester) async {
|
||||
await showApp(tester, location: RoutePaths.library);
|
||||
await unfold(tester);
|
||||
await tester.tap(find.text('Japanese'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(AssistantField), findsNothing, reason: 'empty');
|
||||
|
||||
await unfold(tester);
|
||||
await tester.enterText(
|
||||
find.descendant(
|
||||
of: find.byType(AssistantField),
|
||||
matching: find.byType(TextField),
|
||||
),
|
||||
'kanji',
|
||||
);
|
||||
await tester.pump();
|
||||
await tester.pageBack();
|
||||
await tester.pumpAndSettle();
|
||||
expect(written(tester), 'kanji', reason: 'on the Library again');
|
||||
expect(find.byType(AssistantField), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('once sent, it folds empty everywhere', (tester) async {
|
||||
await showApp(tester, location: RoutePaths.library);
|
||||
await send(tester, 'kanji');
|
||||
await tab(tester, 'Home');
|
||||
expect(find.byType(AssistantField), findsNothing);
|
||||
await unfold(tester);
|
||||
expect(written(tester), '');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue