1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-22 09:23:21 +01:00

[MMI] Added code fences in whats new popup (#19581)

* added code fences in whats new popup

* Improved code

* Added missing prop

* Update LavaMoat policies

* updated functions by using an options object for the rendering functions in order to bypass possible typsecript issues

---------

Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
This commit is contained in:
Albert Olivé 2023-06-27 08:30:42 +02:00 committed by GitHub
parent ec4c4050e6
commit 1e56fdbf66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 157 additions and 28 deletions

View File

@ -5162,6 +5162,9 @@
"viewOnOpensea": {
"message": "View on Opensea"
},
"viewPortfolioDashboard": {
"message": "View Portfolio Dashboard"
},
"viewinCustodianApp": {
"message": "View in custodian app"
},

View File

@ -121,6 +121,9 @@ import {
///: END:ONLY_INCLUDE_IN
} from '../../shared/constants/permissions';
import { UI_NOTIFICATIONS } from '../../shared/notifications';
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
import { UI_INSTITUTIONAL_NOTIFICATIONS } from '../../shared/notifications/institutional';
///: END:ONLY_INCLUDE_IN
import { MILLISECOND, SECOND } from '../../shared/constants/time';
import {
ORIGIN_METAMASK,
@ -618,9 +621,16 @@ export default class MetamaskController extends EventEmitter {
const announcementMessenger = this.controllerMessenger.getRestricted({
name: 'AnnouncementController',
});
let allAnnouncements = UI_NOTIFICATIONS;
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
allAnnouncements = UI_INSTITUTIONAL_NOTIFICATIONS;
///: END:ONLY_INCLUDE_IN
this.announcementController = new AnnouncementController({
messenger: announcementMessenger,
allAnnouncements: UI_NOTIFICATIONS,
allAnnouncements,
state: initState.AnnouncementController,
});

View File

@ -0,0 +1,35 @@
export const UI_INSTITUTIONAL_NOTIFICATIONS = {
1: {
id: 11,
date: '2022-08-28',
image: {
src: 'images/portfolio.svg',
},
hideDate: true,
descriptionInBullets: true,
},
};
export const getTranslatedInstitutionalUINotifications = (t, locale) => {
const formattedLocale = locale.replace('_', '-');
return {
1: {
...UI_INSTITUTIONAL_NOTIFICATIONS[11],
title: 'Portfolio dashboard',
description: [
'Portfolio snapshots',
'Filtering by account and network',
'Sector and protocol allocation',
'Improved navigation',
],
date: new Intl.DateTimeFormat(formattedLocale).format(
new Date(UI_INSTITUTIONAL_NOTIFICATIONS[11].date),
),
customButton: {
name: 'mmi-portfolio',
text: t('viewPortfolioDashboard'),
logo: true,
},
},
};
};

View File

@ -7,9 +7,14 @@ import { debounce } from 'lodash';
import { getCurrentLocale } from '../../../ducks/locale/locale';
import { I18nContext } from '../../../contexts/i18n';
import { useEqualityCheck } from '../../../hooks/useEqualityCheck';
import Button from '../../ui/button';
import Popover from '../../ui/popover';
import { Text } from '../../component-library';
import {
Button,
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
IconName,
///: END:ONLY_INCLUDE_IN
Text,
} from '../../component-library';
import { updateViewedNotifications } from '../../../store/actions';
import { getTranslatedUINotifications } from '../../../../shared/notifications';
import { getSortedAnnouncementsToShow } from '../../../selectors';
@ -20,7 +25,12 @@ import {
EXPERIMENTAL_ROUTE,
SECURITY_ROUTE,
} from '../../../helpers/constants/routes';
import { TextVariant } from '../../../helpers/constants/design-system';
import {
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
Size,
///: END:ONLY_INCLUDE_IN
TextVariant,
} from '../../../helpers/constants/design-system';
import ZENDESK_URLS from '../../../helpers/constants/zendesk-url';
import { MetaMetricsContext } from '../../../contexts/metametrics';
import {
@ -118,15 +128,36 @@ const renderDescription = (description) => {
);
};
const renderFirstNotification = (
const renderFirstNotification = ({
notification,
idRefMap,
history,
isLast,
trackEvent,
) => {
const { id, date, title, description, image, actionText } = notification;
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
mmiPortfolioUrl,
seenNotifications,
onClose,
///: END:ONLY_INCLUDE_IN
}) => {
const {
id,
date,
title,
description,
image,
actionText,
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
customButton,
hideDate,
///: END:ONLY_INCLUDE_IN
} = notification;
const actionFunction = getActionFunctionById(id, history);
let showNotificationDate = true;
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
showNotificationDate = !hideDate;
///: END:ONLY_INCLUDE_IN
const imageComponent = image && (
<img
@ -155,7 +186,9 @@ const renderFirstNotification = (
<div className="whats-new-popup__notification-description">
{renderDescription(description)}
</div>
<div className="whats-new-popup__notification-date">{date}</div>
{showNotificationDate && (
<div className="whats-new-popup__notification-date">{date}</div>
)}
</div>
{placeImageBelowDescription && imageComponent}
{actionText && (
@ -173,6 +206,25 @@ const renderFirstNotification = (
{actionText}
</Button>
)}
{
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
customButton && customButton.name === 'mmi-portfolio' && (
<Button
className="whats-new-popup__button"
data-testid="view-mmi-portfolio"
size={Size.SM}
startIconName={IconName.MmmiPortfolioDashboard}
onClick={() => {
updateViewedNotifications(seenNotifications);
onClose();
window.open(mmiPortfolioUrl, '_blank');
}}
>
{customButton.text}
</Button>
)
///: END:ONLY_INCLUDE_IN
}
<div
className="whats-new-popup__intersection-observable"
ref={idRefMap[id]}
@ -181,12 +233,12 @@ const renderFirstNotification = (
);
};
const renderSubsequentNotification = (
const renderSubsequentNotification = ({
notification,
idRefMap,
history,
isLast,
) => {
}) => {
const { id, date, title, description, actionText } = notification;
const actionFunction = getActionFunctionById(id, history);
@ -217,7 +269,12 @@ const renderSubsequentNotification = (
);
};
export default function WhatsNewPopup({ onClose }) {
export default function WhatsNewPopup({
onClose,
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
mmiPortfolioUrl,
///: END:ONLY_INCLUDE_IN
}) {
const t = useContext(I18nContext);
const history = useHistory();
@ -295,6 +352,16 @@ export default function WhatsNewPopup({ onClose }) {
};
}, [idRefMap, setSeenNotifications]);
// Display the swaps notification with full image
// Displays the NFTs & OpenSea notifications 18,19 with full image
const notificationRenderers = {
0: renderFirstNotification,
1: renderFirstNotification,
18: renderFirstNotification,
19: renderFirstNotification,
21: renderFirstNotification,
};
return (
<Popover
title={t('whatsNew')}
@ -321,22 +388,26 @@ export default function WhatsNewPopup({ onClose }) {
{notifications.map(({ id }, index) => {
const notification = getTranslatedUINotifications(t, locale)[id];
const isLast = index === notifications.length - 1;
// Display the swaps notification with full image
// Displays the NFTs & OpenSea notifications 18,19 with full image
return index === 0 || id === 1 || id === 18 || id === 19 || id === 21
? renderFirstNotification(
notification,
idRefMap,
history,
isLast,
trackEvent,
)
: renderSubsequentNotification(
notification,
idRefMap,
history,
isLast,
);
// Choose the appropriate rendering function based on the id
let renderNotification =
notificationRenderers[id] || renderSubsequentNotification;
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
renderNotification = renderFirstNotification;
///: END:ONLY_INCLUDE_IN
return renderNotification({
notification,
idRefMap,
history,
isLast,
trackEvent,
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
mmiPortfolioUrl,
seenNotifications,
onClose,
///: END:ONLY_INCLUDE_IN
});
})}
</div>
</Popover>
@ -345,4 +416,7 @@ export default function WhatsNewPopup({ onClose }) {
WhatsNewPopup.propTypes = {
onClose: PropTypes.func.isRequired,
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
mmiPortfolioUrl: PropTypes.string.isRequired,
///: END:ONLY_INCLUDE_IN
};

View File

@ -755,10 +755,17 @@ export default class Home extends PureComponent {
exact
/>
<div className="home__container">
{showWhatsNew ? (
<WhatsNewPopup
onClose={hideWhatsNewPopup}
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
mmiPortfolioUrl={mmiPortfolioUrl}
///: END:ONLY_INCLUDE_IN
/>
) : null}
{
///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask)
}
{showWhatsNew ? <WhatsNewPopup onClose={hideWhatsNewPopup} /> : null}
{!showWhatsNew && showRecoveryPhraseReminder ? (
<RecoveryPhraseReminder
hasBackedUp={seedPhraseBackedUp}