fix(dictionary): a Hanja reads 물 수, and each radical's form shows once
Korean names a Hanja by its meaning, then its sound; simplified Chinese shares some radicals' forms with Japanese (麦), which showed twice, and writes 黑 as itself. A test can read a language's strokes beforehand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
93c33ce079
commit
e7f3abdb8d
4 changed files with 26 additions and 18 deletions
|
|
@ -154,10 +154,12 @@ class const DictionaryCharacterTile({
|
||||||
final l10n = AppLocalizations.of(context);
|
final l10n = AppLocalizations.of(context);
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final muted = theme.colorScheme.onSurfaceVariant;
|
final muted = theme.colorScheme.onSurfaceVariant;
|
||||||
final readings = [
|
final on = joinReadings(character.onReadings, character.language);
|
||||||
joinReadings(character.onReadings, character.language),
|
final kun = joinReadings(character.kunReadings, character.language);
|
||||||
joinReadings(character.kunReadings, character.language),
|
// Korean names a Hanja by its meaning, then its sound (물 수).
|
||||||
].where((part) => part.isNotEmpty).join(' · ');
|
final readings = primaryLanguageOf(character.language) == 'ko'
|
||||||
|
? [kun, on].where((part) => part.isNotEmpty).join(' ')
|
||||||
|
: [on, kun].where((part) => part.isNotEmpty).join(' · ');
|
||||||
final marks = [
|
final marks = [
|
||||||
...characterMarks(l10n, character),
|
...characterMarks(l10n, character),
|
||||||
if (character.strokes case final strokes?)
|
if (character.strokes case final strokes?)
|
||||||
|
|
|
||||||
|
|
@ -300,14 +300,16 @@ List<String> radicalFormsIn(Radical radical, String language) {
|
||||||
if (_japaneseForms[radical.number] != form) form,
|
if (_japaneseForms[radical.number] != form) form,
|
||||||
];
|
];
|
||||||
final simplified = _simplifiedForms[radical.number];
|
final simplified = _simplifiedForms[radical.number];
|
||||||
return primary == 'ko' || isTraditionalChinese(language) || simplified == null
|
if (primary == 'ko' || isTraditionalChinese(language) || simplified == null) {
|
||||||
? shared
|
return shared;
|
||||||
: [
|
}
|
||||||
// Simplified Chinese writes 食 as 饣 at a character's side.
|
// Simplified Chinese writes 食 as 饣 at a character's side; a form it
|
||||||
for (final form in shared)
|
// shares with Japanese (麦), or the radical itself (黑), only once.
|
||||||
if (radical.number != 184) form,
|
return {
|
||||||
simplified,
|
for (final form in shared)
|
||||||
];
|
if (radical.number != 184) form,
|
||||||
|
simplified,
|
||||||
|
}.where((form) => form != radical.character).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The 214 radicals with the forms they take in [language]
|
/// The 214 radicals with the forms they take in [language]
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ void main() {
|
||||||
expect(radicalFormsIn(food, 'zh-CN'), ['饣']);
|
expect(radicalFormsIn(food, 'zh-CN'), ['饣']);
|
||||||
expect(radicalFormsIn(food, 'zh-TW'), ['飠']);
|
expect(radicalFormsIn(food, 'zh-TW'), ['飠']);
|
||||||
expect(radicalsIn('zh-Hans')[148].variants, ['讠']);
|
expect(radicalsIn('zh-Hans')[148].variants, ['讠']);
|
||||||
|
// Each form once, never the radical itself.
|
||||||
|
expect(radicalFormsIn(radicals[198], 'zh'), ['麦']);
|
||||||
|
expect(radicalFormsIn(radicals[202], 'zh'), isEmpty);
|
||||||
expect((hasRadicals('ko'), hasRadicals('el')), (true, false));
|
expect((hasRadicals('ko'), hasRadicals('el')), (true, false));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/kanji/data/stroke_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/kanji/data/stroke_repository.dart';
|
||||||
|
|
||||||
/// The bundled strokes of [characters], read already: reading an asset is
|
/// The bundled strokes of [characters] in [language], read already:
|
||||||
/// real input, which a widget test's fake clock never lets finish, so it
|
/// reading an asset is real input, which a widget test's fake clock never
|
||||||
/// happens outside it and the app gets this repository
|
/// lets finish, so it happens outside it and the app gets this repository
|
||||||
/// (`testDependencies(strokes: ...)`).
|
/// (`testDependencies(strokes: ...)`).
|
||||||
Future<StrokeRepository> loadedStrokes(
|
Future<StrokeRepository> loadedStrokes(
|
||||||
WidgetTester tester,
|
WidgetTester tester,
|
||||||
Iterable<String> characters,
|
Iterable<String> characters, {
|
||||||
) async {
|
String? language,
|
||||||
|
}) async {
|
||||||
final strokes = StrokeRepository();
|
final strokes = StrokeRepository();
|
||||||
await tester.runAsync(() async {
|
await tester.runAsync(() async {
|
||||||
for (final character in characters) {
|
for (final character in characters) {
|
||||||
await strokes.strokesOf(character);
|
await strokes.strokesOf(character, language: language);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return strokes;
|
return strokes;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue