feat(learn): an Anki deck's import shows its steps, counts and percent, with Abort

Importing an Anki deck showed one bar and "Importing…". It now says which
of its four steps it is in (copying files, writing flashcards, tagging,
bringing over the review history), how many of the step's items are done
and the percent of all of it, and offers Abort (decided 9 Nov 2026), as
the archive's import does.

The importer checks between files and batches of cards. Aborted, it
deletes what it wrote: a studyset it made for the deck for good with all
of it; importing into an existing studyset, the cards it wrote there and
the topics it made for subdecks, leaving what the studyset held before;
and the files' rows it made, not those the person had. Tags it made stay.
Once everything is written, Abort no longer undoes it.

Whats-New: Importing an Anki deck shows its steps and how far it has come, and Abort stops it, keeping nothing of it.
Whats-New-De: Der Import eines Anki-Decks zeigt seine Schritte und wie weit er ist, und „Abbrechen“ beendet ihn, ohne etwas davon zu behalten.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-10 16:17:00 +01:00
commit 7cba684513
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -1,9 +1,11 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_app/testing.dart';
import 'package:halkyon_editor/halkyon_editor.dart';
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
import 'package:halkyon_learn_flutter/src/core/widget/work_progress_view.dart';
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
import 'package:halkyon_learn_flutter/src/feature/note/data/note_repository.dart';
import 'package:halkyon_learn_flutter/src/feature/note/model/note_content.dart';
@ -118,6 +120,30 @@ void main() {
expect(await cards.cardsOf('japanese'), hasLength(4));
});
testWidgets('shows its steps under way, and Abort deletes what came '
'(decided 9 Nov 2026)', (tester) async {
final hold = cardGateway.holdWrites = Completer<void>();
await startImport(tester, fixture('anki_latest.apkg'));
await tester.tap(find.widgetWithText(FilledButton, 'Import'));
await tester.pump();
await tester.pump();
expect(find.text('Step 2 of 4: Writing flashcards'), findsOneWidget);
await tester.tap(find.byKey(WorkProgressView.abortKey));
await tester.pump();
expect(find.text('Aborting…'), findsOneWidget);
hold.complete();
await tester.pumpAndSettle();
expect(
find.text('Import aborted: nothing of it was kept.'),
findsOneWidget,
);
final cards = CardRepository(cardGateway);
addTearDown(cards.dispose);
expect(await cards.cardsOf('japanese'), isEmpty);
});
testWidgets("the Library's Import makes a deck a studyset of its own, "
'named after its top deck, its subdecks inside as chosen', (
tester,