Skip to content

Commit cab6340

Browse files
fix(chat): набранный черновик переживает пересоздание Activity и убийство процесса
draft был обычным remember: смена размера шрифта, тёмной темы или убийство процесса Android'ом стирали набранный текст. rememberSaveable безопасен только для draft - восстановленный sending=true оставил бы кнопку вечно занятой, потому что корутины отправки после смерти процесса уже нет.
1 parent 63d6ecc commit cab6340

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

‎CHANGELOG.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ Play: листинг, скриншоты, политика конфиденци
116116
удалить данные. Аналитики и трекеров в сборке нет (проверено по зависимостям).
117117
- Осталось: доступ к Play Console и URL политики (файл есть, хостинг — нет).
118118

119+
Чат: набранный черновик больше не теряется (26.10.2026)
120+
- `draft` был обычным `remember`, поэтому пересоздание Activity (смена размера шрифта,
121+
тёмной темы) и убийство процесса Android'ом стирали набранный текст: человек возвращался
122+
в чат и видел пустое поле. Теперь `rememberSaveable` — строка это saveable тип.
123+
- Остальные состояния saveable НЕ сделаны намеренно: восстановленный `sending=true`
124+
оставил бы кнопку вечно занятой (корутины отправки после смерти процесса уже нет).
125+
- Проверено сборкой, юнит-тестами и запуском на устройстве (в т.ч. пересоздание по смене
126+
uiMode — падений нет). Восстановление НЕПУСТОГО черновика вручную не проверялось: для
127+
этого нужен ввод текста в поле, а UI-автоматизация в этом проекте запрещена.
128+
119129
Инструмент: проверка музыки после бана запускается сама (26.10.2026)
120130
- Каждый вызов музыкального инструмента во время go-away продлевает бан на новый час,
121131
поэтому закрыть трек можно только полной тишиной до дедлайна и ровно одним замером.

‎app/src/main/java/org/opencode/mobile/ui/ChatOverlay.kt‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ import androidx.compose.runtime.mutableIntStateOf
7272
import androidx.compose.runtime.mutableStateOf
7373
import androidx.compose.runtime.remember
7474
import androidx.compose.runtime.rememberCoroutineScope
75+
import androidx.compose.runtime.saveable.rememberSaveable
7576
import androidx.compose.runtime.setValue
7677
import androidx.compose.runtime.snapshotFlow
7778
import androidx.compose.ui.Alignment
@@ -326,7 +327,13 @@ fun ChatOverlay(
326327
// квота не восстановится. Поэтому держим плашку, пока идёт ход, и гасим только
327328
// когда opencode дошёл до успешного assistant-шага (thinking снят).
328329
var noticeLatch by remember { mutableStateOf<ChatNotice?>(null) }
329-
var draft by remember { mutableStateOf("") }
330+
// Черновик переживает и пересоздание Activity, и убийство процесса: строка —
331+
// saveable тип, а терять набранный текст из-за смены размера шрифта или
332+
// возврата из другого приложения нельзя. Остальные состояния НЕ saveable
333+
// намеренно: восстановленный sending=true оставил бы кнопку вечно занятой
334+
// (корутины отправки после смерти процесса уже нет), а noticeLatch и typingKey
335+
// восстановились бы без своего контекста.
336+
var draft by rememberSaveable { mutableStateOf("") }
330337
var sending by remember { mutableStateOf(false) }
331338
var stopping by remember { mutableStateOf(false) }
332339
var whisperRecorder: AudioRecorder? = null

0 commit comments

Comments
 (0)