feat: add conversation shortcuts (#280)
* Declare intent filter to open ThreadActivity from shortcut * Add SimpleContact utilities * Create the ShortcutHelper class * update shortcuts on sending message, notification received and when opening thread. * format code * Avoid error when getConversations is called from UI thread * Changed ranking of create new conversation shortcut to 0 * removed exception handling * Run shortcut registration in background * Changed shortcut creation and usage report * do not create shortcut on opening conversation * optimize imports * Delete shortcut with conversation * Show main activity if conversation does not exist * removed old intent filter * Specify Fossify thread activity in shortcut's intent * Avoid dismissing activity if it's a new conversation * Try to fix private contacts appearing as numbers * Removed intent sanitizer since activity isn't exported anymore * Update shortcut label and picture when changing conversation name * refactor: cleanup code * refactor: collapse empty tag --------- Co-authored-by: Naveen Singh <36371707+naveensingh@users.noreply.github.com> Co-authored-by: Naveen Singh <snaveen935@gmail.com>
This commit is contained in:
parent
0b7434568b
commit
857a1fd445
8 changed files with 265 additions and 5 deletions
|
|
@ -531,6 +531,7 @@ class MainActivity : SimpleActivity() {
|
||||||
.setLongLabel(newEvent)
|
.setLongLabel(newEvent)
|
||||||
.setIcon(Icon.createWithBitmap(bmp))
|
.setIcon(Icon.createWithBitmap(bmp))
|
||||||
.setIntent(intent)
|
.setIntent(intent)
|
||||||
|
.setRank(0)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ import org.fossify.messages.helpers.CAPTURE_AUDIO_INTENT
|
||||||
import org.fossify.messages.helpers.CAPTURE_PHOTO_INTENT
|
import org.fossify.messages.helpers.CAPTURE_PHOTO_INTENT
|
||||||
import org.fossify.messages.helpers.CAPTURE_VIDEO_INTENT
|
import org.fossify.messages.helpers.CAPTURE_VIDEO_INTENT
|
||||||
import org.fossify.messages.helpers.FILE_SIZE_NONE
|
import org.fossify.messages.helpers.FILE_SIZE_NONE
|
||||||
|
import org.fossify.messages.helpers.IS_LAUNCHED_FROM_SHORTCUT
|
||||||
import org.fossify.messages.helpers.IS_RECYCLE_BIN
|
import org.fossify.messages.helpers.IS_RECYCLE_BIN
|
||||||
import org.fossify.messages.helpers.MESSAGES_LIMIT
|
import org.fossify.messages.helpers.MESSAGES_LIMIT
|
||||||
import org.fossify.messages.helpers.PICK_CONTACT_INTENT
|
import org.fossify.messages.helpers.PICK_CONTACT_INTENT
|
||||||
|
|
@ -192,7 +193,6 @@ import org.joda.time.DateTime
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import kotlin.collections.set
|
|
||||||
|
|
||||||
class ThreadActivity : SimpleActivity() {
|
class ThreadActivity : SimpleActivity() {
|
||||||
private val MIN_DATE_TIME_DIFF_SECS = 300
|
private val MIN_DATE_TIME_DIFF_SECS = 300
|
||||||
|
|
@ -220,6 +220,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
private var allMessagesFetched = false
|
private var allMessagesFetched = false
|
||||||
private var oldestMessageDate = -1
|
private var oldestMessageDate = -1
|
||||||
private var isRecycleBin = false
|
private var isRecycleBin = false
|
||||||
|
private var isLaunchedFromShortcut = false
|
||||||
|
|
||||||
private var isScheduledMessage: Boolean = false
|
private var isScheduledMessage: Boolean = false
|
||||||
private var messageToResend: Long? = null
|
private var messageToResend: Long? = null
|
||||||
|
|
@ -263,6 +264,7 @@ class ThreadActivity : SimpleActivity() {
|
||||||
binding.threadToolbar.title = it
|
binding.threadToolbar.title = it
|
||||||
}
|
}
|
||||||
isRecycleBin = intent.getBooleanExtra(IS_RECYCLE_BIN, false)
|
isRecycleBin = intent.getBooleanExtra(IS_RECYCLE_BIN, false)
|
||||||
|
isLaunchedFromShortcut = intent.getBooleanExtra(IS_LAUNCHED_FROM_SHORTCUT, false)
|
||||||
|
|
||||||
bus = EventBus.getDefault()
|
bus = EventBus.getDefault()
|
||||||
bus!!.register(this)
|
bus!!.register(this)
|
||||||
|
|
@ -463,6 +465,16 @@ class ThreadActivity : SimpleActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupThread() {
|
private fun setupThread() {
|
||||||
|
if (conversation == null && isLaunchedFromShortcut) {
|
||||||
|
if (isTaskRoot) {
|
||||||
|
Intent(this, MainActivity::class.java).apply {
|
||||||
|
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||||
|
startActivity(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
val privateCursor = getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
|
val privateCursor = getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
|
||||||
ensureBackgroundThread {
|
ensureBackgroundThread {
|
||||||
privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
|
privateContacts = MyContactsContentProvider.getSimpleContacts(this, privateCursor)
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ import org.fossify.commons.extensions.normalizeString
|
||||||
import org.fossify.commons.extensions.notificationManager
|
import org.fossify.commons.extensions.notificationManager
|
||||||
import org.fossify.commons.extensions.queryCursor
|
import org.fossify.commons.extensions.queryCursor
|
||||||
import org.fossify.commons.extensions.showErrorToast
|
import org.fossify.commons.extensions.showErrorToast
|
||||||
import org.fossify.commons.extensions.toInt
|
|
||||||
import org.fossify.commons.extensions.toast
|
import org.fossify.commons.extensions.toast
|
||||||
import org.fossify.commons.extensions.trimToComparableNumber
|
import org.fossify.commons.extensions.trimToComparableNumber
|
||||||
import org.fossify.commons.helpers.DAY_SECONDS
|
import org.fossify.commons.helpers.DAY_SECONDS
|
||||||
|
|
@ -59,6 +58,7 @@ import org.fossify.messages.helpers.FILE_SIZE_NONE
|
||||||
import org.fossify.messages.helpers.MAX_MESSAGE_LENGTH
|
import org.fossify.messages.helpers.MAX_MESSAGE_LENGTH
|
||||||
import org.fossify.messages.helpers.MESSAGES_LIMIT
|
import org.fossify.messages.helpers.MESSAGES_LIMIT
|
||||||
import org.fossify.messages.helpers.NotificationHelper
|
import org.fossify.messages.helpers.NotificationHelper
|
||||||
|
import org.fossify.messages.helpers.ShortcutHelper
|
||||||
import org.fossify.messages.helpers.generateRandomId
|
import org.fossify.messages.helpers.generateRandomId
|
||||||
import org.fossify.messages.interfaces.AttachmentsDao
|
import org.fossify.messages.interfaces.AttachmentsDao
|
||||||
import org.fossify.messages.interfaces.ConversationsDao
|
import org.fossify.messages.interfaces.ConversationsDao
|
||||||
|
|
@ -107,6 +107,8 @@ val Context.messagingUtils
|
||||||
val Context.smsSender
|
val Context.smsSender
|
||||||
get() = SmsSender.getInstance(applicationContext as Application)
|
get() = SmsSender.getInstance(applicationContext as Application)
|
||||||
|
|
||||||
|
val Context.shortcutHelper get() = ShortcutHelper(this)
|
||||||
|
|
||||||
fun Context.getMessages(
|
fun Context.getMessages(
|
||||||
threadId: Long,
|
threadId: Long,
|
||||||
getImageResolutions: Boolean,
|
getImageResolutions: Boolean,
|
||||||
|
|
@ -855,6 +857,9 @@ fun Context.deleteConversation(threadId: Long) {
|
||||||
config.removeCustomNotificationsByThreadId(threadId)
|
config.removeCustomNotificationsByThreadId(threadId)
|
||||||
notificationManager.deleteNotificationChannel(threadId.toString())
|
notificationManager.deleteNotificationChannel(threadId.toString())
|
||||||
}
|
}
|
||||||
|
if(shortcutHelper.getShortcut(threadId) != null) {
|
||||||
|
shortcutHelper.removeShortcutForThread(threadId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.checkAndDeleteOldRecycleBinMessages(callback: (() -> Unit)? = null) {
|
fun Context.checkAndDeleteOldRecycleBinMessages(callback: (() -> Unit)? = null) {
|
||||||
|
|
@ -1253,6 +1258,9 @@ fun Context.renameConversation(conversation: Conversation, newTitle: String): Co
|
||||||
val updatedConv = conversation.copy(title = newTitle, usesCustomTitle = true)
|
val updatedConv = conversation.copy(title = newTitle, usesCustomTitle = true)
|
||||||
try {
|
try {
|
||||||
conversationsDB.insertOrUpdate(updatedConv)
|
conversationsDB.insertOrUpdate(updatedConv)
|
||||||
|
ensureBackgroundThread {
|
||||||
|
shortcutHelper.createOrUpdateShortcut(updatedConv)
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,52 @@
|
||||||
package org.fossify.messages.extensions
|
package org.fossify.messages.extensions
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.net.Uri
|
||||||
|
import android.provider.ContactsContract
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
|
import androidx.core.app.Person
|
||||||
|
import androidx.core.graphics.drawable.IconCompat
|
||||||
|
import org.fossify.commons.helpers.SimpleContactsHelper
|
||||||
import org.fossify.commons.models.SimpleContact
|
import org.fossify.commons.models.SimpleContact
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
|
||||||
fun ArrayList<SimpleContact>.getThreadTitle(): String = TextUtils.join(", ", map { it.name }.toTypedArray()).orEmpty()
|
fun ArrayList<SimpleContact>.getThreadTitle(): String {
|
||||||
|
return TextUtils.join(", ", map { it.name }.toTypedArray()).orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ArrayList<SimpleContact>.getAddresses(): List<String> {
|
||||||
|
return flatMap { it.phoneNumbers }.map { it.normalizedNumber }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SimpleContact.toPerson(context: Context? = null): Person {
|
||||||
|
val uri =
|
||||||
|
Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, contactId.toString())
|
||||||
|
val iconCompat = if (context != null) {
|
||||||
|
loadIcon(context)
|
||||||
|
} else {
|
||||||
|
IconCompat.createWithContentUri(photoUri)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Person.Builder()
|
||||||
|
.setName(name)
|
||||||
|
.setUri(uri.toString())
|
||||||
|
.setIcon(iconCompat)
|
||||||
|
.setKey(uri.toString())
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun SimpleContact.loadIcon(context: Context): IconCompat {
|
||||||
|
try {
|
||||||
|
val stream = context.contentResolver.openInputStream(photoUri.toUri())
|
||||||
|
val bitmap = BitmapFactory.decodeStream(stream)
|
||||||
|
stream?.close()
|
||||||
|
val iconCompat = IconCompat.createWithAdaptiveBitmap(bitmap)
|
||||||
|
return iconCompat
|
||||||
|
} catch (e: Exception) {
|
||||||
|
return IconCompat.createWithAdaptiveBitmap(
|
||||||
|
SimpleContactsHelper(context).getContactLetterIcon(name)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun ArrayList<SimpleContact>.getAddresses() = flatMap { it.phoneNumbers }.map { it.normalizedNumber }
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ const val LAST_RECYCLE_BIN_CHECK = "last_recycle_bin_check"
|
||||||
const val IS_RECYCLE_BIN = "is_recycle_bin"
|
const val IS_RECYCLE_BIN = "is_recycle_bin"
|
||||||
const val IS_ARCHIVE_AVAILABLE = "is_archive_available"
|
const val IS_ARCHIVE_AVAILABLE = "is_archive_available"
|
||||||
const val CUSTOM_NOTIFICATIONS = "custom_notifications"
|
const val CUSTOM_NOTIFICATIONS = "custom_notifications"
|
||||||
|
const val IS_LAUNCHED_FROM_SHORTCUT = "is_launched_from_shortcut"
|
||||||
|
|
||||||
private const val PATH = "org.fossify.org.fossify.messages.action."
|
private const val PATH = "org.fossify.org.fossify.messages.action."
|
||||||
const val MARK_AS_READ = PATH + "mark_as_read"
|
const val MARK_AS_READ = PATH + "mark_as_read"
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,11 @@ import androidx.core.app.RemoteInput
|
||||||
import org.fossify.commons.extensions.getProperPrimaryColor
|
import org.fossify.commons.extensions.getProperPrimaryColor
|
||||||
import org.fossify.commons.extensions.notificationManager
|
import org.fossify.commons.extensions.notificationManager
|
||||||
import org.fossify.commons.helpers.SimpleContactsHelper
|
import org.fossify.commons.helpers.SimpleContactsHelper
|
||||||
|
import org.fossify.commons.helpers.ensureBackgroundThread
|
||||||
import org.fossify.messages.R
|
import org.fossify.messages.R
|
||||||
import org.fossify.messages.activities.ThreadActivity
|
import org.fossify.messages.activities.ThreadActivity
|
||||||
import org.fossify.messages.extensions.config
|
import org.fossify.messages.extensions.config
|
||||||
|
import org.fossify.messages.extensions.shortcutHelper
|
||||||
import org.fossify.messages.messaging.isShortCodeWithLetters
|
import org.fossify.messages.messaging.isShortCodeWithLetters
|
||||||
import org.fossify.messages.receivers.DeleteSmsReceiver
|
import org.fossify.messages.receivers.DeleteSmsReceiver
|
||||||
import org.fossify.messages.receivers.DirectReplyReceiver
|
import org.fossify.messages.receivers.DirectReplyReceiver
|
||||||
|
|
@ -166,7 +168,22 @@ class NotificationHelper(private val context: Context) {
|
||||||
deleteSmsPendingIntent
|
deleteSmsPendingIntent
|
||||||
).setChannelId(notificationChannelId)
|
).setChannelId(notificationChannelId)
|
||||||
}
|
}
|
||||||
notificationManager.notify(notificationId, builder.build())
|
|
||||||
|
var shortcut = context.shortcutHelper.getShortcut(threadId)
|
||||||
|
if (shortcut == null) {
|
||||||
|
ensureBackgroundThread {
|
||||||
|
shortcut = context.shortcutHelper.createOrUpdateShortcut(threadId)
|
||||||
|
builder.setShortcutInfo(shortcut)
|
||||||
|
notificationManager.notify(notificationId, builder.build())
|
||||||
|
context.shortcutHelper.reportReceiveMessageUsage(threadId)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.setShortcutInfo(shortcut)
|
||||||
|
notificationManager.notify(notificationId, builder.build())
|
||||||
|
ensureBackgroundThread {
|
||||||
|
context.shortcutHelper.reportReceiveMessageUsage(threadId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,170 @@
|
||||||
|
package org.fossify.messages.helpers
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.core.app.Person
|
||||||
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
|
import androidx.core.graphics.drawable.IconCompat
|
||||||
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
|
import androidx.core.text.isDigitsOnly
|
||||||
|
import org.fossify.commons.extensions.getMyContactsCursor
|
||||||
|
import org.fossify.commons.helpers.MyContactsContentProvider
|
||||||
|
import org.fossify.commons.helpers.SimpleContactsHelper
|
||||||
|
import org.fossify.commons.helpers.isOnMainThread
|
||||||
|
import org.fossify.commons.models.SimpleContact
|
||||||
|
import org.fossify.messages.activities.ThreadActivity
|
||||||
|
import org.fossify.messages.extensions.conversationsDB
|
||||||
|
import org.fossify.messages.extensions.getThreadParticipants
|
||||||
|
import org.fossify.messages.extensions.toPerson
|
||||||
|
import org.fossify.messages.models.Conversation
|
||||||
|
|
||||||
|
|
||||||
|
class ShortcutHelper(private val context: Context) {
|
||||||
|
val contactsHelper = SimpleContactsHelper(context)
|
||||||
|
|
||||||
|
fun getShortcuts(): List<ShortcutInfoCompat> {
|
||||||
|
return ShortcutManagerCompat.getDynamicShortcuts(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getShortcut(threadId: Long): ShortcutInfoCompat? {
|
||||||
|
return getShortcuts().find { it.id == threadId.toString() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildShortcut(
|
||||||
|
conv: Conversation,
|
||||||
|
capabilities: List<String> = emptyList(),
|
||||||
|
): ShortcutInfoCompat {
|
||||||
|
val contactsMap: HashMap<Int, SimpleContact>? = if (!isOnMainThread()) {
|
||||||
|
val privateCursor =
|
||||||
|
context.getMyContactsCursor(favoritesOnly = false, withPhoneNumbersOnly = true)
|
||||||
|
val contacts = MyContactsContentProvider.getSimpleContacts(context, privateCursor)
|
||||||
|
HashMap(contacts.associateBy { it.rawId })
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val participants = context.getThreadParticipants(conv.threadId, contactsMap)
|
||||||
|
val persons: Array<Person> = participants.map { it.toPerson(context) }.toTypedArray()
|
||||||
|
val intent = Intent(context, ThreadActivity::class.java).apply {
|
||||||
|
action = Intent.ACTION_VIEW
|
||||||
|
putExtra(THREAD_ID, conv.threadId)
|
||||||
|
putExtra(THREAD_TITLE, conv.title)
|
||||||
|
putExtra(IS_RECYCLE_BIN, false) // TODO: verify that thread isn't in recycle bin
|
||||||
|
putExtra(IS_LAUNCHED_FROM_SHORTCUT, true)
|
||||||
|
putExtra(THREAD_NUMBER, conv.phoneNumber.ifEmpty { "unknown_phone_number" })
|
||||||
|
addCategory(Intent.CATEGORY_DEFAULT)
|
||||||
|
addCategory(Intent.CATEGORY_BROWSABLE)
|
||||||
|
}
|
||||||
|
|
||||||
|
val shortcut = ShortcutInfoCompat.Builder(context, conv.threadId.toString()).apply {
|
||||||
|
setShortLabel(conv.title)
|
||||||
|
setLongLabel(conv.title)
|
||||||
|
setIsConversation()
|
||||||
|
setLongLived(true)
|
||||||
|
setPersons(persons)
|
||||||
|
setIntent(intent)
|
||||||
|
setRank(1)
|
||||||
|
if (!conv.isGroupConversation && !conv.usesCustomTitle) {
|
||||||
|
setIcon(persons[0].icon)
|
||||||
|
} else {
|
||||||
|
val icon = if (conv.isGroupConversation) {
|
||||||
|
IconCompat.createWithAdaptiveBitmap(
|
||||||
|
contactsHelper.getColoredGroupIcon(conv.title).toBitmap()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
IconCompat.createWithAdaptiveBitmap(
|
||||||
|
contactsHelper.getContactLetterIcon(conv.title)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
setIcon(icon)
|
||||||
|
}
|
||||||
|
capabilities.forEach { c ->
|
||||||
|
addCapabilityBinding(c)
|
||||||
|
}
|
||||||
|
if (!shouldPresentShortcut(conv)) {
|
||||||
|
setRank(99)
|
||||||
|
}
|
||||||
|
}.build()
|
||||||
|
|
||||||
|
return shortcut
|
||||||
|
}
|
||||||
|
|
||||||
|
fun buildShortcut(
|
||||||
|
threadId: Long,
|
||||||
|
capabilities: List<String> = emptyList(),
|
||||||
|
): ShortcutInfoCompat {
|
||||||
|
val conv = if (!isOnMainThread()) {
|
||||||
|
context.conversationsDB.getConversationWithThreadId(threadId)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conv == null) {
|
||||||
|
val conv = Conversation(
|
||||||
|
threadId = threadId,
|
||||||
|
snippet = "",
|
||||||
|
date = 0,
|
||||||
|
read = false,
|
||||||
|
title = threadId.toString(),
|
||||||
|
photoUri = "",
|
||||||
|
isGroupConversation = false,
|
||||||
|
phoneNumber = "",
|
||||||
|
isScheduled = false,
|
||||||
|
usesCustomTitle = false,
|
||||||
|
isArchived = false,
|
||||||
|
)
|
||||||
|
return buildShortcut(conv, capabilities)
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildShortcut(conv, capabilities)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createOrUpdateShortcut(conv: Conversation): ShortcutInfoCompat {
|
||||||
|
val shortcut = buildShortcut(conv)
|
||||||
|
createOrUpdateShortcut(shortcut)
|
||||||
|
return shortcut
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createOrUpdateShortcut(threadId: Long): ShortcutInfoCompat {
|
||||||
|
val shortcut = buildShortcut(threadId)
|
||||||
|
createOrUpdateShortcut(shortcut)
|
||||||
|
return shortcut
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createOrUpdateShortcut(shortcut: ShortcutInfoCompat) {
|
||||||
|
if (getShortcut(shortcut.id.toLong()) != null) {
|
||||||
|
ShortcutManagerCompat.updateShortcuts(context, listOf(shortcut))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ShortcutManagerCompat.pushDynamicShortcut(context, shortcut)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report the usage of a thread. create shortcut if it doesn't exist
|
||||||
|
*/
|
||||||
|
fun reportSendMessageUsage(threadId: Long) {
|
||||||
|
val shortcut = buildShortcut(threadId, listOf("actions.intent.SEND_MESSAGE"))
|
||||||
|
ShortcutManagerCompat.pushDynamicShortcut(context, shortcut)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reportReceiveMessageUsage(threadId: Long) {
|
||||||
|
val shortcut = buildShortcut(threadId, listOf("actions.intent.RECEIVE_MESSAGE"))
|
||||||
|
ShortcutManagerCompat.pushDynamicShortcut(context, shortcut)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeShortcutForThread(threadId: Long) {
|
||||||
|
val shortcut = getShortcut(threadId) ?: return
|
||||||
|
ShortcutManagerCompat.removeDynamicShortcuts(context, mutableListOf(shortcut.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun shouldPresentShortcut(conv: Conversation): Boolean {
|
||||||
|
if (conv.isGroupConversation) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (conv.isArchived || !conv.phoneNumber.isDigitsOnly()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,9 +7,12 @@ import android.widget.Toast.LENGTH_LONG
|
||||||
import com.klinker.android.send_message.Settings
|
import com.klinker.android.send_message.Settings
|
||||||
import org.fossify.commons.extensions.showErrorToast
|
import org.fossify.commons.extensions.showErrorToast
|
||||||
import org.fossify.commons.extensions.toast
|
import org.fossify.commons.extensions.toast
|
||||||
|
import org.fossify.commons.helpers.ensureBackgroundThread
|
||||||
import org.fossify.messages.R
|
import org.fossify.messages.R
|
||||||
import org.fossify.messages.extensions.config
|
import org.fossify.messages.extensions.config
|
||||||
|
import org.fossify.messages.extensions.getThreadId
|
||||||
import org.fossify.messages.extensions.messagingUtils
|
import org.fossify.messages.extensions.messagingUtils
|
||||||
|
import org.fossify.messages.extensions.shortcutHelper
|
||||||
import org.fossify.messages.messaging.SmsException.Companion.EMPTY_DESTINATION_ADDRESS
|
import org.fossify.messages.messaging.SmsException.Companion.EMPTY_DESTINATION_ADDRESS
|
||||||
import org.fossify.messages.messaging.SmsException.Companion.ERROR_PERSISTING_MESSAGE
|
import org.fossify.messages.messaging.SmsException.Companion.ERROR_PERSISTING_MESSAGE
|
||||||
import org.fossify.messages.messaging.SmsException.Companion.ERROR_SENDING_MESSAGE
|
import org.fossify.messages.messaging.SmsException.Companion.ERROR_SENDING_MESSAGE
|
||||||
|
|
@ -94,6 +97,10 @@ fun Context.sendMessageCompat(
|
||||||
showErrorToast(e)
|
showErrorToast(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ensureBackgroundThread {
|
||||||
|
val threadId = getThreadId(addresses.toSet())
|
||||||
|
shortcutHelper.reportSendMessageUsage(threadId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue