Bimba.git

commit 21e0cf7e22a8975e88a54e145dae8b2fc51aff45

Author: Adam Pioterek <adam.pioterek@protonmail.ch>

bugfix: VM works in full favourite

 .idea/misc.xml | 2 
 app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt | 21 
 app/src/main/java/ml/adamsprogs/bimba/TimetableDownloader.kt | 2 
 app/src/main/java/ml/adamsprogs/bimba/VmClient.kt | 28 
 app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt | 6 
 app/src/main/java/ml/adamsprogs/bimba/activities/NoDbActivity.kt | 2 
 app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt | 26 +
 app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt | 3 
 app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt | 43 +


diff --git a/.idea/misc.xml b/.idea/misc.xml
index 635999df1e86791ad3787e455b4524e4d8879b93..ba7052b8197ddf8ba8756022d905d03055c7ad60 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -24,7 +24,7 @@         
       </value>
     </option>
   </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>
   <component name="ProjectType">




diff --git a/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt b/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt
index 402e0b565b06a8eb16794fd3f7f6533e5cff5a00..0332f77894fdbf108b0b8b4f8dfaff92159c4e34 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt
@@ -5,7 +5,16 @@ import android.content.Context
 import android.content.Intent
 import ml.adamsprogs.bimba.models.Departure
 
-class MessageReceiver : BroadcastReceiver() {
+class MessageReceiver private constructor() : BroadcastReceiver() {
+    companion object {
+        private var receiver:MessageReceiver? = null
+        fun getMessageReceiver(): MessageReceiver {
+            if (receiver == null)
+                receiver = MessageReceiver()
+            return receiver as MessageReceiver
+        }
+    }
+
     private val onTimetableDownloadListeners: HashSet<OnTimetableDownloadListener> = HashSet()
     private val onVmListeners: HashSet<OnVmListener> = HashSet()
 
@@ -19,14 +28,18 @@         }
         if (intent?.action == VmClient.ACTION_DEPARTURES_CREATED) {
             val departures = intent.getStringArrayListExtra(VmClient.EXTRA_DEPARTURES).map { Departure.fromString(it) } as ArrayList<Departure>
             val requester = intent.getStringExtra(VmClient.EXTRA_REQUESTER)
+            val id = intent.getStringExtra(VmClient.EXTRA_ID)
+            val size = intent.getIntExtra(VmClient.EXTRA_SIZE, -1)
             for (listener in onVmListeners) {
-                listener.onVm(departures, requester)
+                listener.onVm(departures, requester, id, size)
             }
         }
         if (intent?.action == VmClient.ACTION_NO_DEPARTURES) {
             val requester = intent.getStringExtra(VmClient.EXTRA_REQUESTER)
+            val id = intent.getStringExtra(VmClient.EXTRA_ID)
+            val size = intent.getIntExtra(VmClient.EXTRA_SIZE, -1)
             for (listener in onVmListeners) {
-                listener.onVm(null, requester)
+                listener.onVm(null, requester, id, size)
             }
         }
     }
@@ -52,6 +65,6 @@         fun onTimetableDownload(result: String?)
     }
 
     interface OnVmListener {
-        fun onVm(vmDepartures: ArrayList<Departure>?, requester: String)
+        fun onVm(vmDepartures: ArrayList<Departure>?, requester: String, id: String, size: Int)
     }
 }
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/TimetableDownloader.kt b/app/src/main/java/ml/adamsprogs/bimba/TimetableDownloader.kt
index b5829717ca489d28aaa7b7a52dac4ce83d89371f..0a3c3a4c18ea63b371fd48371f9fd8dae21d9355 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/TimetableDownloader.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/TimetableDownloader.kt
@@ -43,7 +43,7 @@                 return
             }
             val metadataUrl = URL("https://adamsprogs.ml/w/_media/programmes/bimba/timetable.db.meta")
             var httpCon = metadataUrl.openConnection() as HttpURLConnection
