From 3a6ef25ca6f1ad145a575fc4c41b633cb8483af2 Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 28 Oct 2026 13:36:03 +0100 Subject: [PATCH] Document requested locales and notification language refresh contracts --- .../java/com/utun/chat/data/AppLanguage.kt | 2 +- tools/chatgui-android/doc/ARCHITECTURE.md | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/AppLanguage.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/AppLanguage.kt index 01781a75..748c60e5 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/AppLanguage.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/AppLanguage.kt @@ -46,7 +46,7 @@ object AppLanguage { throw error } - /** Запрошенный Android/AppCompat список через запятую; пусто — следовать системе, это не effective язык ресурсов. + /** После Activity.onCreate: запрошенный Android/AppCompat список через запятую; пусто — система, не effective язык ресурсов. * Ошибка чтения логируется и передаётся вызывающему, не маскируется под системный выбор. */ fun selectedTag(): String = try { AppCompatDelegate.getApplicationLocales().toLanguageTags() } catch (error: Exception) { diff --git a/tools/chatgui-android/doc/ARCHITECTURE.md b/tools/chatgui-android/doc/ARCHITECTURE.md index d45cfda1..2f0cba2d 100644 --- a/tools/chatgui-android/doc/ARCHITECTURE.md +++ b/tools/chatgui-android/doc/ARCHITECTURE.md @@ -134,6 +134,36 @@ UDP-лог — в `[log_udp] ip/port`; полный набор задаёт Conf Начальная генерация ключей пытается сохранить их в `db_path/keys.conf`. `instance_lite_regenerate_keys()` меняет ключи/node_id на месте, без пересоздания соединений. +## Язык интерфейса + +`AppLanguage.supportedTags` читает общий `res/xml/locales_config.xml`: имена +нормализуются в BCP47, пустые/повторные/некорректные записи отклоняются атомарно. +Parser закрывается также при ошибке. Успешный каталог кэшируется; провал lazy +логируется и не запрещает следующую попытку чтения. + +`selectedTag()` возвращает requested список Android/AppCompat через запятую, +пустая строка означает системный выбор. Effective ресурсы получают отдельно +через `context()`/`text()`, в том числе вне Activity: для этого используется +[ContextCompat.getContextForLanguage](https://developer.android.com/reference/androidx/core/content/ContextCompat#getContextForLanguage(android.content.Context)). +`nativeName()` учитывает приоритетный список и именует каждый тег на его языке. + +`select()` вызывается на main после создания Activity, принимает один тег +каталога либо пустую строку. true означает уже выбранный/принятый запрос, +false — отказ, а не подтверждение отката или завершения смены ресурсов. +Выбор хранит Android/AppCompat с `autoStoreLocales`, без дублирования в DataStore; +механизм хранения/пересоздания описан в +[AppCompatDelegate.setApplicationLocales](https://developer.android.com/reference/androidx/appcompat/app/AppCompatDelegate#setApplicationLocales(androidx.core.os.LocaleListCompat)). +UI перечитывает requested состояние после попытки, включая частичный отказ; +ошибки чтения и выбора показываются отдельно с возможностью повторить действие. + +`applied()` на main получает effective locale и при каждом сигнале конфигурации/ +создании Activity заново запрашивает обновление четырёх владельцев уведомлений: +сеть, входящий звонок/рация, текущий звонок и radio overlay. Кэша «этот locale +уже применён» нет: владелец может обработать отказ внутри себя или стать активным +после прежнего сигнала. Обновляются каналы/тексты; ядро, media и сигналы вызова +не перезапускаются. Ошибка одного владельца не прерывает остальные. При отказе +чтения конфигурации сигнал логируется и пропускается до следующего вызова. + ## Каналы, приглашения и DM Создание канала ставится в uasync; channel_id, переданный старому bridge API создания,