Add polls analytics (#1691)

* Refactor location events

* Add poll analytics
This commit is contained in:
Alfonso Grillo
2023-09-13 09:28:44 +02:00
committed by GitHub
parent dc5514bc0b
commit f3618cda9d
10 changed files with 105 additions and 54 deletions
@@ -566,7 +566,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
self.analytics.trackComposer(inThread: false,
isEditing: false,
isReply: false,
locationType: isUserLocation ? .myLocation : .pin,
messageType: isUserLocation ? .location(.user) : .location(.pin),
startsThread: nil)
case .close:
self.navigationSplitCoordinator.setSheetCoordinator(nil)
@@ -606,6 +606,14 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let result = await roomProxy.createPoll(question: question, answers: options, pollKind: pollKind)
self.analytics.trackComposer(inThread: false,
isEditing: false,
isReply: false,
messageType: .poll,
startsThread: nil)
self.analytics.trackPollCreated(isUndisclosed: pollKind == .undisclosed, numberOfAnswers: options.count)
switch result {
case .success:
break
@@ -32,6 +32,7 @@ struct CreatePollScreen: View {
optionsSection
showResultsSection
}
.track(screen: .createPoll)
.compoundForm()
.scrollDismissesKeyboard(.immediately)
.environment(\.editMode, .constant(.active))
@@ -806,6 +806,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
private func sendPollResponse(pollStartID: String, optionID: String) {
Task {
let sendPollResponseResult = await roomProxy.sendPollResponse(pollStartID: pollStartID, answers: [optionID])
analytics.trackPollVote()
switch sendPollResponseResult {
case .success:
break
@@ -819,6 +821,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
Task {
let endPollResult = await roomProxy.endPoll(pollStartID: pollStartID,
text: "The poll with event id: \(pollStartID) has ended")
analytics.trackPollEnd()
switch endPollResult {
case .success:
break
@@ -1,33 +0,0 @@
//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import AnalyticsEvents
enum AnalyticsLocationType {
case myLocation
case pin
}
extension AnalyticsEvent.Composer.LocationType {
init(_ analyticsLocationType: AnalyticsLocationType) {
switch analyticsLocationType {
case .myLocation:
self = .MyLocation
case .pin:
self = .PinDrop
}
}
}
@@ -0,0 +1,50 @@
//
// Copyright 2023 New Vector Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import AnalyticsEvents
enum AnalyticsMessageType {
case location(LocationType)
case poll
case text
enum LocationType {
case pin
case user
}
}
extension AnalyticsEvent.Composer.MessageType {
init(_ analyticsMessageType: AnalyticsMessageType) {
switch analyticsMessageType {
case .location(let locationType):
self = .init(locationType)
case .poll:
self = .Poll
case .text:
self = .Text
}
}
private init(_ locationType: AnalyticsMessageType.LocationType) {
switch locationType {
case .pin:
self = .LocationPin
case .user:
self = .LocationUser
}
}
}
@@ -61,6 +61,7 @@ enum AnalyticsScreen: Int {
case createSpace
case locationSend
case locationView
case createPoll
/// The screen name reported to the AnalyticsEvent.
var screenName: AnalyticsEvent.MobileScreen.ScreenName {
@@ -151,6 +152,8 @@ enum AnalyticsScreen: Int {
return .LocationSend
case .locationView:
return .LocationView
case .createPoll:
return .CreatePollView
}
}
}
@@ -145,18 +145,17 @@ extension AnalyticsService {
/// - inThread: whether the composer is used in a Thread
/// - isEditing: whether the composer is used to edit a message
/// - isReply: whether the composer is used to reply a message
/// - locationType: the type of the shared location
/// - messageType: the type of the message
/// - startsThread: whether the composer is used to start a new thread
func trackComposer(inThread: Bool,
isEditing: Bool,
isReply: Bool,
locationType: AnalyticsLocationType? = nil,
messageType: AnalyticsMessageType = .text,
startsThread: Bool?) {
capture(event: AnalyticsEvent.Composer(inThread: inThread,
isEditing: isEditing,
isLocation: locationType != nil,
isReply: isReply,
locationType: locationType.map { .init($0) },
messageType: .init(messageType),
startsThread: startsThread))
}
@@ -180,4 +179,24 @@ extension AnalyticsService {
}
capture(event: AnalyticsEvent.JoinedRoom(isDM: isDM, isSpace: isSpace, roomSize: roomSize, trigger: nil))
}
/// Track the action of creating a poll
/// - Parameters:
/// - isUndisclosed: whether the poll is undisclosed
/// - numberOfAnswers: the number of options in the poll
func trackPollCreated(isUndisclosed: Bool, numberOfAnswers: Int) {
capture(event: AnalyticsEvent.PollCreation(action: .Create,
isUndisclosed: isUndisclosed,
numberOfAnswers: numberOfAnswers))
}
/// Track the action of voting on a poll
func trackPollVote() {
capture(event: AnalyticsEvent.PollVote(doNotUse: nil))
}
/// Track the action of ending a poll
func trackPollEnd() {
capture(event: AnalyticsEvent.PollEnd(doNotUse: nil))
}
}