feat(im): 添加即时通讯功能模块

- 添加了 IM API 接口定义,包含登录、消息、群组、好友等接口
- 实现了 ImSDK 核心功能,支持发送各类消息和管理会话
- 集成了 WebSocket 连接管理和自动重连机制
- 添加了本地联系人缓存并优化对话标题显示逻辑
- 实现了 HarmonyOS 平台 HTTP 客户端基础功能
这个提交包含在:
XuqmGroup 2026-04-28 16:55:12 +08:00
父节点 b7ecf13908
当前提交 dcb263edc6
共有 3 个文件被更改,包括 34 次插入1 次删除

查看文件

@ -36,6 +36,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import coil3.compose.AsyncImage
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.SearchBarField
import com.xuqm.sdk.utils.TimeFormatters
@ -201,7 +202,11 @@ private fun conversationTitle(
return if (conversation.chatType.equals("GROUP", ignoreCase = true)) {
titles[conversation.targetId].orEmpty().ifBlank { conversation.targetId }
} 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) =
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> =
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.GroupJoinRequest
import com.xuqm.sdk.im.model.ImMessage
import com.xuqm.sdk.im.model.UserProfile
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
@ -209,6 +210,21 @@ interface ImApi {
@Query("blockedUserId") blockedUserId: String,
): 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")
suspend fun listConversations(@Query("appId") appId: String): ApiResponse<List<ConversationData>>