chat: enforce storage_total_size + media orphan cleanup; async_dns: fix use-after-free

- media cache: удаление сирот на старте (сверка ФС с сообщениями) + лимит
  storage_total_size (удаление самых старых файлов, только старше backfill_days)
- ma_dir_walk(): кроссплатформенный рекурсивный обход каталога (POSIX/Windows)
- async_dns: первый драйв slow-пути отложен через call_soon (исключён
  double-free при синхронном завершении запроса); cancel унифицирован
- chat: видимый WARN 'media too large' + честный счётчик started/skipped
This commit is contained in:
evgeny committed 2026-09-13 03:11:10 +03:00
1 parent 7bba39ddcb
commit 1eb0566cb5
7 files changed
+359 -17

No files matched your search

@@ -111,8 +111,22 @@ fun ChatScreen(
val playbackState by viewModel.playbackState.collectAsState()
var initialScrolled by remember { mutableStateOf(false) }
LaunchedEffect(messages.size) {
if (messages.isNotEmpty()) listState.animateScrollToItem(messages.size - 1)
if (messages.isEmpty()) return@LaunchedEffect
val lastIndex = messages.size - 1
if (!initialScrolled) {
/* первый вход — мгновенный прыжок вниз без анимации */
listState.scrollToItem(lastIndex)
initialScrolled = true
return@LaunchedEffect
}
/* новое сообщение: анимируем только если пользователь у нижнего края */
val lastVisible = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1
if (lastIndex - lastVisible <= 1) {
listState.animateScrollToItem(lastIndex)
}
}
Column(