Skip to content

Commit

Permalink
Add 'What's New' notification popup
Browse files Browse the repository at this point in the history
  • Loading branch information
danjm committed Mar 4, 2021
1 parent b549c27 commit f92f532
Show file tree
Hide file tree
Showing 25 changed files with 497 additions and 234 deletions.
4 changes: 4 additions & 0 deletions app/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2223,6 +2223,10 @@
"welcomeBack": {
"message": "Welcome Back!"
},
"whatsNew": {
"message": "What's new",
"description": "This is the title of a popup that gives users notifications about new features and updates to MetaMask."
},
"whatsThis": {
"message": "What's this?"
},
Expand Down
101 changes: 101 additions & 0 deletions app/images/swaps-logos-small.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 0 additions & 9 deletions app/scripts/controllers/app-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,6 @@ export default class AppStateController extends EventEmitter {
});
}

/**
* Record that the user has seen the swap screen welcome message
*/
setSwapsWelcomeMessageHasBeenShown() {
this.store.updateState({
swapsWelcomeMessageHasBeenShown: true,
});
}

/**
* Sets the last active time to the current time
* @returns {void}
Expand Down
19 changes: 15 additions & 4 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ import {
ApprovalController,
CurrencyRateController,
PhishingController,
NotificationController,
} from '@metamask/controllers';
import { getBackgroundMetaMetricState } from '../../ui/app/selectors';
import { TRANSACTION_STATUSES } from '../../shared/constants/transaction';
import { UI_NOTIFICATIONS } from '../../shared/notifications';
import ComposableObservableStore from './lib/ComposableObservableStore';
import AccountTracker from './lib/account-tracker';
import createLoggerMiddleware from './lib/createLoggerMiddleware';
Expand Down Expand Up @@ -162,6 +164,11 @@ export default class MetamaskController extends EventEmitter {

this.phishingController = new PhishingController();

this.notificationController = new NotificationController(
{ allNotifications: UI_NOTIFICATIONS },
initState.NotificationController,
);

// now we can initialize the RPC provider, which other controllers require
this.initializeProvider();
this.provider = this.networkController.getProviderAndBlockTracker().provider;
Expand Down Expand Up @@ -400,6 +407,7 @@ export default class MetamaskController extends EventEmitter {
PermissionsController: this.permissionsController.permissions,
PermissionsMetadata: this.permissionsController.store,
ThreeBoxController: this.threeBoxController.store,
NotificationController: this.notificationController,
});

this.memStore = new ComposableObservableStore(null, {
Expand Down Expand Up @@ -428,6 +436,7 @@ export default class MetamaskController extends EventEmitter {
SwapsController: this.swapsController.store,
EnsController: this.ensController.store,
ApprovalController: this.approvalController,
NotificationController: this.notificationController,
});
this.memStore.subscribe(this.sendUpdate.bind(this));

Expand Down Expand Up @@ -707,10 +716,6 @@ export default class MetamaskController extends EventEmitter {
this.appStateController.setConnectedStatusPopoverHasBeenShown,
this.appStateController,
),
setSwapsWelcomeMessageHasBeenShown: nodeify(
this.appStateController.setSwapsWelcomeMessageHasBeenShown,
this.appStateController,
),

// EnsController
tryReverseResolveAddress: nodeify(
Expand Down Expand Up @@ -918,6 +923,12 @@ export default class MetamaskController extends EventEmitter {
approvalController.reject,
approvalController,
),

// Notifications
updateViewedNotifications: nodeify(
this.notificationController.updateViewed,
this.notificationController,
),
};
}

Expand Down
18 changes: 13 additions & 5 deletions app/scripts/platforms/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,26 @@ export default class ExtensionPlatform {
return extension.runtime.getManifest().version;
}

openExtensionInBrowser(route = null, queryString = null) {
openExtensionInBrowser(
route = null,
queryString = null,
keepCurrentTabOpen = false,
) {
let extensionURL = extension.runtime.getURL('home.html');

if (route) {
extensionURL += `#${route}`;
}

if (queryString) {
extensionURL += `?${queryString}`;
}

if (route) {
extensionURL += `#${route}`;
}
this.openTab({ url: extensionURL });
if (getEnvironmentType() !== ENVIRONMENT_TYPE_BACKGROUND) {
if (
getEnvironmentType() !== ENVIRONMENT_TYPE_BACKGROUND &&
!keepCurrentTabOpen
) {
window.close();
}
}
Expand Down
94 changes: 94 additions & 0 deletions shared/notifications/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { getSwapsFeatureLiveness } from '../../ui/app/ducks/swaps/swaps';
import { getSwapsEthToken, getIsMainnet } from '../../ui/app/selectors';
import { BUILD_QUOTE_ROUTE } from '../../ui/app/helpers/constants/routes';

export const UI_NOTIFICATIONS = {
1: {
id: 1,
title: 'Now Swap tokens directly in your wallet!',
description:
'MetaMask now aggregates multiple decentralized exchange aggregators to ensure you always get the best swap price with the lowest netwrok fees.',
date: '02/22/2020',
image: 'images/swaps-logos-small.svg',
actionText: 'Start swapping',
},
2: {
id: 2,
title: 'MetaMask Mobile is here!',
description:
'Sync with your extension wallet in seconds. Scan the QR code with your phone camera to download the app.',
date: '02/22/2020',
actionText: 'Get the mobile app',
},
3: {
id: 3,
title: 'Help improve MetaMask',
description: 'Please share your experience in this 5 minute survey.',
date: '02/22/2020',
actionText: 'Start survey',
},
};

function getNotificationFilters(state) {
const currentNetworkIsMainnet = getIsMainnet(state);
const swapsIsEnabled = getSwapsFeatureLiveness(state);

return {
1: !currentNetworkIsMainnet || !swapsIsEnabled,
};
}

export function getSortedNotificationsToShow(state) {
const notifications = Object.values(state.metamask.notifications) || [];
const notificationFilters = getNotificationFilters(state);
const notificationsToShow = notifications.filter(
(notification) =>
!notification.isShown && !notificationFilters[notification.id],
);
const notificationsSortedByDate = notificationsToShow.sort(
(a, b) => new Date(b.date) - new Date(a.date),
);
return notificationsSortedByDate;
}

export function notifcationActionFunctions(
// eslint-disable-next-line no-unused-vars
dispatch,
// eslint-disable-next-line no-unused-vars
state,
// eslint-disable-next-line no-unused-vars
history,
// eslint-disable-next-line no-unused-vars
metricsEvent,
) {
const swapsEthToken = getSwapsEthToken(state);

const actionFunctions = {
1: () => {
metricsEvent({
event: 'Swaps Opened',
properties: { source: 'Main View', active_currency: 'ETH' },
category: 'swaps',
});
global.platform.openExtensionInBrowser(
BUILD_QUOTE_ROUTE,
`fromAddress=${swapsEthToken.address}`,
);
},
2: () => {
global.platform.openTab({
url: 'https://metamask.io/download.html',
});
},
3: () => {
global.platform.openTab({
url:
'https://survey.alchemer.com/s3/6173069/MetaMask-Extension-NPS-January-2021',
});
},
};

return (id) => {
return actionFunctions[id];
};
}
1 change: 1 addition & 0 deletions ui/app/components/app/app-components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@
@import 'transaction-list/index';
@import 'transaction-status/index';
@import 'wallet-overview/index';
@import 'whats-new-popup/index';
1 change: 1 addition & 0 deletions ui/app/components/app/whats-new-popup/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './whats-new-popup';
47 changes: 47 additions & 0 deletions ui/app/components/app/whats-new-popup/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
.whats-new-popup {
&__notifications {
display: flex;
flex-direction: column;
align-items: center;
}

&__notification,
&__first-notification {
display: flex;
flex-direction: column;
align-items: left;
margin: 0 24px 24px 24px;
border-bottom: 1px solid $Grey-100;
}

&__notification-image {
margin-bottom: 16px;
}

&__notification-description {
margin-bottom: 16px;
}

&__button {
margin-right: auto;
}

&__button,
&__link {
margin-bottom: 24px;
}

&__link {
@include H6;

color: $Blue-500;
cursor: pointer;
}

&__notification-title {
@include H4;

font-weight: bold;
margin-bottom: 8px;
}
}
Loading

0 comments on commit f92f532

Please sign in to comment.