Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/flipcash/features/messenger/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ android {
}

dependencies {
implementation(project(":apps:flipcash:shared:analytics"))
implementation(project(":apps:flipcash:shared:chat"))
implementation(project(":apps:flipcash:shared:chat-ui"))
implementation(project(":apps:flipcash:shared:amount-entry"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import androidx.paging.PagingData
import androidx.paging.cachedIn
import androidx.paging.flatMap
import androidx.paging.insertSeparators
import com.flipcash.app.analytics.Analytics
import com.flipcash.app.analytics.FlipcashAnalyticsService
import com.flipcash.app.contacts.ContactCoordinator
import com.flipcash.app.core.AppRoute
import com.flipcash.app.core.chat.ChatIdentifier
Expand Down Expand Up @@ -92,6 +94,7 @@ internal class ChatViewModel @Inject constructor(
private val userManager: UserManager,
private val resources: ResourceHelper,
private val featureFlags: FeatureFlagController,
private val analytics: FlipcashAnalyticsService,
) : BaseViewModel<ChatViewModel.State, ChatViewModel.Event>(
initialState = State(),
updateStateForEvent = updateStateForEvent,
Expand Down Expand Up @@ -468,8 +471,14 @@ internal class ChatViewModel @Inject constructor(

viewModelScope.launch {
chatCoordinator.sendMessage(chatId, textToSend)
.onSuccess { trace("message sent successfully") }
.onFailure { trace("message failed to send - ${it.localizedMessage}") }
.onSuccess {
trace("message sent successfully")
analytics.messageSentInChat()
}
.onFailure { cause ->
trace("message failed to send - ${cause.localizedMessage}")
analytics.messageSentInChat(error = cause)
}
}
}
.flowOn(Dispatchers.Main.immediate)
Expand Down Expand Up @@ -613,12 +622,22 @@ internal class ChatViewModel @Inject constructor(
chatCoordinator.refreshFeed()
}
delay(400.milliseconds)
analytics.transfer(
event = Analytics.Transfer.SentCash,
amount = verifiedFiat.localFiat,
successful = true,
)
dispatchEvent(
Dispatchers.Main,
Event.SendComplete(amount.localFiat.nativeAmount)
)
}.onFailure {
}.onFailure { cause ->
dispatchEvent(Event.SendStateUpdated())
analytics.transfer(
event = Analytics.Transfer.SentCash,
amount = verifiedFiat.localFiat,
error = cause,
)
BottomBarManager.showError(
title = resources.getString(R.string.error_title_cashFailedToSend),
message = resources.getString(R.string.error_description_cashFailedToSend),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ interface FlipcashAnalyticsService : AnalyticsService {
fun openTokenInfo(source: Analytics.TokenInfoSource, mint: Mint)
fun buy(method: Analytics.PurchaseMethod, mint: Mint, amount: Fiat, error: Throwable? = null)
fun sell(mint: Mint, amount: Fiat, feeAmount: Fiat, error: Throwable? = null)
fun messageSentInChat(error: Throwable? = null)
fun deeplinkOpened(url: String)
fun deeplinkParsed(type: DeeplinkType?, url: String)
fun deeplinkRouted(type: DeeplinkType, error: Throwable? = null)
Expand All @@ -55,6 +56,8 @@ object Analytics {
data object Clipboard : SentCashLink
data class App(val name: String) : SentCashLink
}

data object SentCash : Transfer
}
enum class OnrampSource { Settings, Balance, Give }
enum class OnrampVerificationStep { ShowInfo, EnterPhone, ConfirmPhone, EnterEmail, ConfirmEmail }
Expand Down Expand Up @@ -96,6 +99,8 @@ class StubFlipcashAnalytics : FlipcashAnalyticsService {
override fun buy(method: Analytics.PurchaseMethod, mint: Mint, amount: Fiat, error: Throwable?) = Unit
override fun sell(mint: Mint, amount: Fiat, feeAmount: Fiat, error: Throwable?) = Unit

override fun messageSentInChat(error: Throwable?) = Unit

override fun deeplinkOpened(url: String) = Unit
override fun deeplinkParsed(type: DeeplinkType?, url: String) = Unit
override fun deeplinkRouted(type: DeeplinkType, error: Throwable?) = Unit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,22 @@ internal sealed interface AnalyticsEvent {
override val name = "Receive Cash Link"
}

sealed interface ChatEvent: AnalyticsEvent {
data object SentCash : ChatEvent {
override val name = "Sent Cash"
}

data class SentMessage(
val error: Throwable? = null
): ChatEvent {
override val name = "Sent Message"

@raulriera raulriera Jun 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we using Send: {something} we normally have a prefix. Regardless of my previous message, I need to track messages still

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

transfers dont have a prefix as of today; deeplinks and onramps do

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in that case I need to change mine regardless

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think we just need to agree on a standard; could be me that needs to update


override fun toProperties() = buildMap {
error?.let { put("Error", it.message.orEmpty()) }
}
}
}

sealed interface PoolEvent : AnalyticsEvent {
val id: ID
override fun toProperties() = mapOf("ID" to id.base58)
Expand Down Expand Up @@ -310,4 +326,5 @@ internal fun Analytics.Transfer.toAnalyticsEvent(): AnalyticsEvent = when (this)
is Analytics.Transfer.ClaimedCashLink -> AnalyticsEvent.ClaimedCashLink
is Analytics.Transfer.SentCashLink.Clipboard -> AnalyticsEvent.SentCashLink(clipboard = true)
is Analytics.Transfer.SentCashLink.App -> AnalyticsEvent.SentCashLink(app = name)
is Analytics.Transfer.SentCash -> AnalyticsEvent.ChatEvent.SentCash
}
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ internal class MixpanelAnalyticsDelegate @Inject constructor(
track(AnalyticsEvent.TokenTransactionEvent.Sell(mint, amount, feeAmount, error))
}

override fun messageSentInChat(error: Throwable?) {
track(AnalyticsEvent.ChatEvent.SentMessage(error = error))
}

override fun deeplinkOpened(url: String) {
track(AnalyticsEvent.DeeplinkEvent.Open(url))
}
Expand Down
Loading