From abb9a9a4267dc9cb08c9afd284366b9b88a0bd53 Mon Sep 17 00:00:00 2001 From: Manoel Aranda Neto <5731772+marandaneto@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:17:15 +0200 Subject: [PATCH] chore: add ios session replay onboarding (#23190) --- frontend/src/scenes/onboarding/Onboarding.tsx | 6 ++- .../onboarding/sdks/feature-flags/ios.tsx | 7 ++++ .../onboarding/sdks/product-analytics/ios.tsx | 39 +++++++++++++++++++ .../sdks/sdk-install-instructions/android.tsx | 8 +++- .../sdks/sdk-install-instructions/ios.tsx | 37 ++++++++++++++++-- .../onboarding/sdks/session-replay/index.tsx | 1 + .../onboarding/sdks/session-replay/ios.tsx | 11 ++++++ 7 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 frontend/src/scenes/onboarding/sdks/session-replay/ios.tsx diff --git a/frontend/src/scenes/onboarding/Onboarding.tsx b/frontend/src/scenes/onboarding/Onboarding.tsx index 83fff791a99c9..c5fdd54c2e890 100644 --- a/frontend/src/scenes/onboarding/Onboarding.tsx +++ b/frontend/src/scenes/onboarding/Onboarding.tsx @@ -20,6 +20,7 @@ import { OnboardingReverseProxy } from './OnboardingReverseProxy' import { FeatureFlagsSDKInstructions } from './sdks/feature-flags/FeatureFlagsSDKInstructions' import { ProductAnalyticsSDKInstructions } from './sdks/product-analytics/ProductAnalyticsSDKInstructions' import { SDKs } from './sdks/SDKs' +import { iOSInstructions } from './sdks/session-replay/ios' import { SessionReplaySDKInstructions } from './sdks/session-replay/SessionReplaySDKInstructions' import { SurveysSDKInstructions } from './sdks/surveys/SurveysSDKInstructions' @@ -155,7 +156,7 @@ const SessionReplayOnboarding = (): JSX.Element => { const { currentTeam } = useValues(teamLogic) const { featureFlags } = useValues(featureFlagLogic) - const hasAndroidOnBoarding = !!featureFlags[FEATURE_FLAGS.SESSION_REPLAY_MOBILE_ONBOARDING] + const hasMobileOnBoarding = !!featureFlags[FEATURE_FLAGS.SESSION_REPLAY_MOBILE_ONBOARDING] const configOptions: ProductConfigOption[] = [ { @@ -192,8 +193,9 @@ const SessionReplayOnboarding = (): JSX.Element => { } const sdkInstructionMap = SessionReplaySDKInstructions - if (hasAndroidOnBoarding) { + if (hasMobileOnBoarding) { sdkInstructionMap[SDKKey.ANDROID] = AndroidInstructions + sdkInstructionMap[SDKKey.IOS] = iOSInstructions } return ( diff --git a/frontend/src/scenes/onboarding/sdks/feature-flags/ios.tsx b/frontend/src/scenes/onboarding/sdks/feature-flags/ios.tsx index 5a9bee6e12017..8612f0ae43c52 100644 --- a/frontend/src/scenes/onboarding/sdks/feature-flags/ios.tsx +++ b/frontend/src/scenes/onboarding/sdks/feature-flags/ios.tsx @@ -1,3 +1,7 @@ +import { FlaggedFeature } from 'lib/components/FlaggedFeature' +import { FEATURE_FLAGS } from 'lib/constants' +import { AdvertiseiOSReplay } from 'scenes/onboarding/sdks/product-analytics' + import { SDKKey } from '~/types' import { SDKInstallIOSInstructions } from '../sdk-install-instructions' @@ -8,6 +12,9 @@ export function FeatureFlagsIOSInstructions(): JSX.Element { <> + + + ) } diff --git a/frontend/src/scenes/onboarding/sdks/product-analytics/ios.tsx b/frontend/src/scenes/onboarding/sdks/product-analytics/ios.tsx index 739bbb7e2c129..1d205fc9b39ca 100644 --- a/frontend/src/scenes/onboarding/sdks/product-analytics/ios.tsx +++ b/frontend/src/scenes/onboarding/sdks/product-analytics/ios.tsx @@ -1,4 +1,14 @@ import { CodeSnippet, Language } from 'lib/components/CodeSnippet' +import { FlaggedFeature } from 'lib/components/FlaggedFeature' +import { FEATURE_FLAGS } from 'lib/constants' +import { LemonBanner } from 'lib/lemon-ui/LemonBanner' +import { LemonDivider } from 'lib/lemon-ui/LemonDivider' +import { LemonTag } from 'lib/lemon-ui/LemonTag' +import { Link } from 'lib/lemon-ui/Link' +import { OnboardingStepKey } from 'scenes/onboarding/onboardingLogic' +import { urls } from 'scenes/urls' + +import { SDKKey } from '~/types' import { SDKInstallIOSInstructions } from '../sdk-install-instructions' import { PersonModeEventPropertyInstructions } from '../shared-snippets' @@ -7,6 +17,32 @@ function IOSCaptureSnippet(): JSX.Element { return {`PostHogSDK.shared.capture("Test Event")`} } +export function AdvertiseiOSReplay({ + context, +}: { + context: 'product-analytics-onboarding' | 'flags-onboarding' +}): JSX.Element { + return ( +
+ + +

+ Session Replay for iOS NEW +

+
+ Session replay is now in beta for iOS.{' '} + + Learn how to set it up + +
+
+
+ ) +} + export function ProductAnalyticsIOSInstructions(): JSX.Element { return ( <> @@ -14,6 +50,9 @@ export function ProductAnalyticsIOSInstructions(): JSX.Element {

Send an event

+ + + ) } diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/android.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/android.tsx index 103a87f183508..d3bc825f9791a 100644 --- a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/android.tsx +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/android.tsx @@ -48,13 +48,17 @@ function AndroidSetupSnippet({ includeReplay }: AndroidSetupProps): JSX.Element config.sessionReplay = true // choose whether to mask images or text config.sessionReplayConfig.maskAllImages = false - config.sessionReplayConfig.maskAllTextInputs = true` + config.sessionReplayConfig.maskAllTextInputs = true + // screenshot is disabled by default + // The screenshot may contain sensitive information, use with caution + config.sessionReplayConfig.screenshot = true` : '' } // Setup PostHog with the given Context and Config PostHogAndroid.setup(this, config) - }`} + } +}`} ) } diff --git a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx index 4b86871452ca0..b8c27bcc683b1 100644 --- a/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx +++ b/frontend/src/scenes/onboarding/sdks/sdk-install-instructions/ios.tsx @@ -1,8 +1,13 @@ +import { LemonBanner, Link } from '@posthog/lemon-ui' import { useValues } from 'kea' import { CodeSnippet, Language } from 'lib/components/CodeSnippet' import { apiHostOrigin } from 'lib/utils/apiHost' import { teamLogic } from 'scenes/teamLogic' +export interface iOSSetupProps { + includeReplay?: boolean +} + function IOSInstallCocoaPodsSnippet(): JSX.Element { return {'pod "PostHog", "~> 3.0.0"'} } @@ -17,7 +22,7 @@ function IOSInstallSPMSnippet(): JSX.Element { ) } -function IOSSetupSnippet(): JSX.Element { +function IOSSetupSnippet({ includeReplay }: iOSSetupProps): JSX.Element { const { currentTeam } = useValues(teamLogic) return ( @@ -32,6 +37,21 @@ class AppDelegate: NSObject, UIApplicationDelegate { let POSTHOG_HOST = "${apiHostOrigin()}" let config = PostHogConfig(apiKey: POSTHOG_API_KEY, host: POSTHOG_HOST) + ${ + includeReplay + ? ` + // check https://posthog.com/docs/session-replay/mobile#installation + // for more config and to learn about how we capture sessions on mobile + // and what to expect + config.sessionReplay = true + // choose whether to mask images or text + config.sessionReplayConfig.maskAllImages = false + config.sessionReplayConfig.maskAllTextInputs = true + // screenshot is disabled by default + // The screenshot may contain sensitive information, use with caution + config.sessionReplayConfig.screenshotMode = true` + : '' + } PostHogSDK.shared.setup(config) return true @@ -41,15 +61,26 @@ class AppDelegate: NSObject, UIApplicationDelegate { ) } -export function SDKInstallIOSInstructions(): JSX.Element { +export function SDKInstallIOSInstructions(props: iOSSetupProps): JSX.Element { return ( <> + {props.includeReplay ? ( + + 🚧 NOTE: Mobile recording is + currently in beta. We are keen to gather as much feedback as possible so if you try this out please + let us know. You can send feedback via the{' '} + + in-app support panel + {' '} + or one of our other support options. + + ) : null}

Install via CocoaPods

Or Install via SPM

Configure

- + ) } diff --git a/frontend/src/scenes/onboarding/sdks/session-replay/index.tsx b/frontend/src/scenes/onboarding/sdks/session-replay/index.tsx index f0e1dee69a6ec..3a5aadfe8909d 100644 --- a/frontend/src/scenes/onboarding/sdks/session-replay/index.tsx +++ b/frontend/src/scenes/onboarding/sdks/session-replay/index.tsx @@ -4,6 +4,7 @@ export * from './astro' export * from './bubble' export * from './framer' export * from './html-snippet' +export * from './ios' export * from './js-web' export * from './next-js' export * from './nuxt' diff --git a/frontend/src/scenes/onboarding/sdks/session-replay/ios.tsx b/frontend/src/scenes/onboarding/sdks/session-replay/ios.tsx new file mode 100644 index 0000000000000..0281faeba1d04 --- /dev/null +++ b/frontend/src/scenes/onboarding/sdks/session-replay/ios.tsx @@ -0,0 +1,11 @@ +import { SDKInstallIOSInstructions } from '../sdk-install-instructions' +import { SessionReplayFinalSteps } from '../shared-snippets' + +export function iOSInstructions(): JSX.Element { + return ( + <> + + + + ) +}