dm-99
This commit is contained in:
parent
0bafc1c04c
commit
a50881a3e0
6 changed files with 40 additions and 47 deletions
|
|
@ -2,10 +2,12 @@ package com.example.login_v3.data.di
|
||||||
|
|
||||||
import androidx.room.Database
|
import androidx.room.Database
|
||||||
import androidx.room.RoomDatabase
|
import androidx.room.RoomDatabase
|
||||||
|
import androidx.room.TypeConverters
|
||||||
import com.example.login_v3.home.Message.ViewModel.Detail.MessageDao
|
import com.example.login_v3.home.Message.ViewModel.Detail.MessageDao
|
||||||
import com.example.login_v3.home.Message.ViewModel.Detail.MessageEntity
|
import com.example.login_v3.home.Message.ViewModel.Detail.MessageEntity
|
||||||
|
|
||||||
@Database(entities = [MessageEntity::class], version = 1, exportSchema = false)
|
@Database(entities = [MessageEntity::class], version = 1, exportSchema = false)
|
||||||
|
@TypeConverters(RoomConverters::class)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
abstract fun messageDao(): MessageDao
|
abstract fun messageDao(): MessageDao
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.example.login_v3.data.di
|
||||||
|
|
||||||
|
import androidx.room.TypeConverter
|
||||||
|
import com.example.login_v3.data.api.api_class.Reaction
|
||||||
|
import com.squareup.moshi.Moshi
|
||||||
|
import com.squareup.moshi.Types
|
||||||
|
|
||||||
|
class RoomConverters {
|
||||||
|
private val moshi = Moshi.Builder().build()
|
||||||
|
private val reactionListType = Types.newParameterizedType(List::class.java, Reaction::class.java)
|
||||||
|
private val adapter = moshi.adapter<List<Reaction>>(reactionListType)
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun fromReactionList(reactions: List<Reaction>?): String? {
|
||||||
|
return adapter.toJson(reactions ?: emptyList())
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun toReactionList(json: String?): List<Reaction>? {
|
||||||
|
if (json.isNullOrBlank()) return emptyList()
|
||||||
|
return try {
|
||||||
|
adapter.fromJson(json)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -61,7 +61,8 @@ class ChatRoomsRepository @Inject constructor(
|
||||||
isEdited = entity.isEdited,
|
isEdited = entity.isEdited,
|
||||||
isDeleted = entity.isDeleted,
|
isDeleted = entity.isDeleted,
|
||||||
replyToId = entity.replyToId,
|
replyToId = entity.replyToId,
|
||||||
status = entity.status // 👈 把 Room 儲存的狀態倒出來給 UI
|
status = entity.status, // 👈 把 Room 儲存的狀態倒出來給 UI
|
||||||
|
reactions = entity.reactions
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,7 +95,8 @@ class ChatRoomsRepository @Inject constructor(
|
||||||
isEdited = networkMessage.isEdited,
|
isEdited = networkMessage.isEdited,
|
||||||
isDeleted = networkMessage.isDeleted,
|
isDeleted = networkMessage.isDeleted,
|
||||||
replyToId = networkMessage.replyToId,
|
replyToId = networkMessage.replyToId,
|
||||||
status = MessageStatus.SUCCESS // 後端來的都是真的發送成功的
|
status = MessageStatus.SUCCESS,
|
||||||
|
reactions = networkMessage.reactions
|
||||||
)
|
)
|
||||||
messageDao.insertOrUpdate(entity)
|
messageDao.insertOrUpdate(entity)
|
||||||
}
|
}
|
||||||
|
|
@ -125,7 +127,8 @@ class ChatRoomsRepository @Inject constructor(
|
||||||
isEdited = false,
|
isEdited = false,
|
||||||
isDeleted = false,
|
isDeleted = false,
|
||||||
replyToId = replyToId,
|
replyToId = replyToId,
|
||||||
status = MessageStatus.SENDING // 👈 畫面馬上呈現半透明淡灰色!
|
status = MessageStatus.SENDING,
|
||||||
|
reactions = emptyList()
|
||||||
)
|
)
|
||||||
|
|
||||||
messageDao.insertOrUpdate(tempMessageEntity)
|
messageDao.insertOrUpdate(tempMessageEntity)
|
||||||
|
|
@ -150,7 +153,8 @@ class ChatRoomsRepository @Inject constructor(
|
||||||
isEdited = body.isEdited,
|
isEdited = body.isEdited,
|
||||||
isDeleted = body.isDeleted,
|
isDeleted = body.isDeleted,
|
||||||
replyToId = body.replyToId,
|
replyToId = body.replyToId,
|
||||||
status = MessageStatus.SUCCESS
|
status = MessageStatus.SUCCESS,
|
||||||
|
reactions = body.reactions
|
||||||
)
|
)
|
||||||
messageDao.insertOrUpdate(successEntity)
|
messageDao.insertOrUpdate(successEntity)
|
||||||
Result.success(Unit)
|
Result.success(Unit)
|
||||||
|
|
@ -317,33 +321,6 @@ class ChatRoomsRepository @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取得點擊特定訊息中某個 Emoji 的使用者清單
|
|
||||||
suspend fun getMessageReactionUsers(
|
|
||||||
roomId: String,
|
|
||||||
messageId: String,
|
|
||||||
emoji: String
|
|
||||||
): Result<MessageReactionUsersResponse> {
|
|
||||||
return try {
|
|
||||||
// 呼叫 API
|
|
||||||
val response = api.getMessageReactionUsers(roomId, messageId, emoji)
|
|
||||||
|
|
||||||
if (response.isSuccessful) {
|
|
||||||
val body = response.body()
|
|
||||||
if (body != null) {
|
|
||||||
Result.success(body)
|
|
||||||
} else {
|
|
||||||
Result.failure(Exception("回應成功但回應身體為空 (Empty response body)"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val errorMsg = response.errorBody()?.string() ?: "未知錯誤"
|
|
||||||
Result.failure(Exception("取得反應使用者失敗,錯誤碼: ${response.code()}, 訊息: $errorMsg"))
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
// 捕捉網路斷線等異常狀況
|
|
||||||
Result.failure(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 新增訊息的 Emoji 反應
|
// 新增訊息的 Emoji 反應
|
||||||
suspend fun addMessageReaction(
|
suspend fun addMessageReaction(
|
||||||
roomId: String,
|
roomId: String,
|
||||||
|
|
|
||||||
|
|
@ -113,9 +113,6 @@ fun MessageMessaging(
|
||||||
//reply function
|
//reply function
|
||||||
val replyingMessage by viewModel.replyingMessage.collectAsStateWithLifecycle()
|
val replyingMessage by viewModel.replyingMessage.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
// 💡 1. 取得 ViewModel 裡的 Reaction 狀態
|
|
||||||
val reactionState by viewModel.reactionUsersState.collectAsStateWithLifecycle()
|
|
||||||
|
|
||||||
//message that selected
|
//message that selected
|
||||||
val actionMessage by viewModel.actionMessage.collectAsStateWithLifecycle()
|
val actionMessage by viewModel.actionMessage.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
|
import com.example.login_v3.data.api.api_class.Reaction
|
||||||
|
|
||||||
enum class MessageStatus { SENDING, SUCCESS, FAILED }
|
enum class MessageStatus { SENDING, SUCCESS, FAILED }
|
||||||
|
|
||||||
|
|
@ -21,7 +22,8 @@ data class MessageEntity(
|
||||||
val isEdited: Boolean, // 👈 新增
|
val isEdited: Boolean, // 👈 新增
|
||||||
val isDeleted: Boolean, // 👈 新增
|
val isDeleted: Boolean, // 👈 新增
|
||||||
val replyToId: String?, // 👈 新增
|
val replyToId: String?, // 👈 新增
|
||||||
val status: MessageStatus // 👈 樂觀更新狀態控制 (SENDING, SUCCESS, FAILED)
|
val status: MessageStatus, // 👈 樂觀更新狀態控制 (SENDING, SUCCESS, FAILED)
|
||||||
|
val reactions: List<Reaction>?
|
||||||
)
|
)
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
|
|
|
||||||
|
|
@ -223,17 +223,6 @@ class ChatViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _reactionUsersState = MutableStateFlow<ReactionUsersState>(ReactionUsersState.Idle)
|
|
||||||
val reactionUsersState: StateFlow<ReactionUsersState> = _reactionUsersState.asStateFlow()
|
|
||||||
|
|
||||||
fun loadMessageReactionUsers(roomId: String, messageId: String, emoji: String) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
_reactionUsersState.value = ReactionUsersState.Loading
|
|
||||||
repository.getMessageReactionUsers(roomId, messageId, emoji)
|
|
||||||
.onSuccess { response -> _reactionUsersState.value = ReactionUsersState.Success(response.users) }
|
|
||||||
.onFailure { error -> _reactionUsersState.value = ReactionUsersState.Error(error.message ?: "無法取得按讚名單") }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addMessageReaction(roomId: String, messageId: String, emoji: String) {
|
fun addMessageReaction(roomId: String, messageId: String, emoji: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
|
@ -255,6 +244,5 @@ class ChatViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetDeleteMessageState() { _deleteMessageState.value = DeleteMessageState.Idle }
|
fun resetDeleteMessageState() { _deleteMessageState.value = DeleteMessageState.Idle }
|
||||||
fun resetReactionUsersState() { _reactionUsersState.value = ReactionUsersState.Idle }
|
|
||||||
fun resetSendMessageState() { _sendMessageState.value = SendMessageState.Idle }
|
fun resetSendMessageState() { _sendMessageState.value = SendMessageState.Idle }
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue