/* Copyright 2018 Jeremiasz Nelz * * 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 . */ 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, "") ?: "" } }