feat(app,learn): the device's appearance and language, halkyon_app's, as Learn's Settings show them

The developer asked for Todo, Train and Meditate to offer Learn's
Appearance and Language (ADR 0014's amendment of 4 Nov 2026). Their
model, store, cubit and card move into halkyon_app: Appearance and Look
(a BCP 47 tag, null for the device's language), FileLookStore keeping it
in the app's support folder as JSON written by rename (per device, not
synced, read before the first frame), LookCubit for the apps to provide
above InstanceGate, and LookSettingsCard / DeviceLookCard with the texts
moved from Learn's arbs (look*, the same words). Each app passes the
languages it speaks, named in their own language.

Learn keeps its stored choice where it was, among its DeviceSettings,
and feeds the shared card from them: no migration, so nobody's language
or appearance moves, and nothing changes on its screen.

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 22:30:29 +01:00
commit 23d3bcb4ca
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -9,7 +9,7 @@ void main() {
// tested there; Learn's own languages are tested here.
test('every language offered is one the app speaks', () {
for (final language in appLanguages) {
final locale = localeOf(language.tag);
final locale = localeOfTag(language.tag);
expect(
resolveAppLocale([locale], AppLocalizations.supportedLocales),
isIn(AppLocalizations.supportedLocales),
@ -28,9 +28,4 @@ void main() {
'Color',
);
});
test('a language tag becomes its locale', () {
expect(localeOf('de'), const Locale('de'));
expect(localeOf('en-GB'), const Locale('en', 'GB'));
});
}