feat: Load user information for requests; enhance dialog title handling and improve data retrieval
This commit is contained in:
@@ -216,6 +216,9 @@ class MessageRepository private constructor(private val context: Context) {
|
|||||||
// Обновляем диалог
|
// Обновляем диалог
|
||||||
updateDialog(toPublicKey, text.trim(), timestamp)
|
updateDialog(toPublicKey, text.trim(), timestamp)
|
||||||
|
|
||||||
|
// 🔥 Отмечаем что я отправлял сообщения в этот диалог (перемещает из requests в chats)
|
||||||
|
dialogDao.markIHaveSent(account, toPublicKey)
|
||||||
|
|
||||||
// Отправляем пакет
|
// Отправляем пакет
|
||||||
val packet = PacketMessage().apply {
|
val packet = PacketMessage().apply {
|
||||||
this.fromPublicKey = account
|
this.fromPublicKey = account
|
||||||
|
|||||||
@@ -103,7 +103,10 @@ data class DialogEntity(
|
|||||||
val lastSeen: Long = 0, // Последний раз онлайн
|
val lastSeen: Long = 0, // Последний раз онлайн
|
||||||
|
|
||||||
@ColumnInfo(name = "verified")
|
@ColumnInfo(name = "verified")
|
||||||
val verified: Int = 0 // Верифицирован
|
val verified: Int = 0, // Верифицирован
|
||||||
|
|
||||||
|
@ColumnInfo(name = "i_have_sent", defaultValue = "0")
|
||||||
|
val iHaveSent: Int = 0 // Отправлял ли я сообщения в этот диалог (0/1)
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -293,15 +296,10 @@ interface DialogDao {
|
|||||||
* Исключает requests (диалоги без исходящих сообщений от нас)
|
* Исключает requests (диалоги без исходящих сообщений от нас)
|
||||||
*/
|
*/
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT d.* FROM dialogs d
|
SELECT * FROM dialogs
|
||||||
WHERE d.account = :account
|
WHERE account = :account
|
||||||
AND EXISTS (
|
AND i_have_sent = 1
|
||||||
SELECT 1 FROM messages m
|
ORDER BY last_message_timestamp DESC
|
||||||
WHERE m.account = :account
|
|
||||||
AND m.from_public_key = :account
|
|
||||||
AND m.to_public_key = d.opponent_key
|
|
||||||
)
|
|
||||||
ORDER BY d.last_message_timestamp DESC
|
|
||||||
""")
|
""")
|
||||||
fun getDialogsFlow(account: String): Flow<List<DialogEntity>>
|
fun getDialogsFlow(account: String): Flow<List<DialogEntity>>
|
||||||
|
|
||||||
@@ -309,15 +307,10 @@ interface DialogDao {
|
|||||||
* Получить requests - диалоги где нам писали, но мы не отвечали
|
* Получить requests - диалоги где нам писали, но мы не отвечали
|
||||||
*/
|
*/
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT d.* FROM dialogs d
|
SELECT * FROM dialogs
|
||||||
WHERE d.account = :account
|
WHERE account = :account
|
||||||
AND NOT EXISTS (
|
AND i_have_sent = 0
|
||||||
SELECT 1 FROM messages m
|
ORDER BY last_message_timestamp DESC
|
||||||
WHERE m.account = :account
|
|
||||||
AND m.from_public_key = :account
|
|
||||||
AND m.to_public_key = d.opponent_key
|
|
||||||
)
|
|
||||||
ORDER BY d.last_message_timestamp DESC
|
|
||||||
""")
|
""")
|
||||||
fun getRequestsFlow(account: String): Flow<List<DialogEntity>>
|
fun getRequestsFlow(account: String): Flow<List<DialogEntity>>
|
||||||
|
|
||||||
@@ -325,14 +318,9 @@ interface DialogDao {
|
|||||||
* Получить количество requests
|
* Получить количество requests
|
||||||
*/
|
*/
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT COUNT(*) FROM dialogs d
|
SELECT COUNT(*) FROM dialogs
|
||||||
WHERE d.account = :account
|
WHERE account = :account
|
||||||
AND NOT EXISTS (
|
AND i_have_sent = 0
|
||||||
SELECT 1 FROM messages m
|
|
||||||
WHERE m.account = :account
|
|
||||||
AND m.from_public_key = :account
|
|
||||||
AND m.to_public_key = d.opponent_key
|
|
||||||
)
|
|
||||||
""")
|
""")
|
||||||
fun getRequestsCountFlow(account: String): Flow<Int>
|
fun getRequestsCountFlow(account: String): Flow<Int>
|
||||||
|
|
||||||
@@ -371,6 +359,12 @@ interface DialogDao {
|
|||||||
@Query("UPDATE dialogs SET unread_count = 0 WHERE account = :account AND opponent_key = :opponentKey")
|
@Query("UPDATE dialogs SET unread_count = 0 WHERE account = :account AND opponent_key = :opponentKey")
|
||||||
suspend fun clearUnreadCount(account: String, opponentKey: String)
|
suspend fun clearUnreadCount(account: String, opponentKey: String)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Отметить что я отправлял сообщения в этот диалог
|
||||||
|
*/
|
||||||
|
@Query("UPDATE dialogs SET i_have_sent = 1 WHERE account = :account AND opponent_key = :opponentKey")
|
||||||
|
suspend fun markIHaveSent(account: String, opponentKey: String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Обновить онлайн статус
|
* Обновить онлайн статус
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import androidx.room.RoomDatabase
|
|||||||
DialogEntity::class,
|
DialogEntity::class,
|
||||||
BlacklistEntity::class
|
BlacklistEntity::class
|
||||||
],
|
],
|
||||||
version = 3,
|
version = 4,
|
||||||
exportSchema = false
|
exportSchema = false
|
||||||
)
|
)
|
||||||
abstract class RosettaDatabase : RoomDatabase() {
|
abstract class RosettaDatabase : RoomDatabase() {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.rosetta.messenger.crypto.CryptoManager
|
|||||||
import com.rosetta.messenger.database.DialogEntity
|
import com.rosetta.messenger.database.DialogEntity
|
||||||
import com.rosetta.messenger.database.RosettaDatabase
|
import com.rosetta.messenger.database.RosettaDatabase
|
||||||
import com.rosetta.messenger.network.PacketOnlineSubscribe
|
import com.rosetta.messenger.network.PacketOnlineSubscribe
|
||||||
|
import com.rosetta.messenger.network.PacketSearch
|
||||||
import com.rosetta.messenger.network.ProtocolManager
|
import com.rosetta.messenger.network.ProtocolManager
|
||||||
import com.rosetta.messenger.network.SearchUser
|
import com.rosetta.messenger.network.SearchUser
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -113,10 +114,17 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
|
|||||||
|
|
||||||
// 📬 Подписываемся на requests (запросы от новых пользователей)
|
// 📬 Подписываемся на requests (запросы от новых пользователей)
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
android.util.Log.d("ChatsVM", "📬 Subscribing to requests for publicKey=${publicKey.take(16)}...")
|
||||||
dialogDao.getRequestsFlow(publicKey)
|
dialogDao.getRequestsFlow(publicKey)
|
||||||
.flowOn(Dispatchers.IO)
|
.flowOn(Dispatchers.IO)
|
||||||
.map { requestsList ->
|
.map { requestsList ->
|
||||||
|
android.util.Log.d("ChatsVM", "📬 Received ${requestsList.size} requests from DB")
|
||||||
requestsList.map { dialog ->
|
requestsList.map { dialog ->
|
||||||
|
// 🔥 Загружаем информацию о пользователе если её нет
|
||||||
|
if (dialog.opponentTitle.isEmpty() || dialog.opponentTitle == dialog.opponentKey) {
|
||||||
|
loadUserInfoForRequest(dialog.opponentKey)
|
||||||
|
}
|
||||||
|
|
||||||
val decryptedLastMessage = try {
|
val decryptedLastMessage = try {
|
||||||
if (privateKey.isNotEmpty() && dialog.lastMessage.isNotEmpty()) {
|
if (privateKey.isNotEmpty() && dialog.lastMessage.isNotEmpty()) {
|
||||||
CryptoManager.decryptWithPassword(dialog.lastMessage, privateKey)
|
CryptoManager.decryptWithPassword(dialog.lastMessage, privateKey)
|
||||||
@@ -132,7 +140,7 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
|
|||||||
id = dialog.id,
|
id = dialog.id,
|
||||||
account = dialog.account,
|
account = dialog.account,
|
||||||
opponentKey = dialog.opponentKey,
|
opponentKey = dialog.opponentKey,
|
||||||
opponentTitle = dialog.opponentTitle,
|
opponentTitle = dialog.opponentTitle, // 🔥 Показываем имя как в обычных чатах
|
||||||
opponentUsername = dialog.opponentUsername,
|
opponentUsername = dialog.opponentUsername,
|
||||||
lastMessage = decryptedLastMessage,
|
lastMessage = decryptedLastMessage,
|
||||||
lastMessageTimestamp = dialog.lastMessageTimestamp,
|
lastMessageTimestamp = dialog.lastMessageTimestamp,
|
||||||
@@ -294,6 +302,34 @@ class ChatsListViewModel(application: Application) : AndroidViewModel(applicatio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 📬 Загрузить информацию о пользователе для request
|
||||||
|
*/
|
||||||
|
private fun loadUserInfoForRequest(publicKey: String) {
|
||||||
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
val sharedPrefs = getApplication<Application>().getSharedPreferences("rosetta", Application.MODE_PRIVATE)
|
||||||
|
val currentUserPrivateKey = sharedPrefs.getString("private_key", "") ?: ""
|
||||||
|
|
||||||
|
if (currentUserPrivateKey.isEmpty()) return@launch
|
||||||
|
|
||||||
|
// 🔥 ВАЖНО: Используем хеш ключа, как в MessageRepository.requestUserInfo
|
||||||
|
val privateKeyHash = CryptoManager.generatePrivateKeyHash(currentUserPrivateKey)
|
||||||
|
|
||||||
|
android.util.Log.d("ChatsVM", "📬 Requesting user info for: ${publicKey.take(16)}...")
|
||||||
|
|
||||||
|
// Запрашиваем информацию о пользователе с сервера
|
||||||
|
val packet = PacketSearch().apply {
|
||||||
|
this.privateKey = privateKeyHash
|
||||||
|
this.search = publicKey
|
||||||
|
}
|
||||||
|
ProtocolManager.send(packet)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
android.util.Log.e("ChatsVM", "📬 Error loading user info: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Проверить заблокирован ли пользователь
|
* Проверить заблокирован ли пользователь
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user