Tusky-App-Android/app/src/main/java/com/keylesspalace/tusky/receiver/SendStatusBroadcastReceiver.kt

145 lines
6.4 KiB
Kotlin

/* Copyright 2018 Jeremiasz Nelz <remi6397(a)gmail.com>
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with Tusky; if not,
* see <http://www.gnu.org/licenses>. */
package com.keylesspalace.tusky.receiver
import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.core.app.RemoteInput
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.notifications.NotificationHelper
import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.service.SendStatusService
import com.keylesspalace.tusky.service.StatusToSend
import com.keylesspalace.tusky.util.randomAlphanumericString
import dagger.android.AndroidInjection
import javax.inject.Inject
private const val TAG = "SendStatusBR"
class SendStatusBroadcastReceiver : BroadcastReceiver() {
@Inject
lateinit var accountManager: AccountManager
@SuppressLint("MissingPermission")
override fun onReceive(context: Context, intent: Intent) {
AndroidInjection.inject(this, context)
if (intent.action == NotificationHelper.REPLY_ACTION) {
val serverNotificationId = intent.getStringExtra(NotificationHelper.KEY_SERVER_NOTIFICATION_ID)
val senderId = intent.getLongExtra(NotificationHelper.KEY_SENDER_ACCOUNT_ID, -1)
val senderIdentifier = intent.getStringExtra(
NotificationHelper.KEY_SENDER_ACCOUNT_IDENTIFIER
)
val senderFullName = intent.getStringExtra(
NotificationHelper.KEY_SENDER_ACCOUNT_FULL_NAME
)
val citedStatusId = intent.getStringExtra(NotificationHelper.KEY_CITED_STATUS_ID)
val visibility = intent.getSerializableExtra(
NotificationHelper.KEY_VISIBILITY
) as Status.Visibility
val spoiler = intent.getStringExtra(NotificationHelper.KEY_SPOILER).orEmpty()
val mentions = intent.getStringArrayExtra(NotificationHelper.KEY_MENTIONS).orEmpty()
val account = accountManager.getAccountById(senderId)
val notificationManager = NotificationManagerCompat.from(context)
val message = getReplyMessage(intent)
if (account == null) {
Log.w(TAG, "Account \"$senderId\" not found in database. Aborting quick reply!")
val notification = NotificationCompat.Builder(
context,
NotificationHelper.CHANNEL_MENTION + senderIdentifier
)
.setSmallIcon(R.drawable.ic_notify)
.setColor(context.getColor(R.color.tusky_blue))
.setGroup(senderFullName)
.setDefaults(0) // We don't want this to make any sound or vibration
.setOnlyAlertOnce(true)
.setContentTitle(context.getString(R.string.error_generic))
.setContentText(context.getString(R.string.error_sender_account_gone))
.setSubText(senderFullName)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setCategory(NotificationCompat.CATEGORY_SOCIAL)
.build()
notificationManager.notify(serverNotificationId, senderId.toInt(), notification)
} else {
val text = mentions.joinToString(" ", postfix = " ") { "@$it" } + message.toString()
val sendIntent = SendStatusService.sendStatusIntent(
context,
StatusToSend(
text = text,
warningText = spoiler,
visibility = visibility.serverString,
sensitive = false,
media = emptyList(),
scheduledAt = null,
inReplyToId = citedStatusId,
poll = null,
replyingStatusContent = null,
replyingStatusAuthorUsername = null,
accountId = account.id,
draftId = -1,
idempotencyKey = randomAlphanumericString(16),
retries = 0,
language = null,
statusId = null
)
)
context.startService(sendIntent)
// Notifications with remote input active can't be cancelled, so let's replace it with another one that will dismiss automatically
val notification = NotificationCompat.Builder(
context,
NotificationHelper.CHANNEL_MENTION + senderIdentifier
)
.setSmallIcon(R.drawable.ic_notify)
.setColor(context.getColor(R.color.notification_color))
.setGroup(senderFullName)
.setDefaults(0) // We don't want this to make any sound or vibration
.setOnlyAlertOnce(true)
.setContentTitle(context.getString(R.string.reply_sending))
.setContentText(context.getString(R.string.reply_sending_long))
.setSubText(senderFullName)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setCategory(NotificationCompat.CATEGORY_SOCIAL)
.setTimeoutAfter(5000)
.build()
notificationManager.notify(serverNotificationId, senderId.toInt(), notification)
}
}
}
private fun getReplyMessage(intent: Intent): CharSequence {
val remoteInput = RemoteInput.getResultsFromIntent(intent)
return remoteInput?.getCharSequence(NotificationHelper.KEY_REPLY, "") ?: ""
}
}