From c4f626067356e43c75003a100eedcef52e6c9f0c Mon Sep 17 00:00:00 2001 From: kyranjamie Date: Mon, 11 Dec 2023 10:18:26 +0100 Subject: [PATCH] feat: sentry feedback --- .github/workflows/playwright.yml | 7 -- package.json | 2 +- panda.config.ts | 2 +- src/app/components/app-version.tsx | 3 +- .../connect-ledger-asset-button.tsx | 2 +- .../feedback-button/feedback-button.tsx | 50 +++++++++++ .../settings-dropdown/settings-dropdown.tsx | 15 +--- src/app/pages/home/home.tsx | 2 + src/app/ui/components/button.tsx | 8 +- .../ui/components/icons/megaphone-icon.tsx | 23 +++++ src/shared/utils/analytics.ts | 30 +++++++ theme/recipes/{button.ts => button-recipe.ts} | 12 ++- yarn.lock | 88 +++++++++++++------ 13 files changed, 192 insertions(+), 52 deletions(-) create mode 100644 src/app/features/feedback-button/feedback-button.tsx create mode 100644 src/app/ui/components/icons/megaphone-icon.tsx rename theme/recipes/{button.ts => button-recipe.ts} (96%) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index df1ebc74e52..3eb4f849bd6 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -110,13 +110,6 @@ jobs: - name: Merge into HTML Report run: npx playwright merge-reports --reporter html ./all-blob-reports - - name: Upload HTML report - uses: actions/upload-artifact@v3 - with: - name: html-report--attempt-${{ github.run_attempt }} - path: playwright-report - retention-days: 14 - - name: Extract branch name shell: bash run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT diff --git a/package.json b/package.json index 3011fb8291e..ba2593bb5f6 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "@scure/bip39": "1.2.1", "@scure/btc-signer": "1.1.0", "@segment/analytics-next": "1.56.0", - "@sentry/react": "7.72.0", + "@sentry/react": "7.86.0", "@sentry/tracing": "7.72.0", "@stacks/auth": "6.9.0", "@stacks/blockchain-api-client": "6.3.4", diff --git a/panda.config.ts b/panda.config.ts index c04aba3f239..347b905b9bc 100644 --- a/panda.config.ts +++ b/panda.config.ts @@ -3,7 +3,7 @@ import { defineConfig } from '@pandacss/dev'; import { breakpoints } from './theme/breakpoints'; import { globalCss } from './theme/global/global'; import { keyframes } from './theme/keyframes'; -import { buttonRecipe } from './theme/recipes/button'; +import { buttonRecipe } from './theme/recipes/button-recipe'; import { semanticTokens } from './theme/semantic-tokens'; import { tokens } from './theme/tokens'; import { textStyles } from './theme/typography'; diff --git a/src/app/components/app-version.tsx b/src/app/components/app-version.tsx index 798b9ab8297..ddd256e2fb4 100644 --- a/src/app/components/app-version.tsx +++ b/src/app/components/app-version.tsx @@ -23,6 +23,7 @@ const AppVersionLabel = forwardRef( ml="space.02" opacity={0.5} textDecoration={isLatestVersion ? 'none' : 'line-through'} + textWrap="nowrap" {...props} > {children} @@ -36,7 +37,7 @@ export function AppVersion() { const version = useMemo(() => { switch (process.env.WALLET_ENVIRONMENT) { case 'development': - return `dev@${BRANCH_NAME}`; + return BRANCH_NAME; case 'feature': return `${BRANCH_NAME}#${COMMIT_SHA?.slice(0, 8)}`; default: diff --git a/src/app/features/asset-list/components/connect-ledger-asset-button.tsx b/src/app/features/asset-list/components/connect-ledger-asset-button.tsx index dae23f221fa..f939a78282d 100644 --- a/src/app/features/asset-list/components/connect-ledger-asset-button.tsx +++ b/src/app/features/asset-list/components/connect-ledger-asset-button.tsx @@ -31,7 +31,7 @@ export function ConnectLedgerAssetBtn({ chain }: ConnectLedgerAssetBtnProps) { display="flex" alignItems="center" variant="outline" - height="36px" + size="sm" gap="space.02" onClick={onClick} > diff --git a/src/app/features/feedback-button/feedback-button.tsx b/src/app/features/feedback-button/feedback-button.tsx new file mode 100644 index 00000000000..08dd1641a99 --- /dev/null +++ b/src/app/features/feedback-button/feedback-button.tsx @@ -0,0 +1,50 @@ +import { BrowserClient, Feedback, getCurrentHub } from '@sentry/react'; +import { Flex } from 'leather-styles/jsx'; + +import { analytics } from '@shared/utils/analytics'; + +import { useThemeSwitcher } from '@app/common/theme-provider'; +import { LeatherButton } from '@app/ui/components/button'; +import { MegaphoneIcon } from '@app/ui/components/icons/megaphone-icon'; + +export function openFeedbackDialog() { + void analytics.track('user_clicked_feedback_button'); + const client = getCurrentHub().getClient(); + const feedback = client?.getIntegration(Feedback); + if (!feedback) return; + feedback.openDialog(); +} + +export function FeedbackButton() { + const { theme } = useThemeSwitcher(); + return ( + + + + Give feedback + + + ); +} diff --git a/src/app/features/settings-dropdown/settings-dropdown.tsx b/src/app/features/settings-dropdown/settings-dropdown.tsx index fedf84c5eae..5e298fe6152 100644 --- a/src/app/features/settings-dropdown/settings-dropdown.tsx +++ b/src/app/features/settings-dropdown/settings-dropdown.tsx @@ -21,6 +21,7 @@ import { useCurrentNetworkId } from '@app/store/networks/networks.selectors'; import { ExternalLinkIcon } from '@app/ui/components/icons/external-link-icon'; import { Caption } from '@app/ui/components/typography/caption'; +import { openFeedbackDialog } from '../feedback-button/feedback-button'; import { extractDeviceNameFromKnownTargetIds } from '../ledger/utils/generic-ledger-utils'; import { AdvancedMenuItems } from './components/advanced-menu-items'; import { LedgerDeviceItemRow } from './components/ledger-item-row'; @@ -109,7 +110,6 @@ export function SettingsDropdown() { { - void analytics.track('click_get_support_menu_item'); openInNewTab('https://leather.gitbook.io/guides/installing/contact-support'); })} > @@ -118,17 +118,7 @@ export function SettingsDropdown() { - { - void analytics.track('click_request_feature_menu_item'); - openInNewTab('https://leather.canny.io/feature-requests'); - })} - > - - Request feature - - - + openFeedbackDialog())}>Give feedback {hasGeneratedWallet ? : null} + {showAdvancedMenuOptions && ( )} diff --git a/src/app/pages/home/home.tsx b/src/app/pages/home/home.tsx index d910d52ea1d..5a78f00a492 100644 --- a/src/app/pages/home/home.tsx +++ b/src/app/pages/home/home.tsx @@ -9,6 +9,7 @@ import { useRouteHeader } from '@app/common/hooks/use-route-header'; import { Header } from '@app/components/header'; import { ActivityList } from '@app/features/activity-list/activity-list'; import { AssetsList } from '@app/features/asset-list/asset-list'; +import { FeedbackButton } from '@app/features/feedback-button/feedback-button'; import { InAppMessages } from '@app/features/hiro-messages/in-app-messages'; import { homePageModalRoutes } from '@app/routes/app-routes'; import { ModalBackgroundWrapper } from '@app/routes/components/modal-background-wrapper'; @@ -37,6 +38,7 @@ export function Home() { return ( }> + } /> diff --git a/src/app/ui/components/button.tsx b/src/app/ui/components/button.tsx index f1864c38dd9..cc7218ac643 100644 --- a/src/app/ui/components/button.tsx +++ b/src/app/ui/components/button.tsx @@ -10,9 +10,13 @@ export type ButtonProps = Omit< ButtonVariantProps; export function LeatherButton(props: ButtonProps) { - const { children, variant, fullWidth, invert, type = 'button', ...rest } = props; + const { children, variant, fullWidth, invert, size, type = 'button', ...rest } = props; return ( - + {children} ); diff --git a/src/app/ui/components/icons/megaphone-icon.tsx b/src/app/ui/components/icons/megaphone-icon.tsx new file mode 100644 index 00000000000..e3b40db5672 --- /dev/null +++ b/src/app/ui/components/icons/megaphone-icon.tsx @@ -0,0 +1,23 @@ +import { styled } from 'leather-styles/jsx'; + +import { SvgProps } from '@app/ui/ui-types'; + +export function MegaphoneIcon({ size = 'sm', ...props }: SvgProps) { + return ( + + + + ); +} diff --git a/src/shared/utils/analytics.ts b/src/shared/utils/analytics.ts index 66869c02834..8594de257bd 100644 --- a/src/shared/utils/analytics.ts +++ b/src/shared/utils/analytics.ts @@ -3,6 +3,7 @@ import { sha256 } from '@noble/hashes/sha256'; import { base58 } from '@scure/base'; import { AnalyticsBrowser } from '@segment/analytics-next'; import * as Sentry from '@sentry/react'; +import { token } from 'leather-styles/tokens'; import { getStoredState } from 'redux-persist'; import { @@ -59,6 +60,35 @@ export function initSentry() { startTransactionOnPageLoad: false, markBackgroundTransactions: false, }), + new Sentry.Feedback({ + colorScheme: 'system', + isEmailRequired: false, + buttonLabel: 'Give feedback', + formTitle: 'Give feedback', + autoInject: false, + showEmail: false, + showName: false, + showBranding: false, + messageLabel: 'Feedback', + submitButtonLabel: 'Send feedback', + messagePlaceholder: 'How can we improve Leather?', + successMessageText: 'Thanks for helping make Leather better', + themeDark: { + background: token('colors.accent.background-primary'), + inputOutlineFocus: token('colors.accent.border-hover'), + submitBackground: token('colors.accent.component-background-default'), + submitBackgroundHover: token('colors.accent.component-background-hover'), + submitOutlineFocus: token('colors.accent.border-hover'), + submitBorder: token('colors.accent.component-background-default'), + cancelBackground: token('colors.colorPalette.action-primary-default'), + cancelBackgroundHover: token('colors.colorPalette.action-primary-hover'), + }, + themeLight: { + submitBackground: token('colors.lightModeInk.12'), + submitBackgroundHover: token('colors.lightModeInk.12'), + submitOutlineFocus: token('colors.lightModeInk.12'), + }, + }), ], ignoreErrors: [ // Harmless error diff --git a/theme/recipes/button.ts b/theme/recipes/button-recipe.ts similarity index 96% rename from theme/recipes/button.ts rename to theme/recipes/button-recipe.ts index 710c76dc6e4..3d1881d6617 100644 --- a/theme/recipes/button.ts +++ b/theme/recipes/button-recipe.ts @@ -4,7 +4,7 @@ import { ColorToken } from 'leather-styles/tokens'; const basePesudoOutlineProps = { content: '""', position: 'absolute', - rounded: '8px', + rounded: 'xs', top: 0, left: 0, bottom: 0, @@ -43,6 +43,7 @@ function loadingStyles(color: ColorToken) { }, }; } + // ts-unused-exports:disable-next-line export const buttonRecipe = defineRecipe({ description: 'The styles for the Button component', @@ -52,11 +53,18 @@ export const buttonRecipe = defineRecipe({ position: 'relative', py: 'space.03', px: 'space.04', - rounded: '8px', + rounded: 'xs', textStyle: 'label.01', _disabled: { cursor: 'not-allowed' }, }, variants: { + size: { + sm: { + textStyle: 'label.02', + py: 'space.02', + px: 'space.03', + }, + }, variant: { // Solid button solid: { diff --git a/yarn.lock b/yarn.lock index f2b6569c602..89d15fa3cee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3535,6 +3535,15 @@ dset "^3.1.1" tiny-hashes "^1.0.1" +"@sentry-internal/feedback@7.86.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.86.0.tgz#01c7b509a3adc9cdd03658082daf29a6cae9cc8f" + integrity sha512-6rl0JYjmAKnhm4/fuFaROh4Ht8oi9f6ZeIcViCuGJcrGICZJJY0s+R77XJI78rNa82PYFrSCcnWXcGji4T8E7g== + dependencies: + "@sentry/core" "7.86.0" + "@sentry/types" "7.86.0" + "@sentry/utils" "7.86.0" + "@sentry-internal/tracing@7.53.1": version "7.53.1" resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.53.1.tgz#85517ba93ee721424c865706f7ff4eaab1569e6d" @@ -3555,17 +3564,26 @@ "@sentry/utils" "7.72.0" tslib "^2.4.1 || ^1.9.3" -"@sentry/browser@7.72.0": - version "7.72.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.72.0.tgz#8920d32920031de7ef70140ac13de267e773e5c7" - integrity sha512-fcFDTzqhPd3VZAmmYW3KvBTBaEfrKjPmRhlAsfhkGWYLCHqVkNtzsFER4cmUNRGNxjyt9tcG3WlTTqgLRucycQ== +"@sentry-internal/tracing@7.86.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.86.0.tgz#657e80eb7d08d1030393902c1a7bc47fc39ccb2d" + integrity sha512-b4dUsNWlPWRwakGwR7bhOkqiFlqQszH1hhVFwrm/8s3kqEBZ+E4CeIfCvuHBHQ1cM/fx55xpXX/BU163cy+3iQ== dependencies: - "@sentry-internal/tracing" "7.72.0" - "@sentry/core" "7.72.0" - "@sentry/replay" "7.72.0" - "@sentry/types" "7.72.0" - "@sentry/utils" "7.72.0" - tslib "^2.4.1 || ^1.9.3" + "@sentry/core" "7.86.0" + "@sentry/types" "7.86.0" + "@sentry/utils" "7.86.0" + +"@sentry/browser@7.86.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.86.0.tgz#9b828a444949f8fe4a47d830cc87b8b52275c24e" + integrity sha512-nfYWpVOmug+W7KJO7/xhA1JScMZcYHcoOVHLsUFm4znx51U4qZEk+zZDM11Q2Nw6MuDyEYg6bsH1QCwaoC6nLw== + dependencies: + "@sentry-internal/feedback" "7.86.0" + "@sentry-internal/tracing" "7.86.0" + "@sentry/core" "7.86.0" + "@sentry/replay" "7.86.0" + "@sentry/types" "7.86.0" + "@sentry/utils" "7.86.0" "@sentry/bundler-plugin-core@2.4.0": version "2.4.0" @@ -3610,6 +3628,14 @@ "@sentry/utils" "7.72.0" tslib "^2.4.1 || ^1.9.3" +"@sentry/core@7.86.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.86.0.tgz#d01f538783dee9a0d79141a63145392ad2c1cb89" + integrity sha512-SbLvqd1bRYzhDS42u7GMnmbDMfth/zRiLElQWbLK/shmuZzTcfQSwNNdF4Yj+VfjOkqPFgGmICHSHVUc9dh01g== + dependencies: + "@sentry/types" "7.86.0" + "@sentry/utils" "7.86.0" + "@sentry/node@7.53.1": version "7.53.1" resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.53.1.tgz#d4c47477cf4305e352b511635d1d3d4d160e8bd7" @@ -3624,25 +3650,25 @@ lru_map "^0.3.3" tslib "^1.9.3" -"@sentry/react@7.72.0": - version "7.72.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.72.0.tgz#badb4b5e28d27c892917210a6816cb6a2af2c2a5" - integrity sha512-BYFO3uyB9FfdUq05NtsS+OfU636HMZ7avbSEALo24x+OPuaD+fCByTdgxYVpDRYrBPa7lALYzCge0PDcGnGiig== +"@sentry/react@7.86.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.86.0.tgz#54b1a27e773f3a4fe6afe5d83bbc3e71e42ac326" + integrity sha512-2bHi+YcG4cT+4xHXXzv+AZpU3pdPUlDBorSgHOpa9At4yxr17UWW2f8bP9wPYRgj+NEIM3YhDgR46FlBu9GSKg== dependencies: - "@sentry/browser" "7.72.0" - "@sentry/types" "7.72.0" - "@sentry/utils" "7.72.0" + "@sentry/browser" "7.86.0" + "@sentry/types" "7.86.0" + "@sentry/utils" "7.86.0" hoist-non-react-statics "^3.3.2" - tslib "^2.4.1 || ^1.9.3" -"@sentry/replay@7.72.0": - version "7.72.0" - resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.72.0.tgz#39da5d971045a6d9bf5d3bd16ccc1f5c0c42c4c8" - integrity sha512-dHH/mYCFBwJ/kYmL9L5KihjwQKcefiuvcH0otHSwKSpbbeEoM/BV+SHQoYGd6OMSYnL9fq1dHfF7Zo26p5Yu0Q== +"@sentry/replay@7.86.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.86.0.tgz#d001eac9687de3555efded9423d3cf00e8ae6d9f" + integrity sha512-YYZO8bfQSx1H87Te/zzyHPLHvExWiYwUfMWW68yGX+PPZIIzxaM81/iCQHkoucxlvuPCOtxCgf7RSMbsnqEa8g== dependencies: - "@sentry/core" "7.72.0" - "@sentry/types" "7.72.0" - "@sentry/utils" "7.72.0" + "@sentry-internal/tracing" "7.86.0" + "@sentry/core" "7.86.0" + "@sentry/types" "7.86.0" + "@sentry/utils" "7.86.0" "@sentry/tracing@7.72.0": version "7.72.0" @@ -3661,6 +3687,11 @@ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.72.0.tgz#b474d3821338a545fb2db109715d9aad502bc810" integrity sha512-g6u0mk62yGshx02rfFADIfyR/S9VXcf3RG2qQPuvykrWtOfN/BOTrZypF7I+MiqKwRW76r3Pcu2C/AB+6z9XQA== +"@sentry/types@7.86.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.86.0.tgz#56ed2f5b15e8130ea5ecfbbc4102d88eaa3b3a67" + integrity sha512-pGAt0+bMfWgo0KG2epthfNV4Wae03tURpoxNjGo5Fr4cXxvLTSijSAQ6rmmO4bXBJ7+rErEjX30g30o/eEdP9g== + "@sentry/utils@7.53.1": version "7.53.1" resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.53.1.tgz#b1f9f1dd4de7127287ad5027c2bd1133c5590486" @@ -3677,6 +3708,13 @@ "@sentry/types" "7.72.0" tslib "^2.4.1 || ^1.9.3" +"@sentry/utils@7.86.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.86.0.tgz#356ec19bf1e3e5c40935dd987fd15bee8c6b37ba" + integrity sha512-6PejFtw9VTFFy5vu0ks+U7Ozkqz+eMt+HN8AZKBKErYzX5/xs0kpkOcSRpu3ETdTYcZf8VAmLVgFgE2BE+3WuQ== + dependencies: + "@sentry/types" "7.86.0" + "@sentry/webpack-plugin@2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-2.4.0.tgz#f2d10ff67d615cdd6d8b9340b189b3cb57eb5857"