feat(app): write kanji, kana and words by hand, each stroke checked

The study option Write by hand (settings schema 7) has character cards
and words written in a session, on a schedule of their own (review mode
`write`; older apps skip a mode they don't know): what to write on top, a
character's meanings and readings or a word's reading and meanings, and
below it a square to write it in, character by character.

Each stroke is checked as it ends against KanjiVG's: both resampled to 22
points, then their shape once centred, where they lie, how long they are
and which way they go, each against what a loose hand strays by; a stroke
closer to one still to come is out of order. One that counts is drawn as
KanjiVG draws it, and the hand's offset from the middle is forgiven in the
strokes after; any other flashes red, says why and counts as a mistake, as
does a hint. Two misses in a row show the next stroke faintly. Once
written, or given up on (Show it), the rating the mistakes suggest is
outlined: none Good, one or two OK, more Bad.

The square takes every touch on it at once, so writing never scrolls the
card or swipes to rate. Characters without a stroke order (in a word) are
written for the person.

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 15:59:40 +02:00
commit 89ad2c237d
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -1950,6 +1950,49 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get kanjiComponents => 'Components';
@override
String get studySettingsCharacters => 'Kanji & kana';
@override
String get studySettingsWriteByHand => 'Write by hand';
@override
String get studySettingsWriteByHandDescription =>
'Kanji, kana and words are written stroke by stroke and checked as you go, on a schedule of their own. Words written aren\'t quizzed or typed.';
@override
String get writingHint => 'Hint';
@override
String get writingShow => 'Show it';
@override
String writingMistakes(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: '$count mistakes',
one: '1 mistake',
zero: 'No mistakes',
);
return '$_temp0';
}
@override
String get writingWrongOrder => 'Not yet: that stroke comes later.';
@override
String get writingWrong => 'That isn\'t the next stroke.';
@override
String writingSuggested(String rating) {
return '$rating suggested';
}
@override
String get writingNoStrokes =>
'There\'s no stroke order for these characters: rate how well you knew them.';
@override
String get aboutDictionaries => 'Dictionaries on this instance';