fix(learn): Archived and Recently deleted fold during a search
A search opened both sections whatever they were set to, so a tap on their headers did nothing while one was under way. A search still opens them, so their matches show, and a tap now folds them until the search ends, which brings them back as they were left before it. Whats-New: While searching the library, Archived and Recently deleted fold again when tapped. Whats-New-De: Beim Suchen in der Bibliothek lassen sich Archiviert und Zuletzt gelöscht wieder einklappen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
9b344141ef
commit
3ee29de391
2 changed files with 62 additions and 6 deletions
|
|
@ -494,6 +494,20 @@ class _GridState() extends State<_Grid> {
|
||||||
var _archiveOpen = false;
|
var _archiveOpen = false;
|
||||||
var _deletedOpen = true;
|
var _deletedOpen = true;
|
||||||
|
|
||||||
|
/// Whether the sections are open during a search: each search opens
|
||||||
|
/// them, so their matches show, and a tap folds them until it ends.
|
||||||
|
var _archiveOpenInSearch = true;
|
||||||
|
var _deletedOpenInSearch = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(_Grid oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
if (oldWidget.query.isEmpty && widget.query.isNotEmpty) {
|
||||||
|
_archiveOpenInSearch = true;
|
||||||
|
_deletedOpenInSearch = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const _spacing = 12.0;
|
static const _spacing = 12.0;
|
||||||
|
|
||||||
// As many columns as fit cards up to 400 dp wide; every card as tall, so
|
// As many columns as fit cards up to 400 dp wide; every card as tall, so
|
||||||
|
|
@ -594,10 +608,11 @@ class _GridState() extends State<_Grid> {
|
||||||
for (final studyset in widget.deleted)
|
for (final studyset in widget.deleted)
|
||||||
if (listed(studyset)) studyset,
|
if (listed(studyset)) studyset,
|
||||||
];
|
];
|
||||||
// A search opens the sections, so their matches show; closing the
|
// A search opens the sections, so their matches show, and a tap folds
|
||||||
// search brings them back as the person left them.
|
// them for the rest of it; closing the search brings them back as the
|
||||||
final archiveOpen = searching || _archiveOpen;
|
// person left them.
|
||||||
final deletedOpen = searching || _deletedOpen;
|
final archiveOpen = searching ? _archiveOpenInSearch : _archiveOpen;
|
||||||
|
final deletedOpen = searching ? _deletedOpenInSearch : _deletedOpen;
|
||||||
// Pulled down, the library syncs.
|
// Pulled down, the library syncs.
|
||||||
return AppRefreshIndicator(
|
return AppRefreshIndicator(
|
||||||
onRefresh: () => _syncNow(context),
|
onRefresh: () => _syncNow(context),
|
||||||
|
|
@ -655,7 +670,13 @@ class _GridState() extends State<_Grid> {
|
||||||
label: l10n.libraryArchivedSection,
|
label: l10n.libraryArchivedSection,
|
||||||
count: archived.length,
|
count: archived.length,
|
||||||
open: archiveOpen,
|
open: archiveOpen,
|
||||||
onToggle: () => setState(() => _archiveOpen = !_archiveOpen),
|
onToggle: () => setState(() {
|
||||||
|
if (searching) {
|
||||||
|
_archiveOpenInSearch = !_archiveOpenInSearch;
|
||||||
|
} else {
|
||||||
|
_archiveOpen = !_archiveOpen;
|
||||||
|
}
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (archiveOpen)
|
if (archiveOpen)
|
||||||
|
|
@ -680,7 +701,13 @@ class _GridState() extends State<_Grid> {
|
||||||
label: l10n.libraryDeletedSection,
|
label: l10n.libraryDeletedSection,
|
||||||
count: deleted.length,
|
count: deleted.length,
|
||||||
open: deletedOpen,
|
open: deletedOpen,
|
||||||
onToggle: () => setState(() => _deletedOpen = !_deletedOpen),
|
onToggle: () => setState(() {
|
||||||
|
if (searching) {
|
||||||
|
_deletedOpenInSearch = !_deletedOpenInSearch;
|
||||||
|
} else {
|
||||||
|
_deletedOpen = !_deletedOpen;
|
||||||
|
}
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (deletedOpen) ...[
|
if (deletedOpen) ...[
|
||||||
|
|
|
||||||
|
|
@ -683,6 +683,35 @@ void main() {
|
||||||
expect(find.text('Kanji'), findsNothing, reason: 'the archive is closed');
|
expect(find.text('Kanji'), findsNothing, reason: 'the archive is closed');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('a search opens the archive, which a tap folds for the rest '
|
||||||
|
'of the search', (tester) async {
|
||||||
|
stored(
|
||||||
|
'kanji',
|
||||||
|
'Kanji',
|
||||||
|
secondaryTitle: 'Japanese',
|
||||||
|
archivedAt: DateTime.utc(2026, 10),
|
||||||
|
);
|
||||||
|
await showLibrary(tester);
|
||||||
|
|
||||||
|
await tester.tap(find.byTooltip('Search'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await tester.enterText(find.byType(TextField), 'kan');
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('Kanji'), findsOneWidget);
|
||||||
|
|
||||||
|
await tester.tap(find.text('Archived'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('Kanji'), findsNothing);
|
||||||
|
|
||||||
|
await tester.enterText(find.byType(TextField), 'kanj');
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('Kanji'), findsNothing, reason: 'still folded');
|
||||||
|
|
||||||
|
await tester.tap(find.text('Archived'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('Kanji'), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('a search lists titles starting with what is typed first, then '
|
testWidgets('a search lists titles starting with what is typed first, then '
|
||||||
'those holding it as a word, then secondary titles, whatever was changed '
|
'those holding it as a word, then secondary titles, whatever was changed '
|
||||||
'last', (tester) async {
|
'last', (tester) async {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue