Merge branch 'main' of github.com:MM2-0/Kvaesitso
This commit is contained in:
commit
d81936212d
@ -18,6 +18,8 @@ import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import de.mm20.launcher2.ktx.foldOrNull
|
||||
import de.mm20.launcher2.ktx.isBetterThan
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
||||
class DevicePoseProvider internal constructor(
|
||||
@ -37,10 +39,16 @@ class DevicePoseProvider internal constructor(
|
||||
}
|
||||
|
||||
fun getLocation(minTimeMs: Long = 1000, minDistanceM: Float = 1f) = channelFlow {
|
||||
fun updateLocation(update: Location?) {
|
||||
if (update == null) return
|
||||
if (!update.isBetterThan(lastLocation)) return
|
||||
lastLocation = update
|
||||
updateDeclination(update)
|
||||
trySend(update)
|
||||
}
|
||||
|
||||
val locationCallback = LocationListenerCompat {
|
||||
lastLocation = it
|
||||
updateDeclination(it)
|
||||
trySend(it)
|
||||
updateLocation(it)
|
||||
}
|
||||
|
||||
context.getSystemService<LocationManager>()
|
||||
@ -50,20 +58,14 @@ class DevicePoseProvider internal constructor(
|
||||
val hasCoarseAccess =
|
||||
context.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
|
||||
val location =
|
||||
(if (hasFineAccess) this@runCatching.getLastKnownLocation(LocationManager.GPS_PROVIDER) else null)
|
||||
?: if (hasCoarseAccess) this@runCatching.getLastKnownLocation(
|
||||
LocationManager.NETWORK_PROVIDER
|
||||
) else null
|
||||
val previousLocation =
|
||||
hasFineAccess.foldOrNull { getLastKnownLocation(LocationManager.GPS_PROVIDER) } ?:
|
||||
hasCoarseAccess.foldOrNull { getLastKnownLocation(LocationManager.NETWORK_PROVIDER) }
|
||||
|
||||
if (location != null) {
|
||||
lastLocation = location
|
||||
updateDeclination(location)
|
||||
trySend(location)
|
||||
}
|
||||
updateLocation(previousLocation)
|
||||
|
||||
if (hasFineAccess) {
|
||||
this@runCatching.requestLocationUpdates(
|
||||
requestLocationUpdates(
|
||||
LocationManager.GPS_PROVIDER,
|
||||
minTimeMs,
|
||||
minDistanceM,
|
||||
@ -71,7 +73,7 @@ class DevicePoseProvider internal constructor(
|
||||
)
|
||||
}
|
||||
if (hasCoarseAccess) {
|
||||
this@runCatching.requestLocationUpdates(
|
||||
requestLocationUpdates(
|
||||
LocationManager.NETWORK_PROVIDER,
|
||||
minTimeMs,
|
||||
minDistanceM,
|
||||
|
||||
@ -318,8 +318,8 @@
|
||||
<string name="search_action_websearch">Internetes keresés</string>
|
||||
<string name="plugin_state_setup_required">Először be kell állítani ezt a bővítményt</string>
|
||||
<string name="plugin_action_setup">Beállítás</string>
|
||||
<string name="plugin_type_weather">Időjárás-előrejelzés szolgáltató</string>
|
||||
<string name="plugin_weather_provider_enable">Beállítás időjárás-előrejelzési szolgáltatónak</string>
|
||||
<string name="plugin_type_weather">Időjáráselőrejelzési szolgáltató</string>
|
||||
<string name="plugin_weather_provider_enable">Beállítás időjáráselőrejelzési szolgáltatónak</string>
|
||||
<string name="preference_clock_widget_alignment_bottom">Alulra</string>
|
||||
<string name="preference_clockwidget_battery_part_summary">Az akkumulátor jelenlegi töltöttségi szintjének megjelenítése, amikor az akkumulátor lemerült vagy töltődik</string>
|
||||
<string name="preference_clockwidget_alarm_part_summary">Azon riasztások megjelenítése, amelyek a következő 8 órán belül megszólalnak</string>
|
||||
@ -379,7 +379,7 @@
|
||||
<string name="preference_search_currencyconverter">Valutaváltó</string>
|
||||
<string name="preference_search_bar_auto_focus_summary">A billentyűzet automatikus megjelenítése az alkalmazásfiók megnyitásakor</string>
|
||||
<string name="note_widget_link_file_summary">Szinkronizálja a modul tartalmát egy külső fájllal</string>
|
||||
<string name="plugin_weather_provider_enabled">Jelenleg időjárás-előrejelzés szolgáltatóként van beállítva</string>
|
||||
<string name="plugin_weather_provider_enabled">Jelenleg időjáráselőrejelzési szolgáltatóként van beállítva</string>
|
||||
<string name="preference_search_websites">Weboldalak</string>
|
||||
<string name="preference_search_websites_summary">Egy weboldal előnézetének megjelenítése, ha a keresési lekérdezés egy webcím</string>
|
||||
<string name="preference_edit_favorites_summary">A kitűzött elemek sorrendjének módosítása</string>
|
||||
@ -835,4 +835,11 @@
|
||||
<string name="gesture_action_widgets">Modulok</string>
|
||||
<string name="bad_configuration_title">Gratulálunk, kizárta saját magát!</string>
|
||||
<string name="bad_configuration_summary">Felfedezte a beállítások olyan kombinációját, amely a keresést és a beállításokat is elérhetetlenné teszi — gyakorlatilag kizárja Önt az indítóból.</string>
|
||||
<string name="preference_screen_shapes">Alakzatok</string>
|
||||
<string name="preference_shapes_default">Alapértelmezett</string>
|
||||
<string name="preference_shapes_extra_round">További lekerekítés</string>
|
||||
<string name="preference_shapes_rect">Négyszögletes</string>
|
||||
<string name="preference_shapes_base">Alap alakzat</string>
|
||||
<string name="confirmation_delete_shapes_scheme">Biztosan törölni szeretné a(z) %1$s nevű alakzatsémát?</string>
|
||||
<string name="new_shapes_name">Új alakzatok</string>
|
||||
</resources>
|
||||
@ -846,4 +846,11 @@
|
||||
<string name="gesture_action_widgets">Widget</string>
|
||||
<string name="bad_configuration_title">Congratulazioni, ti sei chiuso fuori!</string>
|
||||
<string name="bad_configuration_summary">Hai scoperto una combinazione di impostazioni che rende inaccessibili sia la ricerca sia le impostazioni, impedendoti di fatto di accedere al launcher.</string>
|
||||
<string name="preference_shapes_default">Predefinito</string>
|
||||
<string name="preference_screen_shapes">Forme</string>
|
||||
<string name="preference_shapes_extra_round">Arrotondamento extra</string>
|
||||
<string name="preference_shapes_rect">Rettangolare</string>
|
||||
<string name="preference_shapes_base">Forma di base</string>
|
||||
<string name="confirmation_delete_shapes_scheme">Vuoi davvero eliminare lo schema di forme %1$s?</string>
|
||||
<string name="new_shapes_name">Nuove forme</string>
|
||||
</resources>
|
||||
@ -835,4 +835,11 @@
|
||||
<string name="preference_widgets_on_home_screen">Widgets op het thuisscherm</string>
|
||||
<string name="bad_configuration_title">Proficiat, je hebt jezelf buiten gesloten!</string>
|
||||
<string name="bad_configuration_summary">Je hebt een combinatie van instellingen ontdekt die zowel zoeken als de instellingen onbereikbaar maakt - je bent nu volledig uit de startschermapp gesloten.</string>
|
||||
<string name="preference_screen_shapes">Vormen</string>
|
||||
<string name="preference_shapes_default">Standaard</string>
|
||||
<string name="preference_shapes_extra_round">Extra rond</string>
|
||||
<string name="preference_shapes_rect">Rechthoekig</string>
|
||||
<string name="preference_shapes_base">Basisvorm</string>
|
||||
<string name="confirmation_delete_shapes_scheme">Weet je zeker dat je de vorm %1$s wil verwijderen?</string>
|
||||
<string name="new_shapes_name">Nieuwe vormen</string>
|
||||
</resources>
|
||||
@ -0,0 +1,37 @@
|
||||
package de.mm20.launcher2.ktx
|
||||
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.Duration.Companion.nanoseconds
|
||||
|
||||
import android.location.Location as AndroidLocation
|
||||
|
||||
/* https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/util/location/LocationUtils.kt
|
||||
* GPL-3.0-or-later
|
||||
*/
|
||||
fun AndroidLocation.isBetterThan(previous: AndroidLocation?): Boolean {
|
||||
if (longitude.isNaN() || latitude.isNaN()) return false
|
||||
if (previous == null) return true
|
||||
|
||||
val locationTimeDiff = elapsedRealtimeNanos.nanoseconds - previous.elapsedRealtimeNanos.nanoseconds
|
||||
val isMuchNewer = locationTimeDiff > 2.minutes
|
||||
val isMuchOlder = locationTimeDiff < (-2).minutes
|
||||
val isNewer = locationTimeDiff.isPositive()
|
||||
|
||||
val accuracyDelta = accuracy - previous.accuracy
|
||||
val isLessAccurate = accuracyDelta > 0f
|
||||
val isMoreAccurate = accuracyDelta < 0f
|
||||
val isMuchLessAccurate = accuracyDelta > 200f
|
||||
|
||||
val isFromSameProvider = provider == previous.provider
|
||||
|
||||
return when {
|
||||
// the user has likely moved
|
||||
isMuchNewer -> true
|
||||
// If the new location is more than two minutes older, it must be worse
|
||||
isMuchOlder -> false
|
||||
isMoreAccurate -> true
|
||||
isNewer && !isLessAccurate -> true
|
||||
isNewer && !isMuchLessAccurate && isFromSameProvider -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,14 @@
|
||||
package de.mm20.launcher2.ktx
|
||||
|
||||
inline fun Boolean.toInt(): Int {
|
||||
fun Boolean.toInt(): Int {
|
||||
return if (this) 1 else 0
|
||||
}
|
||||
|
||||
fun <T> Boolean.fold(
|
||||
whenTrue: () -> T,
|
||||
otherwise: () -> T
|
||||
): T = if (this) whenTrue() else otherwise()
|
||||
|
||||
fun <T> Boolean.foldOrNull(
|
||||
whenTrue: () -> T
|
||||
): T? = fold(whenTrue) { null }
|
||||
|
||||
@ -388,6 +388,8 @@ internal fun parseOpeningSchedule(
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!rule.holidays.isNullOrEmpty()) {
|
||||
continue // skip PH and SH entries
|
||||
} else if (!rule.times.isNullOrEmpty() || !rule.months.isNullOrEmpty()) {
|
||||
rulesMap.forEach { _, it ->
|
||||
it.add(rule)
|
||||
@ -395,14 +397,12 @@ internal fun parseOpeningSchedule(
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out rules that are not valid for the current year, month, and week. Hopefully,
|
||||
// there is only one rule left per weekday. If not, skip that weekday.
|
||||
val applicableRules = rulesMap.mapNotNull { (day, rules) ->
|
||||
// Filter out rules that are not valid for the current year, month, and week.
|
||||
val applicableRules = rulesMap.flatMap { (day, rules) ->
|
||||
rules.filterYears(localTime)
|
||||
.filterMonths(localTime)
|
||||
.filterNthDays(localTime)
|
||||
.map { it.copy(weekdays = listOf(day)) }
|
||||
.singleOrNull()
|
||||
}
|
||||
|
||||
val hours = mutableSetOf<OpeningHours>()
|
||||
|
||||
@ -302,4 +302,43 @@ class OpeningHoursTest {
|
||||
LocalDateTime.of(2025, Month.APRIL, 10, 0, 0)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun regressTest0() {
|
||||
OpeningSchedule.Hours(
|
||||
setOf(
|
||||
OpeningHours(dayOfWeek = DayOfWeek.MONDAY, startTime = LocalTime.of(8,30), duration = Duration.ofHours(3) + Duration.ofMinutes(30)),
|
||||
OpeningHours(dayOfWeek = DayOfWeek.TUESDAY, startTime = LocalTime.of(8,30), duration = Duration.ofHours(3) + Duration.ofMinutes(30)),
|
||||
OpeningHours(dayOfWeek = DayOfWeek.WEDNESDAY, startTime = LocalTime.of(8,30), duration = Duration.ofHours(3) + Duration.ofMinutes(30)),
|
||||
OpeningHours(dayOfWeek = DayOfWeek.THURSDAY, startTime = LocalTime.of(8,30), duration = Duration.ofHours(3) + Duration.ofMinutes(30)),
|
||||
OpeningHours(dayOfWeek = DayOfWeek.FRIDAY, startTime = LocalTime.of(8,30), duration = Duration.ofHours(3) + Duration.ofMinutes(30)),
|
||||
|
||||
OpeningHours(dayOfWeek = DayOfWeek.MONDAY, startTime = LocalTime.of(14,0), duration = Duration.ofHours(2)),
|
||||
OpeningHours(dayOfWeek = DayOfWeek.TUESDAY, startTime = LocalTime.of(14,0), duration = Duration.ofHours(2)),
|
||||
OpeningHours(dayOfWeek = DayOfWeek.FRIDAY, startTime = LocalTime.of(14,0), duration = Duration.ofHours(2)),
|
||||
|
||||
OpeningHours(dayOfWeek = DayOfWeek.THURSDAY, startTime = LocalTime.of(17,0), duration = Duration.ofHours(2)),
|
||||
)
|
||||
) assertEqualTo parseOpeningSchedule(
|
||||
"Mo-Fr 08:30-12:00; Mo,Tu,Fr 14:00-16:00; Th 17:00-19:00"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun regressTest1() {
|
||||
OpeningSchedule.Hours(
|
||||
setOf(
|
||||
OpeningHours(dayOfWeek = DayOfWeek.TUESDAY, startTime = LocalTime.of(11,45), duration = Duration.ofHours(10) + Duration.ofMinutes(45)),
|
||||
OpeningHours(dayOfWeek = DayOfWeek.WEDNESDAY, startTime = LocalTime.of(11,45), duration = Duration.ofHours(10) + Duration.ofMinutes(45)),
|
||||
OpeningHours(dayOfWeek = DayOfWeek.THURSDAY, startTime = LocalTime.of(11,45), duration = Duration.ofHours(10) + Duration.ofMinutes(45)),
|
||||
OpeningHours(dayOfWeek = DayOfWeek.FRIDAY, startTime = LocalTime.of(11,45), duration = Duration.ofHours(10) + Duration.ofMinutes(45)),
|
||||
OpeningHours(dayOfWeek = DayOfWeek.SATURDAY, startTime = LocalTime.of(11,45), duration = Duration.ofHours(10) + Duration.ofMinutes(45)),
|
||||
|
||||
OpeningHours(dayOfWeek = DayOfWeek.SUNDAY, startTime = LocalTime.of(11,30), duration = Duration.ofHours(11)),
|
||||
// We don't track public holidays. Otherwise, we'd probably go mad!
|
||||
)
|
||||
) assertEqualTo parseOpeningSchedule(
|
||||
"Tu-Sa 11:45-22:30; Su 11:30-22:30; PH 11:30-22:30"
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user