|
|
|
@ -1,14 +1,13 @@
@@ -1,14 +1,13 @@
|
|
|
|
|
package com.adlerosn.brasilfurfest.schedule.managers |
|
|
|
|
|
|
|
|
|
import android.app.AlarmManager |
|
|
|
|
import android.content.Context |
|
|
|
|
import android.os.FileObserver |
|
|
|
|
import android.os.Handler |
|
|
|
|
import android.os.Looper |
|
|
|
|
import android.util.Log |
|
|
|
|
import com.adlerosn.brasilfurfest.helper.* |
|
|
|
|
import com.adlerosn.brasilfurfest.helper.observables.Observable |
|
|
|
|
import com.adlerosn.brasilfurfest.helper.observables.Observer |
|
|
|
|
import com.adlerosn.brasilfurfest.notification.NotificationFirer |
|
|
|
|
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.Announcement |
|
|
|
|
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.Convention |
|
|
|
|
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.ConventionSeries |
|
|
|
|
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.Event |
|
|
|
@ -16,7 +15,6 @@ import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.managed.AttendeeCon
@@ -16,7 +15,6 @@ import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.managed.AttendeeCon
|
|
|
|
|
import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.managed.AttendeeConsFavorites |
|
|
|
|
import com.google.gson.GsonBuilder |
|
|
|
|
import org.jetbrains.anko.doAsync |
|
|
|
|
import org.jetbrains.anko.uiThread |
|
|
|
|
import java.io.File |
|
|
|
|
import java.io.Serializable |
|
|
|
|
import java.util.* |
|
|
|
@ -24,15 +22,20 @@ import java.util.*
@@ -24,15 +22,20 @@ import java.util.*
|
|
|
|
|
class ScheduleManager(context: Context) : UncomplicatedObservable<Any?>(), Observer<Observable<Any?>, Any?>, Serializable { |
|
|
|
|
override fun update(observable: Observable<Any?>, args: Any?) = onAttendeeIntentionsChanged() |
|
|
|
|
|
|
|
|
|
val cacheManager = CacheManager(context).also { it.setupScheduleManagerUpdater(this) } |
|
|
|
|
private val uniqueIdentifierFile = File(context.filesDir, "rduid.txt") |
|
|
|
|
val uniqueIdentifier: String |
|
|
|
|
|
|
|
|
|
val cacheManager = CacheManager(context) |
|
|
|
|
private val cachedChoices = File(context.filesDir, "schedule_choices.json") |
|
|
|
|
private val cachedChoicesCanonicalPath = cachedChoices.canonicalPath |
|
|
|
|
|
|
|
|
|
private inner class InnerFileObserver(path: String, private val scheduleManager: ScheduleManager) : FixedFileObserver(path){ |
|
|
|
|
private val fireNotificationsClosure = { NotificationFirer().fire(context) } |
|
|
|
|
|
|
|
|
|
private inner class InnerFileObserver(path: String, private val closure: ()->Any?) : FixedFileObserver(path){ |
|
|
|
|
override fun onEvent(event: Int, path: String) { |
|
|
|
|
val mask = FileObserver.CLOSE_WRITE |
|
|
|
|
if ((event and mask) != 0) { |
|
|
|
|
scheduleManager.notifyDiskChanges() |
|
|
|
|
closure() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -54,7 +57,8 @@ class ScheduleManager(context: Context) : UncomplicatedObservable<Any?>(), Obser
@@ -54,7 +57,8 @@ class ScheduleManager(context: Context) : UncomplicatedObservable<Any?>(), Obser
|
|
|
|
|
notifyObservers() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private var fileObserver: InnerFileObserver |
|
|
|
|
private val fileObserver: InnerFileObserver |
|
|
|
|
private val scheduleObserver: InnerFileObserver |
|
|
|
|
|
|
|
|
|
fun updateConventionSeries() = |
|
|
|
|
cacheManager[RemoteAssets.json.lastPathPart()]!!.first |
|
|
|
@ -77,33 +81,62 @@ class ScheduleManager(context: Context) : UncomplicatedObservable<Any?>(), Obser
@@ -77,33 +81,62 @@ class ScheduleManager(context: Context) : UncomplicatedObservable<Any?>(), Obser
|
|
|
|
|
//.setExclusionStrategies(ObservableFieldsExclusionStrategy()) |
|
|
|
|
.registerTypeAdapter(Convention::class.java, ConventionInstanceCreator(convention)) |
|
|
|
|
.create() |
|
|
|
|
val nextNotificationTime: Long get(){ |
|
|
|
|
val early: Long = convention.notificationFireMinutesBefore*60*1000.toLong() |
|
|
|
|
val now = conventionTime |
|
|
|
|
val thisRange = now.dayRange.split(convention.splitDayIn).first { conventionTime in it } |
|
|
|
|
val diff = thisRange.finish.timeInMillis - thisRange.start.timeInMillis |
|
|
|
|
val nextEnd = thisRange.start.timeInMillis+(1*diff) |
|
|
|
|
val nextNextEnd = thisRange.start.timeInMillis+(2*diff) |
|
|
|
|
val earlyNextEnd = nextEnd-early |
|
|
|
|
val earlyNextNextEnd = nextNextEnd-early |
|
|
|
|
return if(now.timeInMillis < earlyNextEnd) earlyNextEnd else earlyNextNextEnd |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager |
|
|
|
|
fun onConventionSeriesHasPendingUpdates(){ doAsync { uiThread { updateConventionSeries() } } } |
|
|
|
|
// val nextNotificationTime: Long get(){ |
|
|
|
|
// val early: Long = convention.notificationFireMinutesBefore*60*1000.toLong() |
|
|
|
|
// val now = conventionTime |
|
|
|
|
// val thisRange = now.dayRange.split(convention.splitDayIn).first { conventionTime in it } |
|
|
|
|
// val diff = thisRange.finish.timeInMillis - thisRange.start.timeInMillis |
|
|
|
|
// val nextEnd = thisRange.start.timeInMillis+(1*diff) |
|
|
|
|
// val nextNextEnd = thisRange.start.timeInMillis+(2*diff) |
|
|
|
|
// val earlyNextEnd = nextEnd-early |
|
|
|
|
// val earlyNextNextEnd = nextNextEnd-early |
|
|
|
|
// return if(now.timeInMillis < earlyNextEnd) earlyNextEnd else earlyNextNextEnd |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
init { |
|
|
|
|
loadFromDisk() |
|
|
|
|
if(!cachedChoices.exists()) |
|
|
|
|
saveToDisk(false) |
|
|
|
|
fileObserver = InnerFileObserver(cachedChoicesCanonicalPath, this) |
|
|
|
|
fileObserver.startWatching() |
|
|
|
|
uniqueIdentifier = initUniqueIdentifierFile() |
|
|
|
|
fileObserver = (InnerFileObserver(cachedChoicesCanonicalPath) {notifyDiskChanges()}).apply { startWatching() } |
|
|
|
|
scheduleObserver = (InnerFileObserver(cacheManager.getFileFor(RemoteAssets.json).absolutePath) {notifyScheduleChanged()}).apply { startWatching() } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun notifyScheduleChanged() { |
|
|
|
|
conventionSeries = updateConventionSeries() |
|
|
|
|
setChanged() |
|
|
|
|
notifyObservers() |
|
|
|
|
fireNotificationsClosure() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private val readAnnouncementsFile = File(context.filesDir, "announcements_read.txt") |
|
|
|
|
val unreadAnnouncements: List<Announcement> get() { |
|
|
|
|
if(!readAnnouncementsFile.exists()) |
|
|
|
|
return listOf() |
|
|
|
|
val readAnnouncementUUIDs = readAnnouncementsFile.readLines() |
|
|
|
|
return conventionSeries.announcements.filter { it.uuid !in readAnnouncementUUIDs } |
|
|
|
|
} |
|
|
|
|
fun setAnnouncementsRead() { |
|
|
|
|
readAnnouncementsFile.writeText( |
|
|
|
|
conventionSeries.announcements.map { |
|
|
|
|
it.uuid |
|
|
|
|
}.joinToString(separator = "\n") |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private fun initUniqueIdentifierFile(): String{ |
|
|
|
|
if(!uniqueIdentifierFile.exists()) |
|
|
|
|
uniqueIdentifierFile.writeText(UUID.randomUUID().toString()) |
|
|
|
|
return uniqueIdentifierFile.readText() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun readObject(ois: java.io.ObjectInputStream){ |
|
|
|
|
ois.defaultReadObject() |
|
|
|
|
fileObserver.stopWatching() |
|
|
|
|
fileObserver.startWatching() |
|
|
|
|
scheduleObserver.stopWatching() |
|
|
|
|
scheduleObserver.startWatching() |
|
|
|
|
loadFromDisk() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|