-            if (httpCon.responseCode != HttpURLConnection.HTTP_OK) {
+            if (httpCon.responseCode != HttpURLConnection.HTTP_OK) { //IOEXCEPTION or EOFEXCEPTION or ConnectException
                 sendResult(RESULT_NO_CONNECTIVITY)
                 return
             }




diff --git a/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt b/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt
index 722abb0f13258d53eaab9b684a845b1376b4d49a..ec68bd9916247c8a329d1a2211cd5de1110bbf41 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt
@@ -17,20 +17,24 @@         val EXTRA_STOP_SYMBOL = "stopSymbol"
         val EXTRA_LINE_NUMBER = "lineNumber"
         val EXTRA_REQUESTER = "requester"
         val EXTRA_DEPARTURES = "departures"
+        val EXTRA_SIZE = "size"
+        val EXTRA_ID = "id"
     }
 
     override fun onHandleIntent(intent: Intent?) {
         if (intent != null) {
             val requester = intent.getStringExtra(EXTRA_REQUESTER)
+            val id = intent.getStringExtra(EXTRA_ID)
+            val size = intent.getIntExtra(EXTRA_SIZE, -1)
 
             if (!NetworkStateReceiver.isNetworkAvailable(this)) {
-                sendNullResult(requester)
+                sendNullResult(requester, id, size)
                 return
             }
 
             val stopSymbol = intent.getStringExtra(EXTRA_STOP_SYMBOL)
             if (stopSymbol == null) {
-                sendNullResult(requester)
+                sendNullResult(requester, id, size)
                 return
             }
             val lineNumber = intent.getStringExtra(EXTRA_LINE_NUMBER)
@@ -49,20 +53,20 @@
             val responseBody: String?
             try {
                 responseBody = client.newCall(request).execute().body()?.string()
-            } catch(e: IOException) {
-                sendNullResult(requester)
+            } catch (e: IOException) {
+                sendNullResult(requester, id, size)
                 return
             }
 
             if (responseBody?.get(0) == '<') {
-                sendNullResult(requester)
+                sendNullResult(requester, id, size)
                 return
             }
 
             val javaRootMapObject = Gson().fromJson(responseBody, HashMap::class.java)
             val times = (javaRootMapObject["success"] as Map<*, *>)["times"] as List<*>
             val date = Calendar.getInstance()
-            val todayDay = "${date.get(Calendar.DATE)}"
+            val todayDay = "${date.get(Calendar.DATE)}".padStart(2, '0')
             val todayMode = date.getMode()
             val departuresToday = ArrayList<Departure>()
             for (time in times) {
@@ -78,26 +82,30 @@                     departuresToday.add(departure)
                 }
             }
             if (departuresToday.isEmpty())
-                sendNullResult(requester)
+                sendNullResult(requester, id, size)
             else
-                sendResult(departuresToday, requester)
+                sendResult(departuresToday, requester, id, size)
         }
     }
 
-    private fun sendNullResult(requester: String) {
+    private fun sendNullResult(requester: String, id: String, size: Int) {
         val broadcastIntent = Intent()
         broadcastIntent.action = ACTION_NO_DEPARTURES
         broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT)
         broadcastIntent.putExtra(EXTRA_REQUESTER, requester)
+        broadcastIntent.putExtra(EXTRA_ID, id)
+        broadcastIntent.putExtra(EXTRA_SIZE, size)
         sendBroadcast(broadcastIntent)
     }
 
-    private fun sendResult(departures: ArrayList<Departure>, requester: String) {
+    private fun sendResult(departures: ArrayList<Departure>, requester: String, id: String, size: Int) {
         val broadcastIntent = Intent()
         broadcastIntent.action = ACTION_DEPARTURES_CREATED
         broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT)
         broadcastIntent.putStringArrayListExtra(EXTRA_DEPARTURES, departures.map { it.toString() } as java.util.ArrayList<String>)
         broadcastIntent.putExtra(EXTRA_REQUESTER, requester)
+        broadcastIntent.putExtra(EXTRA_ID, id)
+        broadcastIntent.putExtra(EXTRA_SIZE, size)
         sendBroadcast(broadcastIntent)
     }
 }




diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt
index 2c898aa2ecf98d97a50a5f2f686167f479e8076c..304f5a91338cc47924b9eb8a8f63babc9224e495 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt
@@ -25,7 +25,7 @@ class DashActivity : AppCompatActivity(), MessageReceiver.OnTimetableDownloadListener,
         FavouritesAdapter.OnMenuItemClickListener {
 
     val context: Context = this
-    val receiver = MessageReceiver()
+    val receiver = MessageReceiver.getMessageReceiver()
     lateinit var timetable: Timetable
     var stops: ArrayList<StopSuggestion>? = null
     private lateinit var drawerLayout: DrawerLayout
@@ -35,6 +35,7 @@     lateinit var searchView: FloatingSearchView
     lateinit var favourites: FavouriteStorage
     private var timer = Timer()
     private lateinit var timerTask: TimerTask
+    private var vmRequestId = 0
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -161,10 +162,13 @@                         val line = timetable.getLineNumber(t.line)
                         val intent = Intent(context, VmClient::class.java)
                         intent.putExtra(VmClient.EXTRA_STOP_SYMBOL, symbol)
                         intent.putExtra(VmClient.EXTRA_LINE_NUMBER, line)
+                        intent.putExtra(VmClient.EXTRA_ID, "fav-$vmRequestId")
+                        intent.putExtra(VmClient.EXTRA_SIZE, fav.timetables.size)
                         intent.putExtra(VmClient.EXTRA_REQUESTER,
                                 "${fav.name};${t.stop}${t.line}")
                         context.startService(intent)
                     }
