mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-05-03 20:24:32 -04:00
Inject PlatformAnalytics directly (#3358)
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
<ID>CommentWrapping:SignalMetrics.kt$Metric.SNR$/* Selected 12 as the max to get 4 equal vertical sections. */</ID>
|
||||
<ID>ComposableNaming:NodeDetailScreen.kt$notesSection</ID>
|
||||
<ID>ComposableParamOrder:Channel.kt$ChannelScreen</ID>
|
||||
<ID>ComposableParamOrder:Channel.kt$EditChannelUrl</ID>
|
||||
<ID>ComposableParamOrder:DeviceMetrics.kt$DeviceMetricsChart</ID>
|
||||
<ID>ComposableParamOrder:EmptyStateContent.kt$EmptyStateContent</ID>
|
||||
<ID>ComposableParamOrder:EnvironmentCharts.kt$ChartContent</ID>
|
||||
|
||||
@@ -19,9 +19,7 @@ package com.geeksville.mesh
|
||||
|
||||
import android.app.Application
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import org.meshtastic.core.analytics.platform.PlatformAnalytics
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* The main application class for Meshtastic.
|
||||
@@ -30,26 +28,7 @@ import javax.inject.Inject
|
||||
* application components, including analytics and platform-specific helpers, and manages analytics consent based on
|
||||
* user preferences.
|
||||
*/
|
||||
@HiltAndroidApp
|
||||
class MeshUtilApplication : Application() {
|
||||
|
||||
@Inject lateinit var platformAnalytics: PlatformAnalytics
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Provides access to the platform-specific analytics provider. Initialized via the injected [PlatformAnalytics]
|
||||
* during [onCreate].
|
||||
*/
|
||||
lateinit var analytics: PlatformAnalytics
|
||||
private set
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
// Initialize platform-specific features (analytics, crash reporting, etc.)
|
||||
analytics = platformAnalytics
|
||||
}
|
||||
}
|
||||
@HiltAndroidApp class MeshUtilApplication : Application()
|
||||
|
||||
fun logAssert(executeReliableWrite: Boolean) {
|
||||
if (!executeReliableWrite) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.NavHostController
|
||||
import com.geeksville.mesh.AdminProtos
|
||||
import com.geeksville.mesh.AppOnlyProtos
|
||||
import com.geeksville.mesh.ConfigProtos.Config
|
||||
@@ -55,6 +56,7 @@ import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.shareIn
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.analytics.platform.PlatformAnalytics
|
||||
import org.meshtastic.core.data.repository.FirmwareReleaseRepository
|
||||
import org.meshtastic.core.data.repository.MeshLogRepository
|
||||
import org.meshtastic.core.data.repository.NodeRepository
|
||||
@@ -130,6 +132,7 @@ constructor(
|
||||
firmwareReleaseRepository: FirmwareReleaseRepository,
|
||||
private val uiPreferencesDataSource: UiPreferencesDataSource,
|
||||
private val meshServiceNotifications: MeshServiceNotifications,
|
||||
private val analytics: PlatformAnalytics,
|
||||
) : ViewModel() {
|
||||
|
||||
val theme: StateFlow<Int> = uiPreferencesDataSource.theme
|
||||
@@ -351,4 +354,8 @@ constructor(
|
||||
fun onAppIntroCompleted() {
|
||||
uiPreferencesDataSource.setAppIntroCompleted(true)
|
||||
}
|
||||
|
||||
fun addNavigationTrackingEffect(navController: NavHostController) {
|
||||
analytics.addNavigationTrackingEffect(navController)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import androidx.lifecycle.coroutineScope
|
||||
import com.geeksville.mesh.BuildConfig
|
||||
import com.geeksville.mesh.CoroutineDispatchers
|
||||
import com.geeksville.mesh.MeshProtos
|
||||
import com.geeksville.mesh.MeshUtilApplication
|
||||
import com.geeksville.mesh.android.BinaryLogFile
|
||||
import com.geeksville.mesh.android.BuildUtils
|
||||
import com.geeksville.mesh.concurrent.handledLaunch
|
||||
@@ -46,6 +45,7 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.analytics.platform.PlatformAnalytics
|
||||
import org.meshtastic.core.model.util.anonymize
|
||||
import org.meshtastic.core.prefs.radio.RadioPrefs
|
||||
import org.meshtastic.core.service.ConnectionState
|
||||
@@ -74,6 +74,7 @@ constructor(
|
||||
private val processLifecycle: Lifecycle,
|
||||
private val radioPrefs: RadioPrefs,
|
||||
private val interfaceFactory: InterfaceFactory,
|
||||
private val analytics: PlatformAnalytics,
|
||||
) {
|
||||
|
||||
private val _connectionState = MutableStateFlow(ConnectionState.DISCONNECTED)
|
||||
@@ -307,7 +308,7 @@ constructor(
|
||||
false
|
||||
} else {
|
||||
// Record that this use has configured a new radio
|
||||
MeshUtilApplication.analytics.track("mesh_bond")
|
||||
analytics.track("mesh_bond")
|
||||
|
||||
// Ignore any errors that happen while closing old device
|
||||
ignoreException { stopInterface() }
|
||||
|
||||
@@ -75,7 +75,6 @@ import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.geeksville.mesh.BuildConfig
|
||||
import com.geeksville.mesh.MeshProtos
|
||||
import com.geeksville.mesh.MeshUtilApplication
|
||||
import com.geeksville.mesh.model.BTScanModel
|
||||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.geeksville.mesh.navigation.channelsGraph
|
||||
@@ -158,7 +157,7 @@ fun MainScreen(uIViewModel: UIViewModel = hiltViewModel(), scanModel: BTScanMode
|
||||
}
|
||||
}
|
||||
|
||||
MeshUtilApplication.analytics.addNavigationTrackingEffect(navController = navController)
|
||||
uIViewModel.addNavigationTrackingEffect(navController)
|
||||
|
||||
VersionChecks(uIViewModel)
|
||||
val alertDialogState by uIViewModel.currentAlert.collectAsStateWithLifecycle()
|
||||
|
||||
@@ -92,7 +92,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.geeksville.mesh.AppOnlyProtos.ChannelSet
|
||||
import com.geeksville.mesh.ChannelProtos
|
||||
import com.geeksville.mesh.ConfigProtos
|
||||
import com.geeksville.mesh.MeshUtilApplication.Companion.analytics
|
||||
import com.geeksville.mesh.channelSet
|
||||
import com.geeksville.mesh.copy
|
||||
import com.geeksville.mesh.ui.common.components.ScannedQrCodeDialog
|
||||
@@ -102,7 +101,6 @@ import com.google.accompanist.permissions.rememberPermissionState
|
||||
import com.journeyapps.barcodescanner.ScanContract
|
||||
import com.journeyapps.barcodescanner.ScanOptions
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.analytics.DataPair
|
||||
import org.meshtastic.core.model.Channel
|
||||
import org.meshtastic.core.model.util.getChannelUrl
|
||||
import org.meshtastic.core.model.util.qrCode
|
||||
@@ -311,6 +309,7 @@ fun ChannelScreen(
|
||||
EditChannelUrl(
|
||||
enabled = enabled,
|
||||
channelUrl = selectedChannelSet.getChannelUrl(shouldAdd = shouldAddChannelsState),
|
||||
onTrackShare = viewModel::trackShare,
|
||||
onConfirm = {
|
||||
viewModel.requestChannelUrl(it) {
|
||||
Toast.makeText(context, R.string.channel_invalid, Toast.LENGTH_SHORT).show()
|
||||
@@ -368,7 +367,13 @@ fun ChannelScreen(
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun EditChannelUrl(enabled: Boolean, channelUrl: Uri, modifier: Modifier = Modifier, onConfirm: (Uri) -> Unit) {
|
||||
private fun EditChannelUrl(
|
||||
enabled: Boolean,
|
||||
channelUrl: Uri,
|
||||
modifier: Modifier = Modifier,
|
||||
onTrackShare: () -> Unit,
|
||||
onConfirm: (Uri) -> Unit,
|
||||
) {
|
||||
val focusManager = LocalFocusManager.current
|
||||
val clipboardManager = LocalClipboard.current
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
@@ -416,7 +421,7 @@ private fun EditChannelUrl(enabled: Boolean, channelUrl: Uri, modifier: Modifier
|
||||
|
||||
else -> {
|
||||
// track how many times users share channels
|
||||
analytics.track("share", DataPair("content_type", "channel"))
|
||||
onTrackShare()
|
||||
coroutineScope.launch {
|
||||
clipboardManager.setClipEntry(
|
||||
ClipEntry(ClipData.newPlainText(label, valueState.toString())),
|
||||
|
||||
@@ -34,6 +34,8 @@ import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import org.meshtastic.core.analytics.DataPair
|
||||
import org.meshtastic.core.analytics.platform.PlatformAnalytics
|
||||
import org.meshtastic.core.data.repository.RadioConfigRepository
|
||||
import org.meshtastic.core.model.util.toChannelSet
|
||||
import org.meshtastic.core.proto.getChannelList
|
||||
@@ -47,6 +49,7 @@ class ChannelViewModel
|
||||
constructor(
|
||||
private val serviceRepository: ServiceRepository,
|
||||
private val radioConfigRepository: RadioConfigRepository,
|
||||
private val analytics: PlatformAnalytics,
|
||||
) : ViewModel() {
|
||||
|
||||
val connectionState = serviceRepository.connectionState
|
||||
@@ -121,6 +124,10 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun trackShare() {
|
||||
analytics.track("share", DataPair("content_type", "channel"))
|
||||
}
|
||||
|
||||
private inline fun updateLoraConfig(crossinline body: (Config.LoRaConfig) -> Config.LoRaConfig) {
|
||||
val data = body(localConfig.value.lora)
|
||||
setConfig(config { lora = data })
|
||||
|
||||
Reference in New Issue
Block a user