Polls analytics (#1285)
Send poll analytics event (creation, vote, end) where appropriate.
This commit is contained in:
parent
aeaf3409bf
commit
5b018fd308
8 changed files with 90 additions and 20 deletions
|
|
@ -30,6 +30,7 @@ import androidx.compose.runtime.setValue
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
|
import im.vector.app.features.analytics.plan.PollEnd
|
||||||
import io.element.android.features.messages.impl.actionlist.ActionListEvents
|
import io.element.android.features.messages.impl.actionlist.ActionListEvents
|
||||||
import io.element.android.features.messages.impl.actionlist.ActionListPresenter
|
import io.element.android.features.messages.impl.actionlist.ActionListPresenter
|
||||||
import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
|
import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
|
||||||
|
|
@ -74,6 +75,7 @@ import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType
|
||||||
import io.element.android.libraries.matrix.ui.room.canRedactAsState
|
import io.element.android.libraries.matrix.ui.room.canRedactAsState
|
||||||
import io.element.android.libraries.matrix.ui.room.canSendMessageAsState
|
import io.element.android.libraries.matrix.ui.room.canSendMessageAsState
|
||||||
import io.element.android.libraries.textcomposer.MessageComposerMode
|
import io.element.android.libraries.textcomposer.MessageComposerMode
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
|
@ -92,6 +94,7 @@ class MessagesPresenter @AssistedInject constructor(
|
||||||
private val messageSummaryFormatter: MessageSummaryFormatter,
|
private val messageSummaryFormatter: MessageSummaryFormatter,
|
||||||
private val dispatchers: CoroutineDispatchers,
|
private val dispatchers: CoroutineDispatchers,
|
||||||
private val clipboardHelper: ClipboardHelper,
|
private val clipboardHelper: ClipboardHelper,
|
||||||
|
private val analyticsService: AnalyticsService,
|
||||||
@Assisted private val navigator: MessagesNavigator,
|
@Assisted private val navigator: MessagesNavigator,
|
||||||
) : Presenter<MessagesState> {
|
) : Presenter<MessagesState> {
|
||||||
|
|
||||||
|
|
@ -321,8 +324,10 @@ class MessagesPresenter @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun handleEndPollAction(event: TimelineItem.Event) {
|
private suspend fun handleEndPollAction(event: TimelineItem.Event) {
|
||||||
event.eventId?.let { room.endPoll(it, "The poll with event id: $it has ended.") }
|
event.eventId?.let {
|
||||||
// TODO Polls: Send poll end analytic
|
room.endPoll(it, "The poll with event id: $it has ended.")
|
||||||
|
analyticsService.capture(PollEnd())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun handleCopyContents(event: TimelineItem.Event) {
|
private suspend fun handleCopyContents(event: TimelineItem.Event) {
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
import im.vector.app.features.analytics.plan.PollVote
|
||||||
import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory
|
import io.element.android.features.messages.impl.timeline.factories.TimelineItemsFactory
|
||||||
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
|
|
@ -35,6 +36,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
import io.element.android.libraries.matrix.api.room.MessageEventType
|
import io.element.android.libraries.matrix.api.room.MessageEventType
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin
|
import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin
|
||||||
import io.element.android.libraries.matrix.ui.room.canSendMessageAsState
|
import io.element.android.libraries.matrix.ui.room.canSendMessageAsState
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
|
@ -51,6 +53,7 @@ class TimelinePresenter @Inject constructor(
|
||||||
private val room: MatrixRoom,
|
private val room: MatrixRoom,
|
||||||
private val dispatchers: CoroutineDispatchers,
|
private val dispatchers: CoroutineDispatchers,
|
||||||
private val appScope: CoroutineScope,
|
private val appScope: CoroutineScope,
|
||||||
|
private val analyticsService: AnalyticsService,
|
||||||
) : Presenter<TimelineState> {
|
) : Presenter<TimelineState> {
|
||||||
|
|
||||||
private val timeline = room.timeline
|
private val timeline = room.timeline
|
||||||
|
|
@ -93,7 +96,7 @@ class TimelinePresenter @Inject constructor(
|
||||||
pollStartId = event.pollStartId,
|
pollStartId = event.pollStartId,
|
||||||
answers = listOf(event.answerId),
|
answers = listOf(event.answerId),
|
||||||
)
|
)
|
||||||
// TODO Polls: Send poll vote analytic
|
analyticsService.capture(PollVote())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import app.cash.molecule.RecompositionMode
|
||||||
import app.cash.molecule.moleculeFlow
|
import app.cash.molecule.moleculeFlow
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import im.vector.app.features.analytics.plan.PollEnd
|
||||||
import io.element.android.features.messages.fixtures.aMessageEvent
|
import io.element.android.features.messages.fixtures.aMessageEvent
|
||||||
import io.element.android.features.messages.fixtures.aTimelineItemsFactory
|
import io.element.android.features.messages.fixtures.aTimelineItemsFactory
|
||||||
import io.element.android.features.messages.impl.InviteDialogAction
|
import io.element.android.features.messages.impl.InviteDialogAction
|
||||||
|
|
@ -575,7 +576,11 @@ class MessagesPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle poll end`() = runTest {
|
fun `present - handle poll end`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom()
|
||||||
val presenter = createMessagePresenter(matrixRoom = room)
|
val analyticsService = FakeAnalyticsService()
|
||||||
|
val presenter = createMessagePresenter(
|
||||||
|
matrixRoom = room,
|
||||||
|
analyticsService = analyticsService,
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -586,7 +591,8 @@ class MessagesPresenterTest {
|
||||||
assertThat(room.endPollInvocations.size).isEqualTo(1)
|
assertThat(room.endPollInvocations.size).isEqualTo(1)
|
||||||
assertThat(room.endPollInvocations.first().pollStartId).isEqualTo(AN_EVENT_ID)
|
assertThat(room.endPollInvocations.first().pollStartId).isEqualTo(AN_EVENT_ID)
|
||||||
assertThat(room.endPollInvocations.first().text).isEqualTo("The poll with event id: \$anEventId has ended.")
|
assertThat(room.endPollInvocations.first().text).isEqualTo("The poll with event id: \$anEventId has ended.")
|
||||||
// TODO Polls: Test poll end analytic
|
assertThat(analyticsService.capturedEvents.size).isEqualTo(1)
|
||||||
|
assertThat(analyticsService.capturedEvents.last()).isEqualTo(PollEnd())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -595,6 +601,7 @@ class MessagesPresenterTest {
|
||||||
matrixRoom: MatrixRoom = FakeMatrixRoom(),
|
matrixRoom: MatrixRoom = FakeMatrixRoom(),
|
||||||
navigator: FakeMessagesNavigator = FakeMessagesNavigator(),
|
navigator: FakeMessagesNavigator = FakeMessagesNavigator(),
|
||||||
clipboardHelper: FakeClipboardHelper = FakeClipboardHelper(),
|
clipboardHelper: FakeClipboardHelper = FakeClipboardHelper(),
|
||||||
|
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
|
||||||
): MessagesPresenter {
|
): MessagesPresenter {
|
||||||
val messageComposerPresenter = MessageComposerPresenter(
|
val messageComposerPresenter = MessageComposerPresenter(
|
||||||
appCoroutineScope = this,
|
appCoroutineScope = this,
|
||||||
|
|
@ -604,7 +611,7 @@ class MessagesPresenterTest {
|
||||||
localMediaFactory = FakeLocalMediaFactory(mockMediaUrl),
|
localMediaFactory = FakeLocalMediaFactory(mockMediaUrl),
|
||||||
mediaSender = MediaSender(FakeMediaPreProcessor(), matrixRoom),
|
mediaSender = MediaSender(FakeMediaPreProcessor(), matrixRoom),
|
||||||
snackbarDispatcher = SnackbarDispatcher(),
|
snackbarDispatcher = SnackbarDispatcher(),
|
||||||
analyticsService = FakeAnalyticsService(),
|
analyticsService = analyticsService,
|
||||||
messageComposerContext = MessageComposerContextImpl(),
|
messageComposerContext = MessageComposerContextImpl(),
|
||||||
richTextEditorStateFactory = TestRichTextEditorStateFactory(),
|
richTextEditorStateFactory = TestRichTextEditorStateFactory(),
|
||||||
|
|
||||||
|
|
@ -613,7 +620,8 @@ class MessagesPresenterTest {
|
||||||
timelineItemsFactory = aTimelineItemsFactory(),
|
timelineItemsFactory = aTimelineItemsFactory(),
|
||||||
room = matrixRoom,
|
room = matrixRoom,
|
||||||
dispatchers = coroutineDispatchers,
|
dispatchers = coroutineDispatchers,
|
||||||
appScope = this
|
appScope = this,
|
||||||
|
analyticsService = analyticsService,
|
||||||
)
|
)
|
||||||
val buildMeta = aBuildMeta()
|
val buildMeta = aBuildMeta()
|
||||||
val actionListPresenter = ActionListPresenter(buildMeta = buildMeta)
|
val actionListPresenter = ActionListPresenter(buildMeta = buildMeta)
|
||||||
|
|
@ -633,6 +641,7 @@ class MessagesPresenterTest {
|
||||||
messageSummaryFormatter = FakeMessageSummaryFormatter(),
|
messageSummaryFormatter = FakeMessageSummaryFormatter(),
|
||||||
navigator = navigator,
|
navigator = navigator,
|
||||||
clipboardHelper = clipboardHelper,
|
clipboardHelper = clipboardHelper,
|
||||||
|
analyticsService = analyticsService,
|
||||||
dispatchers = coroutineDispatchers,
|
dispatchers = coroutineDispatchers,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import app.cash.molecule.RecompositionMode
|
||||||
import app.cash.molecule.moleculeFlow
|
import app.cash.molecule.moleculeFlow
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import im.vector.app.features.analytics.plan.PollVote
|
||||||
import io.element.android.features.messages.fixtures.aTimelineItemsFactory
|
import io.element.android.features.messages.fixtures.aTimelineItemsFactory
|
||||||
import io.element.android.features.messages.impl.timeline.TimelineEvents
|
import io.element.android.features.messages.impl.timeline.TimelineEvents
|
||||||
import io.element.android.features.messages.impl.timeline.TimelinePresenter
|
import io.element.android.features.messages.impl.timeline.TimelinePresenter
|
||||||
|
|
@ -37,6 +38,7 @@ import io.element.android.libraries.matrix.test.room.aMessageContent
|
||||||
import io.element.android.libraries.matrix.test.room.anEventTimelineItem
|
import io.element.android.libraries.matrix.test.room.anEventTimelineItem
|
||||||
import io.element.android.libraries.matrix.test.timeline.FakeMatrixTimeline
|
import io.element.android.libraries.matrix.test.timeline.FakeMatrixTimeline
|
||||||
import io.element.android.libraries.matrix.ui.components.aMatrixUserList
|
import io.element.android.libraries.matrix.ui.components.aMatrixUserList
|
||||||
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
import io.element.android.tests.testutils.awaitWithLatch
|
import io.element.android.tests.testutils.awaitWithLatch
|
||||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
|
|
@ -260,7 +262,11 @@ class TimelinePresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - PollAnswerSelected event calls into rust room api and analytics`() = runTest {
|
fun `present - PollAnswerSelected event calls into rust room api and analytics`() = runTest {
|
||||||
val room = FakeMatrixRoom()
|
val room = FakeMatrixRoom()
|
||||||
val presenter = createTimelinePresenter(room)
|
val analyticsService = FakeAnalyticsService()
|
||||||
|
val presenter = createTimelinePresenter(
|
||||||
|
room = room,
|
||||||
|
analyticsService = analyticsService,
|
||||||
|
)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
}.test {
|
}.test {
|
||||||
|
|
@ -271,7 +277,8 @@ class TimelinePresenterTest {
|
||||||
assertThat(room.sendPollResponseInvocations.size).isEqualTo(1)
|
assertThat(room.sendPollResponseInvocations.size).isEqualTo(1)
|
||||||
assertThat(room.sendPollResponseInvocations.first().answers).isEqualTo(listOf("anAnswerId"))
|
assertThat(room.sendPollResponseInvocations.first().answers).isEqualTo(listOf("anAnswerId"))
|
||||||
assertThat(room.sendPollResponseInvocations.first().pollStartId).isEqualTo(AN_EVENT_ID)
|
assertThat(room.sendPollResponseInvocations.first().pollStartId).isEqualTo(AN_EVENT_ID)
|
||||||
// TODO Polls: Test poll vote analytic
|
assertThat(analyticsService.capturedEvents.size).isEqualTo(1)
|
||||||
|
assertThat(analyticsService.capturedEvents.last()).isEqualTo(PollVote())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TestScope.createTimelinePresenter(
|
private fun TestScope.createTimelinePresenter(
|
||||||
|
|
@ -282,18 +289,21 @@ class TimelinePresenterTest {
|
||||||
timelineItemsFactory = timelineItemsFactory,
|
timelineItemsFactory = timelineItemsFactory,
|
||||||
room = FakeMatrixRoom(matrixTimeline = timeline),
|
room = FakeMatrixRoom(matrixTimeline = timeline),
|
||||||
dispatchers = testCoroutineDispatchers(),
|
dispatchers = testCoroutineDispatchers(),
|
||||||
appScope = this
|
appScope = this,
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun TestScope.createTimelinePresenter(
|
private fun TestScope.createTimelinePresenter(
|
||||||
room: MatrixRoom,
|
room: MatrixRoom,
|
||||||
|
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
|
||||||
): TimelinePresenter {
|
): TimelinePresenter {
|
||||||
return TimelinePresenter(
|
return TimelinePresenter(
|
||||||
timelineItemsFactory = aTimelineItemsFactory(),
|
timelineItemsFactory = aTimelineItemsFactory(),
|
||||||
room = room,
|
room = room,
|
||||||
dispatchers = testCoroutineDispatchers(),
|
dispatchers = testCoroutineDispatchers(),
|
||||||
appScope = this
|
appScope = this,
|
||||||
|
analyticsService = analyticsService,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ dependencies {
|
||||||
implementation(projects.libraries.matrixui)
|
implementation(projects.libraries.matrixui)
|
||||||
implementation(projects.libraries.designsystem)
|
implementation(projects.libraries.designsystem)
|
||||||
implementation(projects.services.analytics.api)
|
implementation(projects.services.analytics.api)
|
||||||
|
implementation(projects.features.messages.api)
|
||||||
implementation(projects.libraries.uiStrings)
|
implementation(projects.libraries.uiStrings)
|
||||||
|
|
||||||
testImplementation(libs.test.junit)
|
testImplementation(libs.test.junit)
|
||||||
|
|
@ -48,6 +49,7 @@ dependencies {
|
||||||
testImplementation(libs.test.turbine)
|
testImplementation(libs.test.turbine)
|
||||||
testImplementation(projects.libraries.matrix.test)
|
testImplementation(projects.libraries.matrix.test)
|
||||||
testImplementation(projects.services.analytics.test)
|
testImplementation(projects.services.analytics.test)
|
||||||
|
testImplementation(projects.features.messages.test)
|
||||||
testImplementation(projects.tests.testutils)
|
testImplementation(projects.tests.testutils)
|
||||||
|
|
||||||
ksp(libs.showkase.processor)
|
ksp(libs.showkase.processor)
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,17 @@ import com.bumble.appyx.core.node.Node
|
||||||
import com.bumble.appyx.core.plugin.Plugin
|
import com.bumble.appyx.core.plugin.Plugin
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
import io.element.android.anvilannotations.ContributesNode
|
import io.element.android.anvilannotations.ContributesNode
|
||||||
import io.element.android.libraries.di.RoomScope
|
import io.element.android.libraries.di.RoomScope
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
|
|
||||||
@ContributesNode(RoomScope::class)
|
@ContributesNode(RoomScope::class)
|
||||||
class CreatePollNode @AssistedInject constructor(
|
class CreatePollNode @AssistedInject constructor(
|
||||||
@Assisted buildContext: BuildContext,
|
@Assisted buildContext: BuildContext,
|
||||||
@Assisted plugins: List<Plugin>,
|
@Assisted plugins: List<Plugin>,
|
||||||
presenterFactory: CreatePollPresenter.Factory,
|
presenterFactory: CreatePollPresenter.Factory,
|
||||||
// analyticsService: AnalyticsService, // TODO Polls: add analytics
|
analyticsService: AnalyticsService,
|
||||||
) : Node(buildContext, plugins = plugins) {
|
) : Node(buildContext, plugins = plugins) {
|
||||||
|
|
||||||
private val presenter = presenterFactory.create(backNavigator = ::navigateUp)
|
private val presenter = presenterFactory.create(backNavigator = ::navigateUp)
|
||||||
|
|
@ -40,8 +42,7 @@ class CreatePollNode @AssistedInject constructor(
|
||||||
init {
|
init {
|
||||||
lifecycle.subscribe(
|
lifecycle.subscribe(
|
||||||
onResume = {
|
onResume = {
|
||||||
// TODO Polls: add analytics
|
analyticsService.screen(MobileScreen(screenName = MobileScreen.ScreenName.CreatePollView))
|
||||||
// analyticsService.screen(MobileScreen(screenName = MobileScreen.ScreenName.PollView))
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,13 @@ import androidx.compose.runtime.setValue
|
||||||
import dagger.assisted.Assisted
|
import dagger.assisted.Assisted
|
||||||
import dagger.assisted.AssistedFactory
|
import dagger.assisted.AssistedFactory
|
||||||
import dagger.assisted.AssistedInject
|
import dagger.assisted.AssistedInject
|
||||||
|
import im.vector.app.features.analytics.plan.Composer
|
||||||
|
import im.vector.app.features.analytics.plan.PollCreation
|
||||||
|
import io.element.android.features.messages.api.MessageComposerContext
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import io.element.android.libraries.matrix.api.poll.PollKind
|
import io.element.android.libraries.matrix.api.poll.PollKind
|
||||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -44,9 +48,9 @@ private const val MAX_SELECTIONS = 1
|
||||||
|
|
||||||
class CreatePollPresenter @AssistedInject constructor(
|
class CreatePollPresenter @AssistedInject constructor(
|
||||||
private val room: MatrixRoom,
|
private val room: MatrixRoom,
|
||||||
// private val analyticsService: AnalyticsService, // TODO Polls: add analytics
|
private val analyticsService: AnalyticsService,
|
||||||
|
private val messageComposerContext: MessageComposerContext,
|
||||||
@Assisted private val navigateUp: () -> Unit,
|
@Assisted private val navigateUp: () -> Unit,
|
||||||
// private val messageComposerContext: MessageComposerContext, // TODO Polls: add analytics
|
|
||||||
) : Presenter<CreatePollState> {
|
) : Presenter<CreatePollState> {
|
||||||
|
|
||||||
@AssistedFactory
|
@AssistedFactory
|
||||||
|
|
@ -78,7 +82,21 @@ class CreatePollPresenter @AssistedInject constructor(
|
||||||
maxSelections = MAX_SELECTIONS,
|
maxSelections = MAX_SELECTIONS,
|
||||||
pollKind = pollKind,
|
pollKind = pollKind,
|
||||||
)
|
)
|
||||||
// analyticsService.capture(PollCreate()) // TODO Polls: add analytics
|
analyticsService.capture(
|
||||||
|
Composer(
|
||||||
|
inThread = messageComposerContext.composerMode.inThread,
|
||||||
|
isEditing = messageComposerContext.composerMode.isEditing,
|
||||||
|
isReply = messageComposerContext.composerMode.isReply,
|
||||||
|
messageType = Composer.MessageType.Poll,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
analyticsService.capture(
|
||||||
|
PollCreation(
|
||||||
|
action = PollCreation.Action.Create,
|
||||||
|
isUndisclosed = pollKind == PollKind.Undisclosed,
|
||||||
|
numberOfAnswers = answers.size,
|
||||||
|
)
|
||||||
|
)
|
||||||
navigateUp()
|
navigateUp()
|
||||||
} else {
|
} else {
|
||||||
Timber.d("Cannot create poll")
|
Timber.d("Cannot create poll")
|
||||||
|
|
@ -153,7 +171,7 @@ private val pollKindSaver: Saver<MutableState<PollKind>, Boolean> = Saver(
|
||||||
},
|
},
|
||||||
restore = {
|
restore = {
|
||||||
mutableStateOf(
|
mutableStateOf(
|
||||||
when(it) {
|
when (it) {
|
||||||
true -> PollKind.Undisclosed
|
true -> PollKind.Undisclosed
|
||||||
else -> PollKind.Disclosed
|
else -> PollKind.Disclosed
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,13 @@ import app.cash.molecule.RecompositionMode
|
||||||
import app.cash.molecule.moleculeFlow
|
import app.cash.molecule.moleculeFlow
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
|
import im.vector.app.features.analytics.plan.Composer
|
||||||
|
import im.vector.app.features.analytics.plan.PollCreation
|
||||||
|
import io.element.android.features.messages.test.MessageComposerContextFake
|
||||||
import io.element.android.libraries.matrix.api.poll.PollKind
|
import io.element.android.libraries.matrix.api.poll.PollKind
|
||||||
import io.element.android.libraries.matrix.test.room.CreatePollInvocation
|
import io.element.android.libraries.matrix.test.room.CreatePollInvocation
|
||||||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||||
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
import io.element.android.tests.testutils.WarmUpRule
|
import io.element.android.tests.testutils.WarmUpRule
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
|
|
@ -37,11 +41,13 @@ class CreatePollPresenterTest {
|
||||||
|
|
||||||
private var navUpInvocationsCount = 0
|
private var navUpInvocationsCount = 0
|
||||||
private val fakeMatrixRoom = FakeMatrixRoom()
|
private val fakeMatrixRoom = FakeMatrixRoom()
|
||||||
// private val fakeAnalyticsService = FakeAnalyticsService() // TODO Polls: add analytics
|
private val fakeAnalyticsService = FakeAnalyticsService()
|
||||||
|
private val messageComposerContextFake = MessageComposerContextFake()
|
||||||
|
|
||||||
private val presenter = CreatePollPresenter(
|
private val presenter = CreatePollPresenter(
|
||||||
room = fakeMatrixRoom,
|
room = fakeMatrixRoom,
|
||||||
// analyticsService = fakeAnalyticsService, // TODO Polls: add analytics
|
analyticsService = fakeAnalyticsService,
|
||||||
|
messageComposerContext = messageComposerContextFake,
|
||||||
navigateUp = { navUpInvocationsCount++ },
|
navigateUp = { navUpInvocationsCount++ },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -104,6 +110,22 @@ class CreatePollPresenterTest {
|
||||||
pollKind = PollKind.Disclosed
|
pollKind = PollKind.Disclosed
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
Truth.assertThat(fakeAnalyticsService.capturedEvents.size).isEqualTo(2)
|
||||||
|
Truth.assertThat(fakeAnalyticsService.capturedEvents[0]).isEqualTo(
|
||||||
|
Composer(
|
||||||
|
inThread = false,
|
||||||
|
isEditing = false,
|
||||||
|
isReply = false,
|
||||||
|
messageType = Composer.MessageType.Poll,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
Truth.assertThat(fakeAnalyticsService.capturedEvents[1]).isEqualTo(
|
||||||
|
PollCreation(
|
||||||
|
action = PollCreation.Action.Create,
|
||||||
|
isUndisclosed = false,
|
||||||
|
numberOfAnswers = 2,
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue