docs: credit KanjiVG in About, and name the kanji dictionary

About lists the data the app comes with beside the instance's
dictionaries: KanjiVG's strokes, by Ulrich Apel under CC BY-SA 3.0, with
the link its licence asks for. The server's README names the dictionary
of kanji and kana beside JMdict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-09 16:05:05 +02:00
commit 9bb3826556
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
8 changed files with 58 additions and 6 deletions

View file

@ -554,6 +554,7 @@
"@writingSuggested": {"placeholders": {"rating": {"type": "String"}}}, "@writingSuggested": {"placeholders": {"rating": {"type": "String"}}},
"writingNoStrokes": "Für diese Schriftzeichen gibt es keine Strichfolge: Bewerte, wie gut du sie wusstest.", "writingNoStrokes": "Für diese Schriftzeichen gibt es keine Strichfolge: Bewerte, wie gut du sie wusstest.",
"aboutDictionaries": "Wörterbücher dieser Instanz", "aboutDictionaries": "Wörterbücher dieser Instanz",
"aboutAppData": "Daten in der App",
"cardReportTitle": "Fehler melden", "cardReportTitle": "Fehler melden",
"cardReportSubtitle": "Markiere diese Karte, um sie später zu finden und zu korrigieren.", "cardReportSubtitle": "Markiere diese Karte, um sie später zu finden und zu korrigieren.",
"cardReportTypo": "Tippfehler", "cardReportTypo": "Tippfehler",

View file

@ -610,6 +610,7 @@
"@writingSuggested": {"placeholders": {"rating": {"type": "String"}}}, "@writingSuggested": {"placeholders": {"rating": {"type": "String"}}},
"writingNoStrokes": "There's no stroke order for these characters: rate how well you knew them.", "writingNoStrokes": "There's no stroke order for these characters: rate how well you knew them.",
"aboutDictionaries": "Dictionaries on this instance", "aboutDictionaries": "Dictionaries on this instance",
"aboutAppData": "Data in the app",
"cardReportTitle": "Report an error", "cardReportTitle": "Report an error",
"cardReportSubtitle": "Flag this card so you can find and fix it later.", "cardReportSubtitle": "Flag this card so you can find and fix it later.",
"cardReportTypo": "Typo", "cardReportTypo": "Typo",

View file

@ -3298,6 +3298,12 @@ abstract class AppLocalizations {
/// **'Dictionaries on this instance'** /// **'Dictionaries on this instance'**
String get aboutDictionaries; String get aboutDictionaries;
/// No description provided for @aboutAppData.
///
/// In en, this message translates to:
/// **'Data in the app'**
String get aboutAppData;
/// No description provided for @cardReportTitle. /// No description provided for @cardReportTitle.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

View file

@ -2008,6 +2008,9 @@ class AppLocalizationsDe extends AppLocalizations {
@override @override
String get aboutDictionaries => 'Wörterbücher dieser Instanz'; String get aboutDictionaries => 'Wörterbücher dieser Instanz';
@override
String get aboutAppData => 'Daten in der App';
@override @override
String get cardReportTitle => 'Fehler melden'; String get cardReportTitle => 'Fehler melden';

View file

@ -1996,6 +1996,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get aboutDictionaries => 'Dictionaries on this instance'; String get aboutDictionaries => 'Dictionaries on this instance';
@override
String get aboutAppData => 'Data in the app';
@override @override
String get cardReportTitle => 'Report an error'; String get cardReportTitle => 'Report an error';

View file

@ -7,9 +7,10 @@ import 'package:halkyon_learn_flutter/src/feature/dictionary/model/dictionary.da
import 'package:material_ui/material_ui.dart'; import 'package:material_ui/material_ui.dart';
/// Shows what Halkyon Learn is under which licences, where the source of /// Shows what Halkyon Learn is under which licences, where the source of
/// what this instance runs is, and whose work its dictionaries are, as their /// what this instance runs is, and whose work its dictionaries and the data
/// licences ask; its "View licenses" lists every package's notice, which the /// the app comes with are, as their licences ask; its "View licenses" lists
/// BSD and MIT packages require in a distributed app, and the fonts'. /// every package's notice, which the BSD and MIT packages require in a
/// distributed app, the fonts' and KanjiVG's.
void showAbout(BuildContext context, AboutRepository about) => showAboutDialog( void showAbout(BuildContext context, AboutRepository about) => showAboutDialog(
context: context, context: context,
applicationName: AppLocalizations.of(context).appTitle, applicationName: AppLocalizations.of(context).appTitle,
@ -20,9 +21,38 @@ void showAbout(BuildContext context, AboutRepository about) => showAboutDialog(
child: const _SourceCode(), child: const _SourceCode(),
), ),
const _Dictionaries(), const _Dictionaries(),
const _AppData(),
], ],
); );
/// Whose work the data the app comes with is: KanjiVG's strokes, whose
/// licence asks for its name and a link to it.
class const _AppData() extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Padding(
padding: const EdgeInsets.only(top: 16),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(AppLocalizations.of(context).aboutAppData),
const SizedBox(height: 8),
Text(
'KanjiVG: Ulrich Apel, CC-BY-SA-3.0',
style: theme.textTheme.bodySmall,
),
SelectableText(
'https://kanjivg.tagaini.net',
style: theme.textTheme.bodySmall,
),
],
),
);
}
}
/// Whose work the instance's dictionaries are, each credit with its /// Whose work the instance's dictionaries are, each credit with its
/// licence and where it is described; nothing without dictionaries, or /// licence and where it is described; nothing without dictionaries, or
/// without the instance. /// without the instance.

View file

@ -338,7 +338,8 @@ void main() {
expect(find.text('Verb'), findsOneWidget); expect(find.text('Verb'), findsOneWidget);
}); });
testWidgets("About names whose work the instance's dictionaries are", ( testWidgets("About names whose work the instance's dictionaries and the "
"app's own data are", (
tester, tester,
) async { ) async {
await pumpApp( await pumpApp(
@ -362,5 +363,9 @@ void main() {
), ),
findsOneWidget, findsOneWidget,
); );
// The app's own data, KanjiVG's strokes, as its licence asks.
expect(find.text('Data in the app'), findsOneWidget);
expect(find.text('KanjiVG: Ulrich Apel, CC-BY-SA-3.0'), findsOneWidget);
expect(find.text('https://kanjivg.tagaini.net'), findsOneWidget);
}); });
} }

View file

@ -27,8 +27,11 @@ entries. A file it can't read is logged and left out.
JMdict in English, with the JLPT levels and Tatoeba's example sentences, is JMdict in English, with the JLPT levels and Tatoeba's example sentences, is
about 20 MB gzipped and takes the server half a minute to load (219,000 about 20 MB gzipped and takes the server half a minute to load (219,000
entries). Its licences (CC BY-SA 4.0; CC BY 2.0 FR for the sentences) ask for entries). KANJIDIC2 in English, with the JLPT levels of the kanji and the kana,
attribution: the app lists the credits each file carries. is a dictionary of characters beside it (`kanjidic-en.jsonl.gz`, 0.7 MB,
12,800 entries): the app's Kanji & kana tab. Their licences (CC BY-SA 4.0;
CC BY 2.0 FR for the sentences; CC BY for the JLPT lists) ask for attribution:
the app lists the credits each file carries.
## Licence ## Licence