Skip to content

Commit

Permalink
Reply on push notification and bug fixes. (#299)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgeblacio authored and not-gabriel committed Oct 25, 2018
1 parent 3f69e3b commit 7a39657
Show file tree
Hide file tree
Showing 22 changed files with 119 additions and 34 deletions.
13 changes: 12 additions & 1 deletion src/main/kotlin/com/criptext/mail/BaseActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import android.view.Menu
import android.view.MenuItem
import com.criptext.mail.push.data.IntentExtrasData
import com.criptext.mail.push.services.LinkDeviceActionService
import com.criptext.mail.push.services.NewMailActionService
import com.criptext.mail.scenes.ActivityMessage
import com.criptext.mail.scenes.SceneController
import com.criptext.mail.scenes.composer.ComposerModel
Expand Down Expand Up @@ -164,7 +165,7 @@ abstract class BaseActivity: AppCompatActivity(), IHostActivity {
is SignInParams -> SignInSceneModel()
is MailboxParams -> MailboxSceneModel(params.showWelcome)
is EmailDetailParams -> EmailDetailSceneModel(params.threadId,
params.currentLabel, params.threadPreview)
params.currentLabel, params.threadPreview, params.doReply)
is ComposerParams -> ComposerModel(params.type)
is SettingsParams -> SettingsModel()
is SignatureParams -> SignatureModel(params.recipientId)
Expand Down Expand Up @@ -223,6 +224,16 @@ abstract class BaseActivity: AppCompatActivity(), IHostActivity {
}
return IntentExtrasData.IntentExtrasDataDevice(intent.action, uuid, deviceType)
}
NewMailActionService.REPLY -> {
val threadId = intent.extras.get(MessagingInstance.THREAD_ID).toString()
val metadataKey = intent.extras.getLong("metadataKey")
if(intent.extras != null) {
for (key in intent.extras.keySet()){
intent.removeExtra(key)
}
}
return IntentExtrasData.IntentExtrasReply(intent.action, threadId, metadataKey)
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import android.os.Build
import android.support.annotation.RequiresApi
import android.support.v4.app.NotificationCompat
import com.criptext.mail.R
import com.criptext.mail.db.KeyValueStorage
import com.criptext.mail.push.services.LinkDeviceActionService
import com.criptext.mail.push.data.PushDataSource
import com.criptext.mail.push.services.NewMailActionService
import com.criptext.mail.scenes.mailbox.MailboxActivity
import com.criptext.mail.services.MessagingInstance
import com.criptext.mail.utils.DeviceUtils
import com.criptext.mail.utils.UIMessage
import com.criptext.mail.utils.Utility
Expand All @@ -28,6 +30,8 @@ import com.criptext.mail.utils.getLocalizedUIMessage
*/
class CriptextNotification(val ctx: Context) {

private val storage = KeyValueStorage.SharedPrefs(ctx)

companion object {
//Actions for Notifications
const val ACTION_OPEN = "open_activity"
Expand Down Expand Up @@ -89,29 +93,34 @@ class CriptextNotification(val ctx: Context) {
return notBuild
}

fun createNewMailNotification(clickIntent: PendingIntent, title: String, body:String, metadataKey: Long,
fun createNewMailNotification(clickIntent: PendingIntent, title: String, body:String,
metadataKey: Long, threadId: String,
notificationId: Int)
: Notification {

val notCount = storage.getInt(KeyValueStorage.StringKey.NewMailNotificationCount, 0)
storage.putInt(KeyValueStorage.StringKey.NewMailNotificationCount, notCount + 1)

val readAction = Intent(ctx, NewMailActionService::class.java)
readAction.action = NewMailActionService.READ
readAction.putExtra("notificationId", INBOX_ID)
readAction.putExtra("notificationId", notificationId)
readAction.putExtra("metadataKey", metadataKey)
val readPendingIntent = PendingIntent.getService(ctx, 0, readAction,
val readPendingIntent = PendingIntent.getService(ctx, notificationId, readAction,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT)

val trashAction = Intent(ctx, NewMailActionService::class.java)
trashAction.action = NewMailActionService.TRASH
trashAction.putExtra("notificationId", INBOX_ID)
trashAction.putExtra("notificationId", notificationId)
trashAction.putExtra("metadataKey", metadataKey)
val trashPendingIntent = PendingIntent.getService(ctx, 0, trashAction,
val trashPendingIntent = PendingIntent.getService(ctx, notificationId, trashAction,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT)

val replyAction = Intent(ctx, MailboxActivity::class.java)
replyAction.action = NewMailActionService.REPLY
replyAction.addCategory(Intent.CATEGORY_LAUNCHER)
replyAction.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT or Intent.FLAG_ACTIVITY_SINGLE_TOP)
replyAction.putExtra("metadataKey", metadataKey)
replyAction.putExtra(MessagingInstance.THREAD_ID, threadId)
val replyPendingAction = PendingIntent.getActivity(ctx, 0, replyAction,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT)

Expand All @@ -126,8 +135,9 @@ class CriptextNotification(val ctx: Context) {
.setGroup(ACTION_INBOX)
.setGroupSummary(false)
.setSmallIcon(R.drawable.push_icon)
.addAction(R.drawable.check, ctx.getString(R.string.push_read), readPendingIntent)
.addAction(R.drawable.x, ctx.getString(R.string.push_trash), trashPendingIntent)
.addAction(R.drawable.mail_opened, ctx.getString(R.string.push_read), readPendingIntent)
.addAction(R.drawable.trash, ctx.getString(R.string.push_trash), trashPendingIntent)
.addAction(R.drawable.reply, ctx.getString(R.string.push_reply), replyPendingAction)
.setLargeIcon(Utility.getBitmapFromText(
title,
250,
Expand Down
12 changes: 11 additions & 1 deletion src/main/kotlin/com/criptext/mail/db/KeyValueStorage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ interface KeyValueStorage {
fun putStringSet(key: StringKey, value: MutableSet<String>)
fun getLong(key: StringKey, default: Long): Long
fun putLong(key: StringKey, value: Long)
fun getInt(key: StringKey, default: Int): Int
fun putInt(key: StringKey, value: Int)
fun clearAll()

enum class StringKey(val stringKey: String) {
ActiveAccount("ActiveAccount"), SignInSession("SignInSession"),
SearchHistory("searchHistory"), LastTimeFeedOpened("LastTimeFeedOpened"),
LastTimeConfirmationLinkSent("LastTimeConfirmationLinkSent"),
LastLoggedUser("LastLoggedUser")
LastLoggedUser("LastLoggedUser"), NewMailNotificationCount("NewMailPushCount")
}

class SharedPrefs(ctx: Context) : KeyValueStorage {
Expand Down Expand Up @@ -58,6 +60,14 @@ interface KeyValueStorage {
withApply { editor -> editor.putLong(key.stringKey, value) }
}

override fun getInt(key: StringKey, default: Int): Int {
return prefs.getInt(key.stringKey, default)
}

override fun putInt(key: StringKey, value: Int) {
withApply { editor -> editor.putInt(key.stringKey, value) }
}

override fun clearAll() {
withApply { editor -> editor.clear() }
}
Expand Down
14 changes: 8 additions & 6 deletions src/main/kotlin/com/criptext/mail/push/NewMailNotifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ sealed class NewMailNotifier(val data: PushData.NewMail): Notifier {
private fun postNotification(ctx: Context, isPostNougat: Boolean) {
val cn = CriptextNotification(ctx)
val notification = buildNotification(ctx, cn)
cn.notify(if(isPostNougat) type.requestCodeRandom() else type.requestCode(), notification, CriptextNotification.ACTION_INBOX)
cn.notify(notification.first, notification.second, CriptextNotification.ACTION_INBOX)
}

private fun postHeaderNotification(ctx: Context){
Expand All @@ -29,7 +29,7 @@ sealed class NewMailNotifier(val data: PushData.NewMail): Notifier {
CriptextNotification.ACTION_INBOX, pendingIntent)
}

protected abstract fun buildNotification(ctx: Context, cn: CriptextNotification): Notification
protected abstract fun buildNotification(ctx: Context, cn: CriptextNotification): Pair<Int, Notification>

override fun notifyPushEvent(ctx: Context) {
if (data.shouldPostNotification){
Expand All @@ -42,13 +42,15 @@ sealed class NewMailNotifier(val data: PushData.NewMail): Notifier {

class Single(data: PushData.NewMail): NewMailNotifier(data) {

override fun buildNotification(ctx: Context, cn: CriptextNotification): Notification {
override fun buildNotification(ctx: Context, cn: CriptextNotification): Pair<Int, Notification> {
val pendingIntent = ActivityIntentFactory.buildSceneActivityPendingIntent(ctx, type,
data.threadId, data.isPostNougat)

return cn.createNewMailNotification(clickIntent = pendingIntent,
title = data.title, body = data.body, metadataKey = data.metadataKey ?: -1,
notificationId = if(data.isPostNougat) type.requestCodeRandom() else type.requestCode())
val notificationId = if(data.isPostNougat) type.requestCodeRandom() else type.requestCode()

return Pair(notificationId, cn.createNewMailNotification(clickIntent = pendingIntent, threadId = data.threadId,
title = data.title, body = data.body, metadataKey = data.metadataKey,
notificationId = notificationId))

}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/com/criptext/mail/push/PushController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class PushController(private val dataSource: PushDataSource, private val host: M
val metadataKey = pushData["metadataKey"]?.toLong()

return PushData.NewMail(title = title, body = body, threadId = threadId,
metadataKey = metadataKey, shouldPostNotification = shouldPostNotification,
metadataKey = metadataKey ?: -1, shouldPostNotification = shouldPostNotification,
isPostNougat = isPostNougat)
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/com/criptext/mail/push/PushData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class PushData {
/**
* POJO that holds all the data from the NewMail push notification
*/
data class NewMail(val title: String, val body: String, val threadId: String?,
val metadataKey: Long?, val isPostNougat: Boolean,
data class NewMail(val title: String, val body: String, val threadId: String,
val metadataKey: Long, val isPostNougat: Boolean,
val shouldPostNotification:Boolean)
data class OpenMailbox(val title: String, val body: String,
val isPostNougat: Boolean, val shouldPostNotification:Boolean)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ sealed class IntentExtrasData(open val action: String) {
data class IntentExtrasDataMail(override val action: String, val threadId: String) : IntentExtrasData(action)
data class IntentExtrasDataDevice(override val action: String, val deviceId: String,
val deviceType: DeviceUtils.DeviceType) : IntentExtrasData(action)
data class IntentExtrasReply(override val action: String, val threadId: String, val metadataKey: Long) : IntentExtrasData(action)

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.criptext.mail.api.HttpClient
import com.criptext.mail.api.HttpErrorHandlingHelper
import com.criptext.mail.db.AppDatabase
import com.criptext.mail.db.EmailDetailLocalDB
import com.criptext.mail.db.KeyValueStorage
import com.criptext.mail.db.dao.EmailDao
import com.criptext.mail.db.models.ActiveAccount
import com.criptext.mail.db.models.EmailLabel
Expand All @@ -28,7 +29,8 @@ import org.json.JSONObject
class PushAPIRequestHandler(private val not: CriptextNotification,
private val manager: NotificationManager,
val activeAccount: ActiveAccount,
val httpClient: HttpClient){
val httpClient: HttpClient,
private val storage: KeyValueStorage){
private val apiClient = PushAPIClient(httpClient, activeAccount.jwt)

private val isPostNougat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
Expand Down Expand Up @@ -75,9 +77,11 @@ class PushAPIRequestHandler(private val not: CriptextNotification,
.flatMap { Result.of { emailDao.toggleCheckingRead(listOf(it.id), false) } }
.flatMap { Result.of { apiClient.postOpenEvent(listOf(metadataKey)) } }
when(operation){
is Result.Success -> manager.cancel(notificationId)
is Result.Success -> {
handleNotificationCountForNewEmail(notificationId)
}
is Result.Failure -> {
manager.cancel(notificationId)
handleNotificationCountForNewEmail(notificationId)
operation.error.printStackTrace()
val data = ErrorNotificationData(UIMessage(R.string.push_email_error_title),
UIMessage(R.string.push_mail_error_message_read))
Expand Down Expand Up @@ -121,10 +125,10 @@ class PushAPIRequestHandler(private val not: CriptextNotification,
db.createLabelEmailRelations(emailLabels)
db.setTrashDate(emailIds)

manager.cancel(notificationId)
handleNotificationCountForNewEmail(notificationId)
}
is Result.Failure -> {
manager.cancel(notificationId)
handleNotificationCountForNewEmail(notificationId)
val data = ErrorNotificationData(UIMessage(R.string.push_email_error_title),
UIMessage(R.string.push_mail_error_message_trash))
val errorNot = not.createErrorNotification(data.title, data.body)
Expand All @@ -133,6 +137,16 @@ class PushAPIRequestHandler(private val not: CriptextNotification,
}
}

private fun handleNotificationCountForNewEmail(notificationId: Int){
val notCount = storage.getInt(KeyValueStorage.StringKey.NewMailNotificationCount, 0)
manager.cancel(notificationId)
if((notCount - 1) == 0) {
manager.cancel(CriptextNotification.INBOX_ID)
}else{
storage.putInt(KeyValueStorage.StringKey.NewMailNotificationCount, notCount - 1)
}
}

private fun postNotification(data: ErrorNotificationData, cn: CriptextNotification,
notification: Notification) {
cn.notify(if(isPostNougat) PushTypes.linkDevice.requestCodeRandom() else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.content.Context
import android.content.Intent
import com.criptext.mail.androidui.CriptextNotification
import com.criptext.mail.api.HttpClient
import com.criptext.mail.db.KeyValueStorage
import com.criptext.mail.db.models.ActiveAccount
import com.criptext.mail.push.data.PushAPIRequestHandler

Expand All @@ -24,7 +25,8 @@ class LinkDeviceActionService : IntentService("Link Device Action Service") {
val manager = this.applicationContext
.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val requestHandler = PushAPIRequestHandler(CriptextNotification(this), manager,
ActiveAccount.loadFromStorage(this)!!, HttpClient.Default())
ActiveAccount.loadFromStorage(this)!!, HttpClient.Default(),
KeyValueStorage.SharedPrefs(this))

when {
APPROVE == data.action -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.criptext.mail.androidui.CriptextNotification
import com.criptext.mail.api.HttpClient
import com.criptext.mail.db.AppDatabase
import com.criptext.mail.db.EmailDetailLocalDB
import com.criptext.mail.db.KeyValueStorage
import com.criptext.mail.db.models.ActiveAccount
import com.criptext.mail.push.data.PushAPIRequestHandler

Expand All @@ -27,7 +28,8 @@ class NewMailActionService : IntentService("New Mail Action Service") {
val manager = this.applicationContext
.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val requestHandler = PushAPIRequestHandler(CriptextNotification(this), manager,
ActiveAccount.loadFromStorage(this)!!, HttpClient.Default())
ActiveAccount.loadFromStorage(this)!!, HttpClient.Default(),
KeyValueStorage.SharedPrefs(this))
val db = AppDatabase.getAppDatabase(this)

when {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class EmailDetailSceneController(private val scene: EmailDetailScene,
is EmailDetailResult.UpdateUnreadStatus -> onUpdateUnreadStatus(result)
is EmailDetailResult.MoveEmailThread -> onMoveEmailThread(result)
is EmailDetailResult.DownloadFile -> onDownloadedFile(result)
is EmailDetailResult.ReadEmails -> onReadEmails(result)
}
}

Expand Down Expand Up @@ -283,6 +284,16 @@ class EmailDetailSceneController(private val scene: EmailDetailScene,
}
}

private fun onReadEmails(result: EmailDetailResult.ReadEmails){
when(result){
is EmailDetailResult.ReadEmails.Success -> {
if(model.doReply){
emailHolderEventListener.onReplyBtnClicked()
}
}
}
}

private fun updateAttachmentProgress(emailId: Long, filetoken: String, progress: Int){
val emailIndex = model.emails.indexOfFirst { it.email.id == emailId }
if (emailIndex < 0) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import com.criptext.mail.utils.virtuallist.VirtualList

class EmailDetailSceneModel(val threadId: String,
val currentLabel: Label,
var threadPreview: EmailPreview) : SceneModel {
var threadPreview: EmailPreview,
val doReply: Boolean = false) : SceneModel {
val emails = ArrayList<FullEmail>()
val fileDetails = HashMap<Long, List<FileDetail>>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import android.content.Intent
import com.criptext.mail.ExternalActivityParams
import com.criptext.mail.push.data.IntentExtrasData
import com.criptext.mail.push.services.LinkDeviceActionService
import com.criptext.mail.push.services.NewMailActionService
import com.criptext.mail.scenes.signin.data.LinkStatusData


Expand Down Expand Up @@ -340,6 +341,11 @@ class MailboxSceneController(private val scene: MailboxScene,
"", "", extrasDevice.deviceType)
generalDataSource.submitRequest(GeneralRequest.LinkAccept(untrustedDeviceInfo))
}
NewMailActionService.REPLY -> {
val extrasMail = extras as IntentExtrasData.IntentExtrasReply
dataSource.submitRequest(MailboxRequest.GetEmailPreview(threadId = extrasMail.threadId,
userEmail = activeAccount.userEmail, doReply = true))
}
}
}

Expand Down Expand Up @@ -688,7 +694,8 @@ class MailboxSceneController(private val scene: MailboxScene,
reloadMailboxThreads()
feedController.reloadFeeds()
host.goToScene(EmailDetailParams(threadId = result.emailPreview.threadId,
currentLabel = model.selectedLabel, threadPreview = result.emailPreview), true)
currentLabel = model.selectedLabel, threadPreview = result.emailPreview,
doReply = result.doReply), true)
}
is MailboxResult.GetEmailPreview.Failure -> {
dataSourceController.updateMailbox(model.selectedLabel)
Expand Down
Loading

0 comments on commit 7a39657

Please sign in to comment.