+                    vmRequestId++
                 }
 
                 runOnUiThread {




diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/NoDbActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/NoDbActivity.kt
index e913730326bcc98b6a0e22a129ffafb4f4c46644..b4c1764983d6054eac57c058afa3ec3999338bd6 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/activities/NoDbActivity.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/activities/NoDbActivity.kt
@@ -9,7 +9,7 @@ import kotlinx.android.synthetic.main.activity_nodb.*
 
 class NoDbActivity : AppCompatActivity(), NetworkStateReceiver.OnConnectivityChangeListener, MessageReceiver.OnTimetableDownloadListener {
     private val networkStateReceiver = NetworkStateReceiver()
-    private val timetableDownloadReceiver = MessageReceiver()
+    private val timetableDownloadReceiver = MessageReceiver.getMessageReceiver()
     private var serviceRunning = false
     private var askedForNetwork = false
 




diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt
index 6df41f975f15c73a5a74bf640a89f46b93d6d26f..3276e3a99ba49d2965c73a1141a1066b805518b0 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt
@@ -42,7 +42,8 @@     private lateinit var tabLayout: TabLayout
     private var timer = Timer()
     private lateinit var timerTask: TimerTask
     private val context = this
-    private val receiver = MessageReceiver()
+    private val receiver = MessageReceiver.getMessageReceiver()
+    private var vmRequestId = 0
 
     private lateinit var sourceType: String
 
@@ -76,8 +77,13 @@         prepareOnDownloadListener()
 
         viewPager = container
         tabLayout = tabs
+        sectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager, null)
 
-        sectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager, null)
+
+        if (sourceType == SOURCE_TYPE_FAV) {
+            favourite!!.registerOnVm(receiver)
+        }
+
         thread {
             if (sourceType == SOURCE_TYPE_STOP) {
                 @Suppress("UNCHECKED_CAST")
@@ -102,6 +108,16 @@
         showFab()
     }
 
+    private fun getFavouriteDepartures() {
+        thread {
+            @Suppress("UNCHECKED_CAST")
+            sectionsPagerAdapter!!.departures = favourite!!.allDepartures() as HashMap<String, ArrayList<Departure>>
+        }
+        runOnUiThread {
+            sectionsPagerAdapter?.notifyDataSetChanged()
+        }
+    }
+
     private fun showFab() {
         if (sourceType == SOURCE_TYPE_FAV)
             return
@@ -133,6 +149,7 @@             override fun run() {
                 val vmIntent = Intent(context, VmClient::class.java)
                 vmIntent.putExtra(VmClient.EXTRA_STOP_SYMBOL, stopSymbol)
                 vmIntent.putExtra(VmClient.EXTRA_REQUESTER, REQUESTER_ID)
+                vmIntent.putExtra(VmClient.EXTRA_ID, "stop-${vmRequestId++}")
                 startService(vmIntent)
                 runOnUiThread {
                     sectionsPagerAdapter?.notifyDataSetChanged()
@@ -149,7 +166,7 @@         registerReceiver(receiver, filter)
         receiver.addOnVmListener(context as MessageReceiver.OnVmListener)
     }
 
-    override fun onVm(vmDepartures: ArrayList<Departure>?, requester: String) {
+    override fun onVm(vmDepartures: ArrayList<Departure>?, requester: String, id: String, size: Int) {
         if (timetableType == "departure" && requester == REQUESTER_ID && sourceType == SOURCE_TYPE_STOP) {
             @Suppress("UNCHECKED_CAST")
             val fullDepartures = Departure.createDepartures(stopId!!) as HashMap<String, ArrayList<Departure>>
@@ -158,6 +175,9 @@                 fullDepartures[today.getMode()] = vmDepartures
             }
             sectionsPagerAdapter?.departures = fullDepartures
             sectionsPagerAdapter?.notifyDataSetChanged()
+        }
+        if (timetableType == "departure" && requester == REQUESTER_ID && sourceType == SOURCE_TYPE_FAV) {
+            getFavouriteDepartures()
         }
     }
 




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt
index 1b5a3d9e7412c48dfb55ccd93e9b0a6273e80033..778d3ef55968479a22f8d0b70ca64042c2d55281 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt
@@ -1,5 +1,6 @@
 package ml.adamsprogs.bimba.models
 
+import android.util.Log
 import java.util.*
 import kotlin.collections.ArrayList
 import kotlin.collections.HashMap
@@ -43,7 +44,7 @@             val departures = timetable.getStopDepartures(stopId)
             return createDepartures(departures)
         }
 
-        fun createDepartures(departures: Map<String, List<Departure>>): Map<String, List<Departure>> {
+        fun createDepartures(departures: Map<String, List<Departure>>): Map<String, List<Departure>> { //todo if departure.timeTill < 0 -> show ‘just departed’
             val moreDepartures = HashMap<String, ArrayList<Departure>>()
             for ((k, v) in departures) {
                 moreDepartures[k] = ArrayList()




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 3fde22b5c600605f48991d54ef70a3bdad5b6409..1d4ccfd33f58e46ab35d3a54ce615dbc81dacb60 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt
@@ -2,6 +2,7 @@ package ml.adamsprogs.bimba.models
 
 import android.os.Parcel
 import android.os.Parcelable
+import android.util.Log
 import ml.adamsprogs.bimba.MessageReceiver
 import ml.adamsprogs.bimba.getMode
 import java.util.*
@@ -20,6 +21,9 @@     private var vmDepartures = ArrayList()
     val timetable = Timetable.getTimetable()
     val size: Int
         get() = timetables.size
+
+    private val requestValidityNumber = HashMap<String, Int>()
+    private val requestValidity = HashMap<String, Boolean>()
 
     constructor(parcel: Parcel) {
         val array = ArrayList<String>()
@@ -106,34 +110,57 @@         val departures = timetable.getStopDepartures(timetables)
         val todayDepartures = departures[today]!!
         val tomorrowDepartures = ArrayList<Departure>()
         val twoDayDepartures = ArrayList<Departure>()
-        departures[tomorrow]!!.mapTo(tomorrowDepartures) {it.copy()}
-        tomorrowDepartures.forEach {it.tomorrow = true}
+        departures[tomorrow]!!.mapTo(tomorrowDepartures) { it.copy() }
+        tomorrowDepartures.forEach { it.tomorrow = true }
 
-        todayDepartures.forEach {twoDayDepartures.add(it)}
-        tomorrowDepartures.forEach {twoDayDepartures.add(it)}
+        todayDepartures.forEach { twoDayDepartures.add(it) }
+        tomorrowDepartures.forEach { twoDayDepartures.add(it) }
         return twoDayDepartures
     }
 
     fun allDepartures(): Map<String, List<Departure>> {
-        return Departure.createDepartures(timetable.getStopDepartures(timetables))
+        val departures = timetable.getStopDepartures(timetables) as HashMap<String, ArrayList<Departure>>
+
+        Log.i("Fav", "$vmDepartures")
+        if (vmDepartures.isNotEmpty()) {
+            val today = Calendar.getInstance().getMode()
+            departures[today] = vmDepartures
+        }
+
+        return Departure.createDepartures(departures)
     }
 
     fun fullTimetable(): Map<String, List<Departure>>? {
         return timetable.getStopDepartures(timetables)
     }
 
-    override fun onVm(vmDepartures: ArrayList<Departure>?, requester: String) {
+    override fun onVm(vmDepartures: ArrayList<Departure>?, requester: String, id: String, size: Int) {
         val requesterName = requester.split(";")[0]
         val requesterTimetable: String = try {
             requester.split(";")[1]
         } catch (e: IndexOutOfBoundsException) {
             ""
         }
+
+        if (!requestValidity.containsKey(id)) {
+            requestValidity[id] = false
+            requestValidityNumber[id] = 0
+        }
         if (vmDepartures != null && requesterName == name) {
             vmDeparturesMap[requesterTimetable] = vmDepartures
             this.vmDepartures = vmDeparturesMap.flatMap { it.value } as ArrayList<Departure>
-        } else
-            this.vmDepartures = ArrayList()
+            requestValidity[id] = true
+            requestValidityNumber[id] = requestValidityNumber[id]!! + 1
+        } else if (requesterName == name) {
+            requestValidityNumber[id] = requestValidityNumber[id]!! + 1
+        }
+        if (requestValidityNumber[id] == size) {
+            if (!requestValidity[id]!!) {
+                this.vmDepartures = ArrayList()
+            }
+            requestValidity.remove(id)
+            requestValidityNumber.remove(id)
+        }
         filterVmDepartures()
     }
 }