Conversations
im.conversations manages the conversation list, drafts, unread counts, pinning and the typing indicator. The SDK maintains the conversation list and updates it with new messages and actions on other devices: just subscribe to it, and don't keep your own copy to sync.
| You want to | See |
|---|---|
| Show the conversation list | Subscribe to the list |
| Start a one-to-one chat from contacts | Open a one-to-one chat |
| Show and clear unread counts | Unread and read |
| Pin or delete conversations, save drafts | Pinning, deletion and drafts |
| Show "typing…" | Typing indicator |
Subscribe to the list
val list = im.conversations.list()
try {
list.snapshot.collect { snapshot ->
snapshot.items.forEach { view ->
println("${view.conversationKey}: ${view.unreadCount}")
}
}
} finally {
list.close()
}The snapshot (LiveListSnapshot) has items, hasMore, loading and error. Call loadMore() when you need more conversations; sorting and updates are handled by the SDK.
You can also use listFlow(): it creates the list when collection starts, releases it when collection stops, and follows the sign-in state (an empty snapshot while signed out), which suits collecting along the UI lifecycle.
Open a one-to-one chat
val conversation = im.conversations.openSingle("bob")
val messages = im.messages.open(conversation.conversationKey)
messages.close() // 本例只演示创建;实际页面在离开时关闭。If the two users haven't exchanged messages yet, you may get a local draft conversation: its conversationKey looks like draft:username and its conversationId is null. Open the message screen with conversationKey, and don't treat the draft key as a server conversation ID. After the first message is sent, the list switches to the real conversation key; you'll see it in MessagesChanged.renamedFrom or in the next list snapshot.
Read an existing conversation with get(conversationId), and update it from the server with refresh(conversationId).
Unread and read
im.conversations.markRead(conversationId)
im.conversations.setMarkedUnread(conversationId, true)
val total = im.conversations.getUnreadTotal(excludeMuted = true)unreadTotalis aStateFlowand doesn't count deleted (hidden) conversations.markReadreturns immediately and the SDK batches the reports; withoutseqit moves to the newest message.setMarkedUnreadonly adds an "unread" mark; it doesn't move the read position back.markAllReadcan be called at most twice per minute; its result hascount(conversations marked) andtruncated(older conversations weren't processed).
Automatic read marking needs autoMarkRead = true and the message list reporting its visibility; see Message list.
Pinning, deletion and drafts
import com.deeprespond.im.*
im.conversations.setPinned(conversationId, true)
im.conversations.setDraft(conversationKey, Draft("稍后回复"))
im.conversations.setDraft(conversationKey, null)remove(conversationId, clearMessages = false)removes the conversation from the user's list; passtrueto clear the history as well.clearMessagesonly clears the history the user sees; it doesn't recall the other user's messages.- Drafts are stored only on this device and don't sync to other devices. Passing
null, or empty text with no quote, deletes the draft.
Typing indicator
typing(conversationKey) tells the other side the user is typing; the SDK sends at most once every 3 seconds, and it works in draft one-to-one chats too. getTyping(conversationKey) returns who's typing now, and changes also emit TypingChanged. For all methods, see ConversationsModule.
