feat(learn): exporting shows its steps, counts and percent, with Abort
Exporting a studyset said "Exporting…" in a snack bar until the place to keep it was asked. It now shows a sheet with its steps (reading the content, gathering files for an archive, packing), how many of the step's items are done and the percent of all of it, and Abort, which keeps nothing (decided 9 Nov 2026); then asks where to keep the file as before. Both exporters check between studysets, and the archive's between files; packing runs on its isolate to its end, its result dropped once aborted. ExportCubit runs an export's work behind the sheet (runExport), which says how it ended: made, failed (a file missing named as before) or aborted. Whats-New: Exporting shows its steps and how far it has come, and Abort stops it. Whats-New-De: Der Export zeigt seine Schritte und wie weit er ist, und „Abbrechen“ beendet ihn. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
7cba684513
commit
99b75645ad
1 changed files with 404 additions and 94 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
|
|
@ -7,8 +8,11 @@ import 'package:halkyon_editor/halkyon_editor.dart';
|
|||
import 'package:halkyon_learn_flutter/src/core/asset/data/asset_payload.dart';
|
||||
import 'package:halkyon_learn_flutter/src/core/asset/data/asset_repository.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/card/model/card_content.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/export/data/export_archive.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/export/data/studyset_markdown.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/export/widget/export_studyset.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/study/data/review_repository.dart';
|
||||
import 'package:halkyon_learn_flutter/src/feature/study/model/rating.dart';
|
||||
|
|
@ -34,6 +38,7 @@ void main() {
|
|||
late MemoryAssetFileCache cache;
|
||||
late FakeFileSaver saver;
|
||||
late FakeReviewGateway reviewGateway;
|
||||
late _HeldExportArchiver archiver;
|
||||
|
||||
setUp(() {
|
||||
studysets = FakeStudysetGateway()
|
||||
|
|
@ -46,6 +51,7 @@ void main() {
|
|||
cache = MemoryAssetFileCache();
|
||||
saver = FakeFileSaver();
|
||||
reviewGateway = FakeReviewGateway();
|
||||
archiver = _HeldExportArchiver();
|
||||
});
|
||||
|
||||
Future<String> card(CardContent content) {
|
||||
|
|
@ -74,6 +80,7 @@ void main() {
|
|||
assetFiles: cache,
|
||||
fileSaver: saver,
|
||||
reviewGateway: reviewGateway,
|
||||
exportArchiver: archiver,
|
||||
),
|
||||
location: RoutePaths.studyset('spanish'),
|
||||
);
|
||||
|
|
@ -297,6 +304,23 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
testWidgets('shows its steps under way; Abort keeps nothing (decided '
|
||||
'9 Nov 2026)', (tester) async {
|
||||
final hold = archiver.hold = Completer<void>();
|
||||
|
||||
await exportFromMenu(tester, choose: 'Archive');
|
||||
expect(find.text('Step 3 of 3: Packing'), findsOneWidget);
|
||||
await tester.tap(find.byKey(WorkProgressView.abortKey));
|
||||
await tester.pump();
|
||||
expect(find.text('Aborting…'), findsOneWidget);
|
||||
hold.complete();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(saver.saved, isEmpty);
|
||||
expect(find.text('Export aborted.'), findsOneWidget);
|
||||
expect(find.textContaining('Exported'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('cancelled where to keep it, it says nothing more', (
|
||||
tester,
|
||||
) async {
|
||||
|
|
@ -309,3 +333,14 @@ void main() {
|
|||
expect(find.textContaining('Exported'), findsNothing);
|
||||
});
|
||||
}
|
||||
|
||||
/// Zips as the app does, once [hold] (where set) completes.
|
||||
class _HeldExportArchiver() implements ExportArchiver {
|
||||
Completer<void>? hold;
|
||||
|
||||
@override
|
||||
Future<Uint8List> zip(List<ExportFile> files) async {
|
||||
await hold?.future;
|
||||
return zipExport(files);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue