Bimba.git

commit e23a8539de29d538ff0ba8d3cb870c59c93fa79c

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) {