diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt index 4468a7f3..2a66fa41 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/MainActivity.kt @@ -36,6 +36,7 @@ import org.greenrobot.eventbus.ThreadMode import java.io.FileOutputStream import java.io.OutputStream import java.util.* +import kotlin.collections.ArrayList class MainActivity : SimpleActivity() { private val MAKE_DEFAULT_APP_REQUEST = 1 @@ -188,7 +189,7 @@ class MainActivity : SimpleActivity() { private fun getCachedConversations() { ensureBackgroundThread { val conversations = try { - conversationsDB.getAll().sortedByDescending { it.date }.toMutableList() as ArrayList + conversationsDB.getAll().toMutableList() as ArrayList } catch (e: Exception) { ArrayList() } @@ -244,6 +245,10 @@ class MainActivity : SimpleActivity() { private fun setupConversations(conversations: ArrayList) { val hasConversations = conversations.isNotEmpty() + val sortedConversations = conversations.sortedWith( + compareByDescending { config.pinnedConversations.contains(it.threadId.toString()) } + .thenByDescending { it.date } + ).toMutableList() as ArrayList conversations_list.beVisibleIf(hasConversations) no_conversations_placeholder.beVisibleIf(!hasConversations) no_conversations_placeholder_2.beVisibleIf(!hasConversations) @@ -255,7 +260,7 @@ class MainActivity : SimpleActivity() { val currAdapter = conversations_list.adapter if (currAdapter == null) { - ConversationsAdapter(this, conversations, conversations_list, conversations_fastscroller) { + ConversationsAdapter(this, sortedConversations, conversations_list, conversations_fastscroller) { Intent(this, ThreadActivity::class.java).apply { putExtra(THREAD_ID, (it as Conversation).threadId) putExtra(THREAD_TITLE, it.title) @@ -272,7 +277,7 @@ class MainActivity : SimpleActivity() { } } else { try { - (currAdapter as ConversationsAdapter).updateConversations(conversations) + (currAdapter as ConversationsAdapter).updateConversations(sortedConversations) } catch (ignored: Exception) { } } 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 28c5b7ef..11532cca 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/activities/ThreadActivity.kt @@ -146,6 +146,7 @@ class ThreadActivity : SimpleActivity() { } updateMenuItemColors(menu) + checkPinBtnVisibility(menu) return true } @@ -159,6 +160,8 @@ class ThreadActivity : SimpleActivity() { R.id.delete -> askConfirmDelete() R.id.manage_people -> managePeople() R.id.mark_as_unread -> markAsUnread() + R.id.pin_conversation -> pinConversation(true) + R.id.unpin_conversation -> pinConversation(false) else -> return super.onOptionsItemSelected(item) } return true @@ -852,6 +855,24 @@ class ThreadActivity : SimpleActivity() { return participants } + private fun pinConversation(pin: Boolean) { + if (pin) { + config.addPinnedConversationByThreadId(threadId) + } else { + config.removePinnedConversationByThreadId(threadId) + } + + runOnUiThread { + refreshMessages() + } + } + + private fun checkPinBtnVisibility(menu: Menu) { + val pinnedConversations = config.pinnedConversations + menu.findItem(R.id.pin_conversation).isVisible = !pinnedConversations.contains(threadId.toString()) + menu.findItem(R.id.unpin_conversation).isVisible = pinnedConversations.contains(threadId.toString()) + } + @SuppressLint("MissingPermission") @Subscribe(threadMode = ThreadMode.ASYNC) fun refreshMessages(event: Events.RefreshMessages) { diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt index 48720bf3..40e0eb26 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/adapters/ConversationsAdapter.kt @@ -22,10 +22,7 @@ import com.simplemobiletools.commons.views.FastScroller import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.smsmessenger.R import com.simplemobiletools.smsmessenger.activities.SimpleActivity -import com.simplemobiletools.smsmessenger.extensions.deleteConversation -import com.simplemobiletools.smsmessenger.extensions.getSmsDraft -import com.simplemobiletools.smsmessenger.extensions.markThreadMessagesRead -import com.simplemobiletools.smsmessenger.extensions.markThreadMessagesUnread +import com.simplemobiletools.smsmessenger.extensions.* import com.simplemobiletools.smsmessenger.helpers.refreshMessages import com.simplemobiletools.smsmessenger.models.Conversation import kotlinx.android.synthetic.main.item_conversation.view.* @@ -52,6 +49,7 @@ class ConversationsAdapter( findItem(R.id.cab_copy_number).isVisible = isOneItemSelected() && selectedItems.firstOrNull()?.isGroupConversation == false findItem(R.id.cab_mark_as_read).isVisible = selectedItems.any { !it.read } findItem(R.id.cab_mark_as_unread).isVisible = selectedItems.any { it.read } + checkPinBtnVisibility(this) } } @@ -68,6 +66,8 @@ class ConversationsAdapter( R.id.cab_delete -> askConfirmDelete() R.id.cab_mark_as_read -> markAsRead() R.id.cab_mark_as_unread -> markAsUnread() + R.id.cab_pin_conversation -> pinConversation(true) + R.id.cab_unpin_conversation -> pinConversation(false) R.id.cab_select_all -> selectAll() } } @@ -241,6 +241,31 @@ class ConversationsAdapter( private fun getSelectedItems() = conversations.filter { selectedKeys.contains(it.hashCode()) } as ArrayList + private fun pinConversation(pin: Boolean) { + val conversations = getSelectedItems() + if (conversations.isEmpty()) { + return + } + + if (pin) { + activity.config.addPinnedConversations(conversations) + } else { + activity.config.removePinnedConversations(conversations) + } + + activity.runOnUiThread { + refreshMessages() + finishActMode() + } + } + + private fun checkPinBtnVisibility(menu: Menu) { + val pinnedConversations = activity.config.pinnedConversations + val selectedConversations = getSelectedItems() + menu.findItem(R.id.cab_pin_conversation).isVisible = selectedConversations.any { !pinnedConversations.contains(it.threadId.toString()) } + menu.findItem(R.id.cab_unpin_conversation).isVisible = selectedConversations.any { pinnedConversations.contains(it.threadId.toString()) } + } + override fun onViewRecycled(holder: ViewHolder) { super.onViewRecycled(holder) if (!activity.isDestroyed && !activity.isFinishing) { @@ -269,6 +294,8 @@ class ConversationsAdapter( draft_indicator.beVisibleIf(smsDraft != null) draft_indicator.setTextColor(adjustedPrimaryColor) + pin_indicator.beVisibleIf(activity.config.pinnedConversations.contains(conversation.threadId.toString())) + conversation_frame.isSelected = selectedKeys.contains(conversation.hashCode()) conversation_address.apply { diff --git a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt index c6e5c601..842c80be 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Config.kt @@ -2,6 +2,8 @@ package com.simplemobiletools.smsmessenger.helpers import android.content.Context import com.simplemobiletools.commons.helpers.BaseConfig +import com.simplemobiletools.smsmessenger.models.Conversation +import java.util.HashSet class Config(context: Context) : BaseConfig(context) { companion object { @@ -34,6 +36,26 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getLong(MMS_FILE_SIZE_LIMIT, FILE_SIZE_1_MB) set(mmsFileSizeLimit) = prefs.edit().putLong(MMS_FILE_SIZE_LIMIT, mmsFileSizeLimit).apply() + var pinnedConversations: Set + get() = prefs.getStringSet(PINNED_CONVERSATIONS, HashSet())!! + set(pinnedConversations) = prefs.edit().putStringSet(PINNED_CONVERSATIONS, pinnedConversations).apply() + + fun addPinnedConversationByThreadId(threadId: Long) { + pinnedConversations = pinnedConversations.plus(threadId.toString()) + } + + fun addPinnedConversations(conversations: List) { + pinnedConversations = pinnedConversations.plus(conversations.map { it.threadId.toString() }) + } + + fun removePinnedConversationByThreadId(threadId: Long) { + pinnedConversations = pinnedConversations.minus(threadId.toString()) + } + + fun removePinnedConversations(conversations: List) { + pinnedConversations = pinnedConversations.minus(conversations.map { it.threadId.toString() }) + } + var lastExportPath: String get() = prefs.getString(LAST_EXPORT_PATH, "")!! set(lastExportPath) = prefs.edit().putString(LAST_EXPORT_PATH, lastExportPath).apply() @@ -53,5 +75,4 @@ class Config(context: Context) : BaseConfig(context) { var importMms: Boolean get() = prefs.getBoolean(IMPORT_MMS, true) set(importMms) = prefs.edit().putBoolean(IMPORT_MMS, importMms).apply() - } 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 9e74d87c..b18c19c8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/smsmessenger/helpers/Constants.kt @@ -17,6 +17,7 @@ const val USE_SIMPLE_CHARACTERS = "use_simple_characters" const val LOCK_SCREEN_VISIBILITY = "lock_screen_visibility" const val ENABLE_DELIVERY_REPORTS = "enable_delivery_reports" const val MMS_FILE_SIZE_LIMIT = "mms_file_size_limit" +const val PINNED_CONVERSATIONS = "pinned_conversations" const val LAST_EXPORT_PATH = "last_export_path" const val EXPORT_SMS = "export_sms" const val EXPORT_MMS = "export_mms" diff --git a/app/src/main/res/drawable-hdpi/ic_pin.png b/app/src/main/res/drawable-hdpi/ic_pin.png new file mode 100644 index 00000000..0f32c2eb Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_pin.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_pin.png b/app/src/main/res/drawable-mdpi/ic_pin.png new file mode 100644 index 00000000..eb56bb8a Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_pin.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_pin.png b/app/src/main/res/drawable-xhdpi/ic_pin.png new file mode 100644 index 00000000..b97d8ac9 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_pin.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_pin.png b/app/src/main/res/drawable-xxhdpi/ic_pin.png new file mode 100644 index 00000000..4a1a3dd2 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_pin.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_pin.png b/app/src/main/res/drawable-xxxhdpi/ic_pin.png new file mode 100644 index 00000000..c516e08f Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_pin.png differ diff --git a/app/src/main/res/layout/item_conversation.xml b/app/src/main/res/layout/item_conversation.xml index 6cde1caa..6c61a3d6 100644 --- a/app/src/main/res/layout/item_conversation.xml +++ b/app/src/main/res/layout/item_conversation.xml @@ -26,6 +26,24 @@ android:layout_marginStart="@dimen/normal_margin" android:layout_marginEnd="@dimen/normal_margin" /> + + + + + + + + + diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index d3c964b0..cb1694b1 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -15,6 +15,10 @@ Odesílatel nepodporuje odpovědi Návrh Odesílá se… + Export zpráv + Import zpráv + Pin to the top + Unpin Nová konverzace diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 6014767f..19068d08 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -15,6 +15,10 @@ Afsender understøtter ikke svar Udkast Sender… + Eksporter beskeder + Importer beskeder + Pin to the top + Unpin Ny Samtale diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 2539ee17..b6d45b31 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -15,6 +15,10 @@ Der Absender unterstützt keine Antworten. Entwurf Sende… + Export messages + Import messages + Pin to the top + Unpin Neuer Chat diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index a904ebb9..8472aaa7 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -15,6 +15,10 @@ Ο αποστολέας δεν υποστηρίζει απαντήσεις Πρόχειρο Γίνεται αποστολή… + Εξαγωγή μηνυμάτων + Εισαγωγή μηνυμάτων + Pin to the top + Unpin Νέα συνομιλία diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 16b9a7a8..5f135e98 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -15,6 +15,10 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages + Pin to the top + Unpin Nueva conversación diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 14fcf8cd..7d6203f8 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -15,6 +15,10 @@ Lähettäjä ei tue vastauksia Luonnos Lähetetään… + Export messages + Import messages + Pin to the top + Unpin Uusi keskustelu diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 9ac64dff..bc36ed18 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -15,6 +15,10 @@ L\'expéditeur n\'accepte pas les réponses Brouillon Envoi en cours… + Export de messages + Import de messages + Pin to the top + Unpin Nouvelle conversation diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 5244741c..a0c42e28 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -15,6 +15,10 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages + Pin to the top + Unpin Nova conversa diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index 573702c5..84e21e67 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -15,6 +15,10 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages + Pin to the top + Unpin Percakapan baru diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index f19c6920..aea63fd7 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -15,6 +15,10 @@ Il mittente non accetta risposte Bozza Invio… + Export messages + Import messages + Pin to the top + Unpin Nuova conversazione diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 9a3c8982..b890ce8e 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -15,6 +15,10 @@ Sender doesn\'t support replies Draft Sending… + Export messages + Import messages + Pin to the top + Unpin 新しい会話 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 79e79648..0c5eb136 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Pin to the top + Unpin Naujas pokalbis diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 4334c9b8..6bcdf125 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Pin to the top + Unpin പുതിയ സംഭാഷണം diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index acec882f..aefb2f76 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -15,6 +15,8 @@ Afzender ondersteunt geen antwoorden Concept Versturen… + Pin to the top + Unpin Nieuw gesprek diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 10120f86..83a69db6 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -15,6 +15,8 @@ Nadawca nie obsługuje odpowiedzi Szkic Wysyłanie… + Przypnij na górze + Odepnij Nowa rozmowa diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 59a8e881..26e468e1 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -15,6 +15,8 @@ O remetente não aceita respostas Rascunho A enviar… + Pin to the top + Unpin Nova conversa diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 3e9b2bab..c2707c1a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -15,6 +15,8 @@ Отправитель не поддерживает ответы Черновик Отправка… + Pin to the top + Unpin Новая переписка diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 76e9b39c..924233db 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -15,6 +15,8 @@ Odosielateľ nepodporuje odpovede Koncept Odosiela sa… + Pin to the top + Unpin Nová konverzácia diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 491e5350..90bd5459 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Pin to the top + Unpin Yeni görüşme diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 81b42c07..4ed5486a 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Pin to the top + Unpin Нове листування diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c5161790..9ed50193 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Pin to the top + Unpin 新的对话 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index fd6215f3..5411875a 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -5,4 +5,5 @@ 36dp 60dp 24dp + 15dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 23e6e9f5..89b51202 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -15,6 +15,8 @@ Sender doesn\'t support replies Draft Sending… + Pin to the top + Unpin New conversation