Skip to content

Commit 30dcc7e

Browse files
enhanced weather info
1 parent 00768c5 commit 30dcc7e

1 file changed

Lines changed: 62 additions & 29 deletions

File tree

app/src/main/java/com/neko/marquee/text/Greetings.kt

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import android.annotation.SuppressLint
55
import android.content.*
66
import android.content.pm.PackageManager
77
import android.location.Geocoder
8-
import android.location.Location
98
import android.os.*
109
import android.util.AttributeSet
1110
import 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&current_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

Comments
 (0)