feat(meditate): the library says what a recording speaks, and shows the languages chosen (ADR 0038, D17)

An item's page names its spoken language. Where the library has several,
its cards do too and Explore offers them, several at once, none meaning
every one, kept in the person's sealed settings. A library with one
language asks nothing.

Whats-New: The library says each recording's spoken language, and Explore lets you choose among several.
Whats-New-De: Die Bibliothek nennt die gesprochene Sprache jeder Aufnahme, und bei mehreren wählst du sie in „Entdecken“ aus.

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-05 15:54:12 +01:00
commit 3e69e6b2f7
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -2,6 +2,8 @@ import 'package:clock/clock.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_app/halkyon_app.dart';
import 'package:halkyon_app/testing.dart';
import 'package:halkyon_meditate_client/halkyon_meditate_client.dart'
show LibraryAudio, LibraryItem;
import 'package:halkyon_meditate_flutter/src/app/meditate_app.dart';
import 'package:halkyon_meditate_flutter/src/app/meditate_dependencies.dart';
import 'package:halkyon_meditate_flutter/src/core/privacy/meditate_keys.dart';
@ -1280,6 +1282,48 @@ void main() {
expect(find.text('Library credits'), findsNothing);
});
group('spoken languages (5 Nov 2026)', () {
final german = LibraryItem(
id: 'abendruhe',
title: 'Abendruhe',
category: 'meditation',
language: 'de-CH',
audio: [
LibraryAudio(file: 'b.mp3', durationSeconds: 300, size: 1),
],
licence: 'CC0',
credit: 'Niemand',
);
testWidgets('asked only where the library has several', (tester) async {
await exploreLibrary(tester);
await scrollTo(tester, find.text('From meditate.example.org'));
expect(find.text('Spoken language'), findsNothing);
});
testWidgets('where it has several, the items of those chosen show, '
'several at once, none meaning every one', (tester) async {
final sample = sampleCatalogue();
library.answer = sample.copyWith(items: [...sample.items, german]);
await start(tester, usedBefore: true);
await goTab(tester, 'Explore');
await scrollTo(tester, find.text('Spoken language'));
await scrollTo(tester, find.text('Abendruhe'));
expect(find.textContaining('· German ·'), findsOneWidget);
await scrollTo(tester, find.widgetWithText(FilterChip, 'English'));
await tester.tap(find.widgetWithText(FilterChip, 'English'));
await tester.pumpAndSettle();
expect(find.text('Abendruhe'), findsNothing);
expect(find.text('Evening rest'), findsOneWidget);
await tester.tap(find.widgetWithText(FilterChip, 'German'));
await tester.pumpAndSettle();
await scrollTo(tester, find.text('Abendruhe'));
expect(find.text('Abendruhe'), findsOneWidget);
});
});
testWidgets("Explore shows the instance's courses and items below the "
'practices, by category and by the search', (tester) async {
await exploreLibrary(tester);