Merge pull request #438 from Naveen3Singh/feature_schedule_send

Add schedule send feature
This commit is contained in:
Tibor Kaputa 2022-10-14 23:29:49 +02:00 committed by GitHub
commit d41c57093e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 1028 additions and 163 deletions

View file

@ -1,6 +0,0 @@
package com.simplemobiletools.smsmessenger.extensions
import android.text.TextUtils
import com.simplemobiletools.commons.models.SimpleContact
fun ArrayList<SimpleContact>.getThreadTitle() = TextUtils.join(", ", map { it.name }.toTypedArray())

View file

@ -30,3 +30,5 @@ fun Map<String, Any>.toContentValues(): ContentValues {
return contentValues
}
fun <T> Collection<T>.toArrayList() = ArrayList(this)

View file

@ -26,7 +26,6 @@ import android.telephony.SubscriptionManager
import android.text.TextUtils
import androidx.core.app.NotificationCompat
import androidx.core.app.RemoteInput
import com.klinker.android.send_message.Settings
import com.klinker.android.send_message.Transaction.getAddressSeparator
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
@ -58,7 +57,7 @@ val Context.messageAttachmentsDB: MessageAttachmentsDao get() = getMessagesDB().
val Context.messagesDB: MessagesDao get() = getMessagesDB().MessagesDao()
fun Context.getMessages(threadId: Long, getImageResolutions: Boolean, dateFrom: Int = -1): ArrayList<Message> {
fun Context.getMessages(threadId: Long, getImageResolutions: Boolean, dateFrom: Int = -1, includeScheduledMessages: Boolean = true): ArrayList<Message> {
val uri = Sms.CONTENT_URI
val projection = arrayOf(
Sms._ID,
@ -117,8 +116,21 @@ fun Context.getMessages(threadId: Long, getImageResolutions: Boolean, dateFrom:
}
messages.addAll(getMMS(threadId, getImageResolutions, sortOrder))
messages = messages.filter { it.participants.isNotEmpty() }
.sortedWith(compareBy<Message> { it.date }.thenBy { it.id }).toMutableList() as ArrayList<Message>
if (includeScheduledMessages) {
try {
val scheduledMessages = messagesDB.getScheduledThreadMessages(threadId)
messages.addAll(scheduledMessages)
} catch (e: Exception) {
e.printStackTrace()
}
}
messages = messages
.filter { it.participants.isNotEmpty() }
.filterNot { it.isScheduled && it.millis() < System.currentTimeMillis() }
.sortedWith(compareBy<Message> { it.date }.thenBy { it.id })
.toMutableList() as ArrayList<Message>
return messages
}
@ -570,7 +582,11 @@ fun Context.deleteConversation(threadId: Long) {
}
uri = Mms.CONTENT_URI
contentResolver.delete(uri, selection, selectionArgs)
try {
contentResolver.delete(uri, selection, selectionArgs)
} catch (e: Exception) {
e.printStackTrace()
}
conversationsDB.deleteThreadId(threadId)
messagesDB.deleteThreadMessages(threadId)
@ -588,6 +604,14 @@ fun Context.deleteMessage(id: Long, isMMS: Boolean) {
}
}
fun Context.deleteScheduledMessage(messageId: Long) {
try {
messagesDB.delete(messageId)
} catch (e: Exception) {
showErrorToast(e)
}
}
fun Context.markMessageRead(id: Long, isMMS: Boolean) {
val uri = if (isMMS) Mms.CONTENT_URI else Sms.CONTENT_URI
val contentValues = ContentValues().apply {
@ -972,16 +996,6 @@ fun Context.getFileSizeFromUri(uri: Uri): Long {
}
}
fun Context.getSendMessageSettings(): Settings {
val settings = Settings()
settings.useSystemSending = true
settings.deliveryReports = config.enableDeliveryReports
settings.sendLongAsMms = config.sendLongMessageMMS
settings.sendLongAsMmsAfter = 1
settings.group = config.sendGroupMessageMMS
return settings
}
// fix a glitch at enabling Release version minifying from 5.12.3
// reset messages in 5.14.3 again, as PhoneNumber is no longer minified
fun Context.clearAllMessagesIfNeeded() {
@ -1001,3 +1015,52 @@ fun Context.subscriptionManagerCompat(): SubscriptionManager {
SubscriptionManager.from(this)
}
}
fun Context.createTemporaryThread(message: Message, threadId: Long = generateRandomId()) {
val simpleContactHelper = SimpleContactsHelper(this)
val addresses = message.participants.getAddresses()
val photoUri = if (addresses.size == 1) simpleContactHelper.getPhotoUriFromPhoneNumber(addresses.first()) else ""
val conversation = Conversation(
threadId = threadId,
snippet = message.body,
date = message.date,
read = true,
title = message.participants.getThreadTitle(),
photoUri = photoUri,
isGroupConversation = addresses.size > 1,
phoneNumber = addresses.first(),
isScheduled = true
)
try {
conversationsDB.insertOrUpdate(conversation)
} catch (e: Exception) {
e.printStackTrace()
}
}
fun Context.updateScheduledMessagesThreadId(messages: List<Message>, newThreadId: Long) {
val scheduledMessages = messages.map { it.copy(threadId = newThreadId) }.toTypedArray()
messagesDB.insertMessages(*scheduledMessages)
}
fun Context.clearExpiredScheduledMessages(threadId: Long, messagesToDelete: List<Message>? = null) {
val messages = messagesToDelete ?: messagesDB.getScheduledThreadMessages(threadId)
val now = System.currentTimeMillis() + 500L
try {
messages.filter { it.isScheduled && it.millis() < now }.forEach { msg ->
messagesDB.delete(msg.id)
}
if (messages.filterNot { it.isScheduled && it.millis() < now }.isEmpty()) {
// delete empty temporary thread
val conversation = conversationsDB.getConversationWithThreadId(threadId)
if (conversation != null && conversation.isScheduled) {
conversationsDB.deleteThreadId(threadId)
}
}
} catch (e: Exception) {
e.printStackTrace()
return
}
}

View file

@ -0,0 +1,8 @@
package com.simplemobiletools.smsmessenger.extensions
import kotlin.math.roundToInt
/**
* Returns the closest number divisible by [multipleOf].
*/
fun Int.roundToClosestMultipleOf(multipleOf: Int = 1) = (toDouble() / multipleOf).roundToInt() * multipleOf

View file

@ -0,0 +1,8 @@
package com.simplemobiletools.smsmessenger.extensions
import android.text.TextUtils
import com.simplemobiletools.commons.models.SimpleContact
fun ArrayList<SimpleContact>.getThreadTitle(): String = TextUtils.join(", ", map { it.name }.toTypedArray()).orEmpty()
fun ArrayList<SimpleContact>.getAddresses() = flatMap { it.phoneNumbers }.map { it.normalizedNumber }

View file

@ -4,7 +4,6 @@ import com.google.gson.*
import java.math.BigDecimal
import java.math.BigInteger
val JsonElement.optString: String?
get() = safeConversion { asString }