Repository navigation
feat(analytics): add group chat events and send them from Android - #1561
Merged
Merged
Conversation
Adds a Group domain (GroupEvents) with eleven events covering create, edit, invite, gate, join, leave and info, and Chat Muted / Chat Unmuted in the Chat domain. MuteDuration matches the four options both apps offer. TokenInfoSource CHAT_GATE gets a drift note: iOS's gate buy button pushes the buy screen and never opens Token Info.
…p events chatResult gives the proto result name the Error property carries (Denied, NotFound, RulesNotSatisfied, ...), or Network for a transport failure; class names are spelled out because R8 renames them. gateMint is the listener rule's single mint, or null for an ungated or any-currency group.
New Opened fires on the Create Public Group row, the flow's only entry. Created fires when StartChat returns, with the proto result name on a failure.
Fires when EditChat returns. A picture the blob store refuses never reaches EditChat, so it sends nothing.
The sheet now hands the view model the MuteOption instead of the MuteState built from it, so the picked duration is still known when the event fires. MuteChat carries the chat type because the sheet only had the id; ConversationReference gains chatType so the chat list can pass a DM's kind rather than only isGroup.
…ents ChatViewModel sends Group: Gate Shown, Invite Sheet Opened, Invite Shared, Gate Funding Tapped, Joined, Left and Info Opened. The screens dispatch the taps as events, so the member count and gate mint come from the group the view model already holds, read before the join or leave moves the roster. Gate Shown is taken once per view model, which the chat flow scopes to one visit, so a balance change under an open chat does not send it again.
…ite cards A link is reported from the app's DeepLinkListener, which hears each link once; the cold-start path re-derives its routes on every auth re-emission and would count one link several times. The scanner reports QR in its GroupChatInvite branch, and the transcript reports Chat Card when an invite card opens a different group.
Created, Joined, Left, Muted and Unmuted now go through a FlipcashAnalytics extension next to their callers, as Edited already did, so each call site is one line and the State and Error derivation lives with the event. This drops the two private Result.analyticsState copies.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Group chats sent no analytics beyond the chat events they share with DMs. This adds a
Groupdomain toevents.toml(generatingGroupEvents),Chat MutedandChat Unmutedin the Chat domain, and fires all of them from Android.iOS needs a
flipcash-shared-core-spmrelease after this merges before it can send these events. The Swift typealiases forGroupEventsand the new lists are inAnalyticsEvents.swift.Catalogue
Group: New OpenedGroup: CreatedState,Error?,Gate Mint?,Has PictureGroup: EditedField(Name, Picture),State,Error?Group: Invite Sheet OpenedSource(Chat, Profile),Member CountGroup: Invite SharedMethod(Share, Copy)Group: Invite FollowedSource(Link, QR, Chat Card)Group: Gate ShownAccess(Eligible, Blocked),Gate Mint?,Member CountGroup: Gate Funding TappedMethod(Buy Token, Add Cash),Gate Mint?Group: JoinedState,Error?,Member Count,GatedGroup: LeftState,Error?,Member CountGroup: Info OpenedMember Count,Is MemberChat MutedChat Type,Duration,State,Error?Chat UnmutedChat Type,State,Error?MuteDuration: 1 Hour, 8 Hours, 1 Week, Always. Android'sMuteStateand iOS'sMuteChatSheetoffer the same four.Error: the RPC's result name from the proto (Denied,NotFound,RulesNotSatisfied,TitleModerated, …), orNetworkfor a transport failure.Throwable.chatResultinConversions.ktdoes the mapping. It also returnsValidationwhen a request fails proto validation before it is sent, since there is no server result to name.Gate Mint: left out when the group has no token gate, including a rule that any currency satisfies.Member Count: the roster the screen held before the action.TokenInfoSource.CHAT_GATEnotes that iOS doesn't send it. Its gate buy button pushes the buy screen and never opens Token Info.Group: Gate Funding Tappedcovers that tap on both apps.Android call sites
NewChatScreenandCreateGroupViewModel.create().EditGroupNameViewModelandEditGroupPictureViewModel.MuteChatViewModelonly had the chat id.AppRoute.MuteChatnow carries theChatType, andConversationReferencegainschatTypeso the chat list can say what kind of DM it is instead of onlyisGroup. The sheet passes up theMuteOptionrather than theMuteStatebuilt from it, so the picked duration is still known when the event fires.ChatViewModel. The screens dispatch the taps as events, so the count and mint come from the group the view model holds.Gate Shownis taken once per view model, which the chat flow scopes to one visit, so a balance change under an open chat doesn't send it again.App.kt'sDeepLinkListener, which hears each link once. The cold-start path inMainRootre-derives its routes on every auth re-emission and would count one link several times. The listener runs before auth resolves, so a logged-out tap on an invite counts as followed too.Scanner'sGroupChatInvitebranch.Tests
GroupEventsTestandChatEventsTestpin each new event's literal strings on the Android host,macosArm64andiosSimulatorArm64.AnalyticsEventsTests.swiftcovers one group event through SharedCoreKit.ConversionsTestcoverschatResultandgateMint.ChatGroupAnalyticsTestcovers Gate Shown once, and without a mint for an ungated group. It also covers join and leave results, the invite, funding and info taps, and the chat card. There are also emission tests for create, edit and mute, usingRecordingAnalytics.