Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
AloqaIM-Android
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
AloqaIM-Android
Commits
37d516e2
Commit
37d516e2
authored
Oct 20, 2017
by
Leonardo Aramaki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add experimental Direct Reply feature
parent
fd798148
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
262 additions
and
64 deletions
+262
-64
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+4
-2
AbstractAuthedActivity.java
.../chat/rocket/android/activity/AbstractAuthedActivity.java
+1
-1
PushManager.kt
app/src/main/java/chat/rocket/android/push/PushManager.kt
+257
-61
No files found.
app/src/main/AndroidManifest.xml
View file @
37d516e2
...
@@ -77,8 +77,10 @@
...
@@ -77,8 +77,10 @@
</service>
</service>
<receiver
android:name=
".push.PushManager$DeleteReceiver"
<receiver
android:name=
".push.PushManager$DeleteReceiver"
android:exported=
"false"
>
android:exported=
"false"
/>
</receiver>
<receiver
android:name=
".push.PushManager$ReplyReceiver"
android:exported=
"false"
/>
<meta-data
<meta-data
android:name=
"io.fabric.ApiKey"
android:name=
"io.fabric.ApiKey"
...
...
app/src/main/java/chat/rocket/android/activity/AbstractAuthedActivity.java
View file @
37d516e2
...
@@ -76,7 +76,7 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
...
@@ -76,7 +76,7 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
if
(
intent
.
hasExtra
(
PushConstants
.
NOT_ID
))
{
if
(
intent
.
hasExtra
(
PushConstants
.
NOT_ID
))
{
isNotification
=
true
;
isNotification
=
true
;
int
notificationId
=
intent
.
getIntExtra
(
PushConstants
.
NOT_ID
,
0
);
int
notificationId
=
intent
.
getIntExtra
(
PushConstants
.
NOT_ID
,
0
);
PushManager
.
INSTANCE
.
clearMessage
Stack
(
notificationId
);
PushManager
.
INSTANCE
.
clearMessage
Bundle
(
notificationId
);
}
}
}
}
...
...
app/src/main/java/chat/rocket/android/push/PushManager.kt
View file @
37d516e2
...
@@ -7,74 +7,109 @@ import android.app.PendingIntent
...
@@ -7,74 +7,109 @@ import android.app.PendingIntent
import
android.content.BroadcastReceiver
import
android.content.BroadcastReceiver
import
android.content.Context
import
android.content.Context
import
android.content.Intent
import
android.content.Intent
import
android.graphics.drawable.Icon
import
android.os.Build
import
android.os.Build
import
android.os.Bundle
import
android.os.Bundle
import
android.support.annotation.RequiresApi
import
android.support.annotation.RequiresApi
import
android.support.v4.app.NotificationCompat
import
android.support.v4.app.NotificationCompat
import
android.support.v4.app.NotificationManagerCompat
import
android.support.v4.app.NotificationManagerCompat
import
android.support.v4.app.RemoteInput
import
android.text.Html
import
android.text.Html
import
android.text.Spanned
import
android.text.Spanned
import
android.util.Log
import
android.util.Log
import
android.util.SparseArray
import
android.util.SparseArray
import
chat.rocket.android.BackgroundLooper
import
chat.rocket.android.BuildConfig
import
chat.rocket.android.BuildConfig
import
chat.rocket.android.R
import
chat.rocket.android.RocketChatCache
import
chat.rocket.android.RocketChatCache
import
chat.rocket.android.activity.MainActivity
import
chat.rocket.android.activity.MainActivity
import
chat.rocket.android.helper.Logger
import
chat.rocket.android.push.PushManager.fromHtml
import
chat.rocket.core.interactors.MessageInteractor
import
chat.rocket.core.models.Room
import
chat.rocket.core.models.User
import
chat.rocket.persistence.realm.repositories.RealmMessageRepository
import
chat.rocket.persistence.realm.repositories.RealmRoomRepository
import
chat.rocket.persistence.realm.repositories.RealmUserRepository
import
io.reactivex.Single
import
io.reactivex.android.schedulers.AndroidSchedulers
import
io.reactivex.functions.BiFunction
import
org.json.JSONObject
import
org.json.JSONObject
import
java.io.Serializable
import
java.util.*
import
java.util.*
import
java.util.concurrent.atomic.AtomicInteger
import
kotlin.collections.HashMap
import
kotlin.collections.HashMap
object
PushManager
{
typealias
HostTotalMsgTuple
<
A
,
B
>
=
Pair
<
A
,
B
>
object
PushManager
{
const
val
REPLY_LABEL
=
"REPLY"
const
val
REMOTE_INPUT_REPLY
=
"REMOTE_INPUT_REPLY"
// Map associating a notification id to a list of corresponding messages ie. an id corresponds
// Map associating a notification id to a list of corresponding messages ie. an id corresponds
// to a user and the corresponding list is all the messages sent by him.
// to a user and the corresponding list is all the messages sent by him.
val
messageStack
=
SparseArray
<
ArrayList
<
String
>>()
private
val
messageStack
=
SparseArray
<
ArrayList
<
CharSequence
>>()
// Notifications received from the same server are grouped in a single bundled notification.
// Notifications received from the same server are grouped in a single bundled notification.
// This map associates a host to a group id.
// This map associates a host to a group id.
val
groupMap
=
HashMap
<
String
,
Int
>()
private
val
groupMap
=
HashMap
<
String
,
HostTotalMsgTuple
<
Int
,
AtomicInteger
>>()
val
randomizer
=
Random
()
private
val
randomizer
=
Random
()
/**
* Handles a receiving push by creating and displaying an appropriate notification based
* on the *data* param bundle received.
*/
@Synchronized
fun
handle
(
context
:
Context
,
data
:
Bundle
)
{
fun
handle
(
context
:
Context
,
data
:
Bundle
)
{
val
appContext
=
context
.
applicationContext
val
appContext
=
context
.
applicationContext
val
message
=
data
[
"message"
]
as
String
val
message
=
data
[
"message"
]
as
String
val
image
=
data
[
"image"
]
as
String
val
image
=
data
[
"image"
]
as
String
val
ejson
=
data
[
"ejson"
]
as
String
val
ejson
=
data
[
"ejson"
]
as
String
val
not
ification
Id
=
data
[
"notId"
]
as
String
val
notId
=
data
[
"notId"
]
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
val
count
=
data
[
"count"
]
as
String
val
count
=
data
[
"count"
]
as
String
val
title
=
data
[
"title"
]
as
String
val
title
=
data
[
"title"
]
as
String
val
pushMessage
=
PushMessage
(
title
,
message
,
image
,
ejson
,
count
,
not
ification
Id
,
summaryText
,
style
)
val
pushMessage
=
PushMessage
(
title
,
message
,
image
,
ejson
,
count
,
notId
,
summaryText
,
style
)
// We should use Timber here
// We should use Timber here
if
(
BuildConfig
.
DEBUG
)
{
if
(
BuildConfig
.
DEBUG
)
{
Log
.
d
(
PushMessage
::
class
.
java
.
simpleName
,
pushMessage
.
toString
())
Log
.
d
(
PushMessage
::
class
.
java
.
simpleName
,
pushMessage
.
toString
())
}
}
val
res
=
appContext
.
resources
bundleMessage
(
notId
.
toInt
(),
pushMessage
.
message
)
val
smallIcon
=
res
.
getIdentifier
(
"rocket_chat_notification"
,
"drawable"
,
appContext
.
packageName
)
showNotification
(
appContext
,
pushMessage
)
}
stackMessage
(
notificationId
.
toInt
(),
pushMessage
.
message
)
/**
* Clear all messages corresponding to a specific notification id (aka specific user)
*/
fun
clearMessageBundle
(
notificationId
:
Int
)
{
messageStack
.
delete
(
notificationId
)
}
private
fun
showNotification
(
context
:
Context
,
pushMessage
:
PushMessage
)
{
val
notificationManager
:
NotificationManager
=
val
notificationManager
:
NotificationManager
=
context
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
context
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
val
groupNotification
=
createGroupNotification
(
context
,
pushMessage
,
data
,
smallIcon
)
val
notId
=
pushMessage
.
notificationId
.
toInt
()
val
groupNotification
=
createGroupNotification
(
context
,
pushMessage
)
val
group
Id
=
groupMap
.
get
(
pushMessage
.
host
)
val
group
Tuple
=
groupMap
[
pushMessage
.
host
]
val
notification
:
Notification
val
notification
:
Notification
if
(
isAndroidVersionAtLeast
(
Build
.
VERSION_CODES
.
O
))
{
if
(
isAndroidVersionAtLeast
(
Build
.
VERSION_CODES
.
O
))
{
notification
=
createNotificationForOreoAndAbove
(
appContext
,
pushMessage
,
smallIcon
,
data
)
notification
=
createNotificationForOreoAndAbove
(
context
,
pushMessage
)
if
(
groupId
!=
null
)
{
if
(
groupTuple
!=
null
)
{
notificationManager
.
notify
(
groupId
,
notification
)
notificationManager
.
notify
(
groupTuple
.
first
,
groupNotification
)
groupTuple
.
second
.
incrementAndGet
()
}
}
notificationManager
.
notify
(
not
ificationId
.
toInt
()
,
notification
)
notificationManager
.
notify
(
not
Id
,
notification
)
}
else
{
}
else
{
notification
=
createCompatNotification
(
appContext
,
pushMessage
,
smallIcon
,
data
)
notification
=
createCompatNotification
(
context
,
pushMessage
)
if
(
groupId
!=
null
)
{
if
(
groupTuple
!=
null
)
{
NotificationManagerCompat
.
from
(
appContext
).
notify
(
groupId
,
groupNotification
)
NotificationManagerCompat
.
from
(
context
).
notify
(
groupTuple
.
first
,
groupNotification
)
groupTuple
.
second
.
incrementAndGet
()
}
}
NotificationManagerCompat
.
from
(
appContext
).
notify
(
notificationId
.
toInt
()
,
notification
)
NotificationManagerCompat
.
from
(
context
).
notify
(
notId
,
notification
)
}
}
}
}
...
@@ -83,60 +118,69 @@ object PushManager {
...
@@ -83,60 +118,69 @@ object PushManager {
private
fun
addGroupToBundle
(
host
:
String
)
{
private
fun
addGroupToBundle
(
host
:
String
)
{
val
size
=
groupMap
.
size
val
size
=
groupMap
.
size
if
(
groupMap
.
get
(
host
)
==
null
)
{
if
(
groupMap
.
get
(
host
)
==
null
)
{
groupMap
.
put
(
host
,
size
+
1
)
groupMap
.
put
(
host
,
HostTotalMsgTuple
(
size
+
1
,
AtomicInteger
(
0
))
)
}
}
}
}
fun
clearMessageStack
(
notificationId
:
Int
)
{
private
fun
createGroupNotification
(
context
:
Context
,
pushMessage
:
PushMessage
):
Notification
{
messageStack
.
delete
(
notificationId
)
}
private
fun
createGroupNotification
(
context
:
Context
,
pushMessage
:
PushMessage
,
data
:
Bundle
,
smallIcon
:
Int
):
Notification
{
// Create notification group.
// Create notification group.
addGroupToBundle
(
pushMessage
.
host
)
addGroupToBundle
(
pushMessage
.
host
)
val
id
=
pushMessage
.
notificationId
.
toInt
()
val
id
=
pushMessage
.
notificationId
.
toInt
()
val
contentIntent
=
getContentIntent
(
context
,
id
,
data
,
pushMessag
e
)
val
contentIntent
=
getContentIntent
(
context
,
id
,
pushMessage
,
group
=
tru
e
)
val
deleteIntent
=
getDismissIntent
(
context
,
id
)
val
deleteIntent
=
getDismissIntent
(
context
,
id
)
val
notGroupBuilder
=
NotificationCompat
.
Builder
(
context
)
val
notGroupBuilder
=
NotificationCompat
.
Builder
(
context
)
.
setAutoCancel
(
true
)
.
setShowWhen
(
true
)
.
setDefaults
(
Notification
.
DEFAULT_ALL
)
.
setWhen
(
pushMessage
.
createdAt
)
.
setWhen
(
pushMessage
.
createdAt
)
.
setContentTitle
(
pushMessage
.
title
.
fromHtml
())
.
setContentTitle
(
pushMessage
.
title
.
fromHtml
())
.
setContentText
(
pushMessage
.
message
.
fromHtml
())
.
setContentText
(
pushMessage
.
message
.
fromHtml
())
.
setGroup
(
pushMessage
.
host
)
.
setGroup
(
pushMessage
.
host
)
.
setGroupSummary
(
true
)
.
setGroupSummary
(
true
)
.
setSmallIcon
(
smallIcon
)
.
setStyle
(
NotificationCompat
.
BigTextStyle
().
bigText
(
pushMessage
.
message
.
fromHtml
()))
.
setStyle
(
NotificationCompat
.
BigTextStyle
().
bigText
(
pushMessage
.
message
.
fromHtml
()))
.
setContentIntent
(
contentIntent
)
.
setContentIntent
(
contentIntent
)
.
setDeleteIntent
(
deleteIntent
)
.
setDeleteIntent
(
deleteIntent
)
.
setMessageNotification
()
val
subText
=
RocketChatCache
(
context
).
getHostSiteName
(
pushMessage
.
host
)
val
subText
=
RocketChatCache
(
context
).
getHostSiteName
(
pushMessage
.
host
)
if
(
subText
.
isNotEmpty
())
{
if
(
subText
.
isNotEmpty
())
{
notGroupBuilder
.
setSubText
(
subText
)
notGroupBuilder
.
setSubText
(
subText
)
}
}
val
messages
=
messageStack
.
get
(
pushMessage
.
notificationId
.
toInt
())
val
messageCount
=
messages
.
size
if
(
messageCount
>
1
)
{
val
summary
=
pushMessage
.
summaryText
.
replace
(
"%n%"
,
messageCount
.
toString
())
val
inbox
=
NotificationCompat
.
InboxStyle
()
.
setBigContentTitle
(
pushMessage
.
title
.
fromHtml
())
.
setSummaryText
(
summary
)
notGroupBuilder
.
setStyle
(
inbox
)
}
else
{
val
bigText
=
NotificationCompat
.
BigTextStyle
()
.
bigText
(
pushMessage
.
message
.
fromHtml
())
.
setBigContentTitle
(
pushMessage
.
title
.
fromHtml
())
notGroupBuilder
.
setStyle
(
bigText
)
}
return
notGroupBuilder
.
build
()
return
notGroupBuilder
.
build
()
}
}
private
fun
createCompatNotification
(
context
:
Context
,
pushMessage
:
PushMessage
,
smallIcon
:
Int
,
data
:
Bundle
):
Notification
{
private
fun
createCompatNotification
(
context
:
Context
,
pushMessage
:
PushMessage
):
Notification
{
with
(
pushMessage
)
{
with
(
pushMessage
)
{
val
id
=
notificationId
.
toInt
()
val
id
=
notificationId
.
toInt
()
val
contentIntent
=
getContentIntent
(
context
,
id
,
data
,
pushMessage
)
val
contentIntent
=
getContentIntent
(
context
,
id
,
pushMessage
)
val
deleteIntent
=
getDismissIntent
(
context
,
id
)
val
deleteIntent
=
getDismissIntent
(
context
,
id
)
val
notificationBuilder
=
NotificationCompat
.
Builder
(
context
)
val
notificationBuilder
=
NotificationCompat
.
Builder
(
context
)
.
setAutoCancel
(
true
)
.
setShowWhen
(
true
)
.
setDefaults
(
Notification
.
DEFAULT_ALL
)
.
setWhen
(
createdAt
)
.
setWhen
(
createdAt
)
.
setContentTitle
(
title
.
fromHtml
())
.
setContentTitle
(
title
.
fromHtml
())
.
setContentText
(
message
.
fromHtml
())
.
setContentText
(
message
.
fromHtml
())
.
setNumber
(
count
.
toInt
())
.
setNumber
(
count
.
toInt
())
.
setGroup
(
host
)
.
setGroup
(
host
)
.
setSmallIcon
(
smallIcon
)
.
setDeleteIntent
(
deleteIntent
)
.
setDeleteIntent
(
deleteIntent
)
.
setContentIntent
(
contentIntent
)
.
setContentIntent
(
contentIntent
)
.
setMessageNotification
()
.
addReplyAction
(
pushMessage
)
val
subText
=
RocketChatCache
(
context
).
getHostSiteName
(
pushMessage
.
host
)
val
subText
=
RocketChatCache
(
context
).
getHostSiteName
(
pushMessage
.
host
)
if
(
subText
.
isNotEmpty
())
{
if
(
subText
.
isNotEmpty
())
{
...
@@ -174,27 +218,26 @@ object PushManager {
...
@@ -174,27 +218,26 @@ object PushManager {
}
}
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
private
fun
createNotificationForOreoAndAbove
(
context
:
Context
,
pushMessage
:
PushMessage
,
smallIcon
:
Int
,
data
:
Bundle
):
Notification
{
private
fun
createNotificationForOreoAndAbove
(
context
:
Context
,
pushMessage
:
PushMessage
):
Notification
{
val
notificationManager
:
NotificationManager
=
val
notificationManager
:
NotificationManager
=
context
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
context
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
with
(
pushMessage
)
{
with
(
pushMessage
)
{
val
id
=
notificationId
.
toInt
()
val
id
=
notificationId
.
toInt
()
val
contentIntent
=
getContentIntent
(
context
,
id
,
data
,
pushMessage
)
val
contentIntent
=
getContentIntent
(
context
,
id
,
pushMessage
)
val
deleteIntent
=
getDismissIntent
(
context
,
id
)
val
deleteIntent
=
getDismissIntent
(
context
,
id
)
val
channel
=
NotificationChannel
(
notificationId
,
sender
.
username
,
NotificationManager
.
IMPORTANCE_HIGH
)
val
channel
=
NotificationChannel
(
notificationId
,
sender
.
username
,
NotificationManager
.
IMPORTANCE_HIGH
)
val
notificationBuilder
=
Notification
.
Builder
(
context
,
pushMessage
.
rid
)
val
notificationBuilder
=
Notification
.
Builder
(
context
,
pushMessage
.
rid
)
.
setAutoCancel
(
true
)
.
setShowWhen
(
true
)
.
setWhen
(
createdAt
)
.
setWhen
(
createdAt
)
.
setContentTitle
(
title
.
fromHtml
())
.
setContentTitle
(
title
.
fromHtml
())
.
setContentText
(
message
.
fromHtml
())
.
setContentText
(
message
.
fromHtml
())
.
setNumber
(
count
.
toInt
())
.
setNumber
(
count
.
toInt
())
.
setGroup
(
host
)
.
setGroup
(
host
)
.
setSmallIcon
(
smallIcon
)
.
setDeleteIntent
(
deleteIntent
)
.
setDeleteIntent
(
deleteIntent
)
.
setContentIntent
(
contentIntent
)
.
setContentIntent
(
contentIntent
)
.
setMessageNotification
(
context
)
.
addReplyAction
(
context
,
pushMessage
)
val
subText
=
RocketChatCache
(
context
).
getHostSiteName
(
pushMessage
.
host
)
val
subText
=
RocketChatCache
(
context
).
getHostSiteName
(
pushMessage
.
host
)
if
(
subText
.
isNotEmpty
())
{
if
(
subText
.
isNotEmpty
())
{
...
@@ -208,11 +251,11 @@ object PushManager {
...
@@ -208,11 +251,11 @@ object PushManager {
}
}
}
}
private
fun
stackMessage
(
id
:
Int
,
message
:
String
)
{
private
fun
bundleMessage
(
id
:
Int
,
message
:
CharSequence
)
{
val
existingStack
:
ArrayList
<
String
>?
=
messageStack
[
id
]
val
existingStack
:
ArrayList
<
CharSequence
>?
=
messageStack
[
id
]
if
(
existingStack
==
null
)
{
if
(
existingStack
==
null
)
{
val
newStack
=
arrayListOf
<
String
>()
val
newStack
=
arrayListOf
<
CharSequence
>()
newStack
.
add
(
message
)
newStack
.
add
(
message
)
messageStack
.
put
(
id
,
newStack
)
messageStack
.
put
(
id
,
newStack
)
}
else
{
}
else
{
...
@@ -226,17 +269,98 @@ object PushManager {
...
@@ -226,17 +269,98 @@ object PushManager {
return
PendingIntent
.
getBroadcast
(
context
,
notificationId
,
deleteIntent
,
0
)
return
PendingIntent
.
getBroadcast
(
context
,
notificationId
,
deleteIntent
,
0
)
}
}
private
fun
getContentIntent
(
context
:
Context
,
notificationId
:
Int
,
extras
:
Bundle
,
pushMessage
:
PushMessag
e
):
PendingIntent
{
private
fun
getContentIntent
(
context
:
Context
,
notificationId
:
Int
,
pushMessage
:
PushMessage
,
group
:
Boolean
=
fals
e
):
PendingIntent
{
val
notificationIntent
=
Intent
(
context
,
MainActivity
::
class
.
java
)
val
notificationIntent
=
Intent
(
context
,
MainActivity
::
class
.
java
)
notificationIntent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_SINGLE_TOP
or
Intent
.
FLAG_ACTIVITY_CLEAR_TOP
)
notificationIntent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_SINGLE_TOP
or
Intent
.
FLAG_ACTIVITY_CLEAR_TOP
)
notificationIntent
.
putExtra
(
PushConstants
.
PUSH_BUNDLE
,
extras
)
notificationIntent
.
putExtra
(
PushConstants
.
NOT_ID
,
notificationId
)
notificationIntent
.
putExtra
(
PushConstants
.
NOT_ID
,
notificationId
)
notificationIntent
.
putExtra
(
PushConstants
.
HOSTNAME
,
pushMessage
.
host
)
notificationIntent
.
putExtra
(
PushConstants
.
HOSTNAME
,
pushMessage
.
host
)
if
(!
group
)
{
notificationIntent
.
putExtra
(
PushConstants
.
ROOM_ID
,
pushMessage
.
rid
)
notificationIntent
.
putExtra
(
PushConstants
.
ROOM_ID
,
pushMessage
.
rid
)
}
return
PendingIntent
.
getActivity
(
context
,
randomizer
.
nextInt
(),
notificationIntent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
)
return
PendingIntent
.
getActivity
(
context
,
randomizer
.
nextInt
(),
notificationIntent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
)
}
}
// CharSequence extensions
fun
CharSequence
.
fromHtml
():
Spanned
{
return
Html
.
fromHtml
(
this
as
String
)
}
//Notification.Builder extensions
@RequiresApi
(
Build
.
VERSION_CODES
.
N
)
private
fun
Notification
.
Builder
.
addReplyAction
(
ctx
:
Context
,
pushMessage
:
PushMessage
):
Notification
.
Builder
{
val
replyRemoteInput
=
android
.
app
.
RemoteInput
.
Builder
(
REMOTE_INPUT_REPLY
)
.
setLabel
(
REPLY_LABEL
)
.
build
()
val
replyIntent
=
Intent
(
ctx
,
ReplyReceiver
::
class
.
java
)
replyIntent
.
putExtra
(
"push"
,
pushMessage
as
Serializable
)
val
pendingIntent
=
PendingIntent
.
getBroadcast
(
ctx
,
randomizer
.
nextInt
(),
replyIntent
,
0
)
val
replyAction
=
Notification
.
Action
.
Builder
(
Icon
.
createWithResource
(
ctx
,
R
.
drawable
.
ic_reply
),
REPLY_LABEL
,
pendingIntent
)
.
addRemoteInput
(
replyRemoteInput
)
.
setAllowGeneratedReplies
(
true
)
.
build
()
this
.
addAction
(
replyAction
)
return
this
}
@RequiresApi
(
Build
.
VERSION_CODES
.
O
)
fun
Notification
.
Builder
.
setMessageNotification
(
ctx
:
Context
):
Notification
.
Builder
{
val
res
=
ctx
.
resources
val
smallIcon
=
res
.
getIdentifier
(
"rocket_chat_notification"
,
"drawable"
,
ctx
.
packageName
)
with
(
this
,
{
setAutoCancel
(
true
)
setShowWhen
(
true
)
setDefaults
(
Notification
.
DEFAULT_ALL
)
setSmallIcon
(
smallIcon
)
})
return
this
}
// NotificationCompat.Builder extensions
private
fun
NotificationCompat
.
Builder
.
addReplyAction
(
pushMessage
:
PushMessage
):
NotificationCompat
.
Builder
{
val
context
=
this
.
mContext
val
replyRemoteInput
=
RemoteInput
.
Builder
(
REMOTE_INPUT_REPLY
)
.
setLabel
(
REPLY_LABEL
)
.
build
()
val
replyIntent
=
Intent
(
context
,
ReplyReceiver
::
class
.
java
)
replyIntent
.
putExtra
(
"push"
,
pushMessage
as
Serializable
)
val
pendingIntent
=
PendingIntent
.
getBroadcast
(
context
,
randomizer
.
nextInt
(),
replyIntent
,
0
)
val
replyAction
=
NotificationCompat
.
Action
.
Builder
(
R
.
drawable
.
ic_reply
,
REPLY_LABEL
,
pendingIntent
)
.
addRemoteInput
(
replyRemoteInput
)
.
setAllowGeneratedReplies
(
true
)
.
build
()
this
.
addAction
(
replyAction
)
return
this
}
fun
NotificationCompat
.
Builder
.
setMessageNotification
():
NotificationCompat
.
Builder
{
val
ctx
=
this
.
mContext
val
res
=
ctx
.
resources
val
smallIcon
=
res
.
getIdentifier
(
"rocket_chat_notification"
,
"drawable"
,
ctx
.
packageName
)
with
(
this
,
{
setAutoCancel
(
true
)
setShowWhen
(
true
)
setDefaults
(
Notification
.
DEFAULT_ALL
)
setSmallIcon
(
smallIcon
)
})
return
this
}
private
data class
MessageGroup
(
val
id
:
Int
,
val
host
:
String
)
{
val
messageStack
:
SparseArray
<
ArrayList
<
String
>>
init
{
messageStack
=
SparseArray
()
}
}
private
data class
PushMessage
(
val
title
:
String
,
private
data class
PushMessage
(
val
title
:
String
,
val
message
:
String
,
val
message
:
String
,
val
image
:
String
?,
val
image
:
String
?,
...
@@ -244,7 +368,7 @@ object PushManager {
...
@@ -244,7 +368,7 @@ object PushManager {
val
count
:
String
,
val
count
:
String
,
val
notificationId
:
String
,
val
notificationId
:
String
,
val
summaryText
:
String
,
val
summaryText
:
String
,
val
style
:
String
)
{
val
style
:
String
)
:
Serializable
{
val
host
:
String
val
host
:
String
val
rid
:
String
val
rid
:
String
val
type
:
String
val
type
:
String
...
@@ -262,7 +386,7 @@ object PushManager {
...
@@ -262,7 +386,7 @@ object PushManager {
createdAt
=
System
.
currentTimeMillis
()
createdAt
=
System
.
currentTimeMillis
()
}
}
data class
Sender
(
val
sender
:
String
)
{
data class
Sender
(
val
sender
:
String
)
:
Serializable
{
val
_id
:
String
val
_id
:
String
val
username
:
String
val
username
:
String
val
name
:
String
val
name
:
String
...
@@ -280,13 +404,85 @@ object PushManager {
...
@@ -280,13 +404,85 @@ object PushManager {
override
fun
onReceive
(
context
:
Context
?,
intent
:
Intent
?)
{
override
fun
onReceive
(
context
:
Context
?,
intent
:
Intent
?)
{
val
notificationId
=
intent
?.
extras
?.
getInt
(
"notId"
)
val
notificationId
=
intent
?.
extras
?.
getInt
(
"notId"
)
if
(
notificationId
!=
null
)
{
if
(
notificationId
!=
null
)
{
PushManager
.
clearMessage
Stack
(
notificationId
)
PushManager
.
clearMessage
Bundle
(
notificationId
)
}
}
}
}
}
}
// String extensions
// EXPERIMENTAL
fun
String
.
fromHtml
():
Spanned
{
class
ReplyReceiver
:
BroadcastReceiver
()
{
return
Html
.
fromHtml
(
this
)
override
fun
onReceive
(
context
:
Context
?,
intent
:
Intent
?)
{
if
(
context
==
null
)
{
return
;
}
val
manager
=
context
.
getSystemService
(
Context
.
NOTIFICATION_SERVICE
)
as
NotificationManager
val
message
:
CharSequence
?
=
extractMessage
(
intent
)
val
pushMessage
=
intent
?.
extras
?.
getSerializable
(
"push"
)
as
PushMessage
?
if
(
pushMessage
!=
null
)
{
val
singleNotId
=
pushMessage
.
notificationId
.
toInt
()
val
groupTuple
=
groupMap
.
get
(
pushMessage
.
host
)
for
(
msg
in
messageStack
[
singleNotId
])
{
manager
.
cancel
(
singleNotId
)
groupTuple
?.
second
?.
decrementAndGet
()
println
(
"Decremented"
)
}
clearMessageBundle
(
singleNotId
)
if
(
groupTuple
!=
null
)
{
val
groupNotId
=
groupTuple
.
first
val
totalNot
=
groupTuple
.
second
.
get
()
if
(
totalNot
==
0
)
{
manager
.
cancel
(
groupNotId
)
}
}
if
(
message
!=
null
)
{
sendMessage
(
context
,
message
,
pushMessage
.
rid
)
}
}
}
private
fun
extractMessage
(
intent
:
Intent
?):
CharSequence
?
{
val
remoteInput
:
Bundle
?
=
RemoteInput
.
getResultsFromIntent
(
intent
)
return
remoteInput
?.
getCharSequence
(
REMOTE_INPUT_REPLY
)
}
// Just kept for reference. We should use this on rewrite with job schedulers
private
fun
sendMessage
(
ctx
:
Context
,
message
:
CharSequence
,
roomId
:
String
)
{
val
hostname
=
RocketChatCache
(
ctx
).
selectedServerHostname
val
roomRepository
=
RealmRoomRepository
(
hostname
)
val
userRepository
=
RealmUserRepository
(
hostname
)
val
messageRepository
=
RealmMessageRepository
(
hostname
)
val
messageInteractor
=
MessageInteractor
(
messageRepository
,
roomRepository
)
val
singleRoom
:
Single
<
Room
>
=
roomRepository
.
getById
(
roomId
)
.
filter
({
it
.
isPresent
})
.
map
({
it
.
get
()
})
.
firstElement
()
.
toSingle
()
val
singleUser
:
Single
<
User
>
=
userRepository
.
getCurrent
()
.
filter
({
it
.
isPresent
})
.
map
({
it
.
get
()
})
.
firstElement
()
.
toSingle
()
val
roomUserTuple
:
Single
<
HostTotalMsgTuple
<
Room
,
User
>>
=
Single
.
zip
(
singleRoom
,
singleUser
,
BiFunction
{
room
,
user
->
HostTotalMsgTuple
(
room
,
user
)
})
roomUserTuple
.
flatMap
{
tuple
->
messageInteractor
.
send
(
tuple
.
first
,
tuple
.
second
,
message
as
String
)
}
.
subscribeOn
(
AndroidSchedulers
.
from
(
BackgroundLooper
.
get
()))
.
observeOn
(
AndroidSchedulers
.
mainThread
())
.
subscribe
(
{
success
->
// Empty
},
{
throwable
->
Logger
.
report
(
throwable
)
})
}
}
}
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment