@@ -84,6 +84,8 @@ class ChatDetailFragment : Fragment() {
8484 private var speechRecognizer: SpeechRecognizer ? = null
8585 private var isListening = false
8686 private var textBeforeVoice: String = " "
87+ private var allConversations: List <RealmConversation > = emptyList()
88+ private var loadedCount = 0
8789
8890 private val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts .RequestPermission ()) { isGranted ->
8991 if (isGranted) {
@@ -266,6 +268,7 @@ class ChatDetailFragment : Fragment() {
266268 }
267269 return @ChatAdapter { job.cancel() }
268270 }
271+ mAdapter.onLoadMoreClick = ::loadMoreConversations
269272 binding.recyclerGchat.apply {
270273 adapter = mAdapter
271274 layoutManager = LinearLayoutManager (requireContext())
@@ -341,7 +344,12 @@ class ChatDetailFragment : Fragment() {
341344 customProgressDialog.setText(getString(R .string.please_wait))
342345 customProgressDialog.show()
343346 try {
344- val messages = sharedViewModel.parseNewsConversations(newsConversations)
347+ val messages = withContext(Dispatchers .IO ) {
348+ val conversations = JsonUtils .gson.fromJson(newsConversations, Array <RealmConversation >::class .java).toList()
349+ allConversations = conversations
350+ loadedCount = minOf(PAGE_SIZE , conversations.size)
351+ buildInitialPage()
352+ }
345353 mAdapter.submitList(messages) {
346354 binding.recyclerGchat.post {
347355 binding.recyclerGchat.scrollToPosition(mAdapter.itemCount - 1 )
@@ -401,14 +409,14 @@ class ChatDetailFragment : Fragment() {
401409 launch {
402410 sharedViewModel.selectedChatHistory.collect { conversations ->
403411 mAdapter.clearData()
412+ allConversations = emptyList()
413+ loadedCount = 0
404414 binding.editGchatMessage.text.clear()
405415 binding.textGchatIndicator.visibility = View .GONE
406416 if (! conversations.isNullOrEmpty()) {
407- val messages = mutableListOf<ChatMessage >()
408- for (conversation in conversations) {
409- conversation.query?.let { messages.add(ChatMessage (it, ChatMessage .QUERY )) }
410- conversation.response?.let { messages.add(ChatMessage (it, ChatMessage .RESPONSE , ChatMessage .RESPONSE_SOURCE_SHARED_VIEW_MODEL )) }
411- }
417+ allConversations = conversations
418+ loadedCount = minOf(PAGE_SIZE , conversations.size)
419+ val messages = buildInitialPage()
412420 mAdapter.submitList(messages) {
413421 binding.recyclerGchat.post {
414422 binding.recyclerGchat.scrollToPosition(mAdapter.itemCount - 1 )
@@ -561,6 +569,8 @@ class ChatDetailFragment : Fragment() {
561569
562570 private fun clearConversation () {
563571 mAdapter.clearData()
572+ allConversations = emptyList()
573+ loadedCount = 0
564574 _id = " "
565575 _rev = " "
566576 currentID = " "
@@ -767,6 +777,47 @@ class ChatDetailFragment : Fragment() {
767777 add(" conversations" , conversationsArray)
768778 }
769779
780+ private fun continueConversationRealm (id : String , query : String , chatResponse : String ) {
781+ val realmChatId = when {
782+ id.isNotBlank() -> id
783+ _id .isNotBlank() -> _id
784+ currentID.isNotBlank() -> currentID
785+ else -> return
786+ }
787+
788+ if (query.isBlank() && chatResponse.isBlank()) return
789+
790+ sharedViewModel.continueConversation(realmChatId, query, chatResponse, _rev )
791+ }
792+
793+ private fun buildMessagesSlice (startIndex : Int , endIndex : Int ): List <ChatMessage > {
794+ val messages = mutableListOf<ChatMessage >()
795+ for (i in startIndex until endIndex) {
796+ val conv = allConversations[i]
797+ conv.query?.let { messages.add(ChatMessage (it, ChatMessage .QUERY )) }
798+ conv.response?.let { messages.add(ChatMessage (it, ChatMessage .RESPONSE , ChatMessage .RESPONSE_SOURCE_SHARED_VIEW_MODEL )) }
799+ }
800+ return messages
801+ }
802+
803+ private fun buildInitialPage (): List <ChatMessage > {
804+ val total = allConversations.size
805+ val startIndex = maxOf(0 , total - loadedCount)
806+ val messages = mutableListOf<ChatMessage >()
807+ if (startIndex > 0 ) messages.add(ChatMessage (" " , ChatMessage .LOAD_MORE ))
808+ messages.addAll(buildMessagesSlice(startIndex, total))
809+ return messages
810+ }
811+
812+ private fun loadMoreConversations () {
813+ val total = allConversations.size
814+ val prevStartIndex = maxOf(0 , total - loadedCount)
815+ loadedCount = minOf(loadedCount + PAGE_SIZE , total)
816+ val newStartIndex = maxOf(0 , total - loadedCount)
817+ val newMessages = buildMessagesSlice(newStartIndex, prevStartIndex)
818+ mAdapter.prependMessages(newMessages, hasLoadMoreAbove = newStartIndex > 0 )
819+ }
820+
770821 private fun clearChatDetail () {
771822 if (newsId == null && sharedViewModel.selectedChatHistory.value.isNullOrEmpty()) {
772823 if (::mAdapter.isInitialized) {
@@ -818,6 +869,7 @@ class ChatDetailFragment : Fragment() {
818869 }
819870
820871 companion object {
872+ private const val PAGE_SIZE = 20
821873 const val ARG_COURSE_TITLE = " course_title"
822874 const val ARG_STEP_TITLE = " step_title"
823875 const val ARG_STEP_DESCRIPTION = " step_description"
0 commit comments