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**
### **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()}
>
)}