feat(im): 添加即时通讯功能模块
- 添加了 IM API 接口定义,包含登录、消息、群组、好友等接口 - 实现了 ImSDK 核心功能,支持发送各类消息和管理会话 - 集成了 WebSocket 连接管理和自动重连机制 - 添加了本地联系人缓存并优化对话标题显示逻辑 - 实现了 HarmonyOS 平台 HTTP 客户端基础功能
这个提交包含在:
父节点
b7ecf13908
当前提交
dcb263edc6
@ -36,6 +36,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
import com.xuqm.sdk.im.model.ConversationData
|
import com.xuqm.sdk.im.model.ConversationData
|
||||||
|
import com.xuqm.sdk.sample.di.AppDependencies
|
||||||
import com.xuqm.sdk.ui.InitialAvatar
|
import com.xuqm.sdk.ui.InitialAvatar
|
||||||
import com.xuqm.sdk.ui.SearchBarField
|
import com.xuqm.sdk.ui.SearchBarField
|
||||||
import com.xuqm.sdk.utils.TimeFormatters
|
import com.xuqm.sdk.utils.TimeFormatters
|
||||||
@ -201,7 +202,11 @@ private fun conversationTitle(
|
|||||||
return if (conversation.chatType.equals("GROUP", ignoreCase = true)) {
|
return if (conversation.chatType.equals("GROUP", ignoreCase = true)) {
|
||||||
titles[conversation.targetId].orEmpty().ifBlank { conversation.targetId }
|
titles[conversation.targetId].orEmpty().ifBlank { conversation.targetId }
|
||||||
} else {
|
} else {
|
||||||
conversation.targetId
|
AppDependencies.localContactCache.loadProfiles()
|
||||||
|
.firstOrNull { it.userId == conversation.targetId }
|
||||||
|
?.nickname
|
||||||
|
?.takeIf { it.isNotBlank() }
|
||||||
|
?: conversation.targetId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -510,6 +510,18 @@ object ImSDK {
|
|||||||
suspend fun removeFromBlacklist(blockedUserId: String) =
|
suspend fun removeFromBlacklist(blockedUserId: String) =
|
||||||
withContext(Dispatchers.IO) { api.removeFromBlacklist(XuqmSDK.appId, blockedUserId) }
|
withContext(Dispatchers.IO) { api.removeFromBlacklist(XuqmSDK.appId, blockedUserId) }
|
||||||
|
|
||||||
|
suspend fun getProfile(userId: String) =
|
||||||
|
withContext(Dispatchers.IO) { api.getProfile(userId, XuqmSDK.appId).data }
|
||||||
|
|
||||||
|
suspend fun updateProfile(
|
||||||
|
userId: String,
|
||||||
|
nickname: String? = null,
|
||||||
|
avatar: String? = null,
|
||||||
|
gender: String? = null,
|
||||||
|
) = withContext(Dispatchers.IO) {
|
||||||
|
api.updateProfile(userId, XuqmSDK.appId, nickname, avatar, gender).data
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun listConversations(): List<ConversationData> =
|
suspend fun listConversations(): List<ConversationData> =
|
||||||
withContext(Dispatchers.IO) { api.listConversations(XuqmSDK.appId).data ?: emptyList() }
|
withContext(Dispatchers.IO) { api.listConversations(XuqmSDK.appId).data ?: emptyList() }
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import com.xuqm.sdk.im.model.FriendRequest
|
|||||||
import com.xuqm.sdk.im.model.ImGroup
|
import com.xuqm.sdk.im.model.ImGroup
|
||||||
import com.xuqm.sdk.im.model.GroupJoinRequest
|
import com.xuqm.sdk.im.model.GroupJoinRequest
|
||||||
import com.xuqm.sdk.im.model.ImMessage
|
import com.xuqm.sdk.im.model.ImMessage
|
||||||
|
import com.xuqm.sdk.im.model.UserProfile
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.DELETE
|
import retrofit2.http.DELETE
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
@ -209,6 +210,21 @@ interface ImApi {
|
|||||||
@Query("blockedUserId") blockedUserId: String,
|
@Query("blockedUserId") blockedUserId: String,
|
||||||
): ApiResponse<Unit>
|
): ApiResponse<Unit>
|
||||||
|
|
||||||
|
@GET("api/im/accounts/{userId}")
|
||||||
|
suspend fun getProfile(
|
||||||
|
@Path("userId") userId: String,
|
||||||
|
@Query("appId") appId: String,
|
||||||
|
): ApiResponse<UserProfile>
|
||||||
|
|
||||||
|
@PUT("api/im/accounts/{userId}")
|
||||||
|
suspend fun updateProfile(
|
||||||
|
@Path("userId") userId: String,
|
||||||
|
@Query("appId") appId: String,
|
||||||
|
@Query("nickname") nickname: String? = null,
|
||||||
|
@Query("avatar") avatar: String? = null,
|
||||||
|
@Query("gender") gender: String? = null,
|
||||||
|
): ApiResponse<UserProfile>
|
||||||
|
|
||||||
@GET("api/im/conversations")
|
@GET("api/im/conversations")
|
||||||
suspend fun listConversations(@Query("appId") appId: String): ApiResponse<List<ConversationData>>
|
suspend fun listConversations(@Query("appId") appId: String): ApiResponse<List<ConversationData>>
|
||||||
|
|
||||||
|
|||||||
正在加载...
在新工单中引用
屏蔽一个用户