Merge pull request #698 from esensar/feature/177-conversations-archive

Implement archive feature for conversations using system API
This commit is contained in:
Tibor Kaputa 2023-07-19 16:40:16 +02:00 committed by GitHub
commit 0c5242df2d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
70 changed files with 1241 additions and 196 deletions

View file

@ -0,0 +1,160 @@
package com.simplemobiletools.smsmessenger.activities
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.smsmessenger.R
import com.simplemobiletools.smsmessenger.adapters.ArchivedConversationsAdapter
import com.simplemobiletools.smsmessenger.extensions.*
import com.simplemobiletools.smsmessenger.helpers.*
import com.simplemobiletools.smsmessenger.models.Conversation
import com.simplemobiletools.smsmessenger.models.Events
import kotlinx.android.synthetic.main.activity_archived_conversations.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class ArchivedConversationsActivity : SimpleActivity() {
private var bus: EventBus? = null
@SuppressLint("InlinedApi")
override fun onCreate(savedInstanceState: Bundle?) {
isMaterialActivity = true
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_archived_conversations)
setupOptionsMenu()
updateMaterialActivityViews(archive_coordinator, conversations_list, useTransparentNavigation = true, useTopSearchMenu = false)
setupMaterialScrollListener(conversations_list, archive_toolbar)
loadArchivedConversations()
}
override fun onResume() {
super.onResume()
setupToolbar(archive_toolbar, NavigationIcon.Arrow)
updateMenuColors()
loadArchivedConversations()
}
override fun onDestroy() {
super.onDestroy()
bus?.unregister(this)
}
private fun setupOptionsMenu() {
archive_toolbar.inflateMenu(R.menu.archive_menu)
archive_toolbar.setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) {
R.id.empty_archive -> removeAll()
else -> return@setOnMenuItemClickListener false
}
return@setOnMenuItemClickListener true
}
}
private fun updateOptionsMenu(conversations: ArrayList<Conversation>) {
archive_toolbar.menu.apply {
findItem(R.id.empty_archive).isVisible = conversations.isNotEmpty()
}
}
private fun updateMenuColors() {
updateStatusbarColor(getProperBackgroundColor())
}
private fun loadArchivedConversations() {
ensureBackgroundThread {
val conversations = try {
conversationsDB.getAllArchived().toMutableList() as ArrayList<Conversation>
} catch (e: Exception) {
ArrayList()
}
runOnUiThread {
setupConversations(conversations)
}
}
bus = EventBus.getDefault()
try {
bus!!.register(this)
} catch (e: Exception) {
}
}
private fun removeAll() {
ConfirmationDialog(this, "", R.string.empty_archive_confirmation, R.string.yes, R.string.no) {
removeAllArchivedConversations {
loadArchivedConversations()
}
}
}
private fun getOrCreateConversationsAdapter(): ArchivedConversationsAdapter {
var currAdapter = conversations_list.adapter
if (currAdapter == null) {
hideKeyboard()
currAdapter = ArchivedConversationsAdapter(
activity = this,
recyclerView = conversations_list,
onRefresh = { notifyDatasetChanged() },
itemClick = { handleConversationClick(it) }
)
conversations_list.adapter = currAdapter
if (areSystemAnimationsEnabled) {
conversations_list.scheduleLayoutAnimation()
}
}
return currAdapter as ArchivedConversationsAdapter
}
private fun setupConversations(conversations: ArrayList<Conversation>) {
val sortedConversations = conversations.sortedWith(
compareByDescending<Conversation> { config.pinnedConversations.contains(it.threadId.toString()) }
.thenByDescending { it.date }
).toMutableList() as ArrayList<Conversation>
showOrHidePlaceholder(conversations.isEmpty())
updateOptionsMenu(conversations)
try {
getOrCreateConversationsAdapter().apply {
updateConversations(sortedConversations)
}
} catch (ignored: Exception) {
}
}
private fun showOrHidePlaceholder(show: Boolean) {
conversations_fastscroller.beGoneIf(show)
no_conversations_placeholder.beVisibleIf(show)
no_conversations_placeholder.text = getString(R.string.no_archived_conversations)
}
@SuppressLint("NotifyDataSetChanged")
private fun notifyDatasetChanged() {
getOrCreateConversationsAdapter().notifyDataSetChanged()
}
private fun handleConversationClick(any: Any) {
Intent(this, ThreadActivity::class.java).apply {
val conversation = any as Conversation
putExtra(THREAD_ID, conversation.threadId)
putExtra(THREAD_TITLE, conversation.title)
putExtra(WAS_PROTECTION_HANDLED, true)
startActivity(this)
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun refreshMessages(event: Events.RefreshMessages) {
loadArchivedConversations()
}
}

View file

@ -177,6 +177,7 @@ class MainActivity : SimpleActivity() {
R.id.import_messages -> tryImportMessages()
R.id.export_messages -> tryToExportMessages()
R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
R.id.show_archived -> launchArchivedConversations()
R.id.settings -> launchSettings()
R.id.about -> launchAbout()
else -> return@setOnMenuItemClickListener false
@ -292,15 +293,21 @@ class MainActivity : SimpleActivity() {
private fun getCachedConversations() {
ensureBackgroundThread {
val conversations = try {
conversationsDB.getAll().toMutableList() as ArrayList<Conversation>
conversationsDB.getNonArchived().toMutableList() as ArrayList<Conversation>
} catch (e: Exception) {
ArrayList()
}
val archived = try {
conversationsDB.getAllArchived()
} catch (e: Exception) {
listOf()
}
updateUnreadCountBadge(conversations)
runOnUiThread {
setupConversations(conversations, cached = true)
getNewConversations(conversations)
getNewConversations((conversations + archived).toMutableList() as ArrayList<Conversation>)
}
conversations.forEach {
clearExpiredScheduledMessages(it.threadId)
@ -354,7 +361,7 @@ class MainActivity : SimpleActivity() {
}
}
val allConversations = conversationsDB.getAll() as ArrayList<Conversation>
val allConversations = conversationsDB.getNonArchived() as ArrayList<Conversation>
runOnUiThread {
setupConversations(allConversations)
}
@ -559,6 +566,11 @@ class MainActivity : SimpleActivity() {
}
}
private fun launchArchivedConversations() {
hideKeyboard()
startActivity(Intent(applicationContext, ArchivedConversationsActivity::class.java))
}
private fun launchSettings() {
hideKeyboard()
startActivity(Intent(applicationContext, SettingsActivity::class.java))

View file

@ -250,6 +250,8 @@ class ThreadActivity : SimpleActivity() {
val firstPhoneNumber = participants.firstOrNull()?.phoneNumbers?.firstOrNull()?.value
thread_toolbar.menu.apply {
findItem(R.id.delete).isVisible = threadItems.isNotEmpty()
findItem(R.id.archive).isVisible = threadItems.isNotEmpty() && conversation?.isArchived == false
findItem(R.id.unarchive).isVisible = threadItems.isNotEmpty() && conversation?.isArchived == true
findItem(R.id.rename_conversation).isVisible = participants.size > 1 && conversation != null
findItem(R.id.conversation_details).isVisible = conversation != null
findItem(R.id.block_number).title = addLockedLabelIfNeeded(R.string.block_number)
@ -274,6 +276,8 @@ class ThreadActivity : SimpleActivity() {
when (menuItem.itemId) {
R.id.block_number -> tryBlocking()
R.id.delete -> askConfirmDelete()
R.id.archive -> archiveConversation()
R.id.unarchive -> unarchiveConversation()
R.id.rename_conversation -> renameConversation()
R.id.conversation_details -> showConversationDetails()
R.id.add_number_to_contact -> addNumberToContact()
@ -913,7 +917,8 @@ class ThreadActivity : SimpleActivity() {
}
private fun askConfirmDelete() {
ConfirmationDialog(this, getString(R.string.delete_whole_conversation_confirmation)) {
val confirmationMessage = R.string.delete_whole_conversation_confirmation
ConfirmationDialog(this, getString(confirmationMessage)) {
ensureBackgroundThread {
deleteConversation(threadId)
runOnUiThread {
@ -924,6 +929,26 @@ class ThreadActivity : SimpleActivity() {
}
}
private fun archiveConversation() {
ensureBackgroundThread {
updateConversationArchivedStatus(threadId, true)
runOnUiThread {
refreshMessages()
finish()
}
}
}
private fun unarchiveConversation() {
ensureBackgroundThread {
updateConversationArchivedStatus(threadId, false)
runOnUiThread {
refreshMessages()
finish()
}
}
}
private fun dialNumber() {
val phoneNumber = participants.first().phoneNumbers.first().normalizedNumber
dialNumber(phoneNumber)
@ -1352,6 +1377,7 @@ class ThreadActivity : SimpleActivity() {
}
}
messagesDB.insertOrUpdate(message)
updateConversationArchivedStatus(message.threadId, false)
}
// show selected contacts, properly split to new lines when appropriate