mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat(logging): Replace Timber with Kermit for multiplatform logging (#4083)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
a927481e4d
commit
0776e029f3
92 changed files with 727 additions and 957 deletions
|
|
@ -32,12 +32,12 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.core.content.ContextCompat
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.google.android.gms.common.api.ResolvableApiException
|
||||
import com.google.android.gms.location.LocationRequest
|
||||
import com.google.android.gms.location.LocationServices
|
||||
import com.google.android.gms.location.LocationSettingsRequest
|
||||
import com.google.android.gms.location.Priority
|
||||
import timber.log.Timber
|
||||
|
||||
private const val INTERVAL_MILLIS = 10000L
|
||||
|
||||
|
|
@ -66,11 +66,11 @@ fun LocationPermissionsHandler(onPermissionResult: (Boolean) -> Unit) {
|
|||
val locationSettingsLauncher =
|
||||
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartIntentSenderForResult()) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
Timber.d("Location settings changed by user.")
|
||||
Logger.d { "Location settings changed by user." }
|
||||
// User has enabled location services or improved accuracy.
|
||||
onPermissionResult(true) // Settings are now adequate, and permission was already granted.
|
||||
} else {
|
||||
Timber.d("Location settings change cancelled by user.")
|
||||
Logger.d { "Location settings change cancelled by user." }
|
||||
// User chose not to change settings. The permission itself is still granted,
|
||||
// but the experience might be degraded. For the purpose of enabling map features,
|
||||
// we consider this as success if the core permission is there.
|
||||
|
|
@ -111,7 +111,7 @@ fun LocationPermissionsHandler(onPermissionResult: (Boolean) -> Unit) {
|
|||
val task = client.checkLocationSettings(builder.build())
|
||||
|
||||
task.addOnSuccessListener {
|
||||
Timber.d("Location settings are satisfied.")
|
||||
Logger.d { "Location settings are satisfied." }
|
||||
onPermissionResult(true) // Permission granted and settings are good
|
||||
}
|
||||
|
||||
|
|
@ -122,11 +122,11 @@ fun LocationPermissionsHandler(onPermissionResult: (Boolean) -> Unit) {
|
|||
locationSettingsLauncher.launch(intentSenderRequest)
|
||||
// Result of this launch will be handled by locationSettingsLauncher's callback
|
||||
} catch (sendEx: ActivityNotFoundException) {
|
||||
Timber.d("Error launching location settings resolution ${sendEx.message}.")
|
||||
Logger.d { "Error launching location settings resolution ${sendEx.message}." }
|
||||
onPermissionResult(true) // Permission is granted, but settings dialog failed. Proceed.
|
||||
}
|
||||
} else {
|
||||
Timber.d("Location settings are not satisfiable.${exception.message}")
|
||||
Logger.d { "Location settings are not satisfiable.${exception.message}" }
|
||||
onPermissionResult(true) // Permission is granted, but settings not ideal. Proceed.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.core.graphics.createBitmap
|
||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.google.android.gms.location.LocationCallback
|
||||
import com.google.android.gms.location.LocationRequest
|
||||
import com.google.android.gms.location.LocationResult
|
||||
|
|
@ -124,7 +125,6 @@ import org.meshtastic.proto.MeshProtos.Position
|
|||
import org.meshtastic.proto.MeshProtos.Waypoint
|
||||
import org.meshtastic.proto.copy
|
||||
import org.meshtastic.proto.waypoint
|
||||
import timber.log.Timber
|
||||
import java.text.DateFormat
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
|
|
@ -219,7 +219,7 @@ fun MapView(
|
|||
try {
|
||||
cameraPositionState.animate(cameraUpdate)
|
||||
} catch (e: IllegalStateException) {
|
||||
Timber.d("Error animating camera to location: ${e.message}")
|
||||
Logger.d { "Error animating camera to location: ${e.message}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -239,14 +239,14 @@ fun MapView(
|
|||
try {
|
||||
@Suppress("MissingPermission")
|
||||
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null)
|
||||
Timber.d("Started location tracking")
|
||||
Logger.d { "Started location tracking" }
|
||||
} catch (e: SecurityException) {
|
||||
Timber.d("Location permission not available: ${e.message}")
|
||||
Logger.d { "Location permission not available: ${e.message}" }
|
||||
isLocationTrackingEnabled = false
|
||||
}
|
||||
} else {
|
||||
fusedLocationClient.removeLocationUpdates(locationCallback)
|
||||
Timber.d("Stopped location tracking")
|
||||
Logger.d { "Stopped location tracking" }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -412,7 +412,7 @@ fun MapView(
|
|||
cameraPositionState.animate(cameraUpdate)
|
||||
hasCenteredTraceroute = true
|
||||
} catch (e: IllegalStateException) {
|
||||
Timber.d("Error centering traceroute overlay: ${e.message}")
|
||||
Logger.d { "Error centering traceroute overlay: ${e.message}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -548,7 +548,7 @@ fun MapView(
|
|||
CameraUpdateFactory.newLatLngBounds(bounds.build(), 100),
|
||||
)
|
||||
}
|
||||
Timber.d("Cluster clicked! $cluster")
|
||||
Logger.d { "Cluster clicked! $cluster" }
|
||||
}
|
||||
true
|
||||
},
|
||||
|
|
@ -679,9 +679,9 @@ fun MapView(
|
|||
val currentPosition = cameraPositionState.position
|
||||
val newCameraPosition = CameraPosition.Builder(currentPosition).bearing(0f).build()
|
||||
cameraPositionState.animate(CameraUpdateFactory.newCameraPosition(newCameraPosition))
|
||||
Timber.d("Oriented map to north")
|
||||
Logger.d { "Oriented map to north" }
|
||||
} catch (e: IllegalStateException) {
|
||||
Timber.d("Error orienting map to north: ${e.message}")
|
||||
Logger.d { "Error orienting map to north: ${e.message}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -715,7 +715,7 @@ fun MapView(
|
|||
internal fun convertIntToEmoji(unicodeCodePoint: Int): String = try {
|
||||
String(Character.toChars(unicodeCodePoint))
|
||||
} catch (e: IllegalArgumentException) {
|
||||
Timber.w(e, "Invalid unicode code point: $unicodeCodePoint")
|
||||
Logger.w(e) { "Invalid unicode code point: $unicodeCodePoint" }
|
||||
"\uD83D\uDCCD"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import android.app.Application
|
|||
import android.net.Uri
|
||||
import androidx.core.net.toFile
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import co.touchlab.kermit.Logger
|
||||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.model.CameraPosition
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
|
|
@ -56,7 +57,6 @@ import org.meshtastic.core.prefs.map.MapPrefs
|
|||
import org.meshtastic.core.service.ServiceRepository
|
||||
import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed
|
||||
import org.meshtastic.proto.ConfigProtos
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
|
@ -200,7 +200,7 @@ constructor(
|
|||
fun selectCustomTileProvider(config: CustomTileProviderConfig?) {
|
||||
if (config != null) {
|
||||
if (!isValidTileUrlTemplate(config.urlTemplate)) {
|
||||
Timber.tag("MapViewModel").w("Attempted to select invalid URL template: ${config.urlTemplate}")
|
||||
Logger.withTag("MapViewModel").w("Attempted to select invalid URL template: ${config.urlTemplate}")
|
||||
_selectedCustomTileProviderUrl.value = null
|
||||
googleMapsPrefs.selectedCustomTileUrl = null
|
||||
return
|
||||
|
|
@ -224,7 +224,8 @@ constructor(
|
|||
|
||||
fun createUrlTileProvider(urlString: String): TileProvider? {
|
||||
if (!isValidTileUrlTemplate(urlString)) {
|
||||
Timber.tag("MapViewModel").e("Tile URL does not contain valid {x}, {y}, and {z} placeholders: $urlString")
|
||||
Logger.withTag("MapViewModel")
|
||||
.e("Tile URL does not contain valid {x}, {y}, and {z} placeholders: $urlString")
|
||||
return null
|
||||
}
|
||||
return object : UrlTileProvider(TILE_SIZE, TILE_SIZE) {
|
||||
|
|
@ -237,7 +238,7 @@ constructor(
|
|||
return try {
|
||||
URL(formattedUrl)
|
||||
} catch (e: MalformedURLException) {
|
||||
Timber.tag("MapViewModel").e(e, "Malformed URL: $formattedUrl")
|
||||
Logger.withTag("MapViewModel").e(e) { "Malformed URL: $formattedUrl" }
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
@ -290,7 +291,7 @@ constructor(
|
|||
try {
|
||||
_selectedGoogleMapType.value = MapType.valueOf(savedGoogleMapTypeName ?: MapType.NORMAL.name)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
Timber.e(e, "Invalid saved Google Map type: $savedGoogleMapTypeName")
|
||||
Logger.e(e) { "Invalid saved Google Map type: $savedGoogleMapTypeName" }
|
||||
_selectedGoogleMapType.value = MapType.NORMAL // Fallback in case of invalid stored name
|
||||
googleMapsPrefs.selectedGoogleMapType = null
|
||||
}
|
||||
|
|
@ -335,14 +336,14 @@ constructor(
|
|||
}
|
||||
_mapLayers.value = loadedItems
|
||||
if (loadedItems.isNotEmpty()) {
|
||||
Timber.tag("MapViewModel").i("Loaded ${loadedItems.size} persisted map layers.")
|
||||
Logger.withTag("MapViewModel").i("Loaded ${loadedItems.size} persisted map layers.")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Timber.tag("MapViewModel").i("Map layers directory does not exist. No layers loaded.")
|
||||
Logger.withTag("MapViewModel").i("Map layers directory does not exist. No layers loaded.")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("MapViewModel").e(e, "Error loading persisted map layers")
|
||||
Logger.withTag("MapViewModel").e(e) { "Error loading persisted map layers" }
|
||||
_mapLayers.value = emptyList()
|
||||
}
|
||||
}
|
||||
|
|
@ -367,7 +368,7 @@ constructor(
|
|||
}
|
||||
|
||||
if (layerType == null) {
|
||||
Timber.tag("MapViewModel").e("Unsupported map layer file type: $extension")
|
||||
Logger.withTag("MapViewModel").e("Unsupported map layer file type: $extension")
|
||||
return@launch
|
||||
}
|
||||
|
||||
|
|
@ -384,7 +385,7 @@ constructor(
|
|||
val newItem = MapLayerItem(name = layerName, uri = localFileUri, layerType = layerType)
|
||||
_mapLayers.value = _mapLayers.value + newItem
|
||||
} else {
|
||||
Timber.tag("MapViewModel").e("Failed to copy file to internal storage.")
|
||||
Logger.withTag("MapViewModel").e("Failed to copy file to internal storage.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -402,7 +403,7 @@ constructor(
|
|||
inputStream?.use { input -> outputStream.use { output -> input.copyTo(output) } }
|
||||
Uri.fromFile(outputFile)
|
||||
} catch (e: IOException) {
|
||||
Timber.tag("MapViewModel").e(e, "Error copying file to internal storage")
|
||||
Logger.withTag("MapViewModel").e(e) { "Error copying file to internal storage" }
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
@ -453,7 +454,7 @@ constructor(
|
|||
file.delete()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("MapViewModel").e(e, "Error deleting file from internal storage")
|
||||
Logger.withTag("MapViewModel").e(e) { "Error deleting file from internal storage" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -465,7 +466,7 @@ constructor(
|
|||
try {
|
||||
application.contentResolver.openInputStream(uriToLoad)
|
||||
} catch (_: Exception) {
|
||||
Timber.d("MapViewModel: Error opening InputStream from URI: $uriToLoad")
|
||||
Logger.d { "MapViewModel: Error opening InputStream from URI: $uriToLoad" }
|
||||
null
|
||||
}
|
||||
}
|
||||
|
|
@ -480,7 +481,7 @@ constructor(
|
|||
LayerType.GEOJSON -> loadGeoJsonLayerIfNeeded(layerItem, map)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.tag("MapViewModel").e(e, "Error loading map layer for ${layerItem.uri}")
|
||||
Logger.withTag("MapViewModel").e(e) { "Error loading map layer for ${layerItem.uri}" }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue