Большой пакет: поиск по сообщениям, клики по тэгам, темы обоев и UX-фиксы

Что вошло:\n- Добавлен полноценный Messages-tab в SearchScreen: поиск по тексту сообщений по всей базе, батчевый проход, параллельная дешифровка, кеш расшифровки, подсветка совпадений, сниппеты и быстрый переход в нужный диалог.\n- В Chats-tab добавлены алиасы для Saved Messages (saved/saved messages/избранное/сохраненные и др.), чтобы чат открывался по текстовому поиску даже без точного username/public key.\n- Для search-бэкенда расширен DAO: getAllMessagesPaged() для постраничного обхода сообщений аккаунта.\n- Исправлена логика клика по @тэгам в сообщениях:\n  - переход теперь ведет сразу в чат пользователя (а не в профиль);\n  - добавлен fallback-резолв username -> user через локальный диалог, кеш протокола и PacketSearch;\n  - добавлен DAO getDialogByUsername() (регистронезависимо и с игнором @).\n- Усилена обработка PacketSearch в ProtocolManager:\n  - добавлена очередь ожидания pendingSearchQueries;\n  - нормализация query (без @, lowercase);\n  - устойчивый матч ответов сервера (raw/normalized/by username);\n  - добавлены методы getCachedUserByUsername() и searchUsers().\n- Исправлен конфликт тачей между ClickableSpan и bubble-menu:\n  - в AppleEmojiText/AppleEmojiTextView добавлен callback начала тапа по span;\n  - улучшен hit-test по span (включая пограничные offset/layout fallback);\n  - suppress performClick на span-тапах;\n  - в MessageBubble добавлен тайм-guard, чтобы tap по span не открывал context menu.\n- Стабилизирован verified-бейдж в заголовке чата: агрегируется из переданного user, кеша протокола, локальной БД и серверного resolve; отображается консистентно в личных чатах.\n- Улучшен пустой экран Saved Messages при обоях: добавлена аккуратная подложка/бордер и выровненный текст, чтобы контент оставался читабельным на любом фоне.\n- Реализована автосвязка обоев между светлой/темной темами:\n  - добавлены pairGroup и mapToTheme/resolveWallpaperForTheme в ThemeWallpapers;\n  - добавлены отдельные prefs-ключи для light/dark wallpaper;\n  - MainActivity теперь автоматически подбирает и сохраняет обои под активную тему и сохраняет выбор по теме.\n- Биометрия: если на устройстве нет hardware fingerprint, экран включения биометрии не показывается (и доступность возвращает NotAvailable).\n- Небольшие UI-фиксы: поправлено позиционирование галочки в сайдбаре.\n- Техдолг: удалена неиспользуемая зависимость jsoup из build.gradle.
This commit is contained in:
2026-03-21 21:12:52 +05:00
parent c929685e04
commit 9d3e5bcb10
14 changed files with 1100 additions and 108 deletions

View File

@@ -28,6 +28,8 @@ class PreferencesManager(private val context: Context) {
val IS_DARK_THEME = booleanPreferencesKey("is_dark_theme")
val THEME_MODE = stringPreferencesKey("theme_mode") // "light", "dark", "auto"
val CHAT_WALLPAPER_ID = stringPreferencesKey("chat_wallpaper_id") // empty = no wallpaper
val CHAT_WALLPAPER_ID_LIGHT = stringPreferencesKey("chat_wallpaper_id_light")
val CHAT_WALLPAPER_ID_DARK = stringPreferencesKey("chat_wallpaper_id_dark")
// Notifications
val NOTIFICATIONS_ENABLED = booleanPreferencesKey("notifications_enabled")
@@ -104,10 +106,21 @@ class PreferencesManager(private val context: Context) {
val chatWallpaperId: Flow<String> =
context.dataStore.data.map { preferences -> preferences[CHAT_WALLPAPER_ID] ?: "" }
val chatWallpaperIdLight: Flow<String> =
context.dataStore.data.map { preferences -> preferences[CHAT_WALLPAPER_ID_LIGHT] ?: "" }
val chatWallpaperIdDark: Flow<String> =
context.dataStore.data.map { preferences -> preferences[CHAT_WALLPAPER_ID_DARK] ?: "" }
suspend fun setChatWallpaperId(value: String) {
context.dataStore.edit { preferences -> preferences[CHAT_WALLPAPER_ID] = value }
}
suspend fun setChatWallpaperIdForTheme(isDarkTheme: Boolean, value: String) {
val key = if (isDarkTheme) CHAT_WALLPAPER_ID_DARK else CHAT_WALLPAPER_ID_LIGHT
context.dataStore.edit { preferences -> preferences[key] = value }
}
// ═════════════════════════════════════════════════════════════
// 🔔 NOTIFICATIONS
// ═════════════════════════════════════════════════════════════