Files
mobile-android/app/src/main/java/com/rosetta/messenger/data/DraftManager.kt

105 lines
3.9 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.rosetta.messenger.data
import android.content.Context
import android.content.SharedPreferences
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
/**
* 📝 Менеджер черновиков сообщений (как в Telegram)
* Хранит текст из инпута для каждого диалога.
* При возврате в список чатов показывает "Draft: текст" красным цветом.
*
* Использует SharedPreferences для персистентности между перезапусками.
* Ключ: "draft_{account}_{opponentKey}" -> текст черновика
*/
object DraftManager {
private const val PREFS_NAME = "rosetta_drafts"
private const val KEY_PREFIX = "draft_"
private var prefs: SharedPreferences? = null
// 🔥 Реактивный Map: opponentKey -> draftText
// Обновляется при каждом изменении черновика для мгновенного обновления UI списка чатов
private val _drafts = MutableStateFlow<Map<String, String>>(emptyMap())
val drafts: StateFlow<Map<String, String>> = _drafts.asStateFlow()
private var currentAccount: String = ""
/** Инициализация с контекстом приложения */
fun init(context: Context) {
if (prefs == null) {
prefs = context.applicationContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
}
}
/** Установить текущий аккаунт и загрузить его черновики */
fun setAccount(account: String) {
if (currentAccount == account) return
currentAccount = account
loadDraftsFromPrefs()
}
/** Сохранить черновик для диалога */
fun saveDraft(opponentKey: String, text: String) {
if (currentAccount.isEmpty()) return
val trimmed = text.trim()
val currentDrafts = _drafts.value.toMutableMap()
if (trimmed.isEmpty()) {
// Удаляем черновик если текст пустой
currentDrafts.remove(opponentKey)
prefs?.edit()?.remove(prefKey(opponentKey))?.apply()
} else {
currentDrafts[opponentKey] = trimmed
prefs?.edit()?.putString(prefKey(opponentKey), trimmed)?.apply()
}
_drafts.value = currentDrafts
}
/** Получить черновик для диалога */
fun getDraft(opponentKey: String): String? {
return _drafts.value[opponentKey]
}
/** Очистить черновик для диалога (после отправки сообщения) */
fun clearDraft(opponentKey: String) {
if (currentAccount.isEmpty()) return
val currentDrafts = _drafts.value.toMutableMap()
currentDrafts.remove(opponentKey)
_drafts.value = currentDrafts
prefs?.edit()?.remove(prefKey(opponentKey))?.apply()
}
/** Очистить все черновики (при смене аккаунта / логауте) */
fun clearAll() {
_drafts.value = emptyMap()
}
/** Загрузить черновики текущего аккаунта из SharedPreferences */
private fun loadDraftsFromPrefs() {
val allPrefs = prefs?.all ?: return
val prefix = "${KEY_PREFIX}${currentAccount}_"
val loaded = mutableMapOf<String, String>()
allPrefs.forEach { (key, value) ->
if (key.startsWith(prefix) && value is String && value.isNotEmpty()) {
val opponentKey = key.removePrefix(prefix)
loaded[opponentKey] = value
}
}
_drafts.value = loaded
}
private fun prefKey(opponentKey: String): String {
return "${KEY_PREFIX}${currentAccount}_${opponentKey}"
}
}