extensions_ui: Add telemetry for docs click-throughs from feature upsells (#14583)

This PR adds some telemetry when the "View docs" button is clicked on a
feature upsell.

The goal here is to get a sense for how effective these upsells are at
getting users to click through if they can't find what they're looking
for.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-07-16 12:59:51 -04:00 committed by GitHub
parent 0556eddc21
commit f9472ce90b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 33 additions and 12 deletions

View file

@ -1,3 +1,6 @@
use std::sync::Arc;
use client::telemetry::Telemetry;
use gpui::{AnyElement, Div, StyleRefinement}; use gpui::{AnyElement, Div, StyleRefinement};
use smallvec::SmallVec; use smallvec::SmallVec;
use ui::{prelude::*, ButtonLike}; use ui::{prelude::*, ButtonLike};
@ -5,15 +8,17 @@ use ui::{prelude::*, ButtonLike};
#[derive(IntoElement)] #[derive(IntoElement)]
pub struct FeatureUpsell { pub struct FeatureUpsell {
base: Div, base: Div,
telemetry: Arc<Telemetry>,
text: SharedString, text: SharedString,
docs_url: Option<SharedString>, docs_url: Option<SharedString>,
children: SmallVec<[AnyElement; 2]>, children: SmallVec<[AnyElement; 2]>,
} }
impl FeatureUpsell { impl FeatureUpsell {
pub fn new(text: impl Into<SharedString>) -> Self { pub fn new(telemetry: Arc<Telemetry>, text: impl Into<SharedString>) -> Self {
Self { Self {
base: h_flex(), base: h_flex(),
telemetry,
text: text.into(), text: text.into(),
docs_url: None, docs_url: None,
children: SmallVec::new(), children: SmallVec::new(),
@ -62,8 +67,14 @@ impl RenderOnce for FeatureUpsell {
.child(Icon::new(IconName::ArrowUpRight)), .child(Icon::new(IconName::ArrowUpRight)),
) )
.on_click({ .on_click({
let telemetry = self.telemetry.clone();
let docs_url = docs_url.clone(); let docs_url = docs_url.clone();
move |_event, cx| cx.open_url(&docs_url) move |_event, cx| {
telemetry.report_app_event(format!(
"feature upsell: viewed docs ({docs_url})"
));
cx.open_url(&docs_url)
}
}), }),
) )
}, },

View file

@ -939,12 +939,14 @@ impl ExtensionsPage {
let upsells_count = self.upsells.len(); let upsells_count = self.upsells.len();
v_flex().children(self.upsells.iter().enumerate().map(|(ix, feature)| { v_flex().children(self.upsells.iter().enumerate().map(|(ix, feature)| {
let telemetry = self.telemetry.clone();
let upsell = match feature { let upsell = match feature {
Feature::Git => FeatureUpsell::new( Feature::Git => FeatureUpsell::new(
telemetry,
"Zed comes with basic Git support. More Git features are coming in the future.", "Zed comes with basic Git support. More Git features are coming in the future.",
) )
.docs_url("https://zed.dev/docs/git"), .docs_url("https://zed.dev/docs/git"),
Feature::Vim => FeatureUpsell::new("Vim support is built-in to Zed!") Feature::Vim => FeatureUpsell::new(telemetry, "Vim support is built-in to Zed!")
.docs_url("https://zed.dev/docs/vim") .docs_url("https://zed.dev/docs/vim")
.child(CheckboxWithLabel::new( .child(CheckboxWithLabel::new(
"enable-vim", "enable-vim",
@ -956,7 +958,7 @@ impl ExtensionsPage {
}, },
cx.listener(move |this, selection, cx| { cx.listener(move |this, selection, cx| {
this.telemetry this.telemetry
.report_app_event("extensions: toggle vim".to_string()); .report_app_event("feature upsell: toggle vim".to_string());
this.update_settings::<VimModeSetting>( this.update_settings::<VimModeSetting>(
selection, selection,
cx, cx,
@ -964,14 +966,22 @@ impl ExtensionsPage {
); );
}), }),
)), )),
Feature::LanguageC => FeatureUpsell::new("C support is built-in to Zed!") Feature::LanguageC => {
.docs_url("https://zed.dev/docs/languages/c"), FeatureUpsell::new(telemetry, "C support is built-in to Zed!")
Feature::LanguageCpp => FeatureUpsell::new("C++ support is built-in to Zed!") .docs_url("https://zed.dev/docs/languages/c")
.docs_url("https://zed.dev/docs/languages/cpp"), }
Feature::LanguagePython => FeatureUpsell::new("Python support is built-in to Zed!") Feature::LanguageCpp => {
.docs_url("https://zed.dev/docs/languages/python"), FeatureUpsell::new(telemetry, "C++ support is built-in to Zed!")
Feature::LanguageRust => FeatureUpsell::new("Rust support is built-in to Zed!") .docs_url("https://zed.dev/docs/languages/cpp")
.docs_url("https://zed.dev/docs/languages/rust"), }
Feature::LanguagePython => {
FeatureUpsell::new(telemetry, "Python support is built-in to Zed!")
.docs_url("https://zed.dev/docs/languages/python")
}
Feature::LanguageRust => {
FeatureUpsell::new(telemetry, "Rust support is built-in to Zed!")
.docs_url("https://zed.dev/docs/languages/rust")
}
}; };
upsell.when(ix < upsells_count, |upsell| upsell.border_b_1()) upsell.when(ix < upsells_count, |upsell| upsell.border_b_1())