Author: Adam Pioterek <adam.pioterek@protonmail.ch>
favourites with vm
%!v(PANIC=String method: strings: negative Repeat count)
diff --git a/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt b/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt index 74c0a57f9d4a927528767567f96afe77bb248194..ac29fc4fceb1e21e7bb2767cf6d0572bf16d8264 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt @@ -3,6 +3,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import android.util.Log import ml.adamsprogs.bimba.models.Departure class MessageReceiver : BroadcastReceiver() { @@ -10,6 +11,7 @@ val onTimetableDownloadListeners: HashSet= HashSet() val onVmListeners: HashSet<OnVmListener> = HashSet() override fun onReceive(context: Context?, intent: Intent?) { + Log.i("Recv", "${intent?.action}") if (intent?.action == TimetableDownloader.ACTION_DOWNLOADED) { val result = intent.getStringExtra(TimetableDownloader.EXTRA_RESULT) for (listener in onTimetableDownloadListeners) { @@ -18,13 +20,17 @@ } } 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) + Log.i("VmRecv", "Got Vm for $requester") for (listener in onVmListeners) { - listener.onVm(departures) + listener.onVm(departures, requester) } } if (intent?.action == VmClient.ACTION_NO_DEPARTURES) { + val requester = intent.getStringExtra(VmClient.EXTRA_REQUESTER) + Log.i("VmRecv", "Got null for $requester") for (listener in onVmListeners) { - listener.onVm(null) + listener.onVm(null, requester) } } } @@ -50,6 +56,6 @@ fun onTimetableDownload(result: String?) } interface OnVmListener { - fun onVm(vmDepartures: ArrayList<Departure>?) + fun onVm(vmDepartures: ArrayList<Departure>?, requester: String) } } \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt b/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt index 86ab7c5b3c2becd0e5031c1af21e2930be46a83d..7a3dadf8b864f53b49addeddb997df0bd9c49cfc 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/VmClient.kt @@ -2,6 +2,7 @@ package ml.adamsprogs.bimba import android.app.IntentService import android.content.Intent +import android.util.Log import ml.adamsprogs.bimba.models.* import okhttp3.* import com.google.gson.Gson @@ -15,13 +16,19 @@ val ACTION_DEPARTURES_CREATED = "ml.adamsprogs.bimba.departuresCreated" val ACTION_NO_DEPARTURES = "ml.adamsprogs.bimba.noVM" val EXTRA_STOP_SYMBOL = "stopSymbol" val EXTRA_LINE_NUMBER = "lineNumber" + val EXTRA_REQUESTER = "requester" val EXTRA_DEPARTURES = "departures" } override fun onHandleIntent(intent: Intent?) { if (intent != null) { + val requester = intent.getStringExtra(EXTRA_REQUESTER) + + Log.i("VMClient", "starting vm for $requester") + if (!NetworkStateReceiver.isNetworkAvailable(this)) { - sendNullResult() + Log.i("VMClient", "offline") + sendNullResult(requester) return } @@ -42,7 +49,8 @@ val responseBody: String? try { responseBody = client.newCall(request).execute().body()?.string() } catch(e: IOException) { - sendNullResult() + Log.i("VMClient", "IO Err") + sendNullResult(requester) return } val javaRootMapObject = Gson().fromJson(responseBody, HashMap::class.java) @@ -64,26 +72,29 @@ departureDay != todayDay, t["onStopPoint"] as Boolean) departuresToday.add(departure) } } + Log.i("VMClient", "Sending") + departuresToday.forEach {Log.i("VMClient", "send: $it")} if (departuresToday.isEmpty()) - sendNullResult() + sendNullResult(requester) else - sendResult(departuresToday) - + sendResult(departuresToday, requester) } } - private fun sendNullResult() { + private fun sendNullResult(requester: String) { val broadcastIntent = Intent() broadcastIntent.action = ACTION_NO_DEPARTURES broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT) + broadcastIntent.putExtra(EXTRA_REQUESTER, requester) sendBroadcast(broadcastIntent) } - private fun sendResult(departures: ArrayList<Departure>) { + private fun sendResult(departures: ArrayList<Departure>, requester: String) { 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) 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 321c32db86b8d30e9a51ab80bdd300df2d59dbd5..4f2f7d19ea02042e944d687c3025a1f936a988ad 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt @@ -148,9 +148,22 @@ private fun createTimerTask() { timerTask = object : TimerTask() { override fun run() { + for (fav in favourites) { + fav.registerOnVm(receiver) + for (t in fav.timetables) { + val symbol = timetable.getStopSymbol(t[Favourite.TAG_STOP]!!) + val line = timetable.getLineNumber(t[Favourite.TAG_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_REQUESTER, + "${fav.name};${t[Favourite.TAG_STOP]}${t[Favourite.TAG_LINE]}") + context.startService(intent) + } + } + runOnUiThread { favouritesList.adapter.notifyDataSetChanged() - //todo vm } } } @@ -163,6 +176,8 @@ } private fun prepareOnDownloadListener() { val filter = IntentFilter(TimetableDownloader.ACTION_DOWNLOADED) + filter.addAction(VmClient.ACTION_DEPARTURES_CREATED) + filter.addAction(VmClient.ACTION_NO_DEPARTURES) filter.addCategory(Intent.CATEGORY_DEFAULT) registerReceiver(receiver, filter) receiver.addOnTimetableDownloadListener(context as MessageReceiver.OnTimetableDownloadListener) 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 3f1c27bd741334890ffc27d29a3015314e7d8b7c..3d8a2d320d9d10d1c84afa08d9e54022be81f941 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt @@ -22,6 +22,7 @@ companion object { val EXTRA_STOP_ID = "stopId" val EXTRA_STOP_SYMBOL = "stopSymbol" + val REQUESTER_ID = "stopActivity" } private lateinit var stopId: String @@ -51,7 +52,7 @@ prepareOnDownloadListener() timetable = Timetable.getTimetable() - supportActionBar?.title = timetable.getStopName(stopId) ?: "Stop" + supportActionBar?.title = timetable.getStopName(stopId) viewPager = findViewById(R.id.container) as ViewPager tabLayout = findViewById(R.id.tabs) as TabLayout @@ -96,6 +97,7 @@ timerTask = object : TimerTask() { override fun run() { val vmIntent = Intent(context, VmClient::class.java) vmIntent.putExtra(VmClient.EXTRA_STOP_SYMBOL, stopSymbol) + vmIntent.putExtra(VmClient.EXTRA_REQUESTER, REQUESTER_ID) startService(vmIntent) } } @@ -109,8 +111,8 @@ registerReceiver(receiver, filter) receiver.addOnVmListener(context as MessageReceiver.OnVmListener) } - override fun onVm(vmDepartures: ArrayList<Departure>?) { - if (timetableType == "departure") { + override fun onVm(vmDepartures: ArrayList<Departure>?, requester:String) { + if (timetableType == "departure" && requester == REQUESTER_ID) { val fullDepartures = Departure.createDepartures(stopId) if (vmDepartures != null) { fullDepartures[today.getMode()] = vmDepartures @@ -147,7 +149,7 @@ if (id == R.id.action_change_type) { if (timetableType == "departure") { timetableType = "full" item.icon = (ResourcesCompat.getDrawable(resources, R.drawable.ic_timetable_departure, this.theme)) - sectionsPagerAdapter?.departures = timetable.getStopDepartures(stopId)!! + sectionsPagerAdapter?.departures = timetable.getStopDepartures(stopId) sectionsPagerAdapter?.relativeTime = false sectionsPagerAdapter?.notifyDataSetChanged() timer.cancel() 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 97a303f74d08250922cae1bc1c2d08b16a0ad609..a5d9aec9bc7885788f50b9708ed9522134122f12 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt @@ -43,11 +43,11 @@ val departures = timetable.getStopDepartures(stopId) val moreDepartures = timetable.getStopDepartures(stopId) val rolledDepartures = HashMap<String, ArrayList<Departure>>() - for ((_, tomorrowDepartures) in moreDepartures!!) { + for ((_, tomorrowDepartures) in moreDepartures) { tomorrowDepartures.forEach { it.tomorrow = true } } - for ((mode, _) in departures!!) { + for ((mode, _) in departures) { rolledDepartures[mode] = (departures[mode] as ArrayList<Departure> + moreDepartures[mode] as ArrayList<Departure>) as ArrayList<Departure> rolledDepartures[mode] = filterDepartures(rolledDepartures[mode]) @@ -61,5 +61,17 @@ val array = string.split("|") return Departure(array[0], array[1], array[2], array[3] == "1", array[4], array[5], array[6] == "true", array[7] == "true", array[8] == "true") } + } + + fun timeTill(): Long { + val time = Calendar.getInstance() + time.set(Calendar.HOUR_OF_DAY, Integer.parseInt(this.time.split(":")[0])) + time.set(Calendar.MINUTE, Integer.parseInt(this.time.split(":")[1])) + time.set(Calendar.SECOND, 0) + time.set(Calendar.MILLISECOND, 0) + val now = Calendar.getInstance() + if (this.tomorrow) + time.add(Calendar.DAY_OF_MONTH, 1) + return (time.timeInMillis - now.timeInMillis) / (1000 * 60) } } \ No newline at end of file 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 976c01548a1079143e8f4ccbe5e8270fa4e1d462..828f537146df436aa4ec9c59e56ee1da81ad00e5 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt @@ -3,15 +3,39 @@ 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.* import kotlin.collections.ArrayList import kotlin.collections.HashMap -class Favourite : Parcelable { +class Favourite : Parcelable, MessageReceiver.OnVmListener { + override fun onVm(vmDepartures: ArrayList<Departure>?, requester: String) { + val requesterName = requester.split(";")[0] + var requesterTimetable: String + try { + requesterTimetable = requester.split(";")[1] + } catch (e: IndexOutOfBoundsException) { + requesterTimetable = "" + } + Log.i("VM", "got vm for $requesterName and my name is $name") + if (vmDepartures != null && requesterName == name) { + Log.i("VM", "so I’m adding") + vmDeparturesMap[requesterTimetable] = vmDepartures + this.vmDepartures = vmDeparturesMap.flatMap { it.value } as ArrayList<Departure> + } + Log.i("VM", "so I’m not adding") + filterVmDepartures() + } + + private var isRegisteredOnVmListener: Boolean = false var name: String + private set var timetables: ArrayList<HashMap<String, String>> + private set private var oneDayDepartures: ArrayList<HashMap<String, ArrayList<Departure>>>? = null + private val vmDeparturesMap = HashMap<String, ArrayList<Departure>>() + private var vmDepartures = ArrayList<Departure>() constructor(parcel: Parcel) { val array = ArrayList<String>() @@ -30,6 +54,7 @@ constructor(name: String, timetables: ArrayList<HashMap<String, String>>) { this.name = name this.timetables = timetables + } override fun describeContents(): Int { @@ -48,19 +73,28 @@ get() = timetables.size var nextDeparture: Departure? = null get() { - if (timetables.isEmpty()) + filterVmDepartures() + if (timetables.isEmpty() && vmDepartures.isEmpty()) return null + + Log.i("FAV", "vmDeps is empty? ${vmDepartures.isEmpty()} so") + if (vmDepartures.isNotEmpty()) { + val d = vmDepartures.minBy { it.timeTill() } + Log.i("FAV", "using vm: ${d.toString()}") + return d + } + + Log.i("FAV", "using offline") + val twoDayDepartures = ArrayList<Departure>() - val now = Calendar.getInstance() - val departureTime = Calendar.getInstance() - val today = now.getMode() + val today = Calendar.getInstance().getMode() val tomorrowCal = Calendar.getInstance() tomorrowCal.add(Calendar.DAY_OF_MONTH, 1) val tomorrow = tomorrowCal.getMode() if (oneDayDepartures == null) { oneDayDepartures = ArrayList<HashMap<String, ArrayList<Departure>>>() - timetables.mapTo(oneDayDepartures!!) { timetable.getStopDepartures(it[TAG_STOP] as String, it[TAG_LINE])!! } + timetables.mapTo(oneDayDepartures!!) { timetable.getStopDepartures(it[TAG_STOP] as String, it[TAG_LINE]) } } oneDayDepartures!!.forEach { @@ -79,29 +113,35 @@ if (twoDayDepartures.isEmpty()) return null - var minDeparture: Departure = twoDayDepartures[0] - var minInterval = 24 * 60L - for (departure in twoDayDepartures) { - departureTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(departure.time.split(":")[0])) - departureTime.set(Calendar.MINUTE, Integer.parseInt(departure.time.split(":")[1])) - if (departure.tomorrow) - departureTime.add(Calendar.DAY_OF_MONTH, 1) - val interval = (departureTime.timeInMillis - now.timeInMillis) / (1000 * 60) - if (interval in 0..(minInterval - 1)) { - minInterval = (departureTime.timeInMillis - now.timeInMillis) / (1000 * 60) - minDeparture = departure - } - } - - Log.i("preInterval", "$minInterval") - return minDeparture + return twoDayDepartures + .filter { it.timeTill() >= 0 } + .minBy { it.timeTill() } } private set + fun filterVmDepartures() { + this.vmDepartures + .filter { it.timeTill() < 0 } + .forEach { this.vmDepartures.remove(it) } + } + fun delete(stop: String, line: String) { Log.i("ROW", "Favourite deleting $stop, $line") timetables.remove(timetables.find { it[TAG_STOP] == stop && it[TAG_LINE] == line }) Log.i("ROW", timetables.toString()) + } + + fun registerOnVm(receiver: MessageReceiver) { + Log.i("FAV", "Shall register? ${!isRegisteredOnVmListener}") + if (!isRegisteredOnVmListener) { + Log.i("FAV", "registering") + receiver.addOnVmListener(this) + isRegisteredOnVmListener = true + } + } + + fun rename(newName: String) { + name = newName } companion object CREATOR : Parcelable.Creator<Favourite> { diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteEditRowAdapter.kt b/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteEditRowAdapter.kt index 336c547c2784a8796b9a6a02c2840ecca6016eb0..5672e0a5d124d93edd93d69fe76ac873a0c78c2f 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteEditRowAdapter.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteEditRowAdapter.kt @@ -22,7 +22,7 @@ favourite.timetables[position][Favourite.TAG_LINE]!!) holder?.rowTextView?.text = favouriteElement holder?.splitButton?.setOnClickListener { favourites.detach(favourite.name, favourite.timetables[position][Favourite.TAG_STOP]!!, - favourite.timetables[position][Favourite.TAG_LINE]!!, favouriteElement!!) + favourite.timetables[position][Favourite.TAG_LINE]!!, favouriteElement) favourite = favourites.favourites[favourite.name]!! notifyDataSetChanged() } 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 533ed3c316d3fbec75ca55c2163f07da656a54f9..2949ffb25807d7320416e2bf7247b6b6a8d35127 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt @@ -8,7 +8,7 @@ import com.google.gson.JsonArray import com.google.gson.JsonObject -class FavouriteStorage private constructor(context: Context) { +class FavouriteStorage private constructor(context: Context) : Iterable<Favourite> { companion object { private var favouriteStorage: FavouriteStorage? = null fun getFavouriteStorage(context: Context? = null): FavouriteStorage { @@ -23,6 +23,7 @@ } else return favouriteStorage as FavouriteStorage } } + val favourites = HashMap<String, Favourite>() val preferences: SharedPreferences = context.getSharedPreferences("ml.adamsprogs.bimba.prefs", Context.MODE_PRIVATE) val favouritesList: List<Favourite> @@ -44,6 +45,8 @@ } favourites[name] = Favourite(name, timetables) } } + + override fun iterator(): Iterator<Favourite> = favourites.values.iterator() fun has(name: String): Boolean = favourites.contains(name) @@ -103,7 +106,7 @@ delete(name, stop, line) } fun merge(names: ArrayList<String>) { - if (names.size < 2 ) + if (names.size < 2) return val newFavourite = Favourite(names[0], ArrayList<HashMap<String, String>>()) for (name in names) { @@ -117,7 +120,7 @@ } fun rename(oldName: String, newName: String) { val favourite = favourites[oldName] ?: return - favourite.name = newName + favourite.rename(newName) favourites.remove(oldName) favourites[newName] = favourite serialize() 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 4d3a236492c6fab3f6506a271f6bfb7aabc8ae4e..be2da2c0ebedf4b2a452871c3a8e73ff3b937627 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/FavouritesAdapter.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/FavouritesAdapter.kt @@ -3,14 +3,12 @@ import android.app.Activity import android.content.Context import android.os.Build -import android.support.v7.widget.CardView +import android.support.v4.content.res.ResourcesCompat +import android.support.v7.widget.* import android.support.v7.widget.PopupMenu -import android.support.v7.widget.RecyclerView import android.util.Log -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView +import android.view.* +import android.widget.* import ml.adamsprogs.bimba.R import android.view.LayoutInflater import java.util.* @@ -61,17 +59,14 @@ } val nextDepartureText: String val nextDepartureLineText: String if (nextDeparture != null) { - val now = Calendar.getInstance() - val departureTime = Calendar.getInstance() - departureTime.set(Calendar.HOUR_OF_DAY, Integer.parseInt(nextDeparture.time.split(":")[0])) - departureTime.set(Calendar.MINUTE, Integer.parseInt(nextDeparture.time.split(":")[1])) - if (nextDeparture.tomorrow) - departureTime.add(Calendar.DAY_OF_MONTH, 1) - val interval = ((departureTime.timeInMillis - now.timeInMillis) / (1000 * 60)) - Log.i("Interval", "$interval") - nextDepartureText = context.getString(Declinator.decline(interval), interval.toString()) //fixme -1 + Log.i("NEXT DEP", nextDeparture.toString()) + val interval = nextDeparture.timeTill() + if (interval < 0) + return@thread + nextDepartureText = context.getString(Declinator.decline(interval), interval.toString()) nextDepartureLineText = context.getString(R.string.departure_to_line, nextDeparture.line, nextDeparture.direction) } else { + //fixme too early nextDepartureText = context.getString(R.string.no_next_departure) nextDepartureLineText = "" } @@ -83,6 +78,12 @@ } holder?.nameTextView?.text = favourite.name holder?.timeTextView?.text = nextDepartureText holder?.lineTextView?.text = nextDepartureLineText + if(nextDeparture!=null) { + if (nextDeparture.vm) + holder?.typeIcon?.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_departure_vm, context.theme)) + else + holder?.typeIcon?.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_departure_timetable, context.theme)) + } holder?.moreButton?.setOnClickListener { unSelect(holder.root, position) val popup = PopupMenu(context, it) @@ -173,6 +174,7 @@ val nameTextView = itemView.findViewById(R.id.favourite_name) as TextView val timeTextView = itemView.findViewById(R.id.favourite_time) as TextView val lineTextView = itemView.findViewById(R.id.favourite_line) as TextView val moreButton = itemView.findViewById(R.id.favourite_more_button) as ImageView + val typeIcon = itemView.findViewById(R.id.departureTypeIcon) as ImageView } interface OnMenuItemClickListener { diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt index fb449ce4a9022308d23a7305aa12aeae0546c4cf..d77862ff8b8c28ad2712b5a33d985c280aa46963 100644 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt +++ b/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt @@ -14,7 +14,7 @@ val MODE_SATURDAYS = "saturdays" val MODE_SUNDAYS = "sundays" private var timetable: Timetable? = null - fun getTimetable(context: Context? = null, force: Boolean = false): Timetable{ + fun getTimetable(context: Context? = null, force: Boolean = false): Timetable { if (timetable == null || force) if (context != null) { val db: SQLiteDatabase? @@ -66,7 +66,7 @@ _stops = stops return stops } - fun getStopName(stopId: String): String? { + fun getStopName(stopId: String): String { val cursor = db.rawQuery("select name from nodes join stops on(stops.symbol = nodes.symbol) where id = ?;", listOf(stopId).toTypedArray()) val name: String @@ -76,7 +76,25 @@ cursor.close() return name } - fun getStopDepartures(stopId: String, lineId: String? = null, tomorrow: Boolean = false): HashMap<String, ArrayList<Departure>>? { + fun getStopSymbol(stopId: String): String { + val cursor = db.rawQuery("select symbol||number from stops where id = ?", listOf(stopId).toTypedArray()) + val symbol: String + cursor.moveToNext() + symbol = cursor.getString(0) + cursor.close() + return symbol + } + + fun getLineNumber(lineId: String): String { + val cursor = db.rawQuery("select number from lines where id = ?", listOf(lineId).toTypedArray()) + val number: String + cursor.moveToNext() + number = cursor.getString(0) + cursor.close() + return number + } + + fun getStopDepartures(stopId: String, lineId: String? = null, tomorrow: Boolean = false): HashMap<String, ArrayList<Departure>> { val andLine: String if (lineId == null) andLine = "" @@ -111,7 +129,7 @@ cursor.close() return lines } - fun getFavouriteElement(stop: String, line: String): String? { + fun getFavouriteElement(stop: String, line: String): String { val cursor = db.rawQuery("select name || ' (' || stops.symbol || stops.number || '): \n' " + "|| lines.number || ' → ' || headsign from timetables join stops on (stops.id = stop_id) " + "join lines on(lines.id = line_id) join nodes on(nodes.symbol = stops.symbol) where " + diff --git a/app/src/main/res/layout/row_departure.xml b/app/src/main/res/layout/row_departure.xml index d6b0a4371cce9c0c482bfb3c53e52a97724d6028..82ad610c4a49c3ee73231d57eddbc75f142d2815 100644 --- a/app/src/main/res/layout/row_departure.xml +++ b/app/src/main/res/layout/row_departure.xml @@ -1,57 +1,56 @@ <?xml version="1.0" encoding="utf-8"?> -<android.support.constraint.ConstraintLayout - xmlns:android="http://schemas.android.com/apk/res/android" +<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - tools:layout_editor_absoluteY="25dp" - tools:layout_editor_absoluteX="0dp"> + tools:layout_editor_absoluteX="0dp" + tools:layout_editor_absoluteY="25dp"> <TextView android:id="@+id/lineNumber" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginBottom="8dp" + android:layout_marginEnd="8dp" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" android:text="" android:textAppearance="@style/TextAppearance.AppCompat.Title" - app:layout_constraintStart_toStartOf="parent" - android:layout_marginStart="8dp" - app:layout_constraintTop_toTopOf="parent" - android:layout_marginTop="8dp" app:layout_constraintBottom_toBottomOf="parent" - android:layout_marginBottom="8dp" app:layout_constraintEnd_toStartOf="@+id/departureTime" - android:layout_marginEnd="8dp" /> + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/departureTypeIcon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:layout_marginTop="8dp" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" - android:contentDescription="@string/departure_type_icon_description" /> + android:layout_marginBottom="16dp" + android:layout_marginEnd="16dp" + android:contentDescription="@string/departure_type_icon_description" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" /> <TextView android:id="@+id/departureTime" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginStart="64dp" + android:layout_marginTop="8dp" android:text="" android:textAppearance="@style/TextAppearance.AppCompat.Headline" - android:layout_marginTop="8dp" - app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toEndOf="parent" - android:layout_marginStart="64dp" /> + app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/departureDirection" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginBottom="8dp" + android:layout_marginStart="64dp" android:text="" app:layout_constraintBottom_toBottomOf="parent" - android:layout_marginBottom="8dp" - app:layout_constraintTop_toBottomOf="@+id/departureTime" app:layout_constraintStart_toEndOf="parent" - android:layout_marginStart="64dp" /> + app:layout_constraintTop_toBottomOf="@+id/departureTime" /> </android.support.constraint.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/row_favourite.xml b/app/src/main/res/layout/row_favourite.xml index e2cae1cdc02502bde3c53a7f88fe934c64c36796..977dae12323f363cc40bd7491a237c147cbee81a 100644 --- a/app/src/main/res/layout/row_favourite.xml +++ b/app/src/main/res/layout/row_favourite.xml @@ -51,6 +51,16 @@ tools:layout_editor_absoluteX="16dp" tools:layout_editor_absoluteY="78dp" /> <ImageView + android:id="@+id/departureTypeIcon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="16dp" + android:layout_marginEnd="16dp" + android:contentDescription="@string/departure_type_icon_description" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" /> + + <ImageView android:id="@+id/favourite_more_button" android:layout_width="24dp" android:layout_height="24dp"