diff --git a/app/build.gradle b/app/build.gradle
index 0bfdfe926..ae3be2945 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -15,8 +15,8 @@ android {
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
// NOTE: Version Code Format (TargetSDK, Version Name, Build Number, Variant Code (Android: 0, WearOS: 1)
- versionCode 345100070
- versionName "5.10.1"
+ versionCode 345100100
+ versionName "5.10.3"
vectorDrawables {
useSupportLibrary true
diff --git a/app/src/androidTestFullgms/java/com/thewizrd/simpleweather/test/UnitTests.kt b/app/src/androidTestFullgms/java/com/thewizrd/simpleweather/test/UnitTests.kt
index b68a1994b..9d9427984 100644
--- a/app/src/androidTestFullgms/java/com/thewizrd/simpleweather/test/UnitTests.kt
+++ b/app/src/androidTestFullgms/java/com/thewizrd/simpleweather/test/UnitTests.kt
@@ -24,6 +24,7 @@ import com.thewizrd.shared_resources.utils.Coordinate
import com.thewizrd.shared_resources.utils.DateTimeUtils
import com.thewizrd.shared_resources.utils.JSONParser
import com.thewizrd.shared_resources.utils.LocaleUtils
+import com.thewizrd.shared_resources.utils.StringUtils.isNullOrWhitespace
import com.thewizrd.shared_resources.utils.ZoneIdCompat
import com.thewizrd.shared_resources.weatherdata.WeatherAPI
import com.thewizrd.shared_resources.weatherdata.WeatherProvider
@@ -33,11 +34,12 @@ import com.thewizrd.simpleweather.images.ImageDatabase
import com.thewizrd.simpleweather.images.model.ImageData
import com.thewizrd.simpleweather.updates.UpdateInfo
import com.thewizrd.weather_api.aqicn.AQICNProvider
+import com.thewizrd.weather_api.google.location.AndroidLocationProvider
import com.thewizrd.weather_api.google.location.GoogleLocationProvider
-import com.thewizrd.weather_api.google.location.createLocationModel
import com.thewizrd.weather_api.google.location.getFromLocationNameAsync
import com.thewizrd.weather_api.google.location.isGeocoderAvailable
import com.thewizrd.weather_api.here.auth.hereOAuthService
+import com.thewizrd.weather_api.locationiq.LocationIQProvider
import com.thewizrd.weather_api.nws.SolCalcAstroProvider
import com.thewizrd.weather_api.nws.alerts.NWSAlertProvider
import com.thewizrd.weather_api.smc.SunMoonCalcProvider
@@ -348,16 +350,12 @@ class UnitTests {
fun androidGeocoderTest() {
runBlocking(Dispatchers.Default) {
assertTrue(isGeocoderAvailable())
- val geocoder = Geocoder(context, Locale.getDefault())
- val addressList = withContext(Dispatchers.IO) {
- //geocoder.getFromLocation(47.6721646, -122.1706614, 1); // Washington
- geocoder.getFromLocation(51.5073884, -0.1334347, 1) // London
+ val locationProvider = AndroidLocationProvider()
+ val location = withContext(Dispatchers.IO) {
+ locationProvider.getLocation(Coordinate(51.5073884, -0.1334347), WeatherAPI.ANDROID)
}
- assertFalse(addressList.isNullOrEmpty())
- val result = addressList!![0]
- assertNotNull(result)
- val locQVM = createLocationModel(result, WeatherAPI.ANDROID)
- assertFalse(locQVM.locationName.toString().contains("null"))
+ assertNotNull(location)
+ assertFalse(location.locationName.toString().contains("null"))
}
}
@@ -381,7 +379,7 @@ class UnitTests {
Coordinate(
queryVM!!.locationLat,
queryVM.locationLong
- ), WeatherAPI.OPENWEATHERMAP
+ ), WeatherAPI.GOOGLE
)
} else if (locationProvider.needsLocationFromID()) {
locationProvider.getLocationFromID(queryVM!!)
@@ -390,18 +388,57 @@ class UnitTests {
}
assertNotNull(locModel)
+ assertFalse(locModel?.locationName.isNullOrWhitespace())
+ assertTrue(locModel?.toLocationData()?.isValid == true)
+ }
+ }
+
+ @Test
+ @Throws(WeatherException::class)
+ fun locIQLocationTest() {
+ runBlocking(Dispatchers.Default) {
+ val locationProvider: WeatherLocationProvider = LocationIQProvider()
+ val locations = withContext(Dispatchers.IO) {
+ locationProvider.getLocations("Redmond, WA", WeatherAPI.LOCATIONIQ)
+ }
+ assertFalse(locations.isEmpty())
+
+ val queryVM = locations.find { it.locationName?.startsWith("Redmond") == true }
+ assertNotNull(queryVM)
- if (locModel!!.locationTZLong.isNullOrBlank() && locModel.locationLat != 0.0 && locModel.locationLong != 0.0) {
- val tzId = weatherModule.tzdbService.getTimeZone(
- locModel.locationLat,
- locModel.locationLong
+ val locModel = if (locationProvider.needsLocationFromName()) {
+ locationProvider.getLocationFromName(queryVM!!)
+ } else if (locationProvider.needsLocationFromGeocoder()) {
+ locationProvider.getLocation(
+ Coordinate(
+ queryVM!!.locationLat,
+ queryVM.locationLong
+ ), WeatherAPI.LOCATIONIQ
)
- if ("unknown" != tzId)
- locModel.locationTZLong = tzId
+ } else if (locationProvider.needsLocationFromID()) {
+ locationProvider.getLocationFromID(queryVM!!)
+ } else {
+ queryVM
+ }
+
+ assertNotNull(locModel)
+ assertFalse(locModel?.locationName.isNullOrWhitespace())
+ assertTrue(locModel?.toLocationData()?.isValid == true)
+ }
+ }
+
+ @Test
+ @Throws(WeatherException::class)
+ fun locIQLocationGeocoderTest() {
+ runBlocking(Dispatchers.Default) {
+ val locationProvider: WeatherLocationProvider = LocationIQProvider()
+ val locModel = withContext(Dispatchers.IO) {
+ locationProvider.getLocation(Coordinate(51.5073884, -0.1334347), WeatherAPI.ANDROID)
}
- assertFalse(locModel.locationTZLong.isNullOrEmpty())
- assertTrue(locModel.toLocationData().isValid)
+ assertNotNull(locModel)
+ assertFalse(locModel?.locationName.isNullOrWhitespace())
+ assertTrue(locModel?.toLocationData()?.isValid == true)
}
}
@@ -425,7 +462,7 @@ class UnitTests {
Coordinate(
queryVM!!.locationLat,
queryVM.locationLong
- ), WeatherAPI.OPENWEATHERMAP
+ ), WeatherAPI.WEATHERAPI
)
} else if (locationProvider.needsLocationFromID()) {
locationProvider.getLocationFromID(queryVM!!)
@@ -434,18 +471,8 @@ class UnitTests {
}
assertNotNull(locModel)
-
- if (locModel!!.locationTZLong.isNullOrBlank() && locModel.locationLat != 0.0 && locModel.locationLong != 0.0) {
- val tzId = weatherModule.tzdbService.getTimeZone(
- locModel.locationLat,
- locModel.locationLong
- )
- if ("unknown" != tzId)
- locModel.locationTZLong = tzId
- }
-
- assertFalse(locModel.locationTZLong.isNullOrEmpty())
- assertTrue(locModel.toLocationData().isValid)
+ assertFalse(locModel?.locationName.isNullOrWhitespace())
+ assertTrue(locModel?.toLocationData()?.isValid == true)
}
}
diff --git a/app/src/main/java/com/thewizrd/simpleweather/widgets/preferences/AbstractWeatherWidgetPreferenceFragment.kt b/app/src/main/java/com/thewizrd/simpleweather/widgets/preferences/AbstractWeatherWidgetPreferenceFragment.kt
index 3243c0973..860a9bbca 100644
--- a/app/src/main/java/com/thewizrd/simpleweather/widgets/preferences/AbstractWeatherWidgetPreferenceFragment.kt
+++ b/app/src/main/java/com/thewizrd/simpleweather/widgets/preferences/AbstractWeatherWidgetPreferenceFragment.kt
@@ -56,6 +56,7 @@ import com.thewizrd.shared_resources.utils.ContextUtils.isSmallestWidth
import com.thewizrd.shared_resources.utils.Logger
import com.thewizrd.shared_resources.weatherdata.model.AirQuality
import com.thewizrd.shared_resources.weatherdata.model.Atmosphere
+import com.thewizrd.shared_resources.weatherdata.model.Beaufort
import com.thewizrd.shared_resources.weatherdata.model.Condition
import com.thewizrd.shared_resources.weatherdata.model.Forecast
import com.thewizrd.shared_resources.weatherdata.model.ForecastExtras
@@ -63,7 +64,9 @@ import com.thewizrd.shared_resources.weatherdata.model.HourlyForecast
import com.thewizrd.shared_resources.weatherdata.model.Location
import com.thewizrd.shared_resources.weatherdata.model.LocationType
import com.thewizrd.shared_resources.weatherdata.model.MinutelyForecast
+import com.thewizrd.shared_resources.weatherdata.model.Pollen
import com.thewizrd.shared_resources.weatherdata.model.Precipitation
+import com.thewizrd.shared_resources.weatherdata.model.UV
import com.thewizrd.shared_resources.weatherdata.model.Weather
import com.thewizrd.simpleweather.R
import com.thewizrd.simpleweather.activities.LocationSearch
@@ -596,15 +599,27 @@ abstract class AbstractWeatherWidgetPreferenceFragment : ToolbarPreferenceFragme
weather = getString(R.string.weather_sunny)
tempF = 70f
tempC = 21f
+ windDegrees = 292
windMph = 5f
windKph = 8f
+ windGustMph = 15f
+ windGustKph = 25f
+ feelslikeF = 75f
+ feelslikeC = 23f
highF = 75f
highC = 23f
lowF = 60f
lowC = 15f
icon = WeatherIcons.DAY_SUNNY
airQuality = AirQuality().apply {
- index = 46
+ index = Random.nextInt(0, 301)
+ }
+ beaufort = Beaufort(Beaufort.BeaufortScale.valueOf(Random.nextInt(0, 12)))
+ uv = UV(Random.nextInt(0, 11).toFloat())
+ pollen = Pollen().apply {
+ treePollenCount = Pollen.PollenCount.VERY_HIGH
+ grassPollenCount = Pollen.PollenCount.LOW
+ ragweedPollenCount = Pollen.PollenCount.MODERATE
}
}
atmosphere = Atmosphere()
diff --git a/app/src/main/java/com/thewizrd/simpleweather/widgets/remoteviews/WeatherWidget4x2Creator.kt b/app/src/main/java/com/thewizrd/simpleweather/widgets/remoteviews/WeatherWidget4x2Creator.kt
index 2fab12e2f..a4853c318 100644
--- a/app/src/main/java/com/thewizrd/simpleweather/widgets/remoteviews/WeatherWidget4x2Creator.kt
+++ b/app/src/main/java/com/thewizrd/simpleweather/widgets/remoteviews/WeatherWidget4x2Creator.kt
@@ -10,6 +10,7 @@ import android.text.style.TextAppearanceSpan
import android.util.TypedValue
import android.view.View
import android.widget.RemoteViews
+import com.thewizrd.common.controls.WeatherDetailsType
import com.thewizrd.common.controls.WeatherUiModel
import com.thewizrd.common.helpers.ColorsUtils
import com.thewizrd.common.utils.ImageUtils
@@ -153,6 +154,10 @@ class WeatherWidget4x2Creator(context: Context, loadBackground: Boolean = true)
R.id.condition_weather,
textColor
)
+ updateViews.setTextColor(
+ R.id.condition_feelslike,
+ textColor
+ )
updateViews.setTextColor(R.id.date_panel, textColor)
updateViews.setTextColor(R.id.clock_panel, textColor)
@@ -170,6 +175,15 @@ class WeatherWidget4x2Creator(context: Context, loadBackground: Boolean = true)
weather.curTemp?.applySpan(textAppearanceSpan)
)
+ weather.weatherDetailsMap[WeatherDetailsType.FEELSLIKE]?.let {
+ updateViews.setTextViewText(
+ R.id.condition_feelslike,
+ "${it.label}: ${it.value}".applySpan(textAppearanceSpan)
+ )
+ } ?: run {
+ updateViews.setViewVisibility(R.id.condition_feelslike, View.GONE)
+ }
+
buildDate(location, updateViews, appWidgetId, newOptions)
// Open default clock/calendar app
updateViews.setOnClickPendingIntent(
@@ -361,6 +375,11 @@ class WeatherWidget4x2Creator(context: Context, loadBackground: Boolean = true)
TypedValue.COMPLEX_UNIT_SP,
12f * txtSizeMultiplier
)
+ updateViews.setTextViewTextSize(
+ R.id.condition_feelslike,
+ TypedValue.COMPLEX_UNIT_SP,
+ 12f * txtSizeMultiplier
+ )
}
private fun updateClockSize(views: RemoteViews, appWidgetId: Int, newOptions: Bundle) {
diff --git a/app/src/main/java/com/thewizrd/simpleweather/widgets/remoteviews/WeatherWidget4x2TomorrowCreator.kt b/app/src/main/java/com/thewizrd/simpleweather/widgets/remoteviews/WeatherWidget4x2TomorrowCreator.kt
index b0cf634ba..804d1e12d 100644
--- a/app/src/main/java/com/thewizrd/simpleweather/widgets/remoteviews/WeatherWidget4x2TomorrowCreator.kt
+++ b/app/src/main/java/com/thewizrd/simpleweather/widgets/remoteviews/WeatherWidget4x2TomorrowCreator.kt
@@ -172,6 +172,10 @@ class WeatherWidget4x2TomorrowCreator(context: Context, loadBackground: Boolean
R.id.condition_weather,
textColor
)
+ updateViews.setTextColor(
+ R.id.condition_feelslike,
+ textColor
+ )
updateViews.setTextColor(R.id.date_panel, textColor)
updateViews.setTextColor(R.id.clock_panel, textColor)
@@ -189,6 +193,15 @@ class WeatherWidget4x2TomorrowCreator(context: Context, loadBackground: Boolean
weather.curTemp?.applySpan(textAppearanceSpan)
)
+ weather.weatherDetailsMap[WeatherDetailsType.FEELSLIKE]?.let {
+ updateViews.setTextViewText(
+ R.id.condition_feelslike,
+ "${it.label}: ${it.value}".applySpan(textAppearanceSpan)
+ )
+ } ?: run {
+ updateViews.setViewVisibility(R.id.condition_feelslike, View.GONE)
+ }
+
buildDate(location, updateViews, appWidgetId, newOptions)
// Open default clock/calendar app
updateViews.setOnClickPendingIntent(
@@ -659,6 +672,11 @@ class WeatherWidget4x2TomorrowCreator(context: Context, loadBackground: Boolean
TypedValue.COMPLEX_UNIT_SP,
12f * txtSizeMultiplier
)
+ updateViews.setTextViewTextSize(
+ R.id.condition_feelslike,
+ TypedValue.COMPLEX_UNIT_SP,
+ 12f * txtSizeMultiplier
+ )
}
private fun updateClockSize(views: RemoteViews, appWidgetId: Int, newOptions: Bundle) {
diff --git a/app/src/main/res/layout/app_widget_4x2.xml b/app/src/main/res/layout/app_widget_4x2.xml
index c359b16e3..f729cd584 100644
--- a/app/src/main/res/layout/app_widget_4x2.xml
+++ b/app/src/main/res/layout/app_widget_4x2.xml
@@ -114,7 +114,8 @@
@@ -156,41 +157,61 @@
-
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:gravity="center_vertical"
+ android:orientation="vertical">
-
+ android:orientation="horizontal"
+ android:paddingVertical="2dp">
+
+
+
+
+
+
+ android:textSize="12sp"
+ tools:ignore="UnusedAttribute"
+ tools:text="Feels like: 75°" />
-
+
diff --git a/app/src/main/res/layout/app_widget_4x2_preview.xml b/app/src/main/res/layout/app_widget_4x2_preview.xml
index a64effdc8..604a14811 100644
--- a/app/src/main/res/layout/app_widget_4x2_preview.xml
+++ b/app/src/main/res/layout/app_widget_4x2_preview.xml
@@ -78,9 +78,10 @@
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:baselineAligned="false"
+ android:orientation="horizontal">
-
-
-
+
+
+ android:orientation="horizontal"
+ android:paddingVertical="2dp">
+
+
+
+
+
+
+ android:textSize="12sp"
+ android:text="Feels like: 75°" />
-
+
diff --git a/app/src/main/res/layout/app_widget_4x2_tomorrow.xml b/app/src/main/res/layout/app_widget_4x2_tomorrow.xml
index 0dc8b39c3..d7894197a 100644
--- a/app/src/main/res/layout/app_widget_4x2_tomorrow.xml
+++ b/app/src/main/res/layout/app_widget_4x2_tomorrow.xml
@@ -114,7 +114,8 @@
@@ -156,41 +157,61 @@
-
+ android:layout_height="match_parent"
+ android:layout_gravity="center_vertical"
+ android:gravity="center_vertical"
+ android:orientation="vertical">
-
+ android:orientation="horizontal"
+ android:paddingVertical="2dp">
+
+
+
+
+
+
+ android:textSize="12sp"
+ tools:ignore="UnusedAttribute"
+ tools:text="Feels like: 75°" />
-
+
diff --git a/app/src/main/res/layout/app_widget_4x2_tomorrow_preview.xml b/app/src/main/res/layout/app_widget_4x2_tomorrow_preview.xml
index 84ab1b763..94e3053a1 100644
--- a/app/src/main/res/layout/app_widget_4x2_tomorrow_preview.xml
+++ b/app/src/main/res/layout/app_widget_4x2_tomorrow_preview.xml
@@ -78,9 +78,10 @@
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:baselineAligned="false"
+ android:orientation="horizontal">
-
-
-
+
+
+ android:orientation="horizontal"
+ android:paddingVertical="2dp">
+
+
+
+
+
+
+ android:textSize="12sp"
+ android:text="Feels like: 75°" />
-
+
diff --git a/build.gradle b/build.gradle
index 61b359311..b20169ab4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -12,12 +12,12 @@ buildscript {
desugar_version = '2.1.3'
- firebase_version = '33.5.1'
+ firebase_version = '33.7.0'
gms_location_version = '21.3.0'
gms_base_version = '18.5.0'
- gms_basement_version = '18.4.0'
+ gms_basement_version = '18.5.0'
gms_tasks_version = '18.2.0'
- gms_wearable_version = '18.2.0'
+ gms_wearable_version = '19.0.0'
annotation_version = '1.9.1'
activity_version = '1.9.3'
@@ -27,8 +27,8 @@ buildscript {
arch_core_runtime_version = '2.2.0'
fragment_version = '1.8.5'
lifecycle_version = '2.8.7'
- nav_version = '2.8.3'
- paging_version = '3.3.2'
+ nav_version = '2.8.4'
+ paging_version = '3.3.4'
preference_version = '1.2.1'
recyclerview_version = '1.3.2'
room_version = '2.6.1'
@@ -46,17 +46,17 @@ buildscript {
material_version = '1.12.0'
compose_compiler_version = '1.5.15'
- compose_bom_version = '2024.10.01'
+ compose_bom_version = '2024.11.00'
wear_compose_version = '1.4.0'
wear_tiles_version = '1.4.1'
wear_watchface_version = '1.2.1'
- horologist_version = '0.6.20'
+ horologist_version = '0.6.21'
accompanist_version = '0.36.0'
glide_version = '4.16.0'
icu4j_version = '76.1'
jjwt_version = '0.12.6'
- moshi_version = '1.15.1'
+ moshi_version = '1.15.2'
okhttp_version = '4.12.0'
timber_version = '5.0.1'
}
@@ -68,7 +68,7 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.7.2'
+ classpath 'com.android.tools.build:gradle:8.7.3'
classpath "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin:$ksp_version"
classpath 'com.google.gms:google-services:4.4.2'
classpath 'com.google.firebase:firebase-crashlytics-gradle:3.0.2'
diff --git a/common/src/main/java/com/thewizrd/common/controls/DetailItemViewModel.java b/common/src/main/java/com/thewizrd/common/controls/DetailItemViewModel.java
index d16edb6fd..20f23db8f 100644
--- a/common/src/main/java/com/thewizrd/common/controls/DetailItemViewModel.java
+++ b/common/src/main/java/com/thewizrd/common/controls/DetailItemViewModel.java
@@ -148,38 +148,44 @@ public DetailItemViewModel(@NonNull MoonPhase.MoonPhaseType moonPhaseType) {
case NEWMOON:
this.icon = WeatherIcons.MOON_NEW;
this.value = context.getString(R.string.moonphase_new);
+ this.shortValue = context.getString(R.string.moonphase_new_short);
break;
case WAXING_CRESCENT:
this.icon = WeatherIcons.MOON_ALT_WAXING_CRESCENT_3;
this.value = context.getString(R.string.moonphase_waxcrescent);
+ this.shortValue = context.getString(R.string.moonphase_waxcrescent_short);
break;
case FIRST_QTR:
this.icon = WeatherIcons.MOON_ALT_FIRST_QUARTER;
this.value = context.getString(R.string.moonphase_firstqtr);
+ this.shortValue = context.getString(R.string.moonphase_firstqtr_short);
break;
case WAXING_GIBBOUS:
this.icon = WeatherIcons.MOON_ALT_WAXING_GIBBOUS_3;
this.value = context.getString(R.string.moonphase_waxgibbous);
+ this.shortValue = context.getString(R.string.moonphase_waxgibbous_short);
break;
case FULL_MOON:
this.icon = WeatherIcons.MOON_ALT_FULL;
this.value = context.getString(R.string.moonphase_full);
+ this.shortValue = context.getString(R.string.moonphase_full_short);
break;
case WANING_GIBBOUS:
this.icon = WeatherIcons.MOON_ALT_WANING_GIBBOUS_3;
this.value = context.getString(R.string.moonphase_wangibbous);
+ this.shortValue = context.getString(R.string.moonphase_wangibbous_short);
break;
case LAST_QTR:
this.icon = WeatherIcons.MOON_ALT_THIRD_QUARTER;
this.value = context.getString(R.string.moonphase_lastqtr);
+ this.shortValue = context.getString(R.string.moonphase_lastqtr_short);
break;
case WANING_CRESCENT:
this.icon = WeatherIcons.MOON_ALT_WANING_CRESCENT_3;
this.value = context.getString(R.string.moonphase_wancrescent);
+ this.shortValue = context.getString(R.string.moonphase_wancrescent_short);
break;
}
-
- this.shortValue = value;
}
public DetailItemViewModel(@NonNull Beaufort.BeaufortScale beaufortScale) {
diff --git a/common/src/main/java/com/thewizrd/common/controls/PollenViewModel.kt b/common/src/main/java/com/thewizrd/common/controls/PollenViewModel.kt
index 3fa23987a..bbca9d15e 100644
--- a/common/src/main/java/com/thewizrd/common/controls/PollenViewModel.kt
+++ b/common/src/main/java/com/thewizrd/common/controls/PollenViewModel.kt
@@ -3,6 +3,7 @@ package com.thewizrd.common.controls
import android.text.Spannable
import android.text.SpannableString
import android.text.style.ForegroundColorSpan
+import androidx.annotation.ColorInt
import com.thewizrd.shared_resources.R
import com.thewizrd.shared_resources.icons.WeatherIcons
import com.thewizrd.shared_resources.sharedDeps
@@ -12,56 +13,98 @@ import com.thewizrd.shared_resources.weatherdata.model.Pollen
class PollenViewModel(pollenData: Pollen) {
var treePollenDesc: CharSequence
private set
+ var treePollenShortDesc: CharSequence
+ private set
var grassPollenDesc: CharSequence
private set
+ var grassPollenShortDesc: CharSequence
+ private set
var ragweedPollenDesc: CharSequence
private set
+ var ragweedPollenShortDesc: CharSequence
+ private set
+
+ var treePollenProgress: Int = pollenData.treePollenCount?.ordinal ?: 0
+ private set
+ var grassPollenProgress: Int = pollenData.grassPollenCount?.ordinal ?: 0
+ private set
+ var ragweedPollenProgress: Int = pollenData.ragweedPollenCount?.ordinal ?: 0
+ private set
+
+ var treePollenProgressColor: Int = pollenData.treePollenCount.toColor()
+ private set
+ var grassPollenProgressColor: Int = pollenData.grassPollenCount.toColor()
+ private set
+ var ragweedPollenProgressColor: Int = pollenData.ragweedPollenCount.toColor()
+ private set
+
+ val progressMax: Int = Pollen.PollenCount.VERY_HIGH.ordinal
init {
- treePollenDesc = getPollenCountDescription(pollenData.treePollenCount)
- grassPollenDesc = getPollenCountDescription(pollenData.grassPollenCount)
- ragweedPollenDesc = getPollenCountDescription(pollenData.ragweedPollenCount)
+ getPollenCountDescription(pollenData.treePollenCount).run {
+ treePollenDesc = first
+ treePollenShortDesc = second
+ }
+
+ getPollenCountDescription(pollenData.grassPollenCount).run {
+ grassPollenDesc = first
+ grassPollenShortDesc = second
+ }
+
+ getPollenCountDescription(pollenData.ragweedPollenCount).run {
+ ragweedPollenDesc = first
+ ragweedPollenShortDesc = second
+ }
}
- private fun getPollenCountDescription(pollenCount: Pollen.PollenCount?): CharSequence {
+ private fun getPollenCountDescription(pollenCount: Pollen.PollenCount?): Pair {
val context = sharedDeps.context
- return when (pollenCount) {
- Pollen.PollenCount.LOW -> SpannableString(context.getString(R.string.label_count_low)).apply {
- setSpan(
- ForegroundColorSpan(Colors.LIMEGREEN),
- 0,
- this.length,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
- )
- }
- Pollen.PollenCount.MODERATE -> SpannableString(context.getString(R.string.label_count_moderate)).apply {
- setSpan(
- ForegroundColorSpan(Colors.ORANGE),
- 0,
- this.length,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
- )
- }
- Pollen.PollenCount.HIGH -> SpannableString(context.getString(R.string.label_count_high)).apply {
- setSpan(
- ForegroundColorSpan(Colors.ORANGERED),
- 0,
- this.length,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
- )
- }
- Pollen.PollenCount.VERY_HIGH -> SpannableString(context.getString(R.string.label_count_veryhigh)).apply {
- setSpan(
- ForegroundColorSpan(Colors.RED),
- 0,
- this.length,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
- )
- }
- else -> WeatherIcons.EM_DASH
+ val description = when (pollenCount) {
+ Pollen.PollenCount.LOW -> SpannableString(context.getString(R.string.label_count_low)) to SpannableString(
+ context.getString(R.string.label_count_low_short)
+ )
+
+ Pollen.PollenCount.MODERATE -> SpannableString(context.getString(R.string.label_count_moderate)) to SpannableString(
+ context.getString(R.string.label_count_moderate_short)
+ )
+
+ Pollen.PollenCount.HIGH -> SpannableString(context.getString(R.string.label_count_high)) to SpannableString(
+ context.getString(R.string.label_count_high_short)
+ )
+
+ Pollen.PollenCount.VERY_HIGH -> SpannableString(context.getString(R.string.label_count_veryhigh)) to SpannableString(
+ context.getString(R.string.label_count_veryhigh_short)
+ )
+
+ else -> WeatherIcons.EM_DASH to WeatherIcons.EM_DASH
+ }
+
+ return description.apply {
+ first.setDescriptionSpan(pollenCount)
+ second.setDescriptionSpan(pollenCount)
+ }
+ }
+
+ @ColorInt
+ private fun Pollen.PollenCount?.toColor(): Int = when (this) {
+ Pollen.PollenCount.LOW -> Colors.LIMEGREEN
+ Pollen.PollenCount.MODERATE -> Colors.ORANGE
+ Pollen.PollenCount.HIGH -> Colors.ORANGERED
+ Pollen.PollenCount.VERY_HIGH -> Colors.RED
+ else -> Colors.TRANSPARENT
+ }
+
+ private fun CharSequence.setDescriptionSpan(pollenCount: Pollen.PollenCount?) {
+ if (this is Spannable) {
+ this.setSpan(
+ ForegroundColorSpan(pollenCount.toColor()),
+ 0,
+ this.length,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
}
}
}
\ No newline at end of file
diff --git a/common/src/main/java/com/thewizrd/common/controls/WeatherUiModel.kt b/common/src/main/java/com/thewizrd/common/controls/WeatherUiModel.kt
index df0ad20d6..80b8fa57c 100644
--- a/common/src/main/java/com/thewizrd/common/controls/WeatherUiModel.kt
+++ b/common/src/main/java/com/thewizrd/common/controls/WeatherUiModel.kt
@@ -8,6 +8,7 @@ import com.thewizrd.common.weatherdata.NoopWeatherProvider
import com.thewizrd.shared_resources.DateTimeConstants
import com.thewizrd.shared_resources.R
import com.thewizrd.shared_resources.appLib
+import com.thewizrd.shared_resources.designer.isInEditMode
import com.thewizrd.shared_resources.di.settingsManager
import com.thewizrd.shared_resources.icons.WeatherIcons
import com.thewizrd.shared_resources.sharedDeps
@@ -154,7 +155,7 @@ class WeatherUiModel() {
}
private fun refreshView() {
- val provider: WeatherProvider = if (appLib.properties.getBoolean("isInEditMode", false)) {
+ val provider: WeatherProvider = if (appLib.isInEditMode()) {
NoopWeatherProvider()
} else {
weatherModule.weatherManager.getWeatherProvider(weatherData!!.source)
@@ -608,16 +609,19 @@ class WeatherUiModel() {
weatherDetailsMap[WeatherDetailsType.TREEPOLLEN] = DetailItemViewModel(
WeatherDetailsType.TREEPOLLEN,
pollenVM.treePollenDesc.toString(),
+ pollenVM.treePollenShortDesc.toString(),
0
)
weatherDetailsMap[WeatherDetailsType.GRASSPOLLEN] = DetailItemViewModel(
WeatherDetailsType.GRASSPOLLEN,
pollenVM.grassPollenDesc.toString(),
+ pollenVM.grassPollenShortDesc.toString(),
0
)
weatherDetailsMap[WeatherDetailsType.RAGWEEDPOLLEN] = DetailItemViewModel(
WeatherDetailsType.RAGWEEDPOLLEN,
pollenVM.ragweedPollenDesc.toString(),
+ pollenVM.ragweedPollenShortDesc.toString(),
0
)
}
diff --git a/shared_resources/src/main/java/com/thewizrd/shared_resources/designer/DesignerUtils.kt b/shared_resources/src/main/java/com/thewizrd/shared_resources/designer/DesignerUtils.kt
index 3e0173c86..4d3691726 100644
--- a/shared_resources/src/main/java/com/thewizrd/shared_resources/designer/DesignerUtils.kt
+++ b/shared_resources/src/main/java/com/thewizrd/shared_resources/designer/DesignerUtils.kt
@@ -50,4 +50,6 @@ fun Context.initializeDependencies(isPhone: Boolean = true) {
get() = SettingsManager(appContext)
}
-}
\ No newline at end of file
+}
+
+fun ApplicationLib.isInEditMode(): Boolean = properties.getBoolean("isInEditMode", false)
\ No newline at end of file
diff --git a/shared_resources/src/main/java/com/thewizrd/shared_resources/exceptions/WeatherException.kt b/shared_resources/src/main/java/com/thewizrd/shared_resources/exceptions/WeatherException.kt
index a7ae29f7d..f95af1cc0 100644
--- a/shared_resources/src/main/java/com/thewizrd/shared_resources/exceptions/WeatherException.kt
+++ b/shared_resources/src/main/java/com/thewizrd/shared_resources/exceptions/WeatherException.kt
@@ -4,7 +4,7 @@ import com.thewizrd.shared_resources.R
import com.thewizrd.shared_resources.sharedDeps
enum class ErrorStatus {
- UNKNOWN, SUCCESS, NOWEATHER, NETWORKERROR, INVALIDAPIKEY, QUERYNOTFOUND
+ UNKNOWN, SUCCESS, NOWEATHER, NETWORKERROR, INVALIDAPIKEY, QUERYNOTFOUND, RATELIMITED
}
class WeatherException : Exception {
@@ -33,6 +33,9 @@ class WeatherException : Exception {
ErrorStatus.QUERYNOTFOUND -> {
sharedDeps.context.getString(R.string.werror_querynotfound)
}
+ ErrorStatus.RATELIMITED -> {
+ sharedDeps.context.getString(R.string.werror_ratelimited)
+ }
else -> {
// ErrorStatus.UNKNOWN
sharedDeps.context.getString(R.string.werror_unknown)
diff --git a/shared_resources/src/main/res/values-de/moonphases.xml b/shared_resources/src/main/res/values-de/moonphases.xml
index 365482b70..16c1f14ee 100644
--- a/shared_resources/src/main/res/values-de/moonphases.xml
+++ b/shared_resources/src/main/res/values-de/moonphases.xml
@@ -2,10 +2,18 @@
"Neumond"
"Zunehmender Sichelmond"
- "Zunehmender Halbmond"
+ "Erstes Viertel"
"Zunehmender Mond"
"Vollmond"
"Abnehmender Mond"
- "Abnehmender Halbmond"
+ "Letztes Viertel"
"Abnehmender Sichelmond"
+ "Neu"
+ "Zunehm."
+ "Erstes V."
+ "Zunehm."
+ "Voll"
+ "Abnehm."
+ "Letztes V."
+ "Abnehm."
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-de/strings.xml b/shared_resources/src/main/res/values-de/strings.xml
index 3cd1701f7..b24212ab5 100644
--- a/shared_resources/src/main/res/values-de/strings.xml
+++ b/shared_resources/src/main/res/values-de/strings.xml
@@ -246,4 +246,9 @@ Minute-by-Minute Forecast -->
"Nutzungsbedingungen"
"Mehr Infos"
"Zurücksetzen"
+ "Niedrig"
+ "Moderat"
+ "Hoch"
+ "Hoch"
+ "Zu viele Anfragen. Bitte versuchen Sie es nach ein paar Minuten erneut"
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-es/moonphases.xml b/shared_resources/src/main/res/values-es/moonphases.xml
index ac256db2d..ba18fcbbe 100644
--- a/shared_resources/src/main/res/values-es/moonphases.xml
+++ b/shared_resources/src/main/res/values-es/moonphases.xml
@@ -8,4 +8,12 @@
"Luna gibosa menguante"
"Cuarto menguante"
"Luna menguante"
+ "Nueva"
+ "Crec."
+ "1/4 cr."
+ "Crec."
+ "Llena"
+ "Meng."
+ "1/4 m."
+ "Meng."
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-es/strings.xml b/shared_resources/src/main/res/values-es/strings.xml
index 74187c5fc..dadec5ad2 100644
--- a/shared_resources/src/main/res/values-es/strings.xml
+++ b/shared_resources/src/main/res/values-es/strings.xml
@@ -233,4 +233,9 @@
"Zmluvné podmienky"
"Más información"
"Restablecer"
+ "Bajo"
+ "Medio"
+ "Alto"
+ "Alto"
+ "Demasiadas solicitudes. Vuelva a intentarlo pasados unos minutos"
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-fr/moonphases.xml b/shared_resources/src/main/res/values-fr/moonphases.xml
index 298449bee..08090e635 100644
--- a/shared_resources/src/main/res/values-fr/moonphases.xml
+++ b/shared_resources/src/main/res/values-fr/moonphases.xml
@@ -8,4 +8,12 @@
"Gibbeuse décroissante"
"Dernier quartier"
"Dernier croissant"
+ "Nouvelle"
+ "Ascend."
+ "1er qu."
+ "Ascend."
+ "Pleine"
+ "Descend."
+ "Dern. qr."
+ "Descend."
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-fr/strings.xml b/shared_resources/src/main/res/values-fr/strings.xml
index c0d611363..1884a08ce 100644
--- a/shared_resources/src/main/res/values-fr/strings.xml
+++ b/shared_resources/src/main/res/values-fr/strings.xml
@@ -200,4 +200,9 @@
"Conditions d'utilisation"
"Plus d'informations"
"Réinitialiser"
+ "Bas"
+ "Modéré"
+ "Élevé"
+ "Élevé"
+ "Trop de demandes. Veuillez réessayer après quelques minutes"
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-nl/moonphases.xml b/shared_resources/src/main/res/values-nl/moonphases.xml
index 7dc544335..123261839 100644
--- a/shared_resources/src/main/res/values-nl/moonphases.xml
+++ b/shared_resources/src/main/res/values-nl/moonphases.xml
@@ -8,4 +8,12 @@
"Afnemende maan"
"Laatste kwartier"
"Afnemende maansikkel"
+ "Nieuw"
+ "Wassend"
+ "Eerste k"
+ "Wassend"
+ "Vol"
+ "Afnemend"
+ "Laatste k"
+ "Afnemend"
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-nl/strings.xml b/shared_resources/src/main/res/values-nl/strings.xml
index 3e5fe2dbd..b2d9df26a 100644
--- a/shared_resources/src/main/res/values-nl/strings.xml
+++ b/shared_resources/src/main/res/values-nl/strings.xml
@@ -204,4 +204,9 @@
"Servicevoorwaarden"
"Meer informatie"
"Resetten"
+ "Laag"
+ "Matig"
+ "Hoog"
+ "Hoog"
+ "Te veel aanvragen. Probeer het opnieuw na een paar minuten"
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-pl/moonphases.xml b/shared_resources/src/main/res/values-pl/moonphases.xml
index de4dcdc01..495ea02c2 100644
--- a/shared_resources/src/main/res/values-pl/moonphases.xml
+++ b/shared_resources/src/main/res/values-pl/moonphases.xml
@@ -8,4 +8,12 @@
"Ubywający księżyc garbaty"
"Trzecia kwadra"
"Sierp ubywający"
+ "Nów"
+ "Przyb."
+ "1 kw."
+ "Przyb."
+ "Pełnia"
+ "Ubyw."
+ "3 kw."
+ "Ubyw."
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-pl/strings.xml b/shared_resources/src/main/res/values-pl/strings.xml
index 6b960621a..e3a3854d0 100644
--- a/shared_resources/src/main/res/values-pl/strings.xml
+++ b/shared_resources/src/main/res/values-pl/strings.xml
@@ -207,4 +207,9 @@
"Warunki korzystania z usługi"
"Więcej informacji"
"Resetuj"
+ "Niski"
+ "Średni"
+ "Wysoki"
+ "Wysoki"
+ "Zbyt wiele żądań. Spróbuj ponownie za kilka minut"
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-sk/moonphases.xml b/shared_resources/src/main/res/values-sk/moonphases.xml
index d5b8a72af..750ceadd6 100644
--- a/shared_resources/src/main/res/values-sk/moonphases.xml
+++ b/shared_resources/src/main/res/values-sk/moonphases.xml
@@ -8,4 +8,12 @@
"zmenšujúci sa mesiac"
"posledná štvrť"
"zmenšujúci sa polmesiac"
+ "Nov"
+ "Dorast."
+ "1. štvrť"
+ "Dorast."
+ "Spln"
+ "Zmenš."
+ "3. štvrť"
+ "Zmenš."
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-sk/strings.xml b/shared_resources/src/main/res/values-sk/strings.xml
index 1aaa5894e..369daddad 100644
--- a/shared_resources/src/main/res/values-sk/strings.xml
+++ b/shared_resources/src/main/res/values-sk/strings.xml
@@ -204,4 +204,9 @@
"Podmienky služby"
"Viac informácií"
"Resetovať"
+ "Nízka"
+ "Stredná"
+ "Vysoká"
+ "Vysoká"
+ "Príliš veľa požiadaviek. Prosím, skúste to znova po niekoľkých minútach"
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-zh-rCN/moonphases.xml b/shared_resources/src/main/res/values-zh-rCN/moonphases.xml
index 678282ee8..f32e7516f 100644
--- a/shared_resources/src/main/res/values-zh-rCN/moonphases.xml
+++ b/shared_resources/src/main/res/values-zh-rCN/moonphases.xml
@@ -8,4 +8,12 @@
"亏凸"
"下弦月"
"残月"
+ "新月"
+ "眉月"
+ "上弦月"
+ "盈凸"
+ "满月"
+ "亏凸"
+ "下弦月"
+ "残月"
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values-zh-rCN/strings.xml b/shared_resources/src/main/res/values-zh-rCN/strings.xml
index f129fbb02..3fcca99d0 100644
--- a/shared_resources/src/main/res/values-zh-rCN/strings.xml
+++ b/shared_resources/src/main/res/values-zh-rCN/strings.xml
@@ -224,4 +224,9 @@
"更多信息"
"重置"
+ "低"
+ "中"
+ "高"
+ "很高"
+ "请求太多。请几分钟后再试一次"
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values/moonphases.xml b/shared_resources/src/main/res/values/moonphases.xml
index d6b1f5c19..19cf167da 100644
--- a/shared_resources/src/main/res/values/moonphases.xml
+++ b/shared_resources/src/main/res/values/moonphases.xml
@@ -1,11 +1,19 @@
New Moon
+ New
Waxing Crescent
+ Waxing
First Quarter
+ First Q
Waxing Gibbous
+ Waxing
Full Moon
+ Full
Waning Gibbous
+ Waning
Last Quarter
+ Last Q
Waning Crescent
+ Waning
\ No newline at end of file
diff --git a/shared_resources/src/main/res/values/strings.xml b/shared_resources/src/main/res/values/strings.xml
index 1831937a5..296c41591 100644
--- a/shared_resources/src/main/res/values/strings.xml
+++ b/shared_resources/src/main/res/values/strings.xml
@@ -151,6 +151,7 @@
Invalid Provider Key
No cities match your search query
Unknown error occurred
+ Too many requests. Please try again after a few minutes
Update Interval
@@ -220,9 +221,13 @@
Ragweed
Ragweed Pollen
Low
+ Low
Moderate
+ Medium
High
+ High
Very High
+ V. High
Current
Refresh
diff --git a/wearapp/build.gradle b/wearapp/build.gradle
index 4bf1ddcc5..faa9bc259 100644
--- a/wearapp/build.gradle
+++ b/wearapp/build.gradle
@@ -17,8 +17,8 @@ android {
minSdkVersion 26
targetSdkVersion rootProject.targetSdkVersion
// NOTE: Version Code Format (TargetSDK, Version Name, Build Number, Variant Code (Android: 0, WearOS: 1)
- versionCode 345100081
- versionName "5.10.1"
+ versionCode 345100101
+ versionName "5.10.3"
vectorDrawables {
useSupportLibrary true
@@ -171,7 +171,7 @@ dependencies {
implementation "androidx.compose.animation:animation-graphics"
implementation "androidx.compose.runtime:runtime-livedata"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
- implementation 'androidx.paging:paging-compose:3.3.2'
+ implementation "androidx.paging:paging-compose:$paging_version"
implementation "androidx.wear.compose:compose-foundation:$wear_compose_version"
implementation "androidx.wear.compose:compose-material:$wear_compose_version"
implementation "androidx.wear.compose:compose-navigation:$wear_compose_version"
diff --git a/wearapp/src/main/java/com/thewizrd/simpleweather/preferences/DetailsWeatherTileUtils.kt b/wearapp/src/main/java/com/thewizrd/simpleweather/preferences/DetailsWeatherTileUtils.kt
index 28d99f888..5b46c39ed 100644
--- a/wearapp/src/main/java/com/thewizrd/simpleweather/preferences/DetailsWeatherTileUtils.kt
+++ b/wearapp/src/main/java/com/thewizrd/simpleweather/preferences/DetailsWeatherTileUtils.kt
@@ -26,14 +26,7 @@ object DetailsWeatherTileUtils {
}
fun isTypeAllowed(detailsType: WeatherDetailsType): Boolean {
- return when (detailsType) {
- WeatherDetailsType.MOONPHASE,
- WeatherDetailsType.TREEPOLLEN,
- WeatherDetailsType.GRASSPOLLEN,
- WeatherDetailsType.RAGWEEDPOLLEN -> false
-
- else -> true
- }
+ return true
}
fun getTileConfig(): List? {
diff --git a/wearapp/src/main/java/com/thewizrd/simpleweather/wearable/tiles/layouts/DetailsWeatherTileLayout.kt b/wearapp/src/main/java/com/thewizrd/simpleweather/wearable/tiles/layouts/DetailsWeatherTileLayout.kt
index 5be77253d..6f11fa34a 100644
--- a/wearapp/src/main/java/com/thewizrd/simpleweather/wearable/tiles/layouts/DetailsWeatherTileLayout.kt
+++ b/wearapp/src/main/java/com/thewizrd/simpleweather/wearable/tiles/layouts/DetailsWeatherTileLayout.kt
@@ -1,14 +1,17 @@
package com.thewizrd.simpleweather.wearable.tiles.layouts
import android.content.Context
+import androidx.annotation.OptIn
import androidx.compose.ui.util.fastCoerceIn
import androidx.core.graphics.ColorUtils
import androidx.wear.protolayout.ActionBuilders
import androidx.wear.protolayout.ColorBuilders.ColorProp
import androidx.wear.protolayout.DeviceParametersBuilders.DeviceParameters
+import androidx.wear.protolayout.DimensionBuilders.DpProp
import androidx.wear.protolayout.DimensionBuilders.degrees
import androidx.wear.protolayout.DimensionBuilders.dp
import androidx.wear.protolayout.DimensionBuilders.expand
+import androidx.wear.protolayout.DimensionBuilders.wrap
import androidx.wear.protolayout.LayoutElementBuilders.Box
import androidx.wear.protolayout.LayoutElementBuilders.CONTENT_SCALE_MODE_FIT
import androidx.wear.protolayout.LayoutElementBuilders.Column
@@ -16,29 +19,44 @@ import androidx.wear.protolayout.LayoutElementBuilders.FONT_WEIGHT_NORMAL
import androidx.wear.protolayout.LayoutElementBuilders.HORIZONTAL_ALIGN_CENTER
import androidx.wear.protolayout.LayoutElementBuilders.Image
import androidx.wear.protolayout.LayoutElementBuilders.LayoutElement
+import androidx.wear.protolayout.LayoutElementBuilders.Row
import androidx.wear.protolayout.LayoutElementBuilders.Spacer
+import androidx.wear.protolayout.LayoutElementBuilders.TEXT_OVERFLOW_MARQUEE
+import androidx.wear.protolayout.LayoutElementBuilders.VERTICAL_ALIGN_CENTER
+import androidx.wear.protolayout.ModifiersBuilders
import androidx.wear.protolayout.ModifiersBuilders.Background
+import androidx.wear.protolayout.ModifiersBuilders.Clickable
import androidx.wear.protolayout.ModifiersBuilders.Corner
import androidx.wear.protolayout.ModifiersBuilders.Modifiers
+import androidx.wear.protolayout.ModifiersBuilders.Padding
+import androidx.wear.protolayout.ModifiersBuilders.Semantics
import androidx.wear.protolayout.ModifiersBuilders.Transformation
import androidx.wear.protolayout.ResourceBuilders.Resources
+import androidx.wear.protolayout.expression.ProtoLayoutExperimental
+import androidx.wear.protolayout.material.Chip
+import androidx.wear.protolayout.material.ChipColors
import androidx.wear.protolayout.material.CircularProgressIndicator
+import androidx.wear.protolayout.material.CompactChip
import androidx.wear.protolayout.material.ProgressIndicatorColors
import androidx.wear.protolayout.material.Text
import androidx.wear.protolayout.material.Typography
import androidx.wear.protolayout.material.layouts.MultiButtonLayout
+import androidx.wear.protolayout.material.layouts.PrimaryLayout
import androidx.wear.tiles.tooling.preview.TilePreviewData
import androidx.wear.tiles.tooling.preview.TilePreviewHelper
import com.google.android.horologist.tiles.images.toImageResource
import com.thewizrd.common.controls.AirQualityViewModel
import com.thewizrd.common.controls.BeaufortViewModel
import com.thewizrd.common.controls.DetailItemViewModel
+import com.thewizrd.common.controls.PollenViewModel
import com.thewizrd.common.controls.UVIndexViewModel
import com.thewizrd.common.controls.WeatherDetailsType
import com.thewizrd.common.controls.toUiModel
import com.thewizrd.common.utils.ImageUtils
import com.thewizrd.common.utils.ImageUtils.rotate
+import com.thewizrd.shared_resources.appLib
import com.thewizrd.shared_resources.designer.initializeDependencies
+import com.thewizrd.shared_resources.designer.isInEditMode
import com.thewizrd.shared_resources.icons.WeatherIcons
import com.thewizrd.shared_resources.sharedDeps
import com.thewizrd.shared_resources.utils.Colors
@@ -53,11 +71,13 @@ import com.thewizrd.shared_resources.weatherdata.model.ForecastExtras
import com.thewizrd.shared_resources.weatherdata.model.HourlyForecast
import com.thewizrd.shared_resources.weatherdata.model.Location
import com.thewizrd.shared_resources.weatherdata.model.MinutelyForecast
+import com.thewizrd.shared_resources.weatherdata.model.MoonPhase
import com.thewizrd.shared_resources.weatherdata.model.Pollen
import com.thewizrd.shared_resources.weatherdata.model.Precipitation
import com.thewizrd.shared_resources.weatherdata.model.UV
import com.thewizrd.shared_resources.weatherdata.model.Weather
import com.thewizrd.simpleweather.LaunchActivity
+import com.thewizrd.simpleweather.R
import com.thewizrd.simpleweather.preferences.DetailsWeatherTileUtils
import com.thewizrd.simpleweather.ui.tiles.tools.WearPreviewDevices
import com.thewizrd.simpleweather.wearable.tiles.ID_WEATHER_ICON_PREFIX
@@ -93,29 +113,171 @@ internal fun detailsWeatherTileLayout(
): LayoutElement {
val tileConfig =
DetailsWeatherTileUtils.getTileConfig() ?: DetailsWeatherTileUtils.DEFAULT_ITEMS
- val maxButtons = DetailsWeatherTileUtils.MAX_BUTTONS
val filteredDetails = weatherDetails.toList()
.filter { tileConfig.contains(it.first) }
.sortedBy { tileConfig.indexOf(it.first) }
+ return detailsWeatherTileLayout(
+ context,
+ deviceParameters,
+ weather,
+ filteredDetails
+ )
+}
+
+internal fun detailsWeatherTileLayout(
+ context: Context,
+ deviceParameters: DeviceParameters,
+ weather: Weather?,
+ filteredTileConfig: List>
+): LayoutElement {
+ val detailItems = filteredTileConfig.take(DetailsWeatherTileUtils.MAX_BUTTONS)
+
return Box.Builder()
.setHeight(expand())
.setWidth(expand())
+ .setVerticalAlignment(VERTICAL_ALIGN_CENTER)
+ .setHorizontalAlignment(HORIZONTAL_ALIGN_CENTER)
.addContent(
- MultiButtonLayout.Builder()
- .apply {
- filteredDetails.take(maxButtons)
- .forEach { (type, model) ->
- addButtonContent(
- detailButtonItem(context, deviceParameters, weather, type, model)
+ when (detailItems.size) {
+ 0 -> {
+ Text.Builder(context, context.getString(R.string.error_noresults))
+ .setTypography(Typography.TYPOGRAPHY_BODY1)
+ .setColor(ColorProp.Builder(Colors.WHITE).build())
+ .setMaxLines(1)
+ .build()
+ }
+
+ 1, 2 -> {
+ PrimaryLayout.Builder(deviceParameters)
+ .setResponsiveContentInsetEnabled(true)
+ .setPrimaryChipContent(
+ CompactChip.Builder(
+ context,
+ Clickable.Builder()
+ .setOnClick(getLaunchAction(context))
+ .build(),
+ deviceParameters
)
+ .setTextContent(context.getString(R.string.label_nav_weathernow))
+ .build()
+ )
+ .setContent(
+ Column.Builder()
+ .setWidth(expand())
+ .apply {
+ detailItems.forEachIndexed { index, (type, model) ->
+ addContent(
+ detailChipItem(
+ context, deviceParameters, weather, type, model
+ )
+ )
+ if (index != detailItems.size - 1) {
+ addContent(Spacer.Builder().setHeight(dp(4f)).build())
+ }
+ }
+ }
+ .build()
+ )
+ .apply {
+ if (deviceParameters.screenWidthDp >= 225) {
+ weather?.location?.name?.let {
+ setPrimaryLabelTextContent(detailLocation(context, it))
+ }
+ }
}
+ .build()
}
- .build()
+
+ 3, 4 -> {
+ Column.Builder()
+ .setHeight(wrap())
+ .setWidth(wrap())
+ .setHorizontalAlignment(HORIZONTAL_ALIGN_CENTER)
+ .setModifiers(
+ Modifiers.Builder()
+ .setPadding(
+ Padding.Builder()
+ .setStart(dp(4f))
+ .setEnd(dp(4f))
+ .build()
+ )
+ .build()
+ )
+ .apply {
+ detailItems.chunked(2)
+ .forEachIndexed { index, list ->
+ addContent(
+ Row.Builder()
+ .setWidth(wrap())
+ .setHeight(wrap())
+ .setVerticalAlignment(VERTICAL_ALIGN_CENTER)
+ .apply {
+ list.forEachIndexed { index, (type, model) ->
+ addContent(
+ Column.Builder()
+ .setWidth(dp(66f))
+ .setHeight(dp(66f))
+ .setHorizontalAlignment(
+ HORIZONTAL_ALIGN_CENTER
+ )
+ .addContent(
+ detailButtonItem(
+ context,
+ deviceParameters,
+ weather,
+ type,
+ model,
+ buttonSize = dp(66f),
+ imageSize = dp(24f),
+ spacerSize = dp(10f),
+ typography = Typography.TYPOGRAPHY_CAPTION2
+ )
+ )
+ .build()
+ )
+ if (index != list.size - 1) {
+ addContent(
+ Spacer.Builder().setWidth(dp(4f))
+ .build()
+ )
+ }
+ }
+ }
+ .build()
+ )
+
+ if (index != detailItems.size - 1) {
+ addContent(Spacer.Builder().setHeight(dp(4f)).build())
+ }
+ }
+ }
+ .build()
+ }
+
+ else -> {
+ MultiButtonLayout.Builder()
+ .apply {
+ detailItems.forEach { (type, model) ->
+ addButtonContent(
+ detailButtonItem(
+ context,
+ deviceParameters,
+ weather,
+ type,
+ model
+ )
+ )
+ }
+ }
+ .build()
+ }
+ }
)
.build()
}
+@OptIn(ProtoLayoutExperimental::class)
internal fun detailLocation(
context: Context,
location: String
@@ -123,6 +285,7 @@ internal fun detailLocation(
return Text.Builder(context, location.split(',').firstOrNull() ?: location)
.setTypography(Typography.TYPOGRAPHY_BODY1)
.setColor(ColorProp.Builder(Colors.WHITE).build())
+ .setOverflow(TEXT_OVERFLOW_MARQUEE)
.setMaxLines(1)
.build()
}
@@ -132,7 +295,11 @@ internal fun detailButtonItem(
deviceParameters: DeviceParameters,
weather: Weather?,
detailsType: WeatherDetailsType,
- model: DetailItemViewModel
+ model: DetailItemViewModel,
+ buttonSize: DpProp = dp(52f),
+ imageSize: DpProp = dp(18f),
+ spacerSize: DpProp = dp(8f),
+ typography: Int? = null
): LayoutElement {
return Box.Builder()
.setHorizontalAlignment(HORIZONTAL_ALIGN_CENTER)
@@ -141,15 +308,15 @@ internal fun detailButtonItem(
.addContent(
Column.Builder()
.setHorizontalAlignment(HORIZONTAL_ALIGN_CENTER)
- .setHeight(expand())
- .setWidth(expand())
+ .setHeight(buttonSize)
+ .setWidth(buttonSize)
.setModifiers(
Modifiers.Builder()
.setBackground(
Background.Builder()
.setCorner(
Corner.Builder()
- .setRadius(dp(32f))
+ .setRadius(dp(buttonSize.value * 13f / 8))
.build()
)
.setColor(
@@ -161,12 +328,12 @@ internal fun detailButtonItem(
.build()
)
.addContent(
- Spacer.Builder().setHeight(dp(10f)).build()
+ Spacer.Builder().setHeight(spacerSize).build()
)
.addContent(
Image.Builder()
- .setWidth(dp(14f))
- .setHeight(dp(14f))
+ .setWidth(imageSize)
+ .setHeight(imageSize)
.setModifiers(
Modifiers.Builder()
.apply {
@@ -191,15 +358,37 @@ internal fun detailButtonItem(
.build()
)
.addContent(
- Spacer.Builder().setHeight(dp(4f)).build()
+ Spacer.Builder().setHeight(dp(3f)).build()
)
.addContent(
Text.Builder(context, model.shortValue.toString())
- .setTypography(Typography.TYPOGRAPHY_CAPTION3)
+ .setTypography(
+ typography ?: when (detailsType) {
+ WeatherDetailsType.FEELSLIKE,
+ WeatherDetailsType.HUMIDITY,
+ WeatherDetailsType.POPCLOUDINESS,
+ WeatherDetailsType.POPCHANCE,
+ WeatherDetailsType.DEWPOINT,
+ WeatherDetailsType.BEAUFORT,
+ WeatherDetailsType.UV,
+ WeatherDetailsType.AIRQUALITY -> Typography.TYPOGRAPHY_CAPTION2
+
+ else -> Typography.TYPOGRAPHY_CAPTION3
+ }
+ )
.setWeight(FONT_WEIGHT_NORMAL)
.setColor(ColorProp.Builder(Colors.WHITE).build())
.setMaxLines(1)
.setScalable(false)
+ .setModifiers(
+ Modifiers.Builder()
+ .setSemantics(
+ Semantics.Builder()
+ .setRole(ModifiersBuilders.SEMANTICS_ROLE_BUTTON)
+ .build()
+ )
+ .build()
+ )
.build()
)
.build()
@@ -217,10 +406,7 @@ internal fun detailButtonItem(
WeatherDetailsType.DEWPOINT,
WeatherDetailsType.MOONRISE,
WeatherDetailsType.MOONSET,
- WeatherDetailsType.MOONPHASE,
- WeatherDetailsType.TREEPOLLEN,
- WeatherDetailsType.GRASSPOLLEN,
- WeatherDetailsType.RAGWEEDPOLLEN -> {
+ WeatherDetailsType.MOONPHASE -> {
}
WeatherDetailsType.UV -> {
@@ -351,11 +537,116 @@ internal fun detailButtonItem(
)
}
}
+
+ WeatherDetailsType.TREEPOLLEN -> {
+ weather?.condition?.pollen?.let {
+ val pollenModel = PollenViewModel(it)
+
+ addContent(
+ CircularProgressIndicator.Builder()
+ .setProgress(
+ pollenModel.treePollenProgress.div(pollenModel.progressMax.toFloat())
+ .fastCoerceIn(0f, 1f)
+ )
+ .setStrokeWidth(dp(2f))
+ .setOuterMarginApplied(false)
+ .setCircularProgressIndicatorColors(
+ ProgressIndicatorColors(
+ pollenModel.treePollenProgressColor,
+ ColorUtils.blendARGB(
+ pollenModel.treePollenProgressColor,
+ 0xFF1B1B1B.toInt(),
+ 0.95f
+ )
+ )
+ )
+ .build()
+ )
+ }
+ }
+
+ WeatherDetailsType.GRASSPOLLEN -> {
+ weather?.condition?.pollen?.let {
+ val pollenModel = PollenViewModel(it)
+
+ addContent(
+ CircularProgressIndicator.Builder()
+ .setProgress(
+ pollenModel.grassPollenProgress.div(pollenModel.progressMax.toFloat())
+ .fastCoerceIn(0f, 1f)
+ )
+ .setStrokeWidth(dp(2f))
+ .setOuterMarginApplied(false)
+ .setCircularProgressIndicatorColors(
+ ProgressIndicatorColors(
+ pollenModel.grassPollenProgressColor,
+ ColorUtils.blendARGB(
+ pollenModel.grassPollenProgressColor,
+ 0xFF1B1B1B.toInt(),
+ 0.95f
+ )
+ )
+ )
+ .build()
+ )
+ }
+ }
+
+ WeatherDetailsType.RAGWEEDPOLLEN -> {
+ weather?.condition?.pollen?.let {
+ val pollenModel = PollenViewModel(it)
+
+ addContent(
+ CircularProgressIndicator.Builder()
+ .setProgress(
+ pollenModel.ragweedPollenProgress.div(pollenModel.progressMax.toFloat())
+ .fastCoerceIn(0f, 1f)
+ )
+ .setStrokeWidth(dp(2f))
+ .setOuterMarginApplied(false)
+ .setCircularProgressIndicatorColors(
+ ProgressIndicatorColors(
+ pollenModel.ragweedPollenProgressColor,
+ ColorUtils.blendARGB(
+ pollenModel.ragweedPollenProgressColor,
+ 0xFF1B1B1B.toInt(),
+ 0.95f
+ )
+ )
+ )
+ .build()
+ )
+ }
+ }
}
}
.build()
}
+internal fun detailChipItem(
+ context: Context,
+ deviceParameters: DeviceParameters,
+ weather: Weather?,
+ detailsType: WeatherDetailsType,
+ model: DetailItemViewModel
+): LayoutElement {
+ return Chip.Builder(context, Clickable.Builder().build(), deviceParameters)
+ .setWidth(expand())
+ .setIconContent(
+ if (appLib.isInEditMode() || deviceParameters.supportsTransformation() || model.iconRotation == 0) {
+ "${ID_WEATHER_ICON_PREFIX}${model.icon}"
+ } else {
+ "${ID_ROTATION_PREFIX}${model.iconRotation}:${ID_WEATHER_ICON_PREFIX}${model.icon}"
+ }
+ )
+ .setPrimaryLabelContent(model.label.toString())
+ .setSecondaryLabelContent(model.value.toString())
+ .setChipColors(
+ ChipColors.secondaryChipColors(androidx.wear.protolayout.material.Colors.DEFAULT)
+ )
+ .build()
+}
+
private fun getLaunchAction(context: Context): ActionBuilders.Action {
return ActionBuilders.LaunchAction.Builder()
.setAndroidActivity(
@@ -370,11 +661,18 @@ private fun getLaunchAction(context: Context): ActionBuilders.Action {
@WearPreviewDevices
private fun detailsWeatherTilePreview(context: Context): TilePreviewData {
context.initializeDependencies(isPhone = false)
+
val wim = sharedDeps.weatherIconsManager.iconProvider
val weather = buildMockWeatherData()
val viewModel = weather.toUiModel()
val weatherDetails = viewModel.weatherDetailsMap
+ val sampleTileConfig = weatherDetails
+ .filterKeys { DetailsWeatherTileUtils.isTypeAllowed(it) }
+ .toList()
+ .shuffled()
+ .take(Random.nextInt(1, DetailsWeatherTileUtils.MAX_BUTTONS + 1 /* exclusive */))
+ .shuffled()
return TilePreviewData(
onTileResourceRequest = { request ->
@@ -408,8 +706,8 @@ private fun detailsWeatherTilePreview(context: Context): TilePreviewData {
detailsWeatherTileLayout(
context,
request.deviceConfiguration,
- weather = weather,
- weatherDetails = weatherDetails
+ weather,
+ sampleTileConfig
)
).build()
}
@@ -524,12 +822,12 @@ private fun buildMockWeatherData(): Weather {
lowC = 15f
icon = WeatherIcons.DAY_SUNNY
airQuality = AirQuality().apply {
- index = 46
+ index = Random.nextInt(0, 301)
}
- beaufort = Beaufort(Beaufort.BeaufortScale.B1)
- uv = UV(3f)
+ beaufort = Beaufort(Beaufort.BeaufortScale.valueOf(Random.nextInt(0, 12)))
+ uv = UV(Random.nextInt(0, 11).toFloat())
pollen = Pollen().apply {
- treePollenCount = Pollen.PollenCount.HIGH
+ treePollenCount = Pollen.PollenCount.VERY_HIGH
grassPollenCount = Pollen.PollenCount.LOW
ragweedPollenCount = Pollen.PollenCount.MODERATE
}
@@ -544,16 +842,19 @@ private fun buildMockWeatherData(): Weather {
dewpointC = 10f
}
precipitation = Precipitation().apply {
- pop = 15
- cloudiness = 25
+ pop = 100
+ cloudiness = 100
qpfRainIn = 0.05f
qpfRainMm = 1.27f
- qpfSnowIn = 0f
- qpfSnowCm = 0f
+ qpfSnowIn = 10.1f
+ qpfSnowCm = 25.4f
}
astronomy = Astronomy().apply {
- sunrise = LocalDateTime.of(LocalDate.now(), LocalTime.of(6, 0))
- sunset = LocalDateTime.of(LocalDate.now(), LocalTime.of(18, 0))
+ sunrise = LocalDateTime.of(LocalDate.now(), LocalTime.of(0, 0))
+ sunset = LocalDateTime.of(LocalDate.now(), LocalTime.of(12, 0))
+ moonrise = LocalDateTime.of(LocalDate.now(), LocalTime.of(12, 43))
+ moonset = LocalDateTime.of(LocalDate.now(), LocalTime.of(0, 46))
+ moonPhase = MoonPhase(MoonPhase.MoonPhaseType.entries[Random.nextInt(0, 7)])
}
source = WeatherAPI.ANDROID
query = ""
diff --git a/weather-api/build.gradle b/weather-api/build.gradle
index b12cdfd8d..d57b276c3 100644
--- a/weather-api/build.gradle
+++ b/weather-api/build.gradle
@@ -133,7 +133,7 @@ dependencies {
implementation "com.squareup.moshi:moshi-adapters:$moshi_version"
kapt "com.github.nename0:moshi-java-codegen:1.1.1"
- fullgmsImplementation 'com.google.android.libraries.places:places:4.0.0'
+ fullgmsImplementation 'com.google.android.libraries.places:places:4.1.0'
fullgmsImplementation 'com.android.volley:volley:1.2.1' // Required by Places API ^^^
fullgmsImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$kotlinx_version"
}
diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/here/weather/HEREWeatherProvider.kt b/weather-api/src/main/java/com/thewizrd/weather_api/here/weather/HEREWeatherProvider.kt
index 3f8b50fc0..c20b3f6cd 100644
--- a/weather-api/src/main/java/com/thewizrd/weather_api/here/weather/HEREWeatherProvider.kt
+++ b/weather-api/src/main/java/com/thewizrd/weather_api/here/weather/HEREWeatherProvider.kt
@@ -100,7 +100,7 @@ class HEREWeatherProvider : WeatherProviderImpl() {
val authorization = hereOAuthService.getBearerToken(false)
if (authorization.isNullOrBlank()) {
- throw WeatherException(ErrorStatus.NETWORKERROR).apply {
+ throw WeatherException(ErrorStatus.INVALIDAPIKEY).apply {
initCause(Exception("Invalid bearer token: $authorization"))
}
}
diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/locationiq/LocationData.kt b/weather-api/src/main/java/com/thewizrd/weather_api/locationiq/LocationData.kt
index d2796e9f4..172cffb30 100644
--- a/weather-api/src/main/java/com/thewizrd/weather_api/locationiq/LocationData.kt
+++ b/weather-api/src/main/java/com/thewizrd/weather_api/locationiq/LocationData.kt
@@ -2,16 +2,13 @@ package com.thewizrd.weather_api.locationiq
import com.thewizrd.shared_resources.locationdata.LocationQuery
import com.thewizrd.shared_resources.weatherdata.WeatherAPI
-import java.util.*
+import java.util.Locale
/* LocationIQ AutoComplete */
fun createLocationModel(result: AutoCompleteQuery, weatherAPI: String): LocationQuery {
return LocationQuery().apply {
- val town: String
- val region: String
-
// Try to get district name or fallback to city name
- town = if (!result.address.neighbourhood.isNullOrBlank())
+ val town = if (!result.address.neighbourhood.isNullOrBlank())
result.address.neighbourhood
else if (!result.address.hamlet.isNullOrBlank())
result.address.hamlet
@@ -27,7 +24,7 @@ fun createLocationModel(result: AutoCompleteQuery, weatherAPI: String): Location
result.address.name
// Try to get district name or fallback to city name
- region = if (!result.address.region.isNullOrBlank())
+ val region = if (!result.address.region.isNullOrBlank())
result.address.region
else if (!result.address.county.isNullOrBlank())
result.address.county
@@ -44,7 +41,7 @@ fun createLocationModel(result: AutoCompleteQuery, weatherAPI: String): Location
String.format("%s, %s", town, region)
locationCountry = if (!result.address.countryCode.isNullOrBlank())
- result.address.countryCode.toUpperCase(Locale.ROOT)
+ result.address.countryCode.uppercase(Locale.ROOT)
else
result.address.country
@@ -62,44 +59,30 @@ fun createLocationModel(result: AutoCompleteQuery, weatherAPI: String): Location
/* LocationIQ Geocoder */
fun createLocationModel(result: GeoLocation, weatherAPI: String): LocationQuery {
return LocationQuery().apply {
- val town: String
- val region: String
-
// Try to get district name or fallback to city name
- town = if (!result.address.neighbourhood.isNullOrBlank())
+ val town = if (!result.address.neighbourhood.isNullOrBlank())
result.address.neighbourhood
- else if (!result.address.hamlet.isNullOrBlank())
- result.address.hamlet
else if (!result.address.suburb.isNullOrBlank())
result.address.suburb
- else if (!result.address.village.isNullOrBlank())
- result.address.village
- else if (!result.address.town.isNullOrBlank())
- result.address.town
- else if (!result.address.city.isNullOrBlank())
- result.address.city
+ else if (!result.address.county.isNullOrBlank())
+ result.address.county
else
- result.address.name
+ result.address.city
// Try to get district name or fallback to city name
- region = if (!result.address.region.isNullOrBlank())
- result.address.region
- else if (!result.address.county.isNullOrBlank())
+ val region = if (!result.address.county.isNullOrBlank() && town != result.address.city)
result.address.county
- else if (!result.address.stateDistrict.isNullOrBlank())
- result.address.stateDistrict
+ else if (!result.address.city.isNullOrBlank() && town != result.address.city)
+ result.address.city
else if (!result.address.state.isNullOrBlank())
result.address.state
else
result.address.country
- locationName = if (!result.address.name.isNullOrBlank() && result.address.name != town)
- String.format("%s, %s, %s", result.address.name, town, region)
- else
- String.format("%s, %s", town, region)
+ locationName = String.format("%s, %s", town, region)
locationCountry = if (!result.address.countryCode.isNullOrBlank())
- result.address.countryCode.toUpperCase(Locale.ROOT)
+ result.address.countryCode.uppercase(Locale.ROOT)
else
result.address.country
diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/locationiq/LocationIQProvider.kt b/weather-api/src/main/java/com/thewizrd/weather_api/locationiq/LocationIQProvider.kt
index f4655a013..ac6d4ba7e 100644
--- a/weather-api/src/main/java/com/thewizrd/weather_api/locationiq/LocationIQProvider.kt
+++ b/weather-api/src/main/java/com/thewizrd/weather_api/locationiq/LocationIQProvider.kt
@@ -35,7 +35,7 @@ class LocationIQProvider : WeatherLocationProviderImpl() {
private const val AUTOCOMPLETE_QUERY_URL =
"https://api.locationiq.com/v1/autocomplete.php?key=%s&q=%s&limit=10&normalizecity=1&addressdetails=1&accept-language=%s"
private const val GEOLOCATION_QUERY_URL =
- "https://api.locationiq.com/v1/reverse.php?key=%s&lat=%s&lon=%s&format=json&zoom=14&namedetails=0&addressdetails=1&accept-language=%s&normalizecity=1"
+ "https://api.locationiq.com/v1/reverse.php?key=%s&lat=%s&lon=%s&format=json&zoom=14&namedetails=0&addressdetails=1&accept-language=%s&normalizecity=1&normalizeaddress=1"
private const val KEY_QUERY_URL = "https://us1.unwiredlabs.com/v2/timezone.php?token=%s"
}
diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/utils/APIRequestUtils.kt b/weather-api/src/main/java/com/thewizrd/weather_api/utils/APIRequestUtils.kt
index f8e698def..adc08004b 100644
--- a/weather-api/src/main/java/com/thewizrd/weather_api/utils/APIRequestUtils.kt
+++ b/weather-api/src/main/java/com/thewizrd/weather_api/utils/APIRequestUtils.kt
@@ -97,7 +97,7 @@ object APIRequestUtils {
setRetryCount(apiID, 1)
setNextRetryTime(apiID, retryTimeInMs)
}
- throw WeatherException(ErrorStatus.NETWORKERROR)
+ throw WeatherException(ErrorStatus.RATELIMITED)
.initCause(createThrowable(response))
}
}
@@ -138,7 +138,7 @@ object APIRequestUtils {
val nextRetryTime = getNextRetryTime(apiID)
if (currentTime < nextRetryTime) {
- throw WeatherException(ErrorStatus.NETWORKERROR)
+ throw WeatherException(ErrorStatus.RATELIMITED)
}
}
diff --git a/weather-api/src/main/java/com/thewizrd/weather_api/weatherkit/WeatherKitProvider.kt b/weather-api/src/main/java/com/thewizrd/weather_api/weatherkit/WeatherKitProvider.kt
index c7b74d5b3..b5b3dd9ee 100644
--- a/weather-api/src/main/java/com/thewizrd/weather_api/weatherkit/WeatherKitProvider.kt
+++ b/weather-api/src/main/java/com/thewizrd/weather_api/weatherkit/WeatherKitProvider.kt
@@ -121,7 +121,7 @@ class WeatherKitProvider : WeatherProviderImpl() {
val authorization = weatherKitJwtService.getBearerToken(false)
if (authorization.isNullOrBlank()) {
- throw WeatherException(ErrorStatus.NETWORKERROR).apply {
+ throw WeatherException(ErrorStatus.INVALIDAPIKEY).apply {
initCause(Exception("Invalid bearer token: $authorization"))
}
}