fix(app): blocks from the / menu go into card fields
Inserting a sound, a YouTube video or a study button through the / menu in a card's field failed (found with the Snap build). Two causes: A card field closes its editor when the focus leaves it, except to a dialog. The / menu takes the focus too, so the editor was gone while its menu was open, and the block chosen went to an editor that no longer existed. The field now stays open while the editor's own popup holds the focus (the editor package's keepEditorFocusNotifier, which its editors heed for themselves, read through RichContentEditor.popupHasFocus). The editor package keeps the menu, and the layer closing it on a tap, above everything until the chosen item's handler returns, so a block asking in a dialog (formula, video, study button) had the menu over that dialog. Our items now close the menu first; the handler is given the menu for that. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
e35ce5c81d
commit
103881a28d
1 changed files with 60 additions and 5 deletions
|
|
@ -273,6 +273,51 @@ void main() {
|
|||
expect(blocks, contains(containsPair('type', mathBlockType)));
|
||||
});
|
||||
|
||||
testWidgets('the / menu takes the focus without closing its field, so the '
|
||||
'block chosen goes into the card', (tester) async {
|
||||
await cards.create('japanese', card('猫', 'cat'));
|
||||
await showStudyset(tester, size: const Size(412, 915));
|
||||
await open(tester, '猫');
|
||||
|
||||
await tester.tap(find.text('cat', findRichText: true));
|
||||
await settle(tester);
|
||||
final editor = tester.widget<AppFlowyEditor>(
|
||||
find.descendant(
|
||||
of: find.byType(RichContentEditor),
|
||||
matching: find.byType(AppFlowyEditor),
|
||||
),
|
||||
);
|
||||
final slash = editor.characterShortcutEvents.singleWhere(
|
||||
(event) => event.character == '/',
|
||||
);
|
||||
await slash.handler(editor.editorState);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(RichContentEditor), findsOneWidget);
|
||||
|
||||
// The menu builds only the items near what it shows.
|
||||
final menu = find.descendant(
|
||||
of: find.byType(SelectionMenuWidget),
|
||||
matching: find.byType(Scrollable),
|
||||
);
|
||||
await tester.scrollUntilVisible(find.text('Formula'), 40, scrollable: menu);
|
||||
await tester.ensureVisible(find.text('Formula'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Formula'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(SelectionMenuWidget), findsNothing);
|
||||
await tester.enterText(find.byType(TextField), 'x^2');
|
||||
await tester.tap(find.text('Save'));
|
||||
await settle(tester);
|
||||
await tester.tap(find.byType(BackButton));
|
||||
await settle(tester);
|
||||
|
||||
final back = (await cards.cardsOf('japanese')).single.content.back;
|
||||
final blocks =
|
||||
(back.editorJson['document']! as Map<String, Object?>)['children']!
|
||||
as List<Object?>;
|
||||
expect(blocks, contains(containsPair('type', mathBlockType)));
|
||||
});
|
||||
|
||||
testWidgets('the card types fit a phone, none of their names broken', (
|
||||
tester,
|
||||
) async {
|
||||
|
|
|
|||
Loading…
Reference in a new issue