@@ -13,24 +13,24 @@ import kotlinx.coroutines.flow.StateFlow
1313import kotlinx.coroutines.flow.asStateFlow
1414import kotlinx.coroutines.launch
1515import org.wordpress.android.R
16+ import org.wordpress.android.analytics.AnalyticsTracker.Stat
1617import org.wordpress.android.fluxc.model.jetpackai.JetpackAIAssistantFeature
1718import org.wordpress.android.modules.UI_THREAD
1819import org.wordpress.android.ui.mysite.SelectedSiteRepository
19- import org.wordpress.android.util.audio.IAudioRecorder
20- import org.wordpress.android.viewmodel.ContextProvider
21- import org.wordpress.android.viewmodel.ScopedViewModel
22- import org.wordpress.android.ui.voicetocontent.VoiceToContentUIStateType.INITIALIZING
23- import org.wordpress.android.ui.voicetocontent.VoiceToContentUIStateType.READY_TO_RECORD
24- import org.wordpress.android.ui.voicetocontent.VoiceToContentUIStateType.RECORDING
2520import org.wordpress.android.ui.voicetocontent.VoiceToContentUIStateType.ERROR
2621import org.wordpress.android.ui.voicetocontent.VoiceToContentUIStateType.INELIGIBLE_FOR_FEATURE
22+ import org.wordpress.android.ui.voicetocontent.VoiceToContentUIStateType.INITIALIZING
2723import org.wordpress.android.ui.voicetocontent.VoiceToContentUIStateType.PROCESSING
28-
24+ import org.wordpress.android.ui.voicetocontent.VoiceToContentUIStateType.READY_TO_RECORD
25+ import org.wordpress.android.ui.voicetocontent.VoiceToContentUIStateType.RECORDING
26+ import org.wordpress.android.util.audio.IAudioRecorder
27+ import org.wordpress.android.util.audio.IAudioRecorder.AudioRecorderResult.Error
28+ import org.wordpress.android.util.audio.IAudioRecorder.AudioRecorderResult.Success
29+ import org.wordpress.android.viewmodel.ContextProvider
30+ import org.wordpress.android.viewmodel.ScopedViewModel
2931import java.io.File
3032import javax.inject.Inject
3133import javax.inject.Named
32- import org.wordpress.android.util.audio.IAudioRecorder.AudioRecorderResult.Success
33- import org.wordpress.android.util.audio.IAudioRecorder.AudioRecorderResult.Error
3434
3535@HiltViewModel
3636class VoiceToContentViewModel @Inject constructor(
@@ -41,7 +41,7 @@ class VoiceToContentViewModel @Inject constructor(
4141 private val recordingUseCase : RecordingUseCase ,
4242 private val contextProvider : ContextProvider ,
4343 private val prepareVoiceToContentUseCase : PrepareVoiceToContentUseCase ,
44- private val logger : VoiceToContentLogger
44+ private val logger : VoiceToContentTelemetry
4545) : ScopedViewModel(mainDispatcher) {
4646 private val _requestPermission = MutableLiveData <Unit >()
4747 val requestPermission = _requestPermission as LiveData <Unit >
@@ -52,6 +52,11 @@ class VoiceToContentViewModel @Inject constructor(
5252 private val _amplitudes = MutableLiveData <List <Float >>()
5353 val amplitudes: LiveData <List <Float >> get() = _amplitudes
5454
55+ private val _onIneligibleForVoiceToContent = MutableLiveData <String >()
56+ val onIneligibleForVoiceToContent = _onIneligibleForVoiceToContent as LiveData <String >
57+
58+ private var isStarted = false
59+
5560 private val _state = MutableStateFlow (VoiceToContentUiState (
5661 uiStateType = INITIALIZING ,
5762 header = HeaderUIModel (
@@ -79,6 +84,10 @@ class VoiceToContentViewModel @Inject constructor(
7984 val site = selectedSiteRepository.getSelectedSite()
8085 if (site == null || ! isVoiceToContentEnabled()) return
8186
87+ if (! isStarted) {
88+ logger.track(Stat .VOICE_TO_CONTENT_SHEET_SHOWN )
89+ }
90+
8291 viewModelScope.launch {
8392 when (val result = prepareVoiceToContentUseCase.execute(site)) {
8493 is PrepareVoiceToContentResult .Success -> {
@@ -90,6 +99,8 @@ class VoiceToContentViewModel @Inject constructor(
9099 }
91100 }
92101 }
102+
103+ isStarted = true
93104 }
94105
95106 // Recording
@@ -167,6 +178,7 @@ class VoiceToContentViewModel @Inject constructor(
167178
168179 // Permissions
169180 private fun onRequestPermission () {
181+ logger.track(Stat .VOICE_TO_CONTENT_BUTTON_START_RECORDING_TAPPED )
170182 _requestPermission .postValue(Unit )
171183 }
172184
@@ -185,14 +197,17 @@ class VoiceToContentViewModel @Inject constructor(
185197
186198 // user actions
187199 private fun onMicTap () {
200+ logger.track(Stat .VOICE_TO_CONTENT_BUTTON_START_RECORDING_TAPPED )
188201 startRecording()
189202 }
190203
191204 private fun onStopTap () {
205+ logger.track(Stat .VOICE_TO_CONTENT_BUTTON_DONE_TAPPED )
192206 stopRecording()
193207 }
194208
195209 private fun onClose () {
210+ logger.track(Stat .VOICE_TO_CONTENT_BUTTON_CLOSE_TAPPED )
196211 _dismiss .postValue(Unit )
197212 }
198213
@@ -201,6 +216,13 @@ class VoiceToContentViewModel @Inject constructor(
201216 start()
202217 }
203218
219+ private fun onLinkTap (url : String? ) {
220+ logger.track(Stat .VOICE_TO_CONTENT_BUTTON_UPGRADE_TAPPED )
221+ url?.let {
222+ _onIneligibleForVoiceToContent .postValue(it)
223+ }
224+ }
225+
204226 // transitions
205227 private fun transitionToInitializing () {
206228 _state .value = VoiceToContentUiState (
@@ -222,6 +244,9 @@ class VoiceToContentViewModel @Inject constructor(
222244
223245 private fun transitionToReadyToRecordOrIneligibleForFeature (model : JetpackAIAssistantFeature ) {
224246 val isEligibleForFeature = voiceToContentFeatureUtils.isEligibleForVoiceToContent(model)
247+ if (! isEligibleForFeature) {
248+ logger.track(Stat .VOICE_TO_CONTENT_BUTTON_RECORDING_LIMIT_REACHED )
249+ }
225250 val requestsAvailable = voiceToContentFeatureUtils.getRequestLimit(model)
226251 val currentState = _state .value
227252 _state .value = currentState.copy(
@@ -236,7 +261,8 @@ class VoiceToContentViewModel @Inject constructor(
236261 onMicTap = ::onMicTap,
237262 onRequestPermission = ::onRequestPermission,
238263 hasPermission = hasAllPermissionsForRecording(),
239- upgradeUrl = model.upgradeUrl
264+ upgradeUrl = model.upgradeUrl,
265+ onLinkTap = ::onLinkTap
240266 )
241267 )
242268 }
0 commit comments