Commit cf48262f authored by Leonardo Aramaki's avatar Leonardo Aramaki

Add support to push messages not containing a an ejson field and thus having...

Add support to push messages not containing a an ejson field and thus having no more than a message an a title. This way, a simple notification should be shown and not attached to any real channel list of messages
parent ca99f416
...@@ -26,6 +26,7 @@ import chat.rocket.android.server.domain.siteName ...@@ -26,6 +26,7 @@ import chat.rocket.android.server.domain.siteName
import chat.rocket.android.server.ui.changeServerIntent import chat.rocket.android.server.ui.changeServerIntent
import chat.rocket.common.model.RoomType import chat.rocket.common.model.RoomType
import chat.rocket.common.model.roomTypeOf import chat.rocket.common.model.roomTypeOf
import chat.rocket.common.util.ifNull
import com.squareup.moshi.Json import com.squareup.moshi.Json
import com.squareup.moshi.Moshi import com.squareup.moshi.Moshi
import kotlinx.coroutines.experimental.runBlocking import kotlinx.coroutines.experimental.runBlocking
...@@ -41,14 +42,15 @@ import javax.inject.Inject ...@@ -41,14 +42,15 @@ import javax.inject.Inject
* for old source code. * for old source code.
*/ */
class PushManager @Inject constructor( class PushManager @Inject constructor(
private val groupedPushes: GroupedPush, private val groupedPushes: GroupedPush,
private val manager: NotificationManager, private val manager: NotificationManager,
private val moshi: Moshi, private val moshi: Moshi,
private val getAccountInteractor: GetAccountInteractor, private val getAccountInteractor: GetAccountInteractor,
private val getSettingsInteractor: GetSettingsInteractor, private val getSettingsInteractor: GetSettingsInteractor,
private val context: Context private val context: Context
) { ) {
private val randomizer = Random()
private val random = Random()
/** /**
* Handles a receiving push by creating and displaying an appropriate notification based * Handles a receiving push by creating and displaying an appropriate notification based
...@@ -59,7 +61,7 @@ class PushManager @Inject constructor( ...@@ -59,7 +61,7 @@ class PushManager @Inject constructor(
val message = data["message"] as String? val message = data["message"] as String?
val ejson = data["ejson"] as String? val ejson = data["ejson"] as String?
val title = data["title"] as String? val title = data["title"] as String?
val notId = data["notId"] as String? ?: randomizer.nextInt().toString() val notId = data["notId"] as String? ?: random.nextInt().toString()
val image = data["image"] as String? val image = data["image"] as String?
val style = data["style"] as String? val style = data["style"] as String?
val summaryText = data["summaryText"] as String? val summaryText = data["summaryText"] as String?
...@@ -67,9 +69,13 @@ class PushManager @Inject constructor( ...@@ -67,9 +69,13 @@ class PushManager @Inject constructor(
try { try {
val adapter = moshi.adapter<PushInfo>(PushInfo::class.java) val adapter = moshi.adapter<PushInfo>(PushInfo::class.java)
val info = adapter.fromJson(ejson)
val pushMessage = PushMessage(title!!, message!!, info!!, image, count, notId, summaryText, style) val pushMessage = if (ejson != null) {
val info = adapter.fromJson(ejson)
PushMessage(title!!, message!!, info!!, image, count, notId, summaryText, style)
} else {
PushMessage(title!!, message!!, PushInfo.EMPTY, image, count, notId, summaryText, style)
}
Timber.d("Received push message: $pushMessage") Timber.d("Received push message: $pushMessage")
...@@ -82,13 +88,17 @@ class PushManager @Inject constructor( ...@@ -82,13 +88,17 @@ class PushManager @Inject constructor(
@SuppressLint("NewApi") @SuppressLint("NewApi")
suspend fun showNotification(pushMessage: PushMessage) { suspend fun showNotification(pushMessage: PushMessage) {
if (!hasAccount(pushMessage.info.host)) { val notId = pushMessage.notificationId.toInt()
Timber.d("ignoring push message: $pushMessage") val host = pushMessage.info.host
if (!hasAccount(host)) {
createSingleNotification(pushMessage)?.let {
NotificationManagerCompat.from(context).notify(notId, it)
}
Timber.d("ignoring push message: $pushMessage (maybe a test notification?)")
return return
} }
val notId = pushMessage.notificationId.toInt()
val host = pushMessage.info.host
val groupTuple = getGroupForHost(host) val groupTuple = getGroupForHost(host)
groupTuple.second.incrementAndGet() groupTuple.second.incrementAndGet()
...@@ -103,7 +113,7 @@ class PushManager @Inject constructor( ...@@ -103,7 +113,7 @@ class PushManager @Inject constructor(
val pushMessageList = groupedPushes.hostToPushMessageList[host] val pushMessageList = groupedPushes.hostToPushMessageList[host]
notification?.let { notification?.let {
manager.notify(notId, notification) manager.notify(notId, it)
} }
pushMessageList?.let { pushMessageList?.let {
...@@ -137,7 +147,7 @@ class PushManager @Inject constructor( ...@@ -137,7 +147,7 @@ class PushManager @Inject constructor(
val host = info.host val host = info.host
val builder = createBaseNotificationBuilder(pushMessage, grouped = true) val builder = createBaseNotificationBuilder(pushMessage, grouped = true)
.setGroupSummary(true) .setGroupSummary(true)
if (style == null || style == "inbox") { if (style == null || style == "inbox") {
val pushMessageList = groupedPushes.hostToPushMessageList[host] val pushMessageList = groupedPushes.hostToPushMessageList[host]
...@@ -150,7 +160,7 @@ class PushManager @Inject constructor( ...@@ -150,7 +160,7 @@ class PushManager @Inject constructor(
builder.setContentTitle(getTitle(count, title)) builder.setContentTitle(getTitle(count, title))
val inbox = NotificationCompat.InboxStyle() val inbox = NotificationCompat.InboxStyle()
.setBigContentTitle(getTitle(count, title)) .setBigContentTitle(getTitle(count, title))
for (push in pushMessageList) { for (push in pushMessageList) {
inbox.addLine(push.message) inbox.addLine(push.message)
...@@ -160,8 +170,8 @@ class PushManager @Inject constructor( ...@@ -160,8 +170,8 @@ class PushManager @Inject constructor(
} }
} else { } else {
val bigText = NotificationCompat.BigTextStyle() val bigText = NotificationCompat.BigTextStyle()
.bigText(message.fromHtml()) .bigText(message.fromHtml())
.setBigContentTitle(title.fromHtml()) .setBigContentTitle(title.fromHtml())
builder.setStyle(bigText) builder.setStyle(bigText)
} }
...@@ -177,12 +187,12 @@ class PushManager @Inject constructor( ...@@ -177,12 +187,12 @@ class PushManager @Inject constructor(
val host = info.host val host = info.host
val builder = createBaseNotificationBuilder(pushMessage) val builder = createBaseNotificationBuilder(pushMessage)
.setGroupSummary(false) .setGroupSummary(false)
if (style == null || "inbox" == style) { if (style == null || "inbox" == style) {
val pushMessageList = groupedPushes.hostToPushMessageList.get(host) val pushMessageList = groupedPushes.hostToPushMessageList.get(host)
pushMessageList?.let { if (pushMessageList != null) {
val userMessages = pushMessageList.filter { val userMessages = pushMessageList.filter {
it.notificationId == pushMessage.notificationId it.notificationId == pushMessage.notificationId
} }
...@@ -203,18 +213,23 @@ class PushManager @Inject constructor( ...@@ -203,18 +213,23 @@ class PushManager @Inject constructor(
builder.setStyle(inbox) builder.setStyle(inbox)
} else { } else {
val bigTextStyle = NotificationCompat.BigTextStyle() val bigTextStyle = NotificationCompat.BigTextStyle()
.bigText(message.fromHtml()) .bigText(message.fromHtml())
builder.setStyle(bigTextStyle) builder.setStyle(bigTextStyle)
} }
} else {
// We don't know which kind of push is this - maybe a test push, so just show it
val bigTextStyle = NotificationCompat.BigTextStyle()
.bigText(message.fromHtml())
builder.setStyle(bigTextStyle)
return builder.build()
} }
} else { } else {
val bigTextStyle = NotificationCompat.BigTextStyle() val bigTextStyle = NotificationCompat.BigTextStyle()
.bigText(message.fromHtml()) .bigText(message.fromHtml())
builder.setStyle(bigTextStyle) builder.setStyle(bigTextStyle)
} }
return builder.addReplyAction(pushMessage) return builder.addReplyAction(pushMessage).build()
.build()
} }
} }
...@@ -227,21 +242,32 @@ class PushManager @Inject constructor( ...@@ -227,21 +242,32 @@ class PushManager @Inject constructor(
val deleteIntent = getDismissIntent(context, pushMessage) val deleteIntent = getDismissIntent(context, pushMessage)
val builder = NotificationCompat.Builder(context, host) val builder = NotificationCompat.Builder(context, host)
.setWhen(info.createdAt) .setWhen(info.createdAt)
.setContentTitle(title.fromHtml()) .setContentTitle(title.fromHtml())
.setContentText(message.fromHtml()) .setContentText(message.fromHtml())
.setGroup(host) .setGroup(host)
.setDeleteIntent(deleteIntent) .setDeleteIntent(deleteIntent)
.setContentIntent(contentIntent) .setContentIntent(contentIntent)
.setMessageNotification() .setMessageNotification()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(host, host, NotificationManager.IMPORTANCE_HIGH) val channelId: String
val channelName: String
if (host.isEmpty()) {
builder.setContentIntent(deleteIntent)
channelName = "Test Notification"
channelId = "test-channel"
} else {
channelName = host
channelId = host
}
val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
channel.enableLights(false) channel.enableLights(false)
channel.enableVibration(true) channel.enableVibration(true)
channel.setShowBadge(true) channel.setShowBadge(true)
manager.createNotificationChannel(channel) manager.createNotificationChannel(channel)
builder.setChannelId(channelId)
} }
//TODO: Get Site_Name PublicSetting from cache //TODO: Get Site_Name PublicSetting from cache
...@@ -265,8 +291,8 @@ class PushManager @Inject constructor( ...@@ -265,8 +291,8 @@ class PushManager @Inject constructor(
private fun getDismissIntent(context: Context, pushMessage: PushMessage): PendingIntent { private fun getDismissIntent(context: Context, pushMessage: PushMessage): PendingIntent {
val deleteIntent = Intent(context, DeleteReceiver::class.java) val deleteIntent = Intent(context, DeleteReceiver::class.java)
.putExtra(EXTRA_NOT_ID, pushMessage.notificationId.toInt()) .putExtra(EXTRA_NOT_ID, pushMessage.notificationId.toInt())
.putExtra(EXTRA_HOSTNAME, pushMessage.info.host) .putExtra(EXTRA_HOSTNAME, pushMessage.info.host)
return PendingIntent.getBroadcast(context, pushMessage.notificationId.toInt(), deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT) return PendingIntent.getBroadcast(context, pushMessage.notificationId.toInt(), deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT)
} }
...@@ -276,7 +302,7 @@ class PushManager @Inject constructor( ...@@ -276,7 +302,7 @@ class PushManager @Inject constructor(
/*if (!grouped) { /*if (!grouped) {
notificationIntent.putExtra(EXTRA_ROOM_ID, pushMessage.info.roomId) notificationIntent.putExtra(EXTRA_ROOM_ID, pushMessage.info.roomId)
}*/ }*/
return PendingIntent.getActivity(context, randomizer.nextInt(), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT) return PendingIntent.getActivity(context, random.nextInt(), notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT)
} }
// CharSequence extensions // CharSequence extensions
...@@ -288,13 +314,13 @@ class PushManager @Inject constructor( ...@@ -288,13 +314,13 @@ class PushManager @Inject constructor(
private fun NotificationCompat.Builder.addReplyAction(pushMessage: PushMessage): NotificationCompat.Builder { private fun NotificationCompat.Builder.addReplyAction(pushMessage: PushMessage): NotificationCompat.Builder {
val replyTextHint = context.getText(R.string.notif_action_reply_hint) val replyTextHint = context.getText(R.string.notif_action_reply_hint)
val replyRemoteInput = RemoteInput.Builder(REMOTE_INPUT_REPLY) val replyRemoteInput = RemoteInput.Builder(REMOTE_INPUT_REPLY)
.setLabel(replyTextHint) .setLabel(replyTextHint)
.build() .build()
val pendingIntent = getReplyPendingIntent(pushMessage) val pendingIntent = getReplyPendingIntent(pushMessage)
val replyAction = NotificationCompat.Action.Builder(R.drawable.ic_action_message_reply_24dp, replyTextHint, pendingIntent) val replyAction = NotificationCompat.Action.Builder(R.drawable.ic_action_message_reply_24dp, replyTextHint, pendingIntent)
.addRemoteInput(replyRemoteInput) .addRemoteInput(replyRemoteInput)
.setAllowGeneratedReplies(true) .setAllowGeneratedReplies(true)
.build() .build()
this.addAction(replyAction) this.addAction(replyAction)
return this return this
...@@ -317,17 +343,17 @@ class PushManager @Inject constructor( ...@@ -317,17 +343,17 @@ class PushManager @Inject constructor(
val replyIntent = getReplyIntent(pushMessage) val replyIntent = getReplyIntent(pushMessage)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
PendingIntent.getBroadcast( PendingIntent.getBroadcast(
context, context,
randomizer.nextInt(), random.nextInt(),
replyIntent, replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT PendingIntent.FLAG_UPDATE_CURRENT
) )
} else { } else {
PendingIntent.getActivity( PendingIntent.getActivity(
context, context,
randomizer.nextInt(), random.nextInt(),
replyIntent, replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT PendingIntent.FLAG_UPDATE_CURRENT
) )
} }
} }
...@@ -336,7 +362,7 @@ class PushManager @Inject constructor( ...@@ -336,7 +362,7 @@ class PushManager @Inject constructor(
val alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION) val alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val res = context.resources val res = context.resources
val smallIcon = res.getIdentifier( val smallIcon = res.getIdentifier(
"rocket_chat_notification", "drawable", context.packageName) "rocket_chat_notification", "drawable", context.packageName)
with(this, { with(this, {
setAutoCancel(true) setAutoCancel(true)
setShowWhen(true) setShowWhen(true)
...@@ -350,24 +376,25 @@ class PushManager @Inject constructor( ...@@ -350,24 +376,25 @@ class PushManager @Inject constructor(
} }
data class PushMessage( data class PushMessage(
val title: String, val title: String,
val message: String, val message: String,
val info: PushInfo, val info: PushInfo,
val image: String? = null, val image: String? = null,
val count: String? = null, val count: String? = null,
val notificationId: String, val notificationId: String,
val summaryText: String? = null, val summaryText: String? = null,
val style: String? = null val style: String? = null
) : Parcelable { ) : Parcelable {
constructor(parcel: Parcel) : this( constructor(parcel: Parcel) : this(
parcel.readString(), parcel.readString(),
parcel.readString(), parcel.readString(),
parcel.readParcelable(PushMessage::class.java.classLoader), parcel.readParcelable(PushMessage::class.java.classLoader),
parcel.readString(), parcel.readString(),
parcel.readString(), parcel.readString(),
parcel.readString(), parcel.readString(),
parcel.readString(), parcel.readString(),
parcel.readString()) parcel.readString())
override fun writeToParcel(parcel: Parcel, flags: Int) { override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(title) parcel.writeString(title)
...@@ -397,11 +424,11 @@ data class PushMessage( ...@@ -397,11 +424,11 @@ data class PushMessage(
@JsonSerializable @JsonSerializable
data class PushInfo @KotshiConstructor constructor( data class PushInfo @KotshiConstructor constructor(
@Json(name = "host") val hostname: String, @Json(name = "host") val hostname: String,
@Json(name = "rid") val roomId: String, @Json(name = "rid") val roomId: String,
val type: RoomType, val type: RoomType,
val name: String?, val name: String?,
val sender: PushSender? val sender: PushSender?
) : Parcelable { ) : Parcelable {
val createdAt: Long val createdAt: Long
get() = System.currentTimeMillis() get() = System.currentTimeMillis()
...@@ -410,11 +437,11 @@ data class PushInfo @KotshiConstructor constructor( ...@@ -410,11 +437,11 @@ data class PushInfo @KotshiConstructor constructor(
} }
constructor(parcel: Parcel) : this( constructor(parcel: Parcel) : this(
parcel.readString(), parcel.readString(),
parcel.readString(), parcel.readString(),
roomTypeOf(parcel.readString()), roomTypeOf(parcel.readString()),
parcel.readString(), parcel.readString(),
parcel.readParcelable(PushInfo::class.java.classLoader)) parcel.readParcelable(PushInfo::class.java.classLoader))
private fun sanitizeUrl(baseUrl: String): String { private fun sanitizeUrl(baseUrl: String): String {
var url = baseUrl.trim() var url = baseUrl.trim()
...@@ -438,6 +465,9 @@ data class PushInfo @KotshiConstructor constructor( ...@@ -438,6 +465,9 @@ data class PushInfo @KotshiConstructor constructor(
} }
companion object CREATOR : Parcelable.Creator<PushInfo> { companion object CREATOR : Parcelable.Creator<PushInfo> {
val EMPTY = PushInfo(hostname = "", roomId = "", type = RoomType.CHANNEL, name = "",
sender = null)
override fun createFromParcel(parcel: Parcel): PushInfo { override fun createFromParcel(parcel: Parcel): PushInfo {
return PushInfo(parcel) return PushInfo(parcel)
} }
...@@ -450,14 +480,14 @@ data class PushInfo @KotshiConstructor constructor( ...@@ -450,14 +480,14 @@ data class PushInfo @KotshiConstructor constructor(
@JsonSerializable @JsonSerializable
data class PushSender @KotshiConstructor constructor( data class PushSender @KotshiConstructor constructor(
@Json(name = "_id") val id: String, @Json(name = "_id") val id: String,
val username: String?, val username: String?,
val name: String? val name: String?
) : Parcelable { ) : Parcelable {
constructor(parcel: Parcel) : this( constructor(parcel: Parcel) : this(
parcel.readString(), parcel.readString(),
parcel.readString(), parcel.readString(),
parcel.readString()) parcel.readString())
override fun writeToParcel(parcel: Parcel, flags: Int) { override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(id) parcel.writeString(id)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment