From 0b39b1fb3c462eb6410ea3f259d3aa98dbda4341 Mon Sep 17 00:00:00 2001 From: Jonathan Ferreira <44679989+Jonathansoufer@users.noreply.github.com> Date: Thu, 12 Sep 2024 16:06:38 +0100 Subject: [PATCH] feat: add product announcements toggle (#11175) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** This PR implements Product Announcement's toggle on custom notifications. [NOTIFY-1087](https://consensyssoftware.atlassian.net/browse/NOTIFY-1087?atlOrigin=eyJpIjoiYWM0MWY1M2ZjNGM5NDZjOGJiYTY3ZTdkYWEwYTBiMTkiLCJwIjoiaiJ9) ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to Settings Page 2. Go to Notifications Settings ## **Screenshots/Recordings** ### **Before** Screenshot 2024-09-10 at 9 15 37 PM ### **After** ![Screenshot 2024-09-12 at 13 38 19](https://github.com/user-attachments/assets/1866bd9c-5c26-4c56-ae9f-efd18dee1351) ## **Pre-merge author checklist** - [ ] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. [NOTIFY-1087]: https://consensyssoftware.atlassian.net/browse/NOTIFY-1087?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --- .../__snapshots__/index.test.tsx.snap | 95 +++++++++++++++ .../CustomNotificationsRow/index.test.tsx | 19 +++ .../CustomNotificationsRow/index.tsx | 64 ++++++++++ .../__snapshots__/index.test.tsx.snap | 114 ------------------ .../NotificationOptionToggle/index.test.tsx | 33 ----- .../NotificationOptionToggle/index.tsx | 2 +- .../Settings/NotificationsSettings/index.tsx | 34 +++++- 7 files changed, 208 insertions(+), 153 deletions(-) create mode 100644 app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/__snapshots__/index.test.tsx.snap create mode 100644 app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/index.test.tsx create mode 100644 app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/index.tsx delete mode 100644 app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/__snapshots__/index.test.tsx.snap delete mode 100644 app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/index.test.tsx diff --git a/app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/__snapshots__/index.test.tsx.snap b/app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/__snapshots__/index.test.tsx.snap new file mode 100644 index 00000000000..a397ed5b8c6 --- /dev/null +++ b/app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/__snapshots__/index.test.tsx.snap @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CustomNotificationsRow should render correctly 1`] = ` + + + + + Assets Sent + + + Funds and NFT + + + + +`; diff --git a/app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/index.test.tsx b/app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/index.test.tsx new file mode 100644 index 00000000000..589a93bbf0b --- /dev/null +++ b/app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/index.test.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import CustomNotificationsRow from '../CustomNotificationsRow/index'; +import { render } from '@testing-library/react-native'; +import notificationsRows from '../notificationsRows'; + +describe('CustomNotificationsRow', () => { + it('should render correctly', () => { + const { toJSON } = render( + jest.fn()} + />, + ); + expect(toJSON()).toMatchSnapshot(); + }); +}); diff --git a/app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/index.tsx b/app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/index.tsx new file mode 100644 index 00000000000..17992b13c2d --- /dev/null +++ b/app/components/Views/Settings/NotificationsSettings/CustomNotificationsRow/index.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { Switch, View } from 'react-native'; +import { useTheme } from '../../../../../util/theme'; +import { createStyles } from '../NotificationOptionToggle/styles'; +import Text, { + TextVariant, +} from '../../../../../component-library/components/Texts/Text'; +import Icon, { IconColor, IconName, IconSize } from '../../../../../component-library/components/Icons/Icon'; + +interface CustomNotificationsRowProps { + title: string; + description?: string; + icon: IconName; + isEnabled: boolean; + onChange: () => void; +} + +const CustomNotificationsRow = ({ + title, + description, + icon, + isEnabled, + onChange, +}: CustomNotificationsRowProps) => { + const theme = useTheme(); + const { colors } = theme; + const styles = createStyles(); + + return ( + + + + + {title} + + { + description && + ( + {description} + ) + } + + + + ); +}; + + + export default React.memo(CustomNotificationsRow); diff --git a/app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/__snapshots__/index.test.tsx.snap b/app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 62a3b7d8b75..00000000000 --- a/app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,114 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NotificationOptionToggle should render correctly 1`] = ` - - - - - - - 0x123123123 - - - 0x123123123 - - - - - - -`; diff --git a/app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/index.test.tsx b/app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/index.test.tsx deleted file mode 100644 index 42b4c32b837..00000000000 --- a/app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/index.test.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -import NotificationOptionToggle from './index'; -import { render } from '@testing-library/react-native'; -import { NotificationsToggleTypes } from '../NotificationsSettings.constants'; -import { AvatarAccountType } from '../../../../../component-library/components/Avatars/Avatar'; - -jest.mock('@react-navigation/native', () => ({ - ...jest.requireActual('@react-navigation/native'), - useNavigation: jest.fn(() => ({})), -})); - -jest.mock('react-redux', () => ({ - useSelector: jest.fn().mockImplementation((selector) => selector()), -})); - -jest.mock('../../../../../selectors/notifications', () => ({ - getNotificationsList: jest.fn(), -})); -describe('NotificationOptionToggle', () => { - it('should render correctly', () => { - const { toJSON } = render( - Promise.resolve()} - />, - ); - expect(toJSON()).toMatchSnapshot(); - }); -}); diff --git a/app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/index.tsx b/app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/index.tsx index be97c3bde61..238a8debb55 100644 --- a/app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/index.tsx +++ b/app/components/Views/Settings/NotificationsSettings/NotificationOptionToggle/index.tsx @@ -32,7 +32,7 @@ interface NotificationOptionsToggleProps { testId?: string; isEnabled: boolean; - refetchAccountSettings: () => Promise; + refetchAccountSettings?: () => Promise; } function useUpdateAccountSetting(address: string) { diff --git a/app/components/Views/Settings/NotificationsSettings/index.tsx b/app/components/Views/Settings/NotificationsSettings/index.tsx index e688d0e9a8b..ca340f1a39f 100644 --- a/app/components/Views/Settings/NotificationsSettings/index.tsx +++ b/app/components/Views/Settings/NotificationsSettings/index.tsx @@ -22,8 +22,8 @@ import { Props } from './NotificationsSettings.types'; import { useStyles } from '../../../../component-library/hooks'; import NotificationOptionToggle from './NotificationOptionToggle'; +import CustomNotificationsRow from './CustomNotificationsRow'; import { NotificationsToggleTypes } from './NotificationsSettings.constants'; - import { selectIsMetamaskNotificationsEnabled } from '../../../../selectors/notifications'; import { @@ -31,7 +31,7 @@ import { asyncAlert, } from '../../../../util/notifications'; import Routes from '../../../../constants/navigation/Routes'; -import { IconName } from '../../../../component-library/components/Icons/Icon'; + import ButtonIcon, { ButtonIconSizes, } from '../../../../component-library/components/Buttons/ButtonIcon'; @@ -40,10 +40,12 @@ import { useDisableNotifications, useEnableNotifications, } from '../../../../util/notifications/hooks/useNotifications'; -import { useAccountSettingsProps } from '../../../../util/notifications/hooks/useSwitchNotifications'; +import { useAccountSettingsProps, useSwitchNotifications } from '../../../../util/notifications/hooks/useSwitchNotifications'; import styleSheet from './NotificationsSettings.styles'; import AppConstants from '../../../../core/AppConstants'; import { store } from '../../../../store'; +import notificationsRows from './notificationsRows'; +import { IconName } from '../../../../component-library/components/Icons/Icon'; interface MainNotificationSettingsProps extends Props { @@ -93,6 +95,7 @@ const MainNotificationSettings = ({ styles, toggleNotificationsEnabled, isMetama );}; const NotificationsSettings = ({ navigation, route }: Props) => { const { accounts } = useAccounts(); + const { switchFeatureAnnouncements } = useSwitchNotifications(); const accountsNotificationState = store.getState().notifications; const theme = useTheme(); const accountAddresses = useMemo( @@ -121,6 +124,7 @@ const NotificationsSettings = ({ navigation, route }: Props) => { (state: RootState) => state.settings.basicFunctionalityEnabled, ); const [uiNotificationStatus, setUiNotificationStatus] = React.useState(false); + const [platformAnnouncementsState, setPlatformAnnouncementsState] = React.useState(false); const loading = enableLoading || disableLoading; const errorText = enablingError || disablingError; @@ -177,6 +181,12 @@ const NotificationsSettings = ({ navigation, route }: Props) => { navigation, ]); + + const toggleCustomNotificationsEnabled = useCallback(async() => { + setPlatformAnnouncementsState(!platformAnnouncementsState); + await switchFeatureAnnouncements(!platformAnnouncementsState); + },[platformAnnouncementsState, switchFeatureAnnouncements]); + const goToLearnMore = () => { Linking.openURL(AppConstants.URLS.PROFILE_SYNC); }; @@ -198,8 +208,6 @@ const NotificationsSettings = ({ navigation, route }: Props) => { reFetchingAccountSettings(); }, [colors, isFullScreenModal, navigation, reFetchingAccountSettings]); - - const refetchAccountSettings = useCallback(async () => { await accountSettingsProps.update(accountAddresses); }, [accountSettingsProps, accountAddresses]); @@ -237,6 +245,21 @@ const NotificationsSettings = ({ navigation, route }: Props) => { {isMetamaskNotificationsEnabled && ( <> + + { )} styles={styles} /> + {renderAccounts()} )}