@@ -10,13 +10,18 @@ import androidx.paging.RemoteMediator
1010import com.getcode.db.AppDatabase
1111import com.getcode.db.Database
1212import com.getcode.manager.SessionManager
13+ import com.getcode.mapper.ConversationMapper
1314import com.getcode.model.chat.ChatType
1415import com.getcode.model.Conversation
1516import com.getcode.model.ConversationMessage
1617import com.getcode.model.ID
18+ import com.getcode.model.chat.ChatMessage
19+ import com.getcode.model.chat.MessageContent
20+ import com.getcode.model.chat.Reference
1721import com.getcode.network.client.ChatMessageStreamReference
1822import com.getcode.network.client.Client
1923import com.getcode.network.client.openChatStream
24+ import com.getcode.network.client.startChat
2025import com.getcode.network.exchange.Exchange
2126import com.getcode.network.repository.base58
2227import com.getcode.utils.bytes
@@ -29,12 +34,12 @@ import kotlin.jvm.Throws
2934
3035interface ConversationController {
3136 fun observeConversationForMessage (messageId : ID ): Flow <Conversation ?>
32- suspend fun createConversation (identifier : ID , type : ChatType )
37+ suspend fun createConversation (identifier : ID , type : ChatType ): Conversation
3338 suspend fun getConversation (identifier : ID ): Conversation ?
34- fun openChatStream (scope : CoroutineScope , messageId : ID )
39+ suspend fun getOrCreateConversation (identifier : ID , type : ChatType ): Conversation ?
40+ fun openChatStream (scope : CoroutineScope , identifier : ID )
3541 fun closeChatStream ()
36- suspend fun hasThanked (messageId : ID ): Boolean
37- suspend fun thankTipper (messageId : ID )
42+ suspend fun hasInteracted (messageId : ID ): Boolean
3843 suspend fun revealIdentity (messageId : ID )
3944 fun sendMessage (conversationId : ID , message : String )
4045 fun conversationPagingData (conversationId : ID ): Flow <PagingData <ConversationMessage >>
@@ -43,7 +48,8 @@ interface ConversationController {
4348class ConversationStreamController @Inject constructor(
4449 private val historyController : HistoryController ,
4550 private val exchange : Exchange ,
46- private val client : Client
51+ private val client : Client ,
52+ private val conversationMapper : ConversationMapper ,
4753): ConversationController {
4854 private val pagingConfig = PagingConfig (pageSize = 20 )
4955
@@ -60,24 +66,50 @@ class ConversationStreamController @Inject constructor(
6066 return db.conversationDao().observeConversationForMessage(messageId)
6167 }
6268
63- override suspend fun createConversation (identifier : ID , type : ChatType ) {
69+ override suspend fun createConversation (identifier : ID , type : ChatType ): Conversation {
70+ val owner = SessionManager .getOrganizer()?.ownerKeyPair ? : throw IllegalStateException ()
71+ val lookup = { msg: ChatMessage ->
72+ msg.id == identifier ||
73+ msg.contents.filterIsInstance<MessageContent .Exchange >()
74+ .map { it.reference }
75+ .filterIsInstance<Reference .IntentId >()
76+ .any { it.id == identifier }
77+ }
6478
79+ val message = historyController.chats.value?.firstOrNull {
80+ it.messages.find { msg -> lookup(msg) } != null
81+ }?.messages?.firstOrNull { msg -> lookup(msg) } ? : throw IllegalArgumentException ()
82+
83+ return client.startChat(owner, identifier, type)
84+ .map { conversationMapper.map(it to message) }
85+ .onSuccess {
86+ db.conversationDao().upsertConversations(it)
87+ // update chats
88+ historyController.fetchChats()
89+ }
90+ .getOrThrow()
6591 }
6692
6793 override suspend fun getConversation (identifier : ID ): Conversation ? {
68- return null
94+ return db.conversationDao().findConversation(identifier)
95+ }
96+
97+ override suspend fun getOrCreateConversation (identifier : ID , type : ChatType ): Conversation ? {
98+ return getConversation(identifier) ? : createConversation(identifier, type)
6999 }
70100
71101 @Throws(IllegalStateException ::class )
72- override fun openChatStream (scope : CoroutineScope , messageId : ID ) {
102+ override fun openChatStream (scope : CoroutineScope , identifier : ID ) {
73103 val owner = SessionManager .getOrganizer()?.ownerKeyPair ? : throw IllegalStateException ()
74104 val chat = historyController.chats.value?.firstOrNull {
75- it.messages.find { msg -> msg.id == messageId } != null
105+ it.messages.find { msg -> msg.id == identifier } != null
76106 } ? : throw IllegalArgumentException ()
77107
78- stream = client.openChatStream(scope, chat, memberId.bytes, owner) { result ->
108+ stream = client.openChatStream(scope, chat, identifier, memberId.bytes, owner) { result ->
79109 if (result.isSuccess) {
80110 println (" chat messages: ${result.getOrNull()} " )
111+ } else {
112+ println (" Error: ${result.exceptionOrNull()?.message} " )
81113 }
82114 }
83115 }
@@ -86,12 +118,9 @@ class ConversationStreamController @Inject constructor(
86118 stream?.destroy()
87119 }
88120
89- override suspend fun hasThanked (messageId : ID ): Boolean {
121+ override suspend fun hasInteracted (messageId : ID ): Boolean {
90122 val conversation = db.conversationDao().findConversationForMessage(messageId) ? : return false
91- return db.conversationDao().hasThanked(conversation.messageId)
92- }
93-
94- override suspend fun thankTipper (messageId : ID ) {
123+ return db.conversationDao().hasInteracted(conversation.messageId)
95124 }
96125
97126 override suspend fun revealIdentity (messageId : ID ) {
0 commit comments