Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: onboarding modal #109

Merged
merged 7 commits into from
Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.development
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ REACT_APP_STARKNET_CONTRACT_ADDRESS=0xde29d060D45901Fb19ED6C6e959EB22d8626708e
REACT_APP_ETHERSCAN_URL=//goerli.etherscan.io
REACT_APP_VOYAGER_URL=//goerli.voyager.online
REACT_APP_LOCAL_STORAGE_TRANSFERS_LOG_KEY=STARKGATE_TRANSFERS
REACT_APP_LOCAL_STORAGE_ONBOARDING_TIMESTAMP_KEY=STARKGATE_ONBOARDING_TIMESTAMP
REACT_APP_ONBOARDING_MODAL_TIMEOUT_HRS=24
2 changes: 2 additions & 0 deletions .env.production
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ REACT_APP_STARKNET_CONTRACT_ADDRESS=
REACT_APP_ETHERSCAN_URL=//etherscan.io
REACT_APP_VOYAGER_URL=//voyager.online
REACT_APP_LOCAL_STORAGE_TRANSFERS_LOG_KEY=STARKGATE_TRANSFERS
REACT_APP_LOCAL_STORAGE_ONBOARDING_TIMESTAMP_KEY=STARKGATE_ONBOARDING_TIMESTAMP
REACT_APP_ONBOARDING_MODAL_TIMEOUT_HRS=24
15 changes: 14 additions & 1 deletion src/__tests__/utils/date.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import utils from '../../utils';

const {get24Time, getDate} = utils.date;
const {get24Time, getDate, getMsFromHrs} = utils.date;

describe('getDate', () => {
it('should return date of the form DD/MM/YYYY from timestamp', () => {
Expand All @@ -13,3 +13,16 @@ describe('get24Time', () => {
expect(get24Time(1644828892412).endsWith(':54:52')).toBeTruthy();
});
});

describe('getMsFromHrs', () => {
it('should return the equivalent time from hours to milliseconds', () => {
expect(getMsFromHrs(1)).toEqual(3600000);
expect(getMsFromHrs('24')).toEqual(86400000);
expect(getMsFromHrs('0')).toEqual(0);
});

it('should return undefined if parseFloat got NaN', () => {
expect(getMsFromHrs('something')).toEqual(undefined);
expect(getMsFromHrs(undefined)).toEqual(undefined);
});
});
25 changes: 24 additions & 1 deletion src/components/Features/Bridge/Bridge.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
import React from 'react';
import React, {useEffect} from 'react';

import {Account, Faq, SelectToken, ToastProvider, Transfer} from '..';
import envs from '../../../config/envs';
import {MenuType} from '../../../enums';
import {useMenu} from '../../../providers/MenuProvider';
import {useOnboardingModal} from '../../../providers/ModalProvider';
import utils from '../../../utils';
import styles from './Bridge.module.scss';

const {localStorageOnboardingExpirationTimestampKey, onboardingModalTimeoutHrs} = envs;

export const Bridge = () => {
const {menu, menuProps} = useMenu();
const showOnboardingModal = useOnboardingModal();

useEffect(() => {
maybeShowOnboardingModal();
}, []);

const maybeShowOnboardingModal = () => {
const onboardingTimestamp = utils.storage.getItem(localStorageOnboardingExpirationTimestampKey);
const now = Date.now();
const onboardingModalTimeoutMs = utils.date.getMsFromHrs(onboardingModalTimeoutHrs);
if (!onboardingTimestamp || onboardingTimestamp < now) {
showOnboardingModal();
utils.storage.setItem(
localStorageOnboardingExpirationTimestampKey,
now + onboardingModalTimeoutMs
);
}
};

const renderMenu = () => {
switch (menu) {
Expand Down
20 changes: 20 additions & 0 deletions src/components/UI/Modal/OnboardingModal/OnboardingModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';

import styles from './OnboardingModal.module.scss';
import {SUBTITLE_TXT, BULLETS_TXT, INCOGNITO_TXT} from './OnboardingModal.strings';

const OnboardingModal = () => {
return (
<div className={styles.onboardingModal}>
<h3>{SUBTITLE_TXT}</h3>
<ul>
{BULLETS_TXT.map((bullet, i) => (
<li key={`b-${i}`}>{bullet}</li>
))}
</ul>
<p dangerouslySetInnerHTML={{__html: INCOGNITO_TXT}} />
</div>
);
};

export default OnboardingModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import '../../../../index';

.onboardingModal {
h3 {
color: $--color-alpha-5;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import utils from '../../../../utils';

const {title_txt, subtitle_txt, bullets_txt, incognito_txt} =
utils.getTranslation('modals.onboarding');

export const TITLE_TXT = title_txt;
export const SUBTITLE_TXT = subtitle_txt;
export const BULLETS_TXT = bullets_txt;
export const INCOGNITO_TXT = incognito_txt;
5 changes: 4 additions & 1 deletion src/config/envs.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ const envs = {
voyagerTxUrl: tx => utils.object.evaluate(`${process.env.REACT_APP_VOYAGER_URL}/tx/{{tx}}`, {tx}),
voyagerAccountUrl: contract =>
utils.object.evaluate(`${process.env.REACT_APP_VOYAGER_URL}/contract/{{contract}}`, {contract}),
localStorageTransfersLogKey: process.env.REACT_APP_LOCAL_STORAGE_TRANSFERS_LOG_KEY
localStorageTransfersLogKey: process.env.REACT_APP_LOCAL_STORAGE_TRANSFERS_LOG_KEY,
localStorageOnboardingExpirationTimestampKey:
process.env.REACT_APP_LOCAL_STORAGE_ONBOARDING_TIMESTAMP_KEY,
onboardingModalTimeoutHrs: process.env.REACT_APP_ONBOARDING_MODAL_TIMEOUT_HRS
};

export default envs;
12 changes: 12 additions & 0 deletions src/config/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ const strings = {
'We have reached the upper limit of the amount we allow the bridge to hold at this point so it is not possible to use the token you have chosen now.\n\nPlease try later or use another token.',
error_title: 'Transaction error',
limitation_error_title: 'Limitation error'
},
onboarding: {
title_txt: 'Before takeoff, a few important notes!',
subtitle_txt: 'While using StarkGate Alpha:',
bullets_txt: [
'Use Google Chrome',
'Refrain from switching browsers',
'Do not refresh the page while the transfer is being processed',
'Do not delete the local storage of the browser'
],
incognito_txt:
'The current StarkGate Alpha version <b>does not</b> support browsing in incognito mode.'
}
},
toasts: {
Expand Down
13 changes: 13 additions & 0 deletions src/providers/ModalProvider/modal-hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,16 @@ export const useErrorModal = () => {
[showModal]
);
};

export const useOnboardingModal = () => {
const {showModal} = useContext(ModalContext);

return useCallback(() => {
showModal({
componentPath: 'UI/Modal/OnboardingModal/OnboardingModal',
componentProps: null,
title: utils.getTranslation('modals.onboarding.title_txt'),
isClosable: true
});
}, [showModal]);
};
7 changes: 7 additions & 0 deletions src/utils/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,10 @@ export const get24Time = timestamp => {
export const getFullTime = timestamp => {
return `${getDate(timestamp)}, ${get24Time(timestamp)}`;
};

export const getMsFromHrs = hours => {
const parsed = parseFloat(hours, 10);
if (!isNaN(parsed)) {
return parsed * 60 * 60 * 1000;
}
};
Loading