Skip to content

Commit

Permalink
make push notification clickable to jump you into agenda detail
Browse files Browse the repository at this point in the history
  • Loading branch information
Ken Yee committed Mar 26, 2018
1 parent 416176e commit 4a4827b
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.mentalmachines.droidcon_boston.R
import com.mentalmachines.droidcon_boston.data.Schedule.ScheduleDetail
import com.mentalmachines.droidcon_boston.data.Schedule.ScheduleRow
import com.mentalmachines.droidcon_boston.utils.NotificationUtils
import com.mentalmachines.droidcon_boston.utils.ServiceLocator
import com.mentalmachines.droidcon_boston.utils.getHtmlFormattedSpanned
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZoneId
Expand Down Expand Up @@ -37,9 +38,10 @@ open class FirebaseDatabase {
return ZonedDateTime.parse(startTime).withZoneSameInstant(ZoneId.systemDefault()).toLocalDateTime()
}

fun scheduleNotification(context: Context, eventId: String) {
fun scheduleNotification(context: Context, eventId: String, sessionDetail: ScheduleRow) {
NotificationUtils(context).scheduleNotificationAlarm(getLocalStartTime().minusMinutes(SESSION_REMINDER_MINUTES_BEFORE),
eventId, context.getString(R.string.str_session_start_soon, name), description.getHtmlFormattedSpanned().toString())
eventId, context.getString(R.string.str_session_start_soon, name), description.getHtmlFormattedSpanned().toString(),
ServiceLocator.gson.toJson(sessionDetail, ScheduleRow::class.java))
}

