Author: Adam Pioterek <adam.pioterek@protonmail.ch>
vm
app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt | 2 app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt | 65 app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt | 7 app/src/main/java/ml/adamsprogs/bimba/models/DeparturesAdapter.kt | 26 app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt | 2 app/src/main/res/values-de/strings.xml | 1 app/src/main/res/values-it/strings.xml | 1 app/src/main/res/values-pl/strings.xml | 1 app/src/main/res/values/strings.xml | 1
diff --git a/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt b/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt index ea1b08cc58bf6bf9ae26d92616f29057e485ded5..9668aa001bce218cf2f16f22b1e70a19b4a8ff75 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt @@ -29,7 +29,7 @@ listener.onTimetableDownload(result) } } if (intent?.action == VmClient.ACTION_READY) { - val departures = intent.getStringArrayListExtra(VmClient.EXTRA_DEPARTURES)?.map { Departure.fromString(it) }?.toSet() as HashSet<Departure>? + val departures = intent.getStringArrayListExtra(VmClient.EXTRA_DEPARTURES)?.map { Departure.fromString(it) }?.toSet() val plateId = intent.getSerializableExtra(VmClient.EXTRA_PLATE_ID) as Plate.ID for (listener in onVmListeners) { listener.onVm(departures, plateId) 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 379fdcf5eabdc2bae0b4e879e65d338ac42f69c8..c6e9a118bfcd0d6ae14e5048e9884c5f35e56894 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt @@ -31,6 +31,7 @@ import ml.adamsprogs.bimba.getMode import ml.adamsprogs.bimba.models.gtfs.AgencyAndId import ml.adamsprogs.bimba.models.* import java.util.* +import kotlin.collections.ArrayList import kotlin.concurrent.thread class StopActivity : AppCompatActivity(), MessageReceiver.OnTimetableDownloadListener, MessageReceiver.OnVmListener, Favourite.OnVmPreparedListener { @@ -82,7 +83,7 @@ favourite!!.addOnVmPreparedListener(this) } } - sectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager, HashMap<AgencyAndId, ArrayList<Departure>>()) + sectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager, null) container.adapter = sectionsPagerAdapter @@ -102,9 +103,20 @@ refreshAdapter(favourite!!.allDepartures()) } } - private fun refreshAdapter(departures: Map<AgencyAndId, List<Departure>>) { + private fun refreshAdapterFromStop() { + val departures = HashMap<AgencyAndId, List<Departure>>() + if (this.vmDepartures.isNotEmpty()) { + departures[timetable.getServiceForToday()] = this.vmDepartures.flatMap { it.value }.sortedBy { it.timeTill(true) } + refreshAdapter(departures) + } else { + refreshAdapter(Departure.createDepartures(stopSegment!!.stop)) + hasDepartures = true + } + } - sectionsPagerAdapter?.departures = departures + private fun refreshAdapter(departures: Map<AgencyAndId, List<Departure>>?) { + if (departures != null) + sectionsPagerAdapter?.departures = departures runOnUiThread { sectionsPagerAdapter?.notifyDataSetChanged() selectTodayPage() @@ -167,14 +179,7 @@ if (vmDepartures != null) this.vmDepartures[plateId] = vmDepartures else this.vmDepartures.remove(plateId) - val departures = HashMap<AgencyAndId, List<Departure>>() - if (this.vmDepartures.isNotEmpty()) { - departures[timetable.getServiceForToday()] = this.vmDepartures.flatMap { it.value }.sortedBy { it.timeTill(true) } - refreshAdapter(departures) - } else { - refreshAdapter(Departure.createDepartures(stopSegment!!.stop)) - hasDepartures = true - } + refreshAdapterFromStop() } } @@ -219,7 +224,7 @@ timetableType = "departure" item.icon = (ResourcesCompat.getDrawable(resources, R.drawable.ic_timetable_full, this.theme)) sectionsPagerAdapter?.relativeTime = true if (sourceType == SOURCE_TYPE_STOP) - refreshAdapter(Departure.createDepartures(stopSegment!!.stop)) + refreshAdapterFromStop() else refreshAdapter(favourite!!.allDepartures()) } @@ -243,23 +248,27 @@ favourite!!.deregisterOnVm(receiver, context) unregisterReceiver(receiver) } - inner class SectionsPagerAdapter(fm: FragmentManager, var departures: Map<AgencyAndId, List<Departure>>) : FragmentStatePagerAdapter(fm) { + inner class SectionsPagerAdapter(fm: FragmentManager, var departures: Map<AgencyAndId, List<Departure>>?) : FragmentStatePagerAdapter(fm) { var relativeTime = true override fun getItem(position: Int): Fragment { - if (departures.isEmpty()) + if (departures == null) + return PlaceholderFragment.newInstance(null, relativeTime) + if (departures!!.isEmpty()) return PlaceholderFragment.newInstance(ArrayList(), relativeTime) val sat = timetable.getServiceFor("saturday") val sun = timetable.getServiceFor("sunday") val list: List<Departure> = when (position) { - 1 -> departures[sat]!! - 2 -> departures[sun]!! + 1 -> departures!![sat] ?: ArrayList() + 2 -> departures!![sun] ?: ArrayList() 0 -> try { - departures + departures!! .filter { it.key != sat && it.key != sun } .filter { it.value.isNotEmpty() }.toList()[0].second } catch (e: IndexOutOfBoundsException) { - departures.filter { it.key != sat && it.key != sun }.toList()[0].second + departures!!.filter { it.key != sat && it.key != sun }.toList()[0].second + } catch (e: Exception) { + ArrayList<Departure>() } else -> throw IndexOutOfBoundsException("No tab at index $position") } @@ -283,9 +292,9 @@ val rootView = inflater.inflate(R.layout.fragment_stop, container, false) val layoutManager = LinearLayoutManager(activity) val departuresList: RecyclerView = rootView.findViewById(R.id.departuresList) + val departures = arguments?.getStringArrayList("departures")?.map { Departure.fromString(it) } + if (departures != null && departures.isNotEmpty()) departuresList.addItemDecoration(DividerItemDecoration(departuresList.context, layoutManager.orientation)) - - val departures = arguments?.getStringArrayList("departures")!!.map { Departure.fromString(it) } departuresList.adapter = DeparturesAdapter(activity as Context, departures, @@ -295,15 +304,17 @@ return rootView } companion object { - fun newInstance(departures: List<Departure>, relativeTime: Boolean): PlaceholderFragment { + fun newInstance(departures: List<Departure>?, relativeTime: Boolean): PlaceholderFragment { val fragment = PlaceholderFragment() val args = Bundle() - if (departures.isNotEmpty()) { - val d = ArrayList<String>() - departures.mapTo(d) { it.toString() } - args.putStringArrayList("departures", d) - } else - args.putStringArrayList("departures", ArrayList<String>()) + if (departures != null){ + if (departures.isNotEmpty()) { + val d = ArrayList<String>() + departures.mapTo(d) { it.toString() } + args.putStringArrayList("departures", d) + } else + args.putStringArrayList("departures", ArrayList<String>()) + } args.putBoolean("relativeTime", relativeTime) fragment.arguments = args return fragment diff --git a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt b/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt index bca95c8095ea42c1ee18018bb09d082fba1f8a28..5fd92d1569833ad9b2ab4a035028c512757d4131 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt @@ -212,14 +212,15 @@ ArrayList(), it["direction"] as String, it["realTime"] as Boolean, departureDay != todayDay, it["onStopPoint"] as Boolean) departures.add(departure) } - } - val departuresForPlate = HashMap<AgencyAndId, HashSet<Departure>>() departuresForPlate[timetable.getServiceForToday()] = departures val vm = vms[plateId.stop] ?: HashSet() - vm.remove(vm.filter { it.id == plateId }[0]) //fixme outOfBound when vm is still empty (1st time) + try { + vm.remove(vm.filter { it.id == plateId }[0]) //fixme outOfBound when vm is still empty (1st time) + } catch (e: IndexOutOfBoundsException) { + } vm.add(Plate(plateId, departuresForPlate)) vms[plateId.stop] = vm if (departures.isEmpty()) diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/DeparturesAdapter.kt b/app/src/main/java/ml/adamsprogs/bimba/models/DeparturesAdapter.kt index 9396ef56f99e887052ee82ea9a8634eb5799a0ea..6317687b892755457d3b245a21d8890f7f93e0d3 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/DeparturesAdapter.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/DeparturesAdapter.kt @@ -15,29 +15,38 @@ import ml.adamsprogs.bimba.Declinator import ml.adamsprogs.bimba.rollTime import java.util.* -class DeparturesAdapter(val context: Context, private val departures: List<Departure>, private val relativeTime: Boolean) : +class DeparturesAdapter(val context: Context, private val departures: List<Departure>?, private val relativeTime: Boolean) : RecyclerView.Adapter<DeparturesAdapter.ViewHolder>() { companion object { const val VIEW_TYPE_LOADING: Int = 0 const val VIEW_TYPE_CONTENT: Int = 1 + const val VIEW_TYPE_EMPTY: Int = 2 } override fun getItemCount(): Int { - if (departures.isEmpty()) + if (departures == null || departures.isEmpty()) return 1 return departures.size } override fun getItemViewType(position: Int): Int { - return if (departures.isEmpty()) - VIEW_TYPE_LOADING - else - VIEW_TYPE_CONTENT + return when { + departures == null -> VIEW_TYPE_EMPTY + departures.isEmpty() -> VIEW_TYPE_LOADING + else -> VIEW_TYPE_CONTENT + } } override fun onBindViewHolder(holder: ViewHolder?, position: Int) { + if (departures == null) { + return + } + val line = holder?.lineTextView + val time = holder?.timeTextView + val direction = holder?.directionTextView if (departures.isEmpty()) { + time?.text = context.getString(R.string.no_departures) return } val departure = departures[position] @@ -50,18 +59,15 @@ val departureIn = (departureTime.timeInMillis - now.timeInMillis) / (1000 * 60) val timeString: String timeString = if (departureIn > 60 || departureIn < 0 || !relativeTime) - //todo shall we pad hour too? + //todo shall we pad hour too? context.getString(R.string.departure_at, "${departureTime.get(Calendar.HOUR_OF_DAY)}:${String.format("%02d", departureTime.get(Calendar.MINUTE))}") else if (departureIn > 0 && !departure.onStop) context.getString(Declinator.decline(departureIn), departureIn.toString()) else context.getString(R.string.now) - val line = holder?.lineTextView line?.text = departure.lineText - val time = holder?.timeTextView time?.text = timeString - val direction = holder?.directionTextView direction?.text = context.getString(R.string.departure_to, departure.direction) val icon = holder?.typeIcon if (departure.vm) 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 eb0766cbe163d61bf37d2779ec7c1f5f39c7ae64..39e57b475e9ac11356b7b488a2e27219edf3288b 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt @@ -167,7 +167,7 @@ tomorrowDepartures.forEach { twoDayDepartures.add(it) } return twoDayDepartures } - fun allDepartures(): Map<AgencyAndId, List<Departure>> { + fun allDepartures(): Map<AgencyAndId, List<Departure>> { // fixme departures through vm not the other way around val departures = timetable.getStopDepartures(timetables) as HashMap<AgencyAndId, ArrayList<Departure>> if (vmDepartures.isNotEmpty()) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 61c43b38e2e9e29a8f944db933f85064b7951fda..4c2aa3f1747ad8586be0a39eabe967f0247eb4df 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -74,4 +74,5 @@Refreshing cache. May take some time… <string name="timetable_converting">Converting timetable…</string> <string name="today">Today</string> + <string name="no_departures">No departures</string> </resources> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 47931966e5b73c7c0d12fb83d3f3d9db1c04dc8b..2abb8980791a787c5563600df7f64e06a15364c7 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -61,4 +61,5 @@ <string name="refreshing_cache">Cache wird aktualisiert. Es kann einige Zeit dauern…</string> <string name="timetable_converting">Fahrplan wird umgewandelt…</string> <string name="today">Heute</string> + <string name="no_departures">Keine Abfahrten</string> </resources> diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 295db1ba832686cee8de8844985921d37884e14b..aa491d2970b53e1f37797ab7b1a162f41a6c9e76 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -59,4 +59,5 @@ <string name="refreshing_cache">Cache sta essendo aggiornato. Può richiedere un certo tempo…</string> <string name="timetable_converting">L’orario e stando convertito</string> <string name="today">Oggi</string> + <string name="no_departures">Nessune partenze</string> </resources> diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 281bf8230bdb6dcb656d1d019b3502a76309f29d..8321a41a6027532bb5cb2ecd21df240ccf30ebd5 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -61,4 +61,5 @@Ważny do %1$s <string name="refreshing_cache">Odświeżanie pamięci podręcznej. Może chwilę potrwać…</string> <string name="timetable_converting">Konwertowanie rozkładu</string> <string name="today">Dzisiaj</string> + <string name="no_departures">Brak odjazdów</string> </resources> \ No newline at end of file