Skip to content

Commit

Permalink
Add event labels to opening and (un-)pinning of Safe Apps
Browse files Browse the repository at this point in the history
  • Loading branch information
iamacook committed Nov 29, 2024
1 parent a3cd8e4 commit 97d4391
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SafeAppPreviewDrawer from '@/components/safe-apps/SafeAppPreviewDrawer'
import SafeAppCard, { SafeAppCardContainer } from '@/components/safe-apps/SafeAppCard'
import { AppRoutes } from '@/config/routes'
import ExploreSafeAppsIcon from '@/public/images/apps/explore.svg'
import { SAFE_APPS_LABELS } from '@/services/analytics'

import css from './styles.module.css'

Expand All @@ -34,7 +35,7 @@ const SafeAppsDashboardSection = () => {
<Grid key={rankedSafeApp.id} item xs={12} sm={6} md={4} xl={4}>
<SafeAppCard
safeApp={rankedSafeApp}
onBookmarkSafeApp={togglePin}
onBookmarkSafeApp={(appId) => togglePin(appId, SAFE_APPS_LABELS.dashboard)}
isBookmarked={pinnedSafeAppIds.has(rankedSafeApp.id)}
onClickSafeApp={() => openPreviewDrawer(rankedSafeApp)}
openPreviewDrawer={openPreviewDrawer}
Expand All @@ -51,7 +52,7 @@ const SafeAppsDashboardSection = () => {
safeApp={previewDrawerApp}
isBookmarked={previewDrawerApp && pinnedSafeAppIds.has(previewDrawerApp.id)}
onClose={closePreviewDrawer}
onBookmark={togglePin}
onBookmark={(appId) => togglePin(appId, SAFE_APPS_LABELS.apps_sidebar)}
/>
</WidgetContainer>
)
Expand Down
16 changes: 1 addition & 15 deletions src/components/safe-apps/AppFrame/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import useAddressBook from '@/hooks/useAddressBook'
import useChainId from '@/hooks/useChainId'
import { type AddressBookItem, Methods } from '@safe-global/safe-apps-sdk'
import type { ReactElement } from 'react'
import { useMemo } from 'react'
import { useCallback, useEffect } from 'react'
import { Box, CircularProgress, Typography } from '@mui/material'
import { useRouter } from 'next/router'
import Head from 'next/head'
import type { RequestId } from '@safe-global/safe-apps-sdk'
import { trackSafeAppOpenCount } from '@/services/safe-apps/track-app-usage-count'
import { SAFE_APPS_EVENTS, trackSafeAppEvent } from '@/services/analytics'
import useSafeInfo from '@/hooks/useSafeInfo'
import { useSafeAppFromBackend } from '@/hooks/safe-apps/useSafeAppFromBackend'
import { useSafePermissions } from '@/hooks/safe-apps/permissions'
Expand Down Expand Up @@ -57,13 +55,12 @@ const AppFrame = ({ appUrl, allowedFeaturesList, safeAppFromManifest, isNativeEm
transactions,
} = useTransactionQueueBarState()
const queueBarVisible = transactions.results.length > 0 && !queueBarDismissed
const [remoteApp, , isBackendAppsLoading] = useSafeAppFromBackend(appUrl, safe.chainId)
const [remoteApp] = useSafeAppFromBackend(appUrl, safe.chainId)
const { thirdPartyCookiesDisabled, setThirdPartyCookiesDisabled } = useThirdPartyCookies()
const { iframeRef, appIsLoading, isLoadingSlow, setAppIsLoading } = useAppIsLoading()
useAnalyticsFromSafeApp(iframeRef)
const { permissionsRequest, setPermissionsRequest, confirmPermissionRequest, getPermissions, hasPermission } =
useSafePermissions()
const appName = useMemo(() => (remoteApp ? remoteApp.name : appUrl), [appUrl, remoteApp])

const communicator = useCustomAppCommunicator(iframeRef, remoteApp || safeAppFromManifest, chain, {
onGetPermissions: getPermissions,
Expand Down Expand Up @@ -110,17 +107,6 @@ const AppFrame = ({ appUrl, allowedFeaturesList, safeAppFromManifest, isNativeEm
}
}, [appUrl, iframeRef, setAppIsLoading, router, isNativeEmbed])

useEffect(() => {
if (!isNativeEmbed && !appIsLoading && !isBackendAppsLoading) {
trackSafeAppEvent(
{
...SAFE_APPS_EVENTS.OPEN_APP,
},
appName,
)
}
}, [appIsLoading, isBackendAppsLoading, appName, isNativeEmbed])

if (!safeLoaded) {
return <div />
}
Expand Down
25 changes: 17 additions & 8 deletions src/components/safe-apps/SafeAppList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import css from './styles.module.css'
import { Skeleton } from '@mui/material'
import { useOpenedSafeApps } from '@/hooks/safe-apps/useOpenedSafeApps'
import NativeSwapsCard from '@/components/safe-apps/NativeSwapsCard'
import { SAFE_APPS_EVENTS, SAFE_APPS_LABELS, trackSafeAppEvent } from '@/services/analytics'
import { useSafeApps } from '@/hooks/safe-apps/useSafeApps'

type SafeAppListProps = {
safeAppsList: SafeAppData[]
safeAppsListLoading?: boolean
bookmarkedSafeAppsId?: Set<number>
onBookmarkSafeApp?: (safeAppId: number) => void
eventLabel: SAFE_APPS_LABELS
addCustomApp?: (safeApp: SafeAppData) => void
removeCustomApp?: (safeApp: SafeAppData) => void
title: string
Expand All @@ -29,28 +31,35 @@ const SafeAppList = ({
safeAppsList,
safeAppsListLoading,
bookmarkedSafeAppsId,
onBookmarkSafeApp,
eventLabel,
addCustomApp,
removeCustomApp,
title,
query,
isFiltered = false,
showNativeSwapsCard = false,
}: SafeAppListProps) => {
const { togglePin } = useSafeApps()
const { isPreviewDrawerOpen, previewDrawerApp, openPreviewDrawer, closePreviewDrawer } = useSafeAppPreviewDrawer()
const { openedSafeAppIds } = useOpenedSafeApps()

const showZeroResultsPlaceholder = query && safeAppsList.length === 0

const handleSafeAppClick = useCallback(
(safeApp: SafeAppData) => {
if (openedSafeAppIds.includes(safeApp.id)) {
// We only track if not previously opened as it is then tracked in preview drawer
trackSafeAppEvent({ ...SAFE_APPS_EVENTS.OPEN_APP, label: eventLabel }, safeApp.name)
return
}

const isCustomApp = safeApp.id < 1

if (isCustomApp || openedSafeAppIds.includes(safeApp.id)) return
if (isCustomApp) return

return () => openPreviewDrawer(safeApp)
openPreviewDrawer(safeApp)
},
[openPreviewDrawer, openedSafeAppIds],
[eventLabel, openPreviewDrawer, openedSafeAppIds],
)

return (
Expand Down Expand Up @@ -82,9 +91,9 @@ const SafeAppList = ({
<SafeAppCard
safeApp={safeApp}
isBookmarked={bookmarkedSafeAppsId?.has(safeApp.id)}
onBookmarkSafeApp={onBookmarkSafeApp}
onBookmarkSafeApp={() => togglePin(safeApp.id, eventLabel)}
removeCustomApp={removeCustomApp}
onClickSafeApp={handleSafeAppClick(safeApp)}
onClickSafeApp={() => handleSafeAppClick(safeApp)}
openPreviewDrawer={openPreviewDrawer}
/>
</li>
Expand All @@ -100,7 +109,7 @@ const SafeAppList = ({
safeApp={previewDrawerApp}
isBookmarked={previewDrawerApp && bookmarkedSafeAppsId?.has(previewDrawerApp.id)}
onClose={closePreviewDrawer}
onBookmark={onBookmarkSafeApp}
onBookmark={(appId) => togglePin(appId, SAFE_APPS_LABELS.apps_sidebar)}
/>
</>
)
Expand Down
2 changes: 2 additions & 0 deletions src/components/safe-apps/SafeAppPreviewDrawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import SafeAppSocialLinksCard from '@/components/safe-apps/SafeAppSocialLinksCar
import CloseIcon from '@/public/images/common/close.svg'
import { useOpenedSafeApps } from '@/hooks/safe-apps/useOpenedSafeApps'
import css from './styles.module.css'
import { SAFE_APPS_EVENTS, SAFE_APPS_LABELS, trackSafeAppEvent } from '@/services/analytics'

type SafeAppPreviewDrawerProps = {
safeApp?: SafeAppData
Expand All @@ -35,6 +36,7 @@ const SafeAppPreviewDrawer = ({ isOpen, safeApp, isBookmarked, onClose, onBookma
const onOpenSafe = () => {
if (safeApp) {
markSafeAppOpened(safeApp.id)
trackSafeAppEvent({ ...SAFE_APPS_EVENTS.OPEN_APP, label: SAFE_APPS_LABELS.apps_sidebar }, safeApp.name)
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/hooks/safe-apps/useSafeApps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useCustomSafeApps } from '@/hooks/safe-apps/useCustomSafeApps'
import { usePinnedSafeApps } from '@/hooks/safe-apps/usePinnedSafeApps'
import { useBrowserPermissions, useSafePermissions } from './permissions'
import { useRankedSafeApps } from '@/hooks/safe-apps/useRankedSafeApps'
import { SAFE_APPS_EVENTS, trackSafeAppEvent } from '@/services/analytics'
import { SAFE_APPS_EVENTS, type SAFE_APPS_LABELS, trackSafeAppEvent } from '@/services/analytics'

type ReturnType = {
allSafeApps: SafeAppData[]
Expand All @@ -18,7 +18,7 @@ type ReturnType = {
customSafeAppsLoading: boolean
remoteSafeAppsError?: Error
addCustomApp: (app: SafeAppData) => void
togglePin: (appId: number) => void
togglePin: (appId: number, eventLabel: SAFE_APPS_LABELS) => void
removeCustomApp: (appId: number) => void
}

Expand Down Expand Up @@ -61,17 +61,17 @@ const useSafeApps = (): ReturnType => {
[updateCustomSafeApps, customSafeApps, removeSafePermissions, removeBrowserPermissions],
)

const togglePin = (appId: number) => {
const togglePin = (appId: number, eventLabel: SAFE_APPS_LABELS) => {
const alreadyPinned = pinnedSafeAppIds.has(appId)
const newSet = new Set(pinnedSafeAppIds)
const appName = allSafeApps.find((app) => app.id === appId)?.name

if (alreadyPinned) {
newSet.delete(appId)
trackSafeAppEvent(SAFE_APPS_EVENTS.UNPIN, appName)
trackSafeAppEvent({ ...SAFE_APPS_EVENTS.UNPIN, label: eventLabel }, appName)
} else {
newSet.add(appId)
trackSafeAppEvent(SAFE_APPS_EVENTS.PIN, appName)
trackSafeAppEvent({ ...SAFE_APPS_EVENTS.PIN, label: eventLabel }, appName)
}
updatePinnedSafeApps(newSet)
}
Expand Down
2 changes: 2 additions & 0 deletions src/pages/apps/custom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SafeAppList from '@/components/safe-apps/SafeAppList'
import SafeAppsSDKLink from '@/components/safe-apps/SafeAppsSDKLink'
import { RemoveCustomAppModal } from '@/components/safe-apps/RemoveCustomAppModal'
import type { SafeAppData } from '@safe-global/safe-gateway-typescript-sdk'
import { SAFE_APPS_LABELS } from '@/services/analytics'

const CustomSafeApps: NextPage = () => {
// TODO: create a custom hook instead of use useSafeApps
Expand Down Expand Up @@ -42,6 +43,7 @@ const CustomSafeApps: NextPage = () => {
safeAppsList={customSafeApps}
addCustomApp={addCustomApp}
removeCustomApp={openRemoveCustomAppModal}
eventLabel={SAFE_APPS_LABELS.apps_custom}
/>
</main>

Expand Down
9 changes: 5 additions & 4 deletions src/pages/apps/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import useSafeAppsFilters from '@/hooks/safe-apps/useSafeAppsFilters'
import SafeAppsFilters from '@/components/safe-apps/SafeAppsFilters'
import { useHasFeature } from '@/hooks/useChains'
import { FEATURES } from '@/utils/chains'
import { SAFE_APPS_LABELS } from '@/services/analytics'

const SafeApps: NextPage = () => {
const router = useRouter()
const { remoteSafeApps, remoteSafeAppsLoading, pinnedSafeApps, pinnedSafeAppIds, togglePin } = useSafeApps()
const { remoteSafeApps, remoteSafeAppsLoading, pinnedSafeApps, pinnedSafeAppIds } = useSafeApps()
const { filteredApps, query, setQuery, setSelectedCategories, setOptimizedWithBatchFilter, selectedCategories } =
useSafeAppsFilters(remoteSafeApps)
const isFiltered = filteredApps.length !== remoteSafeApps.length
Expand Down Expand Up @@ -72,7 +73,7 @@ const SafeApps: NextPage = () => {
title="My pinned apps"
safeAppsList={pinnedSafeApps}
bookmarkedSafeAppsId={pinnedSafeAppIds}
onBookmarkSafeApp={togglePin}
eventLabel={SAFE_APPS_LABELS.apps_pinned}
/>
)}

Expand All @@ -82,7 +83,7 @@ const SafeApps: NextPage = () => {
title="Featured apps"
safeAppsList={featuredSafeApps}
bookmarkedSafeAppsId={pinnedSafeAppIds}
onBookmarkSafeApp={togglePin}
eventLabel={SAFE_APPS_LABELS.apps_featured}
/>
)}

Expand All @@ -93,7 +94,7 @@ const SafeApps: NextPage = () => {
safeAppsList={isFiltered ? filteredApps : nonPinnedApps}
safeAppsListLoading={remoteSafeAppsLoading}
bookmarkedSafeAppsId={pinnedSafeAppIds}
onBookmarkSafeApp={togglePin}
eventLabel={SAFE_APPS_LABELS.apps_all}
query={query}
showNativeSwapsCard
/>
Expand Down
9 changes: 9 additions & 0 deletions src/services/analytics/events/safeApps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,12 @@ export const SAFE_APPS_EVENTS = {
action: 'SDK method call',
},
}

export enum SAFE_APPS_LABELS {
dashboard = 'dashboard',
apps_pinned = 'apps_pinned',
apps_featured = 'apps_featured',
apps_all = 'apps_all',
apps_custom = 'apps_custom',
apps_sidebar = 'apps_sidebar',
}
2 changes: 1 addition & 1 deletion src/services/analytics/gtm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export const normalizeAppName = (appName?: string): string => {
}

export const gtmTrackSafeApp = (eventData: AnalyticsEvent, appName?: string, sdkEventData?: SafeAppSDKEvent): void => {
if (!location.pathname.startsWith(AppRoutes.apps.index)) {
if (!location.pathname.startsWith(AppRoutes.apps.index) && !eventData.label) {
return
}

Expand Down

0 comments on commit 97d4391

Please sign in to comment.