Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

fix(profile): click analytics [MOSOWEB-43] #67

Merged
merged 36 commits into from
Oct 25, 2023
Merged

Conversation

jpezninjo
Copy link

@jpezninjo jpezninjo commented Oct 18, 2023

Goal

Add engagement analytics events to stuff on the Profile Page MOSOWEB-43

To Do:

  • Follow Button (this thing has 6 states...)
  • More options dropdown - toggle button and menu items
  • Notify button
  • These 6 links in this screenshot
image

Notes:

I refrained from putting in mastodon_account_id and mastodon_account_handle for links <a> just as a way to cut myself off from adding more work to this already large PR. Will followup with discussion and probably another PR.

This should've broken this up into several PRs. I went crazy plugging in data-glean="name" into everything before realizing I needed to hook into callback functions to add in the extra keys mastodon_account_id and mastodon_account_handle.

@wtfluckey and I paired to decide to call engagement.record() directly.

New Events:

  // follow button
  'profile.follow.unblock'
  'profile.follow.unmute'
  'profile.follow.unfollow'
  'profile.follow.follow'
  'profile.follow.withdraw-follow-request'
  'profile.follow.follow-request'
  // more button
  'profile.more.open'
  'profile.more.open_in_original_site'
  'profile.more.share_account'
  'profile.more.mention'
  'profile.more.direct_message'
  'profile.more.show_boosts'
  'profile.more.hide_boosts'
  'profile.more.add_note'
  'profile.more.remove_note'
  'profile.more.mute'
  'profile.more.unmute'
  'profile.more.block'
  'profile.more.unblock'
  'profile.more.block_domain'
  'profile.more.unblock_domain'
  'profile.more.report'
  'profile.more.goto_pinned'
  'profile.more.goto_favorites'
  'profile.more.goto_mutes'
  'profile.more.goto_blocks'
  'profile.more.goto_domain_blocks'
  // notifications
  'profile.notify_start'
  'profile.notify_stop'
  // modify lists
  'profile.modify_lists'
  // details
  'profile.details.posts'
  'profile.details.following'
  'profile.details.followers'
  // tabs
  'profile.tabs.posts'
  'profile.tabs.posts_and_replies'
  'profile.tabs.media'

@jpezninjo jpezninjo requested a review from a team as a code owner October 18, 2023 21:19
@jpezninjo jpezninjo force-pushed the fix/profile-analytics branch 2 times, most recently from 942fa3a to a680560 Compare October 18, 2023 21:33
import { toggleFollowAccount, useRelationship } from '~~/composables/masto/relationship'

