Author: Adam Pioterek <adam.pioterek@protonmail.ch>
favourites cache
app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt | 52 app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt | 50 app/src/main/java/ml/adamsprogs/bimba/models/FavouritesAdapter.kt | 2
diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt index f0193394cd57e83e74b15979c5dfc843520ba15a..dc521165db58723f1b2cb0833d052396f15caadd 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt @@ -1,17 +1,12 @@ package ml.adamsprogs.bimba.models -import android.content.Context -import android.content.Intent -import android.os.Parcel -import android.os.Parcelable -import ml.adamsprogs.bimba.MessageReceiver +import android.content.* +import android.os.* +import ml.adamsprogs.bimba.* import ml.adamsprogs.bimba.datasources.VmClient import ml.adamsprogs.bimba.models.gtfs.AgencyAndId -import ml.adamsprogs.bimba.secondsAfterMidnight -import java.util.* -import kotlin.collections.ArrayList -import kotlin.collections.HashMap -import kotlin.collections.HashSet +import java.util.Calendar +import kotlin.collections.* class Favourite : Parcelable, MessageReceiver.OnVmListener { private var isRegisteredOnVmListener: Boolean = false @@ -20,6 +15,8 @@ private set var segments: HashSet<StopSegment> private set private var vmDepartures = HashMap<Plate.ID, List<Departure>>() + var fullDepartures: Map<AgencyAndId, List<Departure>> = HashMap() + private set val timetable = Timetable.getTimetable() val size @@ -48,6 +45,19 @@ array.forEach { set.add(it as StopSegment) } this.segments = set + val mapString = parcel.readString() + val map = HashMap<AgencyAndId, List<Departure>>() + mapString.safeSplit("\n").forEach { + val (k, v) = it.split(":") + map[AgencyAndId(k)] = v.split(",").map { Departure.fromString(it) } + } + this.fullDepartures = map + } + + constructor(name :String, segments: HashSet<StopSegment>, cache:Map<AgencyAndId, List<Departure>>) { + this.fullDepartures = cache + this.name = name + this.segments = segments } constructor(name: String, timetables: HashSet<StopSegment>) { @@ -64,6 +74,17 @@ override fun writeToParcel(dest: Parcel?, flags: Int) { dest?.writeString(name) val parcelableSegments = segments.map { it }.toTypedArray() dest?.writeParcelableArray(parcelableSegments, flags) + var isFirst = true + var map = "" + fullDepartures.forEach { + if (isFirst) + isFirst = false + else + map += '\n' + + map += "${it.key}:${it.value.joinToString(",") { it.toString() }}" + } + dest?.writeString(map) } private fun filterVmDepartures() { @@ -160,7 +181,15 @@ val departures = fullTimetable() return Departure.rollDepartures(departures) } - fun fullTimetable() = timetable.getStopDeparturesBySegments(segments) + fun fullTimetable() = + if (fullDepartures.isNotEmpty()) + fullDepartures + else { + fullDepartures = timetable.getStopDeparturesBySegments(segments) + fullDepartures + + } + override fun onVm(vmDepartures: Set<Departure>?, plateId: Plate.ID) { val now = Calendar.getInstance().secondsAfterMidnight() @@ -171,7 +200,6 @@ else this.vmDepartures[plateId] = vmDepartures.sortedBy { it.timeTill(now) } } filterVmDepartures() - //todo<p:1> think about tick onVmPreparedListeners.forEach { it.onVmPrepared() } diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt b/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt index 669568ef29c6b2cfe6325a7c23d70ac05130dae5..65dee0ce3208e8e493b450ffc3d4fa8c1b80d51d 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt @@ -7,6 +7,8 @@ import com.google.gson.JsonArray import com.google.gson.JsonObject import ml.adamsprogs.bimba.MessageReceiver import ml.adamsprogs.bimba.models.gtfs.AgencyAndId +import ml.adamsprogs.bimba.secondsAfterMidnight +import java.util.Calendar class FavouriteStorage private constructor(context: Context) : Iterable<Favourite> { @@ -26,6 +28,7 @@ } } val favourites = HashMap<String, Favourite>() + private val positionIndex = ArrayList<String>() private val preferences: SharedPreferences = context.getSharedPreferences("ml.adamsprogs.bimba.prefs", Context.MODE_PRIVATE) init { @@ -45,7 +48,9 @@ stopSegment.plates = plates stopSegment } favourites[name] = Favourite(name, timetables) + positionIndex.add(name) } + positionIndex.sort() } override fun iterator(): Iterator<Favourite> = favourites.values.iterator() @@ -55,6 +60,7 @@ fun add(name: String, timetables: HashSet<StopSegment>) { if (favourites[name] == null) { favourites[name] = Favourite(name, timetables) + addIndex(name) serialize() } } @@ -62,12 +68,21 @@ fun add(name: String, favourite: Favourite) { if (favourites[name] == null) { favourites[name] = favourite + addIndex(name) serialize() } } + private fun addIndex(name:String) { + positionIndex.apply { + this.add(name) + this.sort() + } + } + fun delete(name: String) { favourites.remove(name) + positionIndex.remove(name) serialize() } @@ -103,26 +118,30 @@ editor.apply() } - fun detach(name: String, plate: Plate.ID, newName: String) { - val plates = HashSet<Plate.ID>() - plates.add(plate) - val segments = HashSet<StopSegment>() - segments.add(StopSegment(plate.stop, plates)) - favourites[newName] = Favourite(newName, segments) - serialize() - - delete(name, plate) - } - fun merge(names: List<String>) { if (names.size < 2) return - val newFavourite = Favourite(names[0], HashSet()) + + val newCache = HashMap<AgencyAndId, ArrayList<Departure>>() + names.forEach { + favourites[it]!!.fullDepartures.forEach { + if (newCache[it.key] == null) + newCache[it.key] = ArrayList() + newCache[it.key]!!.addAll(it.value) + } + } + val now = Calendar.getInstance().secondsAfterMidnight() + newCache.forEach { + it.value.sortBy { it.timeTill(now) } + } + val newFavourite = Favourite(names[0], HashSet(), newCache) for (name in names) { newFavourite.segments.addAll(favourites[name]!!.segments) favourites.remove(name) + positionIndex.remove(name) } favourites[names[0]] = newFavourite + addIndex(names[0]) serialize() } @@ -131,7 +150,9 @@ fun rename(oldName: String, newName: String) { val favourite = favourites[oldName] ?: return favourite.rename(newName) favourites.remove(oldName) + positionIndex.remove(oldName) favourites[newName] = favourite + addIndex(newName) serialize() } @@ -152,12 +173,11 @@ return favourites[name] } operator fun get(position: Int): Favourite? { - return favourites.entries.sortedBy { it.key }[position].value + return favourites[positionIndex[position]] } fun indexOf(name: String): Int { - val favourite = favourites[name] - return favourites.values.sortedBy { it.name }.indexOf(favourite) + return positionIndex.indexOf(name) } val size diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/FavouritesAdapter.kt b/app/src/main/java/ml/adamsprogs/bimba/models/FavouritesAdapter.kt index 597c578f95ae64e941145c04284bbc1dcb61a85d..2643b27522224a6eab1474d0edbb427af0c8a72d 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/FavouritesAdapter.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/FavouritesAdapter.kt @@ -57,6 +57,7 @@ override fun onBindViewHolder(holder: ViewHolder, position: Int) { launch(UI) { val favourite = favourites[position]!! + holder.nameTextView.text = favourite.name holder.selectedOverlay.visibility = if (isSelected(position)) View.VISIBLE else View.INVISIBLE holder.moreButton.setOnClickListener { @@ -90,7 +91,6 @@ } else { nextDepartureText = appContext.getString(R.string.no_next_departure) nextDepartureLineText = "" } - holder.nameTextView.text = favourite.name holder.timeTextView.text = nextDepartureText holder.lineTextView.text = nextDepartureLineText if (nextDeparture != null) {