diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt index 190954ab..9c43960f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt @@ -40,6 +40,7 @@ import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.models.PhoneNumber import com.simplemobiletools.commons.models.SimpleContact +import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.adapters.AutoCompleteTextViewAdapter import com.simplemobiletools.smsmessenger.adapters.ThreadAdapter @@ -75,6 +76,9 @@ class ThreadActivity : SimpleActivity() { private var attachmentSelections = mutableMapOf() private val imageCompressor by lazy { ImageCompressor(this) } private var lastAttachmentUri: String? = null + private var loadingOlderMessages = false + private var allMessagesFetched = false + private var oldestMessageDate = -1 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -320,6 +324,14 @@ class ThreadActivity : SimpleActivity() { }.apply { thread_messages_list.adapter = this } + + thread_messages_list.endlessScrollListener = object : MyRecyclerView.EndlessScrollListener { + override fun updateBottom() {} + + override fun updateTop() { + fetchNextMessages() + } + } } else { (currAdapter as ThreadAdapter).updateMessages(threadItems) } @@ -351,6 +363,39 @@ class ThreadActivity : SimpleActivity() { } } + private fun fetchNextMessages() { + if (messages.isEmpty() || allMessagesFetched || loadingOlderMessages) { + return + } + + val dateOfFirstItem = messages.first().date + if (oldestMessageDate == dateOfFirstItem) { + allMessagesFetched = true + return + } + + oldestMessageDate = dateOfFirstItem + loadingOlderMessages = true + + ensureBackgroundThread { + val firstItem = messages.first() + val olderMessages = getMessages(threadId, true, oldestMessageDate) + + messages.addAll(0, olderMessages) + threadItems = getThreadItems() + + allMessagesFetched = olderMessages.size < MESSAGES_LIMIT || olderMessages.size == 0 + + runOnUiThread { + loadingOlderMessages = false + val itemAtRefreshIndex = threadItems.indexOfFirst { it == firstItem } + (thread_messages_list.adapter as ThreadAdapter).apply { + updateMessages(threadItems, itemAtRefreshIndex) + } + } + } + } + private fun setupButtons() { updateTextColors(thread_holder) val textColor = getProperTextColor() @@ -985,6 +1030,9 @@ class ThreadActivity : SimpleActivity() { @Subscribe(threadMode = ThreadMode.ASYNC) fun refreshMessages(event: Events.RefreshMessages) { refreshedSinceSent = true + allMessagesFetched = false + oldestMessageDate = -1 + if (isActivityVisible) { notificationManager.cancel(threadId.hashCode()) } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt index 232d43c8..75c31e54 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ThreadAdapter.kt @@ -231,14 +231,14 @@ class ThreadAdapter( private fun isThreadDateTime(position: Int) = messages.getOrNull(position) is ThreadDateTime - fun updateMessages(newMessages: ArrayList) { + fun updateMessages(newMessages: ArrayList, scrollPosition: Int = newMessages.size - 1) { val latestMessages = newMessages.clone() as ArrayList val oldHashCode = messages.hashCode() val newHashCode = latestMessages.hashCode() if (newHashCode != oldHashCode) { messages = latestMessages notifyDataSetChanged() - recyclerView.scrollToPosition(messages.size - 1) + recyclerView.scrollToPosition(scrollPosition) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt index 0f581030..ed17ed95 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/extensions/Context.kt @@ -56,7 +56,7 @@ val Context.messageAttachmentsDB: MessageAttachmentsDao get() = getMessagessDB() val Context.messagesDB: MessagesDao get() = getMessagessDB().MessagesDao() -fun Context.getMessages(threadId: Long, getImageResolutions: Boolean): ArrayList { +fun Context.getMessages(threadId: Long, getImageResolutions: Boolean, dateFrom: Int = -1): ArrayList { val uri = Sms.CONTENT_URI val projection = arrayOf( Sms._ID, @@ -70,9 +70,10 @@ fun Context.getMessages(threadId: Long, getImageResolutions: Boolean): ArrayList Sms.STATUS ) - val selection = "${Sms.THREAD_ID} = ?" + val rangeQuery = if (dateFrom == -1) "" else "AND ${Sms.DATE} < ${dateFrom.toLong() * 1000}" + val selection = "${Sms.THREAD_ID} = ? $rangeQuery" val selectionArgs = arrayOf(threadId.toString()) - val sortOrder = "${Sms._ID} DESC LIMIT 100" + val sortOrder = "${Sms.DATE} DESC LIMIT $MESSAGES_LIMIT" val blockStatus = HashMap() val blockedNumbers = getBlockedNumbers() diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt index 6e46f4c9..a4a38499 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt @@ -54,6 +54,8 @@ const val FILE_SIZE_600_KB = 614_400L const val FILE_SIZE_1_MB = 1_048_576L const val FILE_SIZE_2_MB = 2_097_152L +const val MESSAGES_LIMIT = 100 + fun refreshMessages() { EventBus.getDefault().post(Events.RefreshMessages()) }