1 package host.exp.exponent.notifications.managers 2 3 import android.content.Context 4 import com.raizlabs.android.dbflow.sql.language.SQLite 5 import expo.modules.core.interfaces.Function 6 import host.exp.exponent.kernel.ExperienceKey 7 import host.exp.exponent.notifications.exceptions.UnableToScheduleException 8 import host.exp.exponent.notifications.schedulers.* 9 10 internal class SchedulerManagerImpl(private val applicationContext: Context) : SchedulersManager { 11 private var fetchedFromDB = false 12 private val schedulersMap = mutableMapOf<String, Scheduler>() 13 triggerAllnull14 override fun triggerAll(action: String?) { 15 fetchSchedulersMap() 16 17 cancelAlreadyScheduled(null) 18 19 val unsuccessful = mutableListOf<String>() 20 for ((key, value) in schedulersMap) { 21 try { 22 value.schedule(action) 23 } catch (e: UnableToScheduleException) { 24 unsuccessful.add(key) 25 } 26 } 27 28 for (key in unsuccessful) { 29 removeScheduler(key) 30 } 31 } 32 removeAllnull33 override fun removeAll(experienceKey: ExperienceKey?) { 34 fetchSchedulersMap() 35 36 cancelAlreadyScheduled(experienceKey) 37 38 val toRemove = mutableListOf<String>() 39 for ((key, value) in schedulersMap) { 40 if (experienceKey == null || value.ownerExperienceKey == experienceKey) { 41 value.remove() 42 toRemove.add(key) 43 } 44 } 45 46 for (key in toRemove) { 47 schedulersMap.remove(key) 48 } 49 } 50 cancelAlreadySchedulednull51 override fun cancelAlreadyScheduled(experienceKey: ExperienceKey?) { 52 fetchSchedulersMap() 53 54 for (scheduler in schedulersMap.values) { 55 if (experienceKey == null || scheduler.ownerExperienceKey == experienceKey) { 56 scheduler.cancel() 57 } 58 } 59 } 60 rescheduleOrDeletenull61 override fun rescheduleOrDelete(id: String?) { 62 fetchSchedulersMap() 63 64 val scheduler = schedulersMap[id] ?: return 65 if (!scheduler.canBeRescheduled()) { 66 removeScheduler(id) 67 } else { 68 try { 69 scheduler.schedule(null) 70 } catch (e: UnableToScheduleException) { 71 removeScheduler(id) 72 } 73 } 74 } 75 removeSchedulernull76 override fun removeScheduler(id: String?) { 77 fetchSchedulersMap() 78 79 schedulersMap.remove(id)?.apply { 80 cancel() 81 remove() 82 } 83 } 84 addSchedulernull85 override fun addScheduler(scheduler: Scheduler, handler: Function<String, Boolean>) { 86 fetchSchedulersMap() 87 88 scheduler.setApplicationContext(applicationContext) 89 90 val id = scheduler.saveAndGetId() 91 schedulersMap[id] = scheduler 92 val idToApply = try { 93 scheduler.schedule(null) 94 id 95 } catch (e: UnableToScheduleException) { 96 removeScheduler(id) 97 null 98 } 99 100 handler.apply(idToApply) 101 } 102 fetchSchedulersMapnull103 private fun fetchSchedulersMap() { 104 if (!fetchedFromDB) { 105 fetchedFromDB = true 106 107 val calendarSchedulers: List<SchedulerModel> = SQLite.select().from(CalendarSchedulerModel::class.java).queryList() 108 val intervalSchedulers: List<SchedulerModel> = SQLite.select().from(IntervalSchedulerModel::class.java).queryList() 109 for (schedulerModel in calendarSchedulers + intervalSchedulers) { 110 val scheduler = SchedulerImpl(schedulerModel) 111 schedulersMap[scheduler.idAsString] = scheduler 112 } 113 114 for (scheduler in schedulersMap.values) { 115 scheduler.setApplicationContext(applicationContext) 116 } 117 } 118 } 119 } 120