perf(learn): a conversation deleted goes at once, with an Undo
Deleting a kept conversation asked first and then waited while its turns were blanked and deleted. It now goes as a card or a note does: ConversationDeletions, a DelayedDeletions opened with the person's data, takes it off the history at once (the list leaves out what is pending), offers Undo for a moment on the sheet (hasSnackBars), and blanks and deletes it once that is over; a deletion that fails shows the conversation again, as every DelayedDeletions does. The question before deleting goes, as Undo replaces it. Whats-New: A conversation with an assistant is deleted at once, and Undo brings it back. Whats-New-De: Eine Unterhaltung mit einem Assistenten wird sofort gelöscht, und „Rückgängig“ holt sie zurück. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
920e1c6c13
commit
891e9dfd75
12 changed files with 106 additions and 71 deletions
File diff suppressed because one or more lines are too long
|
|
@ -1778,8 +1778,7 @@
|
||||||
"assistantHistoryExplained": "Karte erklärt",
|
"assistantHistoryExplained": "Karte erklärt",
|
||||||
"assistantHistoryChecked": "Auf Fehler geprüft",
|
"assistantHistoryChecked": "Auf Fehler geprüft",
|
||||||
"assistantHistoryDelete": "Unterhaltung löschen",
|
"assistantHistoryDelete": "Unterhaltung löschen",
|
||||||
"assistantHistoryDeleteMessage": "„{title}“ verschwindet von allen deinen Geräten.",
|
"assistantHistoryDeleted": "Unterhaltung gelöscht",
|
||||||
"assistantHistoryDeleteConfirm": "Löschen",
|
|
||||||
"assistantGone": "Ein nicht mehr angebotener Assistent",
|
"assistantGone": "Ein nicht mehr angebotener Assistent",
|
||||||
"assistantGoneNote": "Dieser Assistent wird dir hier nicht mehr angeboten, also lässt sich die Unterhaltung nicht fortsetzen.",
|
"assistantGoneNote": "Dieser Assistent wird dir hier nicht mehr angeboten, also lässt sich die Unterhaltung nicht fortsetzen.",
|
||||||
"assistantNotKept": "Nicht gespeichert: Dieses Gerät kann Unterhaltungen nicht verschlüsseln, also ist diese weg, sobald du sie schließt.",
|
"assistantNotKept": "Nicht gespeichert: Dieses Gerät kann Unterhaltungen nicht verschlüsseln, also ist diese weg, sobald du sie schließt.",
|
||||||
|
|
|
||||||
|
|
@ -2117,9 +2117,7 @@
|
||||||
"assistantHistoryChecked": "Checked for mistakes",
|
"assistantHistoryChecked": "Checked for mistakes",
|
||||||
"@assistantHistoryChecked": {"description": "A conversation that checked what was written (D54)."},
|
"@assistantHistoryChecked": {"description": "A conversation that checked what was written (D54)."},
|
||||||
"assistantHistoryDelete": "Delete conversation",
|
"assistantHistoryDelete": "Delete conversation",
|
||||||
"assistantHistoryDeleteMessage": "“{title}” goes from all your devices.",
|
"assistantHistoryDeleted": "Conversation deleted",
|
||||||
"@assistantHistoryDeleteMessage": {"placeholders": {"title": {"type": "String"}}},
|
|
||||||
"assistantHistoryDeleteConfirm": "Delete",
|
|
||||||
"assistantGone": "An assistant no longer offered",
|
"assistantGone": "An assistant no longer offered",
|
||||||
"assistantGoneNote": "This assistant is no longer offered to you here, so the conversation can't go on.",
|
"assistantGoneNote": "This assistant is no longer offered to you here, so the conversation can't go on.",
|
||||||
"assistantNotKept": "Not kept: this device can't encrypt conversations, so this one is gone once you close it.",
|
"assistantNotKept": "Not kept: this device can't encrypt conversations, so this one is gone once you close it.",
|
||||||
|
|
|
||||||
|
|
@ -10497,17 +10497,11 @@ abstract class AppLocalizations {
|
||||||
/// **'Delete conversation'**
|
/// **'Delete conversation'**
|
||||||
String get assistantHistoryDelete;
|
String get assistantHistoryDelete;
|
||||||
|
|
||||||
/// No description provided for @assistantHistoryDeleteMessage.
|
/// No description provided for @assistantHistoryDeleted.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'“{title}” goes from all your devices.'**
|
/// **'Conversation deleted'**
|
||||||
String assistantHistoryDeleteMessage(String title);
|
String get assistantHistoryDeleted;
|
||||||
|
|
||||||
/// No description provided for @assistantHistoryDeleteConfirm.
|
|
||||||
///
|
|
||||||
/// In en, this message translates to:
|
|
||||||
/// **'Delete'**
|
|
||||||
String get assistantHistoryDeleteConfirm;
|
|
||||||
|
|
||||||
/// No description provided for @assistantGone.
|
/// No description provided for @assistantGone.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -6634,12 +6634,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
String get assistantHistoryDelete => 'Unterhaltung löschen';
|
String get assistantHistoryDelete => 'Unterhaltung löschen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String assistantHistoryDeleteMessage(String title) {
|
String get assistantHistoryDeleted => 'Unterhaltung gelöscht';
|
||||||
return '„$title“ verschwindet von allen deinen Geräten.';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get assistantHistoryDeleteConfirm => 'Löschen';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get assistantGone => 'Ein nicht mehr angebotener Assistent';
|
String get assistantGone => 'Ein nicht mehr angebotener Assistent';
|
||||||
|
|
|
||||||
|
|
@ -6574,12 +6574,7 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||||
String get assistantHistoryDelete => 'Delete conversation';
|
String get assistantHistoryDelete => 'Delete conversation';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String assistantHistoryDeleteMessage(String title) {
|
String get assistantHistoryDeleted => 'Conversation deleted';
|
||||||
return '“$title” goes from all your devices.';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get assistantHistoryDeleteConfirm => 'Delete';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get assistantGone => 'An assistant no longer offered';
|
String get assistantGone => 'An assistant no longer offered';
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import 'package:halkyon_learn_flutter/src/feature/anki/data/anki_package_reader.
|
||||||
import 'package:halkyon_learn_flutter/src/feature/archive/data/archive_reader.dart';
|
import 'package:halkyon_learn_flutter/src/feature/archive/data/archive_reader.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_files.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_files.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_lookups.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_lookups.dart';
|
||||||
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/conversation_deletions.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/conversation_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/conversation_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/photo_picker.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/photo_picker.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/sync_conversation_gateway.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/sync_conversation_gateway.dart';
|
||||||
|
|
@ -567,6 +568,7 @@ Future<PersonDependencies> _openPersonData(
|
||||||
final pathDeletions = LearningPathDeletions(paths);
|
final pathDeletions = LearningPathDeletions(paths);
|
||||||
final stepDeletions = StepDeletions(paths);
|
final stepDeletions = StepDeletions(paths);
|
||||||
final pdfDeletions = PdfDeletions(pdfSources);
|
final pdfDeletions = PdfDeletions(pdfSources);
|
||||||
|
final conversationDeletions = ConversationDeletions(conversations);
|
||||||
final publishing = PublishRepository(
|
final publishing = PublishRepository(
|
||||||
ServerpodPublishGateway(client),
|
ServerpodPublishGateway(client),
|
||||||
FilePublishedStore(File(p.join(folder.path, 'published.json'))),
|
FilePublishedStore(File(p.join(folder.path, 'published.json'))),
|
||||||
|
|
@ -628,6 +630,7 @@ Future<PersonDependencies> _openPersonData(
|
||||||
pathDeletions: pathDeletions,
|
pathDeletions: pathDeletions,
|
||||||
stepDeletions: stepDeletions,
|
stepDeletions: stepDeletions,
|
||||||
pdfDeletions: pdfDeletions,
|
pdfDeletions: pdfDeletions,
|
||||||
|
conversationDeletions: conversationDeletions,
|
||||||
pomodoroRuns: FilePomodoroRunStore(
|
pomodoroRuns: FilePomodoroRunStore(
|
||||||
File(p.join(folder.path, 'pomodoro.json')),
|
File(p.join(folder.path, 'pomodoro.json')),
|
||||||
),
|
),
|
||||||
|
|
@ -666,6 +669,7 @@ Future<PersonDependencies> _openPersonData(
|
||||||
await pathDeletions.dispose();
|
await pathDeletions.dispose();
|
||||||
await stepDeletions.dispose();
|
await stepDeletions.dispose();
|
||||||
await pdfDeletions.dispose();
|
await pdfDeletions.dispose();
|
||||||
|
await conversationDeletions.dispose();
|
||||||
await discussions.dispose();
|
await discussions.dispose();
|
||||||
await counting.dispose();
|
await counting.dispose();
|
||||||
await studysetProgress.dispose();
|
await studysetProgress.dispose();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:halkyon_app/halkyon_app.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/asset/data/asset_repository.dart';
|
import 'package:halkyon_learn_flutter/src/core/asset/data/asset_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/grammar/grammar_checks.dart';
|
import 'package:halkyon_learn_flutter/src/core/grammar/grammar_checks.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_lookups.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_lookups.dart';
|
||||||
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/conversation_deletions.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/conversation_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/conversation_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/card/data/card_deletions.dart';
|
import 'package:halkyon_learn_flutter/src/feature/card/data/card_deletions.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
||||||
|
|
@ -96,6 +97,9 @@ class PersonDependencies({
|
||||||
/// The PDF deletions that can still be undone.
|
/// The PDF deletions that can still be undone.
|
||||||
required final PdfDeletions pdfDeletions,
|
required final PdfDeletions pdfDeletions,
|
||||||
|
|
||||||
|
/// The deletions of kept conversations that can still be undone.
|
||||||
|
required final ConversationDeletions conversationDeletions,
|
||||||
|
|
||||||
/// Where this device keeps the person's Pomodoro timer.
|
/// Where this device keeps the person's Pomodoro timer.
|
||||||
required final PomodoroRunStore pomodoroRuns,
|
required final PomodoroRunStore pomodoroRuns,
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
import 'package:halkyon_app/halkyon_app.dart';
|
||||||
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/conversation_repository.dart';
|
||||||
|
|
||||||
|
/// The person's deletions of kept conversations (ADR 0021, D48), which can
|
||||||
|
/// be undone for a moment (see [DelayedDeletions]), as a card's or a note's:
|
||||||
|
/// the conversation leaves the history at once, and is blanked and deleted
|
||||||
|
/// with its turns once the time to undo is over.
|
||||||
|
class ConversationDeletions(
|
||||||
|
ConversationRepository conversations, {
|
||||||
|
super.undoWindow,
|
||||||
|
}) extends DelayedDeletions {
|
||||||
|
this : super(conversations.delete, logName: 'Conversations');
|
||||||
|
}
|
||||||
|
|
@ -16,8 +16,8 @@ import 'package:material_ui/material_ui.dart';
|
||||||
|
|
||||||
/// The person's kept conversations (ADR 0021, D48), the newest first, those
|
/// The person's kept conversations (ADR 0021, D48), the newest first, those
|
||||||
/// asked on [studysetId] before the rest, each with who answers and how far
|
/// asked on [studysetId] before the rest, each with who answers and how far
|
||||||
/// it looks: opening one continues it in its sheet; deleting one asks
|
/// it looks: opening one continues it in its sheet; deleting one takes it
|
||||||
/// first.
|
/// off at once, with an Undo for a moment.
|
||||||
Future<void> showConversationHistory(
|
Future<void> showConversationHistory(
|
||||||
BuildContext context, {
|
BuildContext context, {
|
||||||
String? studysetId,
|
String? studysetId,
|
||||||
|
|
@ -42,6 +42,11 @@ class _HistoryState() extends State<_History> {
|
||||||
context,
|
context,
|
||||||
).conversations.watch();
|
).conversations.watch();
|
||||||
|
|
||||||
|
/// The conversations being deleted, which the list leaves out at once.
|
||||||
|
late final _deleting = PersonDependencies.of(
|
||||||
|
context,
|
||||||
|
).conversationDeletions.watchPending();
|
||||||
|
|
||||||
/// Every studyset's title, for the conversations asked on one.
|
/// Every studyset's title, for the conversations asked on one.
|
||||||
late final Future<Map<String, String>> _titles =
|
late final Future<Map<String, String>> _titles =
|
||||||
PersonDependencies.of(
|
PersonDependencies.of(
|
||||||
|
|
@ -70,37 +75,49 @@ class _HistoryState() extends State<_History> {
|
||||||
final l10n = AppLocalizations.of(context);
|
final l10n = AppLocalizations.of(context);
|
||||||
return SheetScaffold(
|
return SheetScaffold(
|
||||||
title: l10n.assistantHistory,
|
title: l10n.assistantHistory,
|
||||||
body: StreamBuilder<List<AssistantConversation>>(
|
// A deletion's Undo shows on it, not behind its barrier.
|
||||||
stream: _conversations,
|
hasSnackBars: true,
|
||||||
builder: (context, snapshot) => switch (snapshot.data) {
|
body: StreamBuilder<Set<String>>(
|
||||||
null => const Padding(
|
stream: _deleting,
|
||||||
padding: EdgeInsets.all(24),
|
builder: (context, deleting) =>
|
||||||
child: Center(child: AppLoadingIndicator()),
|
StreamBuilder<List<AssistantConversation>>(
|
||||||
),
|
stream: _conversations,
|
||||||
[] => Padding(
|
builder: (context, snapshot) => switch (snapshot.data
|
||||||
padding: const EdgeInsets.symmetric(vertical: 24),
|
?.where(
|
||||||
child: EmptyListMessage(
|
(conversation) =>
|
||||||
icon: LucideIcons.messagesSquare,
|
!(deleting.data?.contains(conversation.id) ?? false),
|
||||||
title: l10n.assistantHistoryEmpty,
|
)
|
||||||
hint: l10n.assistantHistoryEmptyHint,
|
.toList()) {
|
||||||
),
|
null => const Padding(
|
||||||
),
|
padding: EdgeInsets.all(24),
|
||||||
final all => FutureBuilder<Map<String, String>>(
|
child: Center(child: AppLoadingIndicator()),
|
||||||
future: _titles,
|
),
|
||||||
builder: (context, titles) => Column(
|
[] => Padding(
|
||||||
children: [
|
padding: const EdgeInsets.symmetric(vertical: 24),
|
||||||
for (final conversation in _ordered(all))
|
child: EmptyListMessage(
|
||||||
_ConversationTile(
|
icon: LucideIcons.messagesSquare,
|
||||||
conversation: conversation,
|
title: l10n.assistantHistoryEmpty,
|
||||||
studysetTitle: switch (conversation.scope.studysetId) {
|
hint: l10n.assistantHistoryEmptyHint,
|
||||||
final id? => titles.data?[id],
|
|
||||||
null => null,
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
|
final all => FutureBuilder<Map<String, String>>(
|
||||||
|
future: _titles,
|
||||||
|
builder: (context, titles) => Column(
|
||||||
|
children: [
|
||||||
|
for (final conversation in _ordered(all))
|
||||||
|
_ConversationTile(
|
||||||
|
conversation: conversation,
|
||||||
|
studysetTitle:
|
||||||
|
switch (conversation.scope.studysetId) {
|
||||||
|
final id? => titles.data?[id],
|
||||||
|
null => null,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -152,7 +169,7 @@ class const _ConversationTile({
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
tooltip: l10n.assistantHistoryDelete,
|
tooltip: l10n.assistantHistoryDelete,
|
||||||
icon: const Icon(LucideIcons.trash2),
|
icon: const Icon(LucideIcons.trash2),
|
||||||
onPressed: () => unawaited(_delete(context)),
|
onPressed: () => _delete(context),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// The conversation's sheet over the screen, not over this list,
|
// The conversation's sheet over the screen, not over this list,
|
||||||
|
|
@ -176,16 +193,17 @@ class const _ConversationTile({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _delete(BuildContext context) async {
|
/// Takes the conversation off at once and offers to undo that for a
|
||||||
|
/// moment, as a card or a note; it is blanked and deleted once that is
|
||||||
|
/// over, the deletion outliving this list.
|
||||||
|
void _delete(BuildContext context) {
|
||||||
final l10n = AppLocalizations.of(context);
|
final l10n = AppLocalizations.of(context);
|
||||||
final conversations = PersonDependencies.of(context).conversations;
|
final deletions = PersonDependencies.of(context).conversationDeletions
|
||||||
if (await confirmDestructiveAction(
|
..delete(conversation.id);
|
||||||
|
showUndoSnackBar(
|
||||||
context,
|
context,
|
||||||
title: l10n.assistantHistoryDelete,
|
message: l10n.assistantHistoryDeleted,
|
||||||
message: l10n.assistantHistoryDeleteMessage(conversation.title),
|
onUndo: () => deletions.undo(conversation.id),
|
||||||
confirmLabel: l10n.assistantHistoryDeleteConfirm,
|
);
|
||||||
)) {
|
|
||||||
await conversations.delete(conversation.id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -764,8 +764,8 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('kept conversations are listed in the field, those about '
|
testWidgets('kept conversations are listed in the field, those about '
|
||||||
'where the person is first; one opens in its sheet, and goes after '
|
'where the person is first; one opens in its sheet, and goes at once, '
|
||||||
'asking (D48)', (tester) async {
|
'with an Undo (D48)', (tester) async {
|
||||||
final conversations = ConversationRepository(kept);
|
final conversations = ConversationRepository(kept);
|
||||||
addTearDown(conversations.dispose);
|
addTearDown(conversations.dispose);
|
||||||
final id = await conversations.start(
|
final id = await conversations.start(
|
||||||
|
|
@ -799,13 +799,24 @@ void main() {
|
||||||
|
|
||||||
await tester.tap(find.byTooltip('Conversations'));
|
await tester.tap(find.byTooltip('Conversations'));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
// Gone at once, with an Undo for a moment, as a card or a note.
|
||||||
await tester.tap(find.byTooltip('Delete conversation'));
|
await tester.tap(find.byTooltip('Delete conversation'));
|
||||||
|
await tester.pump();
|
||||||
|
expect(find.text('Why て-form?'), findsNothing);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await tester.tap(find.text('Delete'));
|
expect(find.text('Conversation deleted'), findsOneWidget);
|
||||||
|
await tester.tap(find.text('Undo'));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('Why て-form?'), findsOneWidget);
|
||||||
|
|
||||||
|
await tester.tap(find.byTooltip('Delete conversation'));
|
||||||
|
await tester.pump();
|
||||||
expect(find.text('No conversations yet'), findsOneWidget);
|
expect(find.text('No conversations yet'), findsOneWidget);
|
||||||
|
expect(kept.blanked, isEmpty, reason: 'Undo is still offered');
|
||||||
|
await tester.pump(const Duration(seconds: 5));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
expect(kept.blanked, [id]);
|
expect(kept.blanked, [id]);
|
||||||
|
expect(find.text('No conversations yet'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets("a device that can't seal answers, and says it keeps nothing "
|
testWidgets("a device that can't seal answers, and says it keeps nothing "
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import 'package:halkyon_learn_flutter/src/feature/archive/data/archive_reader.da
|
||||||
import 'package:halkyon_learn_flutter/src/feature/archive/model/import_archive.dart';
|
import 'package:halkyon_learn_flutter/src/feature/archive/model/import_archive.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_files.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_files.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_lookups.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_lookups.dart';
|
||||||
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/conversation_deletions.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/conversation_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/conversation_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/photo_picker.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/photo_picker.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/assistant/data/web_search.dart';
|
import 'package:halkyon_learn_flutter/src/feature/assistant/data/web_search.dart';
|
||||||
|
|
@ -345,6 +346,7 @@ Dependencies testDependencies({
|
||||||
final pathDeletions = LearningPathDeletions(paths);
|
final pathDeletions = LearningPathDeletions(paths);
|
||||||
final stepDeletions = StepDeletions(paths);
|
final stepDeletions = StepDeletions(paths);
|
||||||
final pdfDeletions = PdfDeletions(pdfSources);
|
final pdfDeletions = PdfDeletions(pdfSources);
|
||||||
|
final conversationDeletions = ConversationDeletions(conversations);
|
||||||
final studysetTabs = StudysetTabs(
|
final studysetTabs = StudysetTabs(
|
||||||
studysetTabStore ?? MemoryStudysetTabStore(),
|
studysetTabStore ?? MemoryStudysetTabStore(),
|
||||||
);
|
);
|
||||||
|
|
@ -376,6 +378,7 @@ Dependencies testDependencies({
|
||||||
pathDeletions: pathDeletions,
|
pathDeletions: pathDeletions,
|
||||||
stepDeletions: stepDeletions,
|
stepDeletions: stepDeletions,
|
||||||
pdfDeletions: pdfDeletions,
|
pdfDeletions: pdfDeletions,
|
||||||
|
conversationDeletions: conversationDeletions,
|
||||||
pomodoroRuns: pomodoroRuns ?? MemoryPomodoroRunStore(),
|
pomodoroRuns: pomodoroRuns ?? MemoryPomodoroRunStore(),
|
||||||
studysetTabs: studysetTabs,
|
studysetTabs: studysetTabs,
|
||||||
privateOffer: privateOffer ?? MemoryPrivateOfferStore(),
|
privateOffer: privateOffer ?? MemoryPrivateOfferStore(),
|
||||||
|
|
@ -427,6 +430,7 @@ Dependencies testDependencies({
|
||||||
await pathDeletions.dispose();
|
await pathDeletions.dispose();
|
||||||
await stepDeletions.dispose();
|
await stepDeletions.dispose();
|
||||||
await pdfDeletions.dispose();
|
await pdfDeletions.dispose();
|
||||||
|
await conversationDeletions.dispose();
|
||||||
await studysetProgress.dispose();
|
await studysetProgress.dispose();
|
||||||
await studysets.dispose();
|
await studysets.dispose();
|
||||||
await tags.dispose();
|
await tags.dispose();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue