@@ -5,7 +5,6 @@ import android.annotation.SuppressLint
55import android.content.*
66import android.content.pm.PackageManager
77import android.location.Geocoder
8- import android.location.Location
98import android.os.*
109import android.util.AttributeSet
1110import androidx.annotation.StringRes
@@ -29,13 +28,22 @@ class Greetings @JvmOverloads constructor(
2928 private val fusedClient by lazy { LocationServices .getFusedLocationProviderClient(context) }
3029 private val handler = Handler (Looper .getMainLooper())
3130 private val coroutineScope = CoroutineScope (SupervisorJob () + Dispatchers .Main )
31+ private val prefs by lazy { context.getSharedPreferences(" neko_weather_cache" , Context .MODE_PRIVATE ) }
3232
3333 private var showWeather = false
34- private var lastWeatherTime = 0L
35- private var lastWeatherText: String? = null
3634 private var useManualCity = false
37-
3835 private val weatherInterval = 30 * 60 * 1000L
36+
37+ private var cachedTemp: Int = - 999
38+ private var cachedCode: Int = - 1
39+ private var cachedCity: String = " "
40+ private var lastWeatherTime: Long = 0L
41+
42+ private val KEY_TEMP = " w_temp"
43+ private val KEY_CODE = " w_code"
44+ private val KEY_CITY = " w_city"
45+ private val KEY_TIME = " w_time"
46+
3947 private val locationRequest = LocationRequest .Builder (
4048 Priority .PRIORITY_BALANCED_POWER_ACCURACY , 10_000L
4149 ).setMinUpdateIntervalMillis(60_000L ).build()
@@ -45,14 +53,18 @@ class Greetings @JvmOverloads constructor(
4553 if (intent?.action in listOf (
4654 Intent .ACTION_TIME_TICK , Intent .ACTION_TIME_CHANGED , Intent .ACTION_TIMEZONE_CHANGED
4755 )
48- ) updateGreeting(lastWeatherText ? : " " )
56+ ) updateDisplay( )
4957 }
5058 }
5159
5260 init {
53- showWeather = DataStore .showWeatherInfo
54- useManualCity = DataStore .manualWeatherEnabled
55- updateGreeting()
61+ cachedTemp = prefs.getInt(KEY_TEMP , - 999 )
62+ cachedCode = prefs.getInt(KEY_CODE , - 1 )
63+ cachedCity = prefs.getString(KEY_CITY , " " ) ? : " "
64+ lastWeatherTime = prefs.getLong(KEY_TIME , 0L )
65+
66+ refreshSettings()
67+ updateDisplay()
5668 }
5769
5870 override fun onAttachedToWindow () {
@@ -63,10 +75,16 @@ class Greetings @JvmOverloads constructor(
6375 addAction(Intent .ACTION_TIMEZONE_CHANGED )
6476 })
6577
66- showWeather = DataStore .showWeatherInfo
67- useManualCity = DataStore .manualWeatherEnabled
78+ refreshSettings()
6879
69- if (showWeather) fetchWeather()
80+ if (showWeather) {
81+ val now = System .currentTimeMillis()
82+ if ((now - lastWeatherTime) < weatherInterval && cachedCode != - 1 ) {
83+ updateDisplay()
84+ } else {
85+ fetchWeather()
86+ }
87+ }
7088 scheduleWeatherRefresh()
7189 }
7290
@@ -77,9 +95,13 @@ class Greetings @JvmOverloads constructor(
7795 coroutineScope.cancel()
7896 }
7997
80- override fun isFocused (): Boolean = true
98+ private fun refreshSettings () {
99+ showWeather = DataStore .showWeatherInfo
100+ useManualCity = DataStore .manualWeatherEnabled
101+ }
81102
82103 private fun scheduleWeatherRefresh () {
104+ handler.removeCallbacksAndMessages(null )
83105 handler.postDelayed(object : Runnable {
84106 override fun run () {
85107 if (showWeather) fetchWeather()
@@ -88,7 +110,7 @@ class Greetings @JvmOverloads constructor(
88110 }, weatherInterval)
89111 }
90112
91- private fun updateGreeting ( weatherText : String = "" ) {
113+ private fun updateDisplay ( ) {
92114 val hour = Calendar .getInstance().get(Calendar .HOUR_OF_DAY )
93115 @StringRes val greetRes = when (hour) {
94116 in 5 .. 10 -> R .string.uwu_greeting_morning
@@ -97,9 +119,19 @@ class Greetings @JvmOverloads constructor(
97119 in 19 .. 23 -> R .string.uwu_greeting_night
98120 else -> R .string.uwu_greeting_late_night
99121 }
100-
101122 val greeting = context.getString(greetRes)
102- text = if (weatherText.isNotEmpty() && showWeather) " $greeting $weatherText " else greeting
123+
124+ if (showWeather && cachedCode != - 1 && cachedTemp != - 999 ) {
125+ val condition = getLocalizedCondition(cachedCode)
126+ val emoji = getWeatherEmoji(cachedCode)
127+ val prefix = context.getString(R .string.weather_today)
128+
129+ val locationSuffix = if (cachedCity.isNotEmpty()) " - $cachedCity " else " "
130+
131+ text = " $greeting $prefix $condition $emoji , $cachedTemp °C$locationSuffix "
132+ } else {
133+ text = greeting
134+ }
103135 }
104136
105137 private fun fetchWeather () {
@@ -134,8 +166,9 @@ class Greetings @JvmOverloads constructor(
134166 coroutineScope.launch(Dispatchers .IO ) {
135167 try {
136168 val now = System .currentTimeMillis()
137- if ((now - lastWeatherTime) < weatherInterval && lastWeatherText != null ) {
138- withContext(Dispatchers .Main ) { updateGreeting(lastWeatherText!! ) }
169+
170+ if ((now - lastWeatherTime) < weatherInterval && cachedCode != - 1 ) {
171+ withContext(Dispatchers .Main ) { updateDisplay() }
139172 return @launch
140173 }
141174
@@ -159,19 +192,20 @@ class Greetings @JvmOverloads constructor(
159192 " https://api.open-meteo.com/v1/forecast?latitude=$lat &longitude=$lon ¤t_weather=true"
160193 ).readText()
161194 val current = JSONObject (response).getJSONObject(" current_weather" )
162- val temp = current.getDouble(" temperature" ).roundToInt()
163- val code = current.getInt(" weathercode" )
164-
165- val condition = getLocalizedCondition(code)
166- val emoji = getWeatherEmoji(code)
167- val prefix = context.getString(R .string.weather_today)
168195
169- val locationSuffix = if (! resolvedCity.isNullOrEmpty()) " - $resolvedCity " else " "
170- val weatherText = " $prefix $condition $emoji , $temp °C$locationSuffix "
171-
172- lastWeatherText = weatherText
196+ cachedTemp = current.getDouble(" temperature" ).roundToInt()
197+ cachedCode = current.getInt(" weathercode" )
198+ cachedCity = resolvedCity ? : " "
173199 lastWeatherTime = now
174- withContext(Dispatchers .Main ) { updateGreeting(weatherText) }
200+
201+ prefs.edit()
202+ .putInt(KEY_TEMP , cachedTemp)
203+ .putInt(KEY_CODE , cachedCode)
204+ .putString(KEY_CITY , cachedCity)
205+ .putLong(KEY_TIME , lastWeatherTime)
206+ .apply ()
207+
208+ withContext(Dispatchers .Main ) { updateDisplay() }
175209 } catch (e: Exception ) {
176210 e.printStackTrace()
177211 }
@@ -189,7 +223,6 @@ class Greetings @JvmOverloads constructor(
189223 val first = results.getJSONObject(0 )
190224 val lat = first.getDouble(" latitude" )
191225 val lon = first.getDouble(" longitude" )
192-
193226 val officialName = first.optString(" name" , city)
194227
195228 fetchWeatherByCoords(lat, lon, officialName)
0 commit comments