Author: Adam Evyčędo <git@apiote.xyz>
add transitous departures
%!v(PANIC=String method: strings: negative Repeat count)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 91096abf593d7294f7fb9a4c254b0b069b7e539e..7f86f61f618002f8ad0f054cf998b1ef07de87e2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -39,8 +39,8 @@ resValue("string", "applicationId", applicationId) } compileOptions { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 isCoreLibraryDesugaringEnabled = true } diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/queryables.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/queryables.kt deleted file mode 100644 index fe0b7bde7d55f820581244d91dd74a775ab0b19f..0000000000000000000000000000000000000000 --- a/app/src/main/java/xyz/apiote/bimba/czwek/api/queryables.kt +++ /dev/null @@ -1,125 +0,0 @@ -package xyz.apiote.bimba.czwek.api - -import android.content.Context -import android.os.Build -import android.util.JsonReader -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import xyz.apiote.bimba.czwek.R -import xyz.apiote.bimba.czwek.api.responses.ErrorResponse -import xyz.apiote.bimba.czwek.repo.Position -import xyz.apiote.bimba.czwek.repo.Queryable -import xyz.apiote.bimba.czwek.repo.Stop -import xyz.apiote.bimba.czwek.repo.TrafficResponseException -import java.io.IOException -import java.net.HttpURLConnection -import java.net.URL - -suspend fun getTransitousQueryables(query: String, context: Context): List<Queryable> { - if (!isNetworkAvailable(context)) { - throw TrafficResponseException(0, "", Error(0, R.string.error_offline, R.drawable.error_net)) - } - - val json = """ - { - "destination": { - "type": "Module", - "target": "/guesser" - }, - "content_type": "StationGuesserRequest", - "content": { - "input": "$query", - "guess_count": 6 - } - }""" - val result = withContext(Dispatchers.IO) { - val url = URL("https://routing.spline.de/api/") - val c = (url.openConnection() as HttpURLConnection).apply { - setRequestProperty( - "User-Agent", - "${context.getString(R.string.applicationId)}/${context.getString(R.string.versionName)} (${Build.VERSION.SDK_INT})" - ) - addRequestProperty("Content-Type", "application/json") - requestMethod = "POST" - doOutput = true - outputStream.write(json.toByteArray()) - } - try { - if (c.responseCode == 200) { - Result(c.inputStream, null) - } else { - val (string, image) = mapHttpError(c.responseCode) - Result(c.errorStream, Error(c.responseCode, string, image)) - } - } catch (e: IOException) { - Result(null, Error(0, R.string.error_connecting, R.drawable.error_server)) - } - } - - if (result.error != null) { - if (result.stream != null) { - val response = withContext(Dispatchers.IO) { ErrorResponse.unmarshal(result.stream) } - throw TrafficResponseException(result.error.statusCode, response.message, result.error) - } else { - throw TrafficResponseException(result.error.statusCode, "", result.error) - } - } else { - return withContext(Dispatchers.IO) { - val queryables = mutableListOf<Queryable>() - val r = JsonReader(result.stream!!.bufferedReader()) - r.beginObject() - while (r.hasNext()) { - val rootFieldName = r.nextName() // content - if (rootFieldName == "content") { - r.beginObject() - r.nextName() // guesses - r.beginArray() - while (r.hasNext()) { - var id = "" - var name = "" - var latitude = 0.0 - var longitude = 0.0 - r.beginObject() - while (r.hasNext()) { - val fieldName = r.nextName() - when (fieldName) { - "id" -> id = r.nextString() - "name" -> name = r.nextString() - "pos" -> { - r.beginObject() - while (r.hasNext()) { - val positionFieldName = r.nextName() - when (positionFieldName) { - "lat" -> latitude = r.nextDouble() - "lng" -> longitude = r.nextDouble() - } - } - r.endObject() - } - } - } - r.endObject() - queryables.add( - Stop( - code = id, - name = name, - nodeName = name, - zone = "", - feedID = "transitous", - position = Position(latitude = latitude, longitude = longitude), - changeOptions = emptyList() - ) - ) - } - r.endArray() - r.endObject() - } else { - r.skipValue() - } - } - r.endObject() - - return@withContext queryables - } - } -} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/settings.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/settings.kt deleted file mode 100644 index 2e53c8f207147ae333a35de77d9854e0e3c2c4e6..0000000000000000000000000000000000000000 --- a/app/src/main/java/xyz/apiote/bimba/czwek/api/settings.kt +++ /dev/null @@ -1,8 +0,0 @@ -package xyz.apiote.bimba.czwek.api - -import android.content.Context -import androidx.preference.PreferenceManager - -fun isTransitousEnabled(context: Context): Boolean { - return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("transitous_enabled", false) -} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/transitous.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/transitous.kt index 4c6e3eeeab7d96968d1041e248f5aa80c61feb91..e566210b9774cd999d009f32c9b501433dfdf403 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/api/transitous.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/api/transitous.kt @@ -37,4 +37,4 @@ } catch (e: IOException) { Result(null, Error(0, R.string.error_connecting, R.drawable.error_server)) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousDepartures.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousDepartures.kt index ae907d44738c5b7f79e98c31e48bfe6baef69ca5..66fa6ae249f756a186b7405f5794b29726efd1db 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousDepartures.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousDepartures.kt @@ -278,4 +278,4 @@ f(i) i++ } endArray() -} \ No newline at end of file +} diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousQueryables.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousQueryables.kt index b76c39cdaf563c228ecbc91128e104282fe603c9..1397e0c211c2b4109a72c05b554404717cdb9874 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousQueryables.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousQueryables.kt @@ -191,4 +191,4 @@ r.endObject() return@withContext queryables } } -} \ No newline at end of file +} diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousSettings.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousSettings.kt index b976816c7ce659a9814b7b8a44dbca884ef30ffd..b135a0c210d068dcde94ba25b825e54ded1ea350 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousSettings.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/api/transitousSettings.kt @@ -9,4 +9,4 @@ import androidx.preference.PreferenceManager fun isTransitousEnabled(context: Context): Boolean { return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("transitous_enabled", false) -} \ No newline at end of file +} diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Colour.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Colour.kt index 49d071f82a3db9cb92cc640eb441c6263a570a5a..4b740bd0b13df60606a1ab0eec3e0f1e884a2a39 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Colour.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Colour.kt @@ -16,4 +16,19 @@ rgb = (rgb shl 8) + G.toInt() rgb = (rgb shl 8) + B.toInt() return rgb } + + companion object { + fun fromHex(hex: String): Colour { + return hex.removePrefix("#").let { + if (it.isEmpty()) { + Colour(255u, 255u, 255u) + } else { + val r = it.substring(0 until 2).toUByte(16) + val g = it.substring(2 until 4).toUByte(16) + val b = it.substring(4 until 6).toUByte(16) + Colour(r, g, b) + } + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Interfaces.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Interfaces.kt index 95fa5fa0c75f0c3e765eefd64c22091021260eb8..a337b0178c144f066ffea44ebd3898c475d850c0 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Interfaces.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Interfaces.kt @@ -9,7 +9,9 @@ import android.graphics.drawable.Drawable import xyz.apiote.bimba.czwek.api.Server import java.time.LocalDate -interface Queryable +interface Queryable { + fun location(): Position? +} interface Locatable { fun icon(context: Context, scale: Float = 1f): Drawable fun location(): Position diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Line.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Line.kt index 7a28e2b3e2128782b096ffc2744719151997fe65..6e7822ae6190905832576ddb5d78fd01a8bb1576 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Line.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Line.kt @@ -53,4 +53,8 @@ fun icon(context: Context, scale: Float = 1f): Drawable { return BitmapDrawable(context.resources, super.icon(context, type, colour, scale)) } + + override fun location(): Position? { + return null + } } \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/LineAbstract.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/LineAbstract.kt index db2525fa84c91a88fb53b7d6c1b40de93540f8d7..8cfbfc83fdca77fbde3ae8077f613596bc0317cf 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/LineAbstract.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/LineAbstract.kt @@ -72,6 +72,7 @@ LineType.CABLE_CAR -> R.drawable.cabletram_black LineType.FUNICULAR -> R.drawable.funicular_black LineType.MONORAIL -> R.drawable.monorail_black LineType.UNKNOWN -> R.drawable.vehicle_black + LineType.PLANE -> R.drawable.plane_black } val icon = AppCompatResources.getDrawable(context, iconID)?.mutate()?.apply { setTint(textColour(colour)) diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/LineType.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/LineType.kt index 8dca46f48cb8703d00c19d9a86e0c2dd246dece4..46be84493816f7bcf0e5e8d25416344dc81b6172 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/LineType.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/LineType.kt @@ -9,7 +9,7 @@ import xyz.apiote.bimba.czwek.api.LineTypeV2 import xyz.apiote.bimba.czwek.api.LineTypeV3 enum class LineType { - UNKNOWN, TRAM, BUS, TROLLEYBUS, METRO, RAIL, FERRY, CABLE_TRAM, CABLE_CAR, FUNICULAR, MONORAIL; + UNKNOWN, TRAM, BUS, TROLLEYBUS, METRO, RAIL, FERRY, CABLE_TRAM, CABLE_CAR, FUNICULAR, MONORAIL, PLANE; companion object { fun of(t: LineTypeV1): LineType { @@ -40,6 +40,25 @@ LineTypeV3.CABLE_TRAM -> valueOf("CABLE_TRAM") LineTypeV3.CABLE_CAR -> valueOf("CABLE_CAR") LineTypeV3.FUNICULAR -> valueOf("FUNICULAR") LineTypeV3.MONORAIL -> valueOf("MONORAIL") + } + } + + fun fromTransitous(clasz: Int): LineType { + return when (clasz) { + 0 -> PLANE + 1 -> RAIL + 2 -> RAIL + 3 -> BUS + 4 -> RAIL + 5 -> RAIL + 6 -> RAIL + 7 -> METRO + 8 -> METRO + 9 -> TRAM + 10 -> BUS + 11 -> FERRY + 12 -> UNKNOWN // other + else -> UNKNOWN } } } diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/OfflineRepository.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/OfflineRepository.kt index f8126a10ef5aafae21a5afbbc30bbcca87a1f49e..b11a5dfcccc9048e0390e0dfe9ad530e875a7668 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/OfflineRepository.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/OfflineRepository.kt @@ -16,6 +16,7 @@ import xyz.apiote.fruchtfleisch.Writer import java.io.File import java.net.URLEncoder import java.time.LocalDate +import xyz.apiote.bimba.czwek.R class OfflineRepository(context: Context) : Repository { private val db = @@ -103,9 +104,21 @@ s } // XXX `on conflict` is not supported on older versions of Android - val cursor = db.rawQuery("select * from favourites where feed_id = ? and stop_code = ?", arrayOf(favourite.feedID, favourite.stopCode)) + val cursor = db.rawQuery( + "select * from favourites where feed_id = ? and stop_code = ?", + arrayOf(favourite.feedID, favourite.stopCode) + ) if (cursor.count > 0) { - db.execSQL("update favourites set stop_name = ?, lines = ?, sequence = ? where feed_id = ? and stop_code = ?", arrayOf(favourite.stopName, favourite.lines.joinToString(separator = "||"), favourite.sequence, favourite.feedID, favourite.stopCode)) + db.execSQL( + "update favourites set stop_name = ?, lines = ?, sequence = ? where feed_id = ? and stop_code = ?", + arrayOf( + favourite.stopName, + favourite.lines.joinToString(separator = "||"), + favourite.sequence, + favourite.feedID, + favourite.stopCode + ) + ) } else { db.execSQL( "insert into favourites(sequence, feed_id, feed_name, stop_code, stop_name, lines) values (?, ?,?,?,?,?)", @@ -162,7 +175,23 @@ if (version.toUInt() != FeedInfo.VERSION) { saveFeedCache(context, feeds) } } - return feeds + val feedsWithTransitous = feeds.toMutableMap() + feedsWithTransitous.put( + "transitous", FeedInfo( + "transitous", + "Transitous", + context.getString(R.string.transitous_description), + context.getString(R.string.transitous_attribution), + LocalDate.now(), + "", + QrLocation.NONE, + "", + null, + null, + false + ) + ) + return feedsWithTransitous } override suspend fun getDepartures( diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/OnlineRepository.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/OnlineRepository.kt index 6255bb1ab1f911681dd3577064d557f01667a668..64f5498c6cdb53cc8340ee59a386083a6233db8b 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/OnlineRepository.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/OnlineRepository.kt @@ -7,6 +7,7 @@ import android.content.Context import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import xyz.apiote.bimba.czwek.R import xyz.apiote.bimba.czwek.api.LineV1 import xyz.apiote.bimba.czwek.api.LineV2 import xyz.apiote.bimba.czwek.api.LineV3 @@ -19,6 +20,9 @@ import xyz.apiote.bimba.czwek.api.UnknownResourceException import xyz.apiote.bimba.czwek.api.VehicleV1 import xyz.apiote.bimba.czwek.api.VehicleV2 import xyz.apiote.bimba.czwek.api.VehicleV3 +import xyz.apiote.bimba.czwek.api.getTransitousDepartures +import xyz.apiote.bimba.czwek.api.getTransitousQueryables +import xyz.apiote.bimba.czwek.api.locateTransitousQueryables import xyz.apiote.bimba.czwek.api.responses.DeparturesResponse import xyz.apiote.bimba.czwek.api.responses.DeparturesResponseDev import xyz.apiote.bimba.czwek.api.responses.DeparturesResponseV1 @@ -46,7 +50,6 @@ import xyz.apiote.bimba.czwek.api.responses.QueryablesResponseV1 import xyz.apiote.bimba.czwek.api.responses.QueryablesResponseV2 import xyz.apiote.bimba.czwek.api.responses.QueryablesResponseV3 import xyz.apiote.bimba.czwek.api.responses.QueryablesResponseV4 -import xyz.apiote.bimba.czwek.api.getTransitousQueryables import java.time.LocalDate // todo [3.2] in Repository check if responses are BARE or HTML @@ -83,7 +86,7 @@ throw TrafficResponseException(result.error.statusCode, "", result.error) } } else { val rawResponse = result.stream!!.readBytes() - return when (val response = + val feeds = when (val response = withContext(Dispatchers.IO) { FeedsResponse.unmarshal(rawResponse.inputStream()) }) { is FeedsResponseDev -> response.feeds.associate { Pair(it.id, FeedInfo(it)) } is FeedsResponseV2 -> response.feeds.associate { Pair(it.id, FeedInfo(it)) } @@ -91,6 +94,16 @@ is FeedsResponseV1 -> response.feeds.associate { Pair(it.id, FeedInfo(it)) } else -> null } + val feedsWithTransitous = feeds?.toMutableMap() + feedsWithTransitous?.put( + "transitous", FeedInfo( + "transitous", "Transitous", + context.getString(R.string.transitous_description), + context.getString(R.string.transitous_attribution), + LocalDate.now(), "", QrLocation.NONE, "", null, null, false + ) + ) + return feedsWithTransitous } } @@ -101,8 +114,10 @@ date: LocalDate?, context: Context, limit: Int? ): StopDepartures? { - val result = - xyz.apiote.bimba.czwek.api.getDepartures( + return if (feedID == "transitous") { + getTransitousDepartures(context, stop, date, limit) + } else { + val result = xyz.apiote.bimba.czwek.api.getDepartures( context, Server.get(context), feedID, @@ -110,42 +125,44 @@ stop, date, limit ) - if (result.error != null) { - if (result.stream != null) { - val response = withContext(Dispatchers.IO) { ErrorResponse.unmarshal(result.stream) } - throw TrafficResponseException(result.error.statusCode, response.message, result.error) + + if (result.error != null) { + if (result.stream != null) { + val response = withContext(Dispatchers.IO) { ErrorResponse.unmarshal(result.stream) } + throw TrafficResponseException(result.error.statusCode, response.message, result.error) + } else { + throw TrafficResponseException(result.error.statusCode, "", result.error) + } } else { - throw TrafficResponseException(result.error.statusCode, "", result.error) - } - } else { - return when (val response = - withContext(Dispatchers.IO) { DeparturesResponse.unmarshal(result.stream!!) }) { - is DeparturesResponseDev -> StopDepartures( - response.departures.map { Departure(it) }, - Stop(response.stop), - response.alerts.map { Alert(it) }) + when (val response = + withContext(Dispatchers.IO) { DeparturesResponse.unmarshal(result.stream!!) }) { + is DeparturesResponseDev -> StopDepartures( + response.departures.map { Departure(it) }, + Stop(response.stop), + response.alerts.map { Alert(it) }) - is DeparturesResponseV4 -> StopDepartures( - response.departures.map { Departure(it) }, - Stop(response.stop), - response.alerts.map { Alert(it) }) + is DeparturesResponseV4 -> StopDepartures( + response.departures.map { Departure(it) }, + Stop(response.stop), + response.alerts.map { Alert(it) }) - is DeparturesResponseV3 -> StopDepartures( - response.departures.map { Departure(it) }, - Stop(response.stop), - response.alerts.map { Alert(it) }) + is DeparturesResponseV3 -> StopDepartures( + response.departures.map { Departure(it) }, + Stop(response.stop), + response.alerts.map { Alert(it) }) - is DeparturesResponseV2 -> StopDepartures( - response.departures.map { Departure(it) }, - Stop(response.stop), - response.alerts.map { Alert(it) }) + is DeparturesResponseV2 -> StopDepartures( + response.departures.map { Departure(it) }, + Stop(response.stop), + response.alerts.map { Alert(it) }) - is DeparturesResponseV1 -> StopDepartures( - response.departures.map { Departure(it) }, - Stop(response.stop), - response.alerts.map { Alert(it) }) + is DeparturesResponseV1 -> StopDepartures( + response.departures.map { Departure(it) }, + Stop(response.stop), + response.alerts.map { Alert(it) }) - else -> null + else -> null + } } } } @@ -235,12 +252,16 @@ override suspend fun queryQueryables( query: String, context: Context ): List<Queryable>? { - val transitousQueryables = //if (isTransitousEnabled(context)) { + val transitousQueryables = if (Server.get(context).feeds.transitousEnabled()) { getTransitousQueryables(query, context) - /*} else { + } else { + null + } + val bimbaQueryables = if (Server.get(context).feeds.bimbaEnabled()) { + getQueryables(query, null, context, "query") + } else { null - }*/ - val bimbaQueryables = getQueryables(query, null, context, "query") + } return if (transitousQueryables == null && bimbaQueryables == null) { null } else { @@ -251,7 +272,23 @@ override suspend fun locateQueryables( position: Position, context: Context ): List<Queryable>? { - return getQueryables(null, position, context, "locate") + val transitousQueryables = if (Server.get(context).feeds.transitousEnabled()) { + locateTransitousQueryables(position, context) + } else { + null + } + val bimbaQueryables = if (Server.get(context).feeds.bimbaEnabled()) { + getQueryables(null, position, context, "locate") + } else { + null + } + return if (transitousQueryables == null && bimbaQueryables == null) { + null + } else { + (transitousQueryables ?: listOf()) + (bimbaQueryables ?: listOf()).sortedBy { + it.location()?.distanceTo(position) ?: 0f + } + } } private suspend fun getQueryables( diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Position.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Position.kt index 9b912930f830eb23cee2c74075c318b68186d713..d03cf34ae8cb789df7e078f0f24c509e63343a12 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Position.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Position.kt @@ -4,11 +4,22 @@ // SPDX-License-Identifier: GPL-3.0-or-later package xyz.apiote.bimba.czwek.repo +import android.location.Location import xyz.apiote.bimba.czwek.api.PositionV1 data class Position(val latitude: Double, val longitude: Double) { constructor(p: PositionV1) : this(p.latitude, p.longitude) fun isZero(): Boolean { return latitude == 0.0 && longitude == 0.0 + } + + fun distanceTo(other: Position): Float { + return Location(null).apply { + latitude = this@Position.latitude + longitude = this@Position.longitude + }.distanceTo(Location(null).apply { + latitude = other.latitude + longitude = other.longitude + }) } } \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt b/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt index a13611c7ee852e3421c01a0bdc651128d0ef2d6f..57d79cf7d143b6290b74b68ef7848fc69bb782b4 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt @@ -139,7 +139,7 @@ setImageDrawable(stop.icon(context!!)) contentDescription = context.getString(R.string.stop_content_description) } holder?.title?.text = stop.name - if ((feedsSettings?.activeFeedsCount() ?: 0) > 1) { + if ((feedsSettings?.activeFeedsCount() ?: 0) > 1 || (stop.feedID ?: "") == "transitous") { holder?.feedName?.visibility = View.VISIBLE holder?.feedName?.text = feeds?.get(stop.feedID)?.name ?: "" } diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedSettings.kt b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedSettings.kt index 31c0bcd141c540e1b70d418b402b6859ee6a9199..0407d15f16954e42e900ebad7f43b6e268603eec 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedSettings.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedSettings.kt @@ -17,7 +17,9 @@ @OptIn(ExperimentalStdlibApi::class) data class FeedsSettings(val settings: MutableMap<String, FeedSettings>) { fun activeFeedsCount() = settings.count { it.value.enabled && it.value.useOnline } fun activeFeeds() = settings.filter { it.value.enabled && it.value.useOnline }.keys - fun getIDs() = activeFeeds().joinToString(",") + fun getIDs() = activeFeeds().filter { it != "transitous" }.joinToString(",") + fun transitousEnabled() = activeFeeds().contains("transitous") + fun bimbaEnabled() = activeFeeds().filter { it != "transitous" }.isNotEmpty() fun save(context: Context, server: Server) { val doc = KBson().dump(serializer(), this).toHexString() diff --git a/app/src/main/res/layout/feed_bottom_sheet.xml b/app/src/main/res/layout/feed_bottom_sheet.xml index 97c3bd552d9fd51347bba2fa92c98a0068714e9a..f6acca2b1fd45853063220c1f049100a84beb0bb 100644 --- a/app/src/main/res/layout/feed_bottom_sheet.xml +++ b/app/src/main/res/layout/feed_bottom_sheet.xml @@ -60,9 +60,9 @@android:id="@+id/onlineOfflineDivider" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginTop="16dp" app:dividerInsetEnd="16dp" app:dividerInsetStart="16dp" - android:layout_marginTop="16dp" app:layout_constraintTop_toBottomOf="@+id/onlineSwitch" /> <com.google.android.material.textview.MaterialTextView @@ -71,8 +71,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:text="@string/information_may_be_outdated" - android:textStyle="italic" android:textAppearance="@style/TextAppearance.Material3.BodySmall" + android:textStyle="italic" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/onlineOfflineDivider" /> @@ -82,8 +82,9 @@ android:id="@+id/description" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" + android:layout_marginTop="16dp" android:layout_marginEnd="8dp" - android:layout_marginTop="16dp" + android:autoLink="web" android:textAlignment="center" android:textAppearance="@style/TextAppearance.Material3.BodyLarge" app:layout_constraintEnd_toEndOf="parent" @@ -96,23 +97,24 @@ android:id="@+id/timetable_validity" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" - android:textAlignment="center" + android:layout_marginTop="16dp" android:layout_marginEnd="8dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.BodyMedium" android:visibility="gone" - android:layout_marginTop="16dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - android:textAppearance="@style/TextAppearance.Material3.BodyMedium" app:layout_constraintTop_toBottomOf="@+id/description" tool:text="Current timetable valid: 2024-01-01 to 2024-02-01" /> <com.google.android.material.textview.MaterialTextView android:id="@+id/attribution" - android:layout_marginTop="16dp" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" + android:layout_marginTop="16dp" android:layout_marginEnd="8dp" + android:autoLink="web" android:textAlignment="center" android:textAppearance="@style/TextAppearance.Material3.BodyMedium" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0f28969a1ce9661561811d143e015aedfe141d66..e7276841464dd7fc779cddd62a31bc9b3402309d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -285,4 +285,6 @@ show <string name="terminus_arrival_showing">Terminus arrivals</string> <string name="matrix_button_description">link to Matrix channel</string> <string name="email_button_description">link to email</string> + <string name="transitous_description">A community-run provider-neutral international public transport routing service. Coverage is available at https://transitous.org/sources/</string> + <string name="transitous_attribution">Transitous (https://transitous.org) API provided by Spline (https://routing.spline.de). Localities (https://github.com/public-transport/transitous/tree/main/feeds) maintained by the community.</string> </resources> diff --git a/app/src/main/res/values-en-rUS/strings.xml b/app/src/main/res/values-en-rUS/strings.xml index 229ed1c026cdbd5babade118fd129c6f22f72f1a..1f2aa2c99cc598244676fb0917da77ac392dfb6f 100644 --- a/app/src/main/res/values-en-rUS/strings.xml +++ b/app/src/main/res/values-en-rUS/strings.xml @@ -144,17 +144,17 @@%1$s towards %2$s <string name="departure_headsign">» %1$s</string> <string name="credits">Font yellowcircle8 (https://git.apiote.xyz/yellowcircle8.git) based on Railway Sans © Greg Fleming, OFL-1.1 https://github.com/davelab6/Railway-Sans\n\n Mastodon icon (https://github.com/mastodon/joinmastodon) © Mastodon contributors, AGPL-3.0-or-later\n\n Bimba logo created by https://github.com/tebriz159\n\n Material icons © Google, Apache-2.0\n\n Map data © OpenStreetMap contributors (https://www.openstreetmap.org/copyright), ODbL-1.0\n\n Cities list used for geocoding short plus codes © Geonames (https://geonames.org), CC BY\n\n Matrix logo ™/® Matrix.org</string> <string name="title_about">About</string> - <string name="translation_button_description">" Mastodon icon (https://github.com/mastodon/joinmastodon) © Mastodon contributors, AGPL-3.0-or-later"</string> + <string name="translation_button_description">link to translations service</string> <string name="app_description">FLOSS public transport passenger companion; a timetable in your pocket.</string> - <string name="website_button_description">" Bimba logo created by https://github.com/tebriz159"</string> + <string name="website_button_description">link to website</string> <string name="code_button_description">link to source code</string> - <string name="mastodon_button_description">" Material icons © Google, Apache-2.0"</string> + <string name="mastodon_button_description">link to Mastodon</string> <string name="use_online_feed">Use online feed</string> - <string name="information_may_be_outdated">" Map data © OpenStreetMap contributors (https://www.openstreetmap.org/copyright), ODbL-1.0"</string> + <string name="information_may_be_outdated">Information may be outdated</string> <string name="current_timetable_validity">Current timetable valid: %1$s to %2$s</string> - <string name="error_406">" Cities list used for geocoding short plus codes © Geonames (https://geonames.org), CC BY"</string> + <string name="error_406">App version is not compatible with the server</string> <string name="filter_localities">filter localities</string> - <string name="error_41">" Matrix logo ™/® Matrix.org"</string> + <string name="error_41">This locality is not supported by the server</string> <string name="stop_from_qr_code">QR code stop</string> <string name="title_select_date">Select day of departures</string> <string name="title_select_line">Select line</string> diff --git a/fruchtfleisch/build.gradle.kts b/fruchtfleisch/build.gradle.kts index d8428614c918943ac054616ce6052d6d5a72fc33..51c8ff7f1f4c9ef0671ad822b9866310af7dbbb7 100644 --- a/fruchtfleisch/build.gradle.kts +++ b/fruchtfleisch/build.gradle.kts @@ -15,8 +15,8 @@ //implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.10") } java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } tasks.withType<Test> {