const { account, command, context, ...props } = defineProps<{
const { account, command, context, gleanContext, ...props } = defineProps<{
Copy link
Author

Choose a reason for hiding this comment

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

gleanContext would be profile in profile.follow.unfollow

Several components use AccountFollowButton

Choose a reason for hiding this comment

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

How do you feel about renaming these ones to include something specific to it being the follow button? For instance profile.follow-btn.unfollow - I feel like that might make it a little more clear but also may be overkill?

Copy link
Author

Choose a reason for hiding this comment

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

I thought "follow" would be sufficient to denote the button :( but your comment is proof that it isn't. I will change all these to follow-btn

action = 'follow.unfollow'
else if (relationship?.requested)
action = 'follow.withdraw-follow-request'
else if ((relationship ? relationship.followedBy : context === 'followedBy') && account.locked)
Copy link
Author

Choose a reason for hiding this comment

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

this horrendous conditional comes from somewhere else in the <template> code below

return `${gleanContext}.${action}`
})

function handleClick() {
Copy link
Author

Choose a reason for hiding this comment

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

I did some clever ordering with the contents of this function. I'm open to some non-clever alternatives

Choose a reason for hiding this comment

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

The reordering of contents in this function might be causing the bug where the unfollow modal shows up when trying to unmute someone

Copy link
Author

Choose a reason for hiding this comment

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

Ooh good catch. I was unaware of this "mixed" use case. That counts as a 7th state for this horrible button component :'(

Choose a reason for hiding this comment

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

Let's make sure that whatever changes we make, the end result matches what is on production. We don't want to introduce any usability differences in this PR, only analytics events. We can follow up with improvements to this terrible button in a future PR.

Copy link
Author

Choose a reason for hiding this comment

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

Pushed up fixing the bug by removing my cleverness and bringing back the original order of events

Choose a reason for hiding this comment

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

Verified that I'm no longer seeing that bug!

@@ -21,39 +23,63 @@ const { client } = $(useMasto())
const useStarFavoriteIcon = usePreferences('useStarFavoriteIcon')
const { share, isSupported: isShareSupported } = useShare()

function recordEngagement(dataGlean) {
Copy link
Author

Choose a reason for hiding this comment

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

helper function that just calls engagement.record and helps us avoid code bloat

share({ url: location.href })
}

async function toggleReblogs() {
if (!relationship!.showingReblogs && await openConfirmDialog({
Copy link
Author

Choose a reason for hiding this comment

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

you're gonna see me separate out condition && openConfirmDialog alot (4 times) in this PR

confirm: t('confirm.show_reblogs.confirm'),
cancel: t('confirm.show_reblogs.cancel'),
}) !== 'confirm')
return
Copy link
Author

Choose a reason for hiding this comment

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

perhaps we should add analytics to the cancel cases of these dialogues?

:text="$t('menu.open_in_original_site')"
icon="i-ri:arrow-right-up-line"
:command="command"
data-glean="profile.more.open_in_original_site"
Copy link
Author

Choose a reason for hiding this comment

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

Example of a link that we could do further work in order to add 'target account'-identifiers if we really wanted to

/>
</template>

<template v-else>
<NuxtLink to="/pinned">
<CommonDropdownItem :text="$t('account.pinned')" icon="i-ri:pushpin-line" :command="command" />
<CommonDropdownItem is="button" :text="$t('account.pinned')" icon="i-ri:pushpin-line" :command="command" data-glean="profile.more.goto_pinned" />
Copy link
Author

Choose a reason for hiding this comment

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

This until the end of the file are more links lacking 'target account'-identifiers

@jpezninjo jpezninjo changed the title fix(profile) click analytics [MOSOWEB-43] fix(profile): click analytics [MOSOWEB-43] Oct 18, 2023
Comment on lines 86 to 91
'profile.notify_start': {
engagement_type: 'general',
},
'profile.notify_stop': {
engagement_type: 'general',
},

Choose a reason for hiding this comment

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

How do you feel about profile.notify.start and profile.notify.stop instead of using underscores?

Choose a reason for hiding this comment

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

I sneaked this change into #68

'profile.more.open_in_original_site': {
engagement_type: 'general',
},
'profile.more.share_account': {

Choose a reason for hiding this comment

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

How do you get to this action? It doesn't show up in the dropdown for me?

Copy link
Author

Choose a reason for hiding this comment

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

I hardcoded this one to make it show in the dropdown in order to test

Choose a reason for hiding this comment

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

I put together a PR to be merged into this one that updates the event names to use kebab-case consistently when part of the identifier needs to be multiple words: #68

@wtfluckey
Copy link

This is really excellent @jpezninjo - you've done great work on this!! I still need to test a few things and will do that on Monday, but in the meantime I did find one bug:

When I'm following someone and have muted them, when I click the unmute button it pops up the unfollow modal instead of unmuting them. Since we moved some of that logic of that very complex button around, we might wanna give this a good thorough testing to make sure we didn't introduce any other regressions.

unmute-unfollow

@@ -56,6 +58,7 @@ const userSettings = useUserSettings()
:to="getAccountFollowersRoute(account)"
replace text-secondary
exact-active-class="text-primary"
data-glean="profile.details.followers"

Choose a reason for hiding this comment

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

I'm not able to get these profile.details.* events to fire in the console. I only see the link_click following by page_view event. Not seeing them log to the Glean ping debugger either.

Copy link
Author

Choose a reason for hiding this comment

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

image
<a> current require you to click on them directly instead of any nested children

Copy link
Author

Choose a reason for hiding this comment

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

Whoops this screenshot is for a different UI. But similar reason, the needs to be clicked directly instead of their children -
image

Choose a reason for hiding this comment

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

Okay cool. I'm sure there are some optimizations we can make, but I don't wanna hold up this PR for that so I'm cool with this for now.

Copy link
Author

Choose a reason for hiding this comment

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

Sounds good to me. We can solve this with something applicable to all anchor tags

@@ -34,6 +36,7 @@ const tabs = $computed<CommonRouteTabOption[]>(() => [
},
display: t('tab.media'),
icon: 'i-ri:camera-2-line',
dataGlean: 'profile.tabs.media',

Choose a reason for hiding this comment

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

Same here with these events - I don't see the engagement events fire in console or ping debugger, I only see the link_click and page_view events

Copy link
Author

Choose a reason for hiding this comment

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

My reply for this went to the wrong thread. See #67 (comment)

@wtfluckey
Copy link

Testing is looking good!! I did find reference to the different engagement_types in The Spreadsheet™️. Can I have you update them in profileEvents?

Screenshot 2023-10-25 at 12 27 00 PM

Copy link

@wtfluckey wtfluckey left a comment

Choose a reason for hiding this comment

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

Tested and everything is looking good. I'm sure there are optimizations we can make to the engagement events vs link/button clicks for things like the Posts/Replies/Media buttons, but we can do that in a separate PR.

Great job on this! Thank you for taking this and running with it and then crushing all the feedback!

at-dance-party

@jpezninjo
Copy link
Author

@wtfluckey thank you SOO much for all the testing you've done on this and ensuring everything is okay

giphy

@jpezninjo jpezninjo merged commit 85e3d6a into main Oct 25, 2023
3 checks passed
@jpezninjo jpezninjo deleted the fix/profile-analytics branch October 25, 2023 21:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants