feat(learn): voice mode goes, as a spoken conversation isn't wanted (ADR 0021, D68 withdrawn)

The developer's review of 4 Nov 2026: "an actual conversation with the AI
chatbot is not desirable and necessary". The field's voice-mode button,
the screen it opened, reading answers aloud and its texts go, and with
them flutter_tts, its patched copy in third_party/ (one override fewer),
the TTS_SERVICE query in the manifest and the plugin's registrants. The
microphone stays and dictates into the question. ImageApproval is the
conversation sheet's own again, as only voice mode needed it.

Whats-New: Voice mode is gone; the microphone dictates into your question.
Whats-New-De: Der Sprachmodus ist weg; das Mikrofon diktiert in deine Frage.

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-04 20:38:11 +01:00
commit 00212bf49c
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
2 changed files with 18 additions and 5716 deletions

View file

@ -1,40 +0,0 @@
import 'dart:async';
import 'package:halkyon_learn_flutter/src/feature/assistant/data/speech_output.dart';
/// A [SpeechOutput] that notes what it reads; while [holds], a reading
/// lasts until [finish].
class FakeSpeechOutput() implements SpeechOutput {
@override
bool supported = true;
/// Whether a reading lasts until [finish] rather than ending at once.
bool holds = false;
/// What was read aloud, in order, with the language asked for.
final spoken = <(String, String?)>[];
Completer<void>? _reading;
/// Whether a reading is under way.
bool get speaking => _reading != null;
/// Ends the reading under way.
void finish() {
final reading = _reading;
_reading = null;
reading?.complete();
}
@override
Future<void> speak(String text, {String? language}) async {
spoken.add((text, language));
if (holds) {
final reading = _reading = Completer<void>();
await reading.future;
}
}
@override
Future<void> stop() async => finish();
}

View file

@ -25,7 +25,6 @@ import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_files
import 'package:halkyon_learn_flutter/src/feature/assistant/data/assistant_lookups.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/speech_output.dart';
import 'package:halkyon_learn_flutter/src/feature/assistant/data/web_search.dart';
import 'package:halkyon_learn_flutter/src/feature/card/data/card_deletions.dart';
import 'package:halkyon_learn_flutter/src/feature/card/data/card_gateway.dart';
@ -103,7 +102,6 @@ import 'fake_publish_gateway.dart';
import 'fake_review_gateway.dart';
import 'fake_settings_gateway.dart';
import 'fake_sound_player.dart';
import 'fake_speech_output.dart';
import 'fake_studyset_gateway.dart';
import 'fake_tag_gateway.dart';
import 'fake_youtube_videos.dart';
@ -177,7 +175,6 @@ Dependencies testDependencies({
WebSearch? webSearch,
SpeechInput? speech,
PhotoPicker? photos,
SpeechOutput? speechOutput,
JellyfinGateway? jellyfinGateway,
JellyfinStore? jellyfinStore,
JellyfinSuggestion? jellyfinSuggestion,
@ -271,7 +268,6 @@ Dependencies testDependencies({
),
speech: speech ?? FakeSpeechInput(),
photos: photos ?? FakePhotoPicker(),
speechOutput: speechOutput ?? FakeSpeechOutput(),
jellyfin: JellyfinRepository(
(device) => jellyfinGateway ?? FakeJellyfinGateway(),
jellyfinStore ?? MemoryJellyfinStore(),