Промежуточный результат для 1.0.4 версии
This commit is contained in:
104
app/src/main/java/com/rosetta/messenger/data/DraftManager.kt
Normal file
104
app/src/main/java/com/rosetta/messenger/data/DraftManager.kt
Normal file
@@ -0,0 +1,104 @@
|
||||
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}"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user