Skip to content

Commit

Permalink
android notif: Put React behind our "crunchy shell".
Browse files Browse the repository at this point in the history
We now have a nice crunchy shell that provides a clean version
of the notification data, in a known and reasonable format.
It enables application code to take shelter, in a "soft center",
from the complexity of all the arbitrary stuff we might receive
from the server.

Our Android-native code lives inside that soft center, but
we're still sending React the raw messiness of the data from
the network.  Send it some nice parsed data instead, moving it
into the "soft center".

This was the last use of the `bundle` member, so cut it out.
Now we don't even keep around the raw unparsed data.
  • Loading branch information
gnprice committed Mar 7, 2019
1 parent 6fe96fd commit edf3c08
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ private static Notification.Builder getNotificationBuilder(
final int messageId = fcmMessage.getZulipMessageId();
final Uri uri = Uri.fromParts("zulip", "msgid:" + Integer.toString(messageId), "");
final Intent viewIntent = new Intent(Intent.ACTION_VIEW, uri, context, NotificationIntentService.class);
viewIntent.putExtra(EXTRA_NOTIFICATION_DATA, fcmMessage.getBundle());
viewIntent.putExtra(EXTRA_NOTIFICATION_DATA, fcmMessage.dataForOpen());
final PendingIntent viewPendingIntent =
PendingIntent.getService(context, 0, viewIntent, 0);
builder.setContentIntent(viewPendingIntent);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,36 @@ internal data class MessageFcmMessage(
val zulipMessageId: Int,
val recipient: Recipient,
val content: String,
val time: String,

val bundle: Bundle
val time: String
) : FcmMessage() {

/**
* All the data our React code needs on opening the notification.
*
* For the corresponding type definition on the JS side, see `Notification`
* in `notification/index.js`.
*/
fun dataForOpen(): Bundle {
val bundle = Bundle()
when (recipient) {
// NOTE: Keep the JS-side type definition in sync with this code.
is Recipient.Stream -> {
bundle.putString("recipient_type", "stream")
bundle.putString("stream", recipient.stream)
bundle.putString("topic", recipient.topic)
}
is Recipient.GroupPm -> {
bundle.putString("recipient_type", "private")
bundle.putString("pm_users", recipient.pmUsers)
}
is Recipient.Pm -> {
bundle.putString("recipient_type", "private")
bundle.putString("sender_email", email)
}
}
return bundle
}

companion object {
fun fromBundle(bundle: Bundle): MessageFcmMessage {
val recipientType = bundle.requireString("recipient_type")
Expand Down Expand Up @@ -92,9 +118,7 @@ internal data class MessageFcmMessage(
zulipMessageId = bundle.requireIntString("zulip_message_id"),
recipient = recipient,
content = bundle.requireString("content"),
time = bundle.requireString("time"),

bundle = bundle.clone() as Bundle
time = bundle.requireString("time")
)
}
}
Expand Down
14 changes: 10 additions & 4 deletions src/notification/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ import { identityOfAuth } from '../account/accountMisc';
* pretending they are seems to be the least unpleasant way to get Flow to
* recognize the effect of refinements like `data.pm_users === undefined`.
*
* Currently these objects are translated directly, field by field, from the
* blobs of key/value pairs sent by the Zulip server in the "payload". The
* set of fields therefore differs between server versions, and between iOS
* and Android (because the server logic conditions on that.)
* Currently:
*
* * On iOS, these objects are translated directly, field by field, from
* the blobs of key/value pairs sent by the Zulip server in the
* "payload". The set of fields therefore varies by server version.
*
* * On Android, our platform-native code constructs the exact data to
* send; see `MessageFcmMessage#dataForOpen` in `FcmMessage.kt`.
* That should be kept in sync with this type definition, in which case
* these types really are exact.
*/
export type Notification =
| {| recipient_type: 'stream', stream: string, topic: string |}
Expand Down

0 comments on commit edf3c08

Please sign in to comment.