From 1c542f38baa33b617a1d3e7c08e095d857bdb6ff Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Sun, 17 Dec 2023 19:30:59 +0100 Subject: [PATCH] Add weather plugin language parameter --- .../plugin/config/WeatherPluginConfig.kt | 8 +++- .../plugin/contracts/WeatherPluginContract.kt | 2 + .../de/mm20/launcher2/sdk/weather/Forecast.kt | 2 +- .../launcher2/sdk/weather/WeatherProvider.kt | 38 ++++++++++++++----- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/core/shared/src/main/java/de/mm20/launcher2/plugin/config/WeatherPluginConfig.kt b/core/shared/src/main/java/de/mm20/launcher2/plugin/config/WeatherPluginConfig.kt index 170d0807..6a3c459c 100644 --- a/core/shared/src/main/java/de/mm20/launcher2/plugin/config/WeatherPluginConfig.kt +++ b/core/shared/src/main/java/de/mm20/launcher2/plugin/config/WeatherPluginConfig.kt @@ -1,6 +1,10 @@ package de.mm20.launcher2.plugin.config data class WeatherPluginConfig( - val supportsAutoLocation: Boolean, - val supportsCustomLocation: Boolean, + /** + * Minimum time (in ms) that needs to pass before the provider can be queried again. + * Note that updates can be triggered sooner if the user manually changes their location + * or weather provider. + */ + val minUpdateInterval: Long = 60 * 60 * 1000L, ) \ No newline at end of file diff --git a/core/shared/src/main/java/de/mm20/launcher2/plugin/contracts/WeatherPluginContract.kt b/core/shared/src/main/java/de/mm20/launcher2/plugin/contracts/WeatherPluginContract.kt index aa1998a4..ff332c73 100644 --- a/core/shared/src/main/java/de/mm20/launcher2/plugin/contracts/WeatherPluginContract.kt +++ b/core/shared/src/main/java/de/mm20/launcher2/plugin/contracts/WeatherPluginContract.kt @@ -11,6 +11,7 @@ object WeatherPluginContract { const val Lon = "lon" const val Id = "id" const val LocationName = "location_name" + const val Language = "lang" } object ForecastColumns { @@ -36,6 +37,7 @@ object WeatherPluginContract { object LocationParams { const val Query = "query" + const val Language = "lang" } object LocationColumns { diff --git a/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/weather/Forecast.kt b/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/weather/Forecast.kt index 7f166848..2ab3a6c3 100644 --- a/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/weather/Forecast.kt +++ b/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/weather/Forecast.kt @@ -75,7 +75,7 @@ val Double.inch enum class WeatherIcon { - None, + Unknown, Clear, Cloudy, Cold, diff --git a/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/weather/WeatherProvider.kt b/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/weather/WeatherProvider.kt index 253fcf99..f47284c0 100644 --- a/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/weather/WeatherProvider.kt +++ b/plugins/sdk/src/main/java/de/mm20/launcher2/sdk/weather/WeatherProvider.kt @@ -17,6 +17,7 @@ import de.mm20.launcher2.sdk.utils.launchWithCancellationSignal import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import java.io.IOException +import java.util.Locale import kotlin.math.absoluteValue import kotlin.math.roundToInt @@ -59,9 +60,11 @@ abstract class WeatherProvider( ?.toDoubleOrNull() val id = uri.getQueryParameter(WeatherPluginContract.ForecastParams.Id) val name = uri.getQueryParameter(WeatherPluginContract.ForecastParams.LocationName) + val lang = uri.getQueryParameter(WeatherPluginContract.ForecastParams.Language) + ?: Locale.getDefault().language val forecasts = launchWithCancellationSignal(cancellationSignal) { - getWeatherData(lat, lon, id, name) + getWeatherData(lat, lon, id, name, lang) } ?: return null return createForecastCursor(forecasts) } @@ -69,10 +72,13 @@ abstract class WeatherProvider( uri.pathSegments.size == 1 && uri.pathSegments.first() == WeatherPluginContract.Paths.Locations -> { val query = uri.getQueryParameter(WeatherPluginContract.LocationParams.Query) ?: return null + val lang = uri.getQueryParameter(WeatherPluginContract.LocationParams.Language) + ?: Locale.getDefault().language + val locations = launchWithCancellationSignal( cancellationSignal ) { - findLocations(query) + findLocations(query, lang) } return createLocationsCursor(locations) } @@ -84,16 +90,17 @@ abstract class WeatherProvider( lat: Double?, lon: Double?, id: String?, - locationName: String? + locationName: String?, + lang: String, ): List? { if (lat != null && lon != null && locationName == null) { - return getWeatherData(lat, lon) + return getWeatherData(lat, lon, lang) } if (id != null && locationName != null) { - return getWeatherData(WeatherLocation.Id(id, locationName)) + return getWeatherData(WeatherLocation.Id(id, locationName), lang) } if (locationName != null && lat != null && lon != null) { - return getWeatherData(WeatherLocation.LatLon(locationName, lat, lon)) + return getWeatherData(WeatherLocation.LatLon(locationName, lat, lon), lang) } return null } @@ -208,8 +215,11 @@ abstract class WeatherProvider( * Find locations based on a query string. * The default implementation uses the Android Geocoder and returns a list of lat lon locations. * It also supports lat/lon coordinates in the format "[lat] [lon] [name]" or "[lat] [lon]". + * @param query the query string + * @param lang the ISO 639 language code of the language that the user has set for the launcher. + * Should be used for location names if supported by the provider. */ - open suspend fun findLocations(query: String): List { + open suspend fun findLocations(query: String, lang: String): List { val context = context ?: return emptyList() val parts = query.split(" ", limit = 3) val lat = parts.getOrNull(0)?.toDoubleOrNull() @@ -281,16 +291,24 @@ abstract class WeatherProvider( /** * Get weather data for the current location. This is called when the user has set * the location to "Current location". + * @param lat the latitude of the current location + * @param lon the longitude of the current location + * @param lang the ISO 639 language code of the language that the user has set for the launcher. + * Should be used for weather conditions and location names if supported by the provider. */ - abstract suspend fun getWeatherData(lat: Double, lon: Double): List? + abstract suspend fun getWeatherData(lat: Double, lon: Double, lang: String?): List? /** * Get weather data for a set location. This is called when the user has set * the location to a custom location. * @param location the location that the user has set. This is guaranteed * to be one of the locations returned by [findLocations]. + * @param lang the ISO 639 language code of the language that the user has set for the launcher. + * Should be used for weather conditions if supported by the provider. * @return the weather data for the given location - * Note that returned forecasts should use the same location name as the location parameter. + * Note that returned forecasts should use the name that is set in the [location] parameter as + * the location name, in order to avoid confusion when the user has set the location to a + * custom location. */ - abstract suspend fun getWeatherData(location: WeatherLocation): List? + abstract suspend fun getWeatherData(location: WeatherLocation, lang: String?): List? } \ No newline at end of file