fun toScheduleRow(scheduleId: String): ScheduleRow {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
package com.mentalmachines.droidcon_boston.utils

import android.annotation.TargetApi
import android.app.*
import android.app.AlarmManager
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.os.Build
import android.os.Build.VERSION_CODES
import android.support.v4.app.NotificationCompat
import android.text.TextUtils
import android.util.Log
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.ValueEventListener
import com.mentalmachines.droidcon_boston.receivers.NotificationPublisher
import com.mentalmachines.droidcon_boston.R
import com.mentalmachines.droidcon_boston.data.FirebaseDatabase
import com.mentalmachines.droidcon_boston.data.UserAgendaRepo
import com.mentalmachines.droidcon_boston.firebase.FirebaseHelper
import com.mentalmachines.droidcon_boston.receivers.BootReceiver
import com.mentalmachines.droidcon_boston.receivers.NotificationPublisher
import com.mentalmachines.droidcon_boston.views.MainActivity
import org.threeten.bp.LocalDateTime
import org.threeten.bp.ZoneId
import android.content.pm.PackageManager
import android.content.ComponentName
import com.mentalmachines.droidcon_boston.receivers.BootReceiver


class NotificationUtils(context: Context) : ContextWrapper(context) {
Expand Down Expand Up @@ -91,7 +96,7 @@ class NotificationUtils(context: Context) : ContextWrapper(context) {
scheduleEvent?.let {
if (userRepo.isSessionBookmarked(eventId)
&& scheduleEvent.getLocalStartTime().isAfter(LocalDateTime.now())) {
scheduleEvent.scheduleNotification(context, eventId)
scheduleEvent.scheduleNotification(context, eventId, scheduleEvent.toScheduleRow(eventId))
hasBookmarkedEvents = true
}
}
Expand All @@ -109,9 +114,9 @@ class NotificationUtils(context: Context) : ContextWrapper(context) {
})
}

fun scheduleNotificationAlarm(alarmTime: LocalDateTime, sessionId: String, title: String, body: String) {
fun scheduleNotificationAlarm(alarmTime: LocalDateTime, sessionId: String, title: String, body: String, sessionDetail: String) {
if (alarmTime.isAfter(LocalDateTime.now())) {
val pendingIntent = getAgendaSessionNotificationPendingIntent(sessionId, title, body)
val pendingIntent = getAgendaSessionNotificationPendingIntent(sessionId, title, body, sessionDetail)
val utcInMillis = alarmTime.atZone(ZoneId.systemDefault()).toEpochSecond() * 1000
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.set(AlarmManager.RTC_WAKEUP, utcInMillis, pendingIntent)
Expand All @@ -134,7 +139,7 @@ class NotificationUtils(context: Context) : ContextWrapper(context) {
PackageManager.DONT_KILL_APP)
}

private fun getAgendaSessionNotificationPendingIntent(sessionId: String, title: String = "", body: String = ""): PendingIntent {
private fun getAgendaSessionNotificationPendingIntent(sessionId: String, title: String = "", body: String = "", sessionDetail: String = ""): PendingIntent {
val builder = NotificationCompat.Builder(this, ANDROID_CHANNEL_ID)
.setContentText(title)
.setStyle(NotificationCompat.BigTextStyle()
Expand All @@ -143,6 +148,14 @@ class NotificationUtils(context: Context) : ContextWrapper(context) {
.setSmallIcon(R.drawable.ic_notification_session_start)
.setAutoCancel(true)

if (!TextUtils.isEmpty(sessionDetail)) {
val sessionIntent = MainActivity.getSessionDetailIntent(this, sessionId, sessionDetail)
val contentIntent = PendingIntent.getActivity(this, 0,
sessionIntent, PendingIntent.FLAG_UPDATE_CURRENT)

builder.setContentIntent(contentIntent)
}

val notificationIntent = Intent(this, NotificationPublisher::class.java).apply {
putExtra(NotificationPublisher.NOTIFICATION_ID, sessionId.hashCode())
putExtra(NotificationPublisher.SESSION_ID, sessionId)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package com.mentalmachines.droidcon_boston.views

import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.view.GravityCompat
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AppCompatActivity
import android.text.TextUtils
import android.view.Gravity
import android.view.MenuItem
import com.mentalmachines.droidcon_boston.R
import com.mentalmachines.droidcon_boston.data.Schedule.ScheduleRow
import com.mentalmachines.droidcon_boston.utils.ServiceLocator
import com.mentalmachines.droidcon_boston.views.agenda.AgendaFragment
import com.mentalmachines.droidcon_boston.views.detail.AgendaDetailFragment
import com.mentalmachines.droidcon_boston.views.social.SocialFragment
import com.mentalmachines.droidcon_boston.views.speaker.SpeakerFragment
import com.mentalmachines.droidcon_boston.views.volunteer.VolunteerFragment
Expand All @@ -29,7 +35,14 @@ class MainActivity : AppCompatActivity() {
initNavDrawerToggle()

replaceFragment(getString(R.string.str_agenda))
navView.setCheckedItem(R.id.nav_agenda)

val sessionDetails = intent.extras?.getString(EXTRA_SESSION_DETAILS)
if (!TextUtils.isEmpty(sessionDetails)) {
AgendaDetailFragment.addDetailFragmentToStack(supportFragmentManager,
ServiceLocator.gson.fromJson(sessionDetails, ScheduleRow::class.java))
} else {
navView.setCheckedItem(R.id.nav_agenda)
}
}


Expand Down Expand Up @@ -220,4 +233,17 @@ class MainActivity : AppCompatActivity() {
supportActionBar?.title = title
}
}

companion object {
private const val EXTRA_SESSIONID = "MainActivity.EXTRA_SESSIONID"
private const val EXTRA_SESSION_DETAILS = "MainActivity.EXTRA_SESSION_DETAILS"

fun getSessionDetailIntent(context: Context, sessionId: String, sessionDetail: String): Intent {
val intent = Intent(context, MainActivity::class.java).apply {
putExtra(EXTRA_SESSIONID, sessionId)
putExtra(EXTRA_SESSION_DETAILS, sessionDetail)
}
return intent
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,17 +177,10 @@ class AgendaDayFragment : Fragment(), FlexibleAdapter.OnItemClickListener {
return false
}
}
val arguments = Bundle()
arguments.putString(Schedule.SCHEDULE_ITEM_ROW, gson.toJson(itemData, ScheduleRow::class.java))

val agendaDetailFragment = AgendaDetailFragment()
agendaDetailFragment.arguments = arguments

val fragmentManager = activity?.supportFragmentManager
fragmentManager?.beginTransaction()
?.add(R.id.fragment_container, agendaDetailFragment)
?.addToBackStack(null)
?.commit()
activity?.let {
AgendaDetailFragment.addDetailFragmentToStack(it.supportFragmentManager, itemData);
}
}

return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.res.ColorStateList
import android.os.Bundle
import android.support.design.widget.Snackbar
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.content.ContextCompat
import android.text.method.LinkMovementMethod
import android.util.Log
Expand Down Expand Up @@ -42,7 +43,7 @@ import kotlinx.android.synthetic.main.agenda_detail_fragment.v_agenda_detail_spe

class AgendaDetailFragment : Fragment() {

private lateinit var scheduleDetail: ScheduleDetail
private var scheduleDetail: ScheduleDetail? = null
private lateinit var scheduleRowItem: ScheduleRow
private val eventSpeakers = HashMap<String, EventSpeaker>()

Expand Down Expand Up @@ -78,22 +79,24 @@ class AgendaDetailFragment : Fragment() {

fab_agenda_detail_bookmark.setOnClickListener({

val nextBookmarkStatus = !userAgendaRepo.isSessionBookmarked(scheduleDetail.id)
userAgendaRepo.bookmarkSession(scheduleDetail.id, nextBookmarkStatus)
val context = tv_agenda_detail_title.context
if (nextBookmarkStatus) {
NotificationUtils(context).scheduleMySessionNotifications()
} else {
NotificationUtils(context).cancelNotificationAlarm(scheduleRowItem.id)
}
if (scheduleDetail != null) {
val nextBookmarkStatus = !userAgendaRepo.isSessionBookmarked(scheduleDetail!!.id)
userAgendaRepo.bookmarkSession(scheduleDetail!!.id, nextBookmarkStatus)
val context = tv_agenda_detail_title.context
if (nextBookmarkStatus) {
NotificationUtils(context).scheduleMySessionNotifications()
} else {
NotificationUtils(context).cancelNotificationAlarm(scheduleRowItem.id)
}

Snackbar.make(agendaDetailView,
if (nextBookmarkStatus)
getString(R.string.saved_agenda_item)
else getString(R.string.removed_agenda_item),
Snackbar.LENGTH_SHORT).show()
Snackbar.make(agendaDetailView,
if (nextBookmarkStatus)
getString(R.string.saved_agenda_item)
else getString(R.string.removed_agenda_item),
Snackbar.LENGTH_SHORT).show()

showBookmarkStatus(scheduleDetail)
showBookmarkStatus(scheduleDetail!!)
}
})

populateSpeakersInformation(scheduleRowItem)
Expand All @@ -108,7 +111,7 @@ class AgendaDetailFragment : Fragment() {

if (scheduleRowItem.primarySpeakerName == speaker.name) {
scheduleDetail = speaker.toScheduleDetail(scheduleRowItem)
showAgendaDetail(scheduleDetail)
showAgendaDetail(scheduleDetail!!)
}
}

Expand Down Expand Up @@ -228,4 +231,19 @@ class AgendaDetailFragment : Fragment() {
else
ColorStateList.valueOf(ContextCompat.getColor(context, R.color.colorLightGray))
}

companion object {
fun addDetailFragmentToStack(supportFragmentManager: FragmentManager, itemData: Schedule.ScheduleRow) {
val arguments = Bundle()
arguments.putString(Schedule.SCHEDULE_ITEM_ROW, gson.toJson(itemData, ScheduleRow::class.java))

val agendaDetailFragment = AgendaDetailFragment()
agendaDetailFragment.arguments = arguments

supportFragmentManager.beginTransaction()
?.add(R.id.fragment_container, agendaDetailFragment)
?.addToBackStack(null)
?.commit()
}
}
}

0 comments on commit 4a4827b

Please sign in to comment.