diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index d526af19e4..0000000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index df32698269..ce7a9fb20d 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ lib/ old/ CNAME *.env +.DS_Store \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a0eaa0233c..472ca22d80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3014,8 +3014,8 @@ } }, "blockly": { - "version": "github:binary-com/blockly#6ad25ded4aed0037cee1e523b48934c735191695", - "from": "github:binary-com/blockly#fix-blockly", + "version": "git+ssh://git@github.com/binary-com/blockly.git#6ad25ded4aed0037cee1e523b48934c735191695", + "from": "blockly@github:binary-com/blockly#fix-blockly", "requires": { "jsdom": "^11.11.0" } @@ -4636,6 +4636,11 @@ "tapable": "^0.2.7" } }, + "enquire.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/enquire.js/-/enquire.js-2.1.6.tgz", + "integrity": "sha1-PoeAybi4NQhMP2DhZtvDwqPImBQ=" + }, "ensure-array": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/ensure-array/-/ensure-array-1.0.0.tgz", @@ -10999,6 +11004,14 @@ } } }, + "json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=", + "requires": { + "string-convert": "^0.2.0" + } + }, "json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", @@ -14304,6 +14317,18 @@ } } }, + "react-slick": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/react-slick/-/react-slick-0.28.1.tgz", + "integrity": "sha512-JwRQXoWGJRbUTE7eZI1rGIHaXX/4YuwX6gn7ulfvUZ4vFDVQAA25HcsHSYaUiRCduTr6rskyIuyPMpuG6bbluw==", + "requires": { + "classnames": "^2.2.5", + "enquire.js": "^2.1.6", + "json2mq": "^0.2.0", + "lodash.debounce": "^4.0.8", + "resize-observer-polyfill": "^1.5.0" + } + }, "react-tabs": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-3.2.3.tgz", @@ -14661,6 +14686,11 @@ "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=", "dev": true }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -15509,6 +15539,11 @@ } } }, + "slick-carousel": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/slick-carousel/-/slick-carousel-1.8.1.tgz", + "integrity": "sha512-XB9Ftrf2EEKfzoQXt3Nitrt/IPbT+f1fgqBdoxO3W/+JYvtEOW6EgxnWfr9GH6nmULv7Y2tPmEX3koxThVmebA==" + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -16050,6 +16085,11 @@ "integrity": "sha1-2sMECGkMIfPDYwo/86BYd73L1zY=", "dev": true }, + "string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=" + }, "string-length": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", diff --git a/package.json b/package.json index 892f011bc4..1b6a3e75ab 100644 --- a/package.json +++ b/package.json @@ -105,6 +105,7 @@ "webpack-stream": "^4.0.0" }, "dependencies": { + "@deriv/deriv-charts": "0.3.43", "binary-style": "^0.2.4", "blockly": "github:binary-com/blockly#fix-blockly", "commander": "^2.20.0", @@ -117,7 +118,8 @@ "mobx-react": "^5.4.4", "pako": "^1.0.11", "react-render-html": "^0.6.0", + "react-slick": "^0.28.1", "react-transition-group": "^4.0.1", - "@deriv/deriv-charts": "0.3.43" + "slick-carousel": "^1.8.1" } } diff --git a/src/botPage/view/TradeInfoPanel/index.js b/src/botPage/view/TradeInfoPanel/index.js index 200e4c575e..bc20dc1a7d 100644 --- a/src/botPage/view/TradeInfoPanel/index.js +++ b/src/botPage/view/TradeInfoPanel/index.js @@ -68,6 +68,7 @@ class AnimateTrade extends Component { resetAnimation(); $('.stage-tooltip.top:eq(0)').addClass('running'); this.setState({ indicatorMessage: this.indicatorMessages.starting }); + globalObserver.setState({ isRunning: true }); globalObserver.emit('summary.disable_clear'); globalObserver.register('contract.status', contractStatus => this.animateStage(contractStatus)); }); diff --git a/src/botPage/view/View.js b/src/botPage/view/View.js index b9dc59dadc..1c9be4e917 100644 --- a/src/botPage/view/View.js +++ b/src/botPage/view/View.js @@ -1,5 +1,5 @@ import React from 'react'; -import ReactDOM from 'react-dom'; +import { render } from 'react-dom'; import 'jquery-ui/ui/widgets/dialog'; import _Blockly, { load } from './blockly'; import Chart from './Dialogs/Chart'; @@ -39,6 +39,7 @@ import { get as getStorage, set as setStorage, getToken, + remove, } from '../../common/utils/storageManager'; import { isProduction } from '../../common/utils/tools'; import GTM from '../../common/gtm'; @@ -49,6 +50,7 @@ import { saveBeforeUnload, } from './blockly/utils'; import { moveToDeriv } from '../../common/utils/utility'; +import { setTimeOutBanner } from '../../indexPage/index'; let realityCheckTimeout; let chart; @@ -89,7 +91,18 @@ api.events.on('balance', response => { globalObserver.setState({ balance: b, currency }); }); - +const removeTokens = () => { + logoutAllTokens().then(() => { + updateTokenList(); + globalObserver.emit('ui.log.info', translate('Logged you out!')); + clearRealityCheck(); + clearActiveTokens(); + window.location.reload(); + }); +}; +const clearActiveTokens = () => { + setStorage(AppConstants.STORAGE_ACTIVE_TOKEN, ''); +}; const addBalanceForToken = token => { api.authorize(token).then(() => { api.send({ forget_all: 'balance' }).then(() => { @@ -450,20 +463,6 @@ export default class View { .catch(() => {}); }; - const removeTokens = () => { - logoutAllTokens().then(() => { - updateTokenList(); - globalObserver.emit('ui.log.info', translate('Logged you out!')); - clearRealityCheck(); - clearActiveTokens(); - window.location.reload(); - }); - }; - - const clearActiveTokens = () => { - setStorage(AppConstants.STORAGE_ACTIVE_TOKEN, ''); - }; - $('.panelExitButton').click(function onClick() { $(this) .parent() @@ -624,7 +623,6 @@ export default class View { setTimeout(() => $('#stopButton').triggerHandler('click')); return; } - const token = $('.account-id') .first() .attr('value'); @@ -825,7 +823,7 @@ function initRealityCheck(stopCallback) { } function renderErrorPage() { - ReactDOM.render( + render( , $('#server-time')[0]); - ReactDOM.render(, $('#tour')[0]); - ReactDOM.render( - , - $('#footer')[0] - ); - document.getElementById('errorArea').remove(); - ReactDOM.render(, $('#summaryPanel')[0]); - ReactDOM.render(, $('#logTable')[0]); + $('.barspinner').show(); + const bannerToken = getStorage('setDueDateForBanner'); + if (new Date().getTime() > Number(bannerToken)) { + remove('setDueDateForBanner'); + const getqueryParameter = document.location.search; + const getDefaultPath = window.location.href.replace('/bot.html', getqueryParameter); + window.location.replace(getDefaultPath); + return false; + } + if (bannerToken === null || bannerToken === undefined) { + const getqueryParameter = document.location.search; + const getDefaultPath = window.location.href.replace('/bot.html', getqueryParameter); + window.location.replace(getDefaultPath); + document.getElementById('errorArea').remove(); + $('.barspinner').hide(); + } else { + setTimeOutBanner('views'); + render(, $('#server-time')[0]); + render(, $('#tour')[0]); + render( + , + $('#footer')[0] + ); + document.getElementById('errorArea').remove(); + render(, $('#summaryPanel')[0]); + render(, $('#logTable')[0]); + document.getElementById('bot-main').classList.remove('hidden'); + $('.barspinner').hide(); + } } diff --git a/src/common/appId.js b/src/common/appId.js index 63f5b42cba..30bc537746 100644 --- a/src/common/appId.js +++ b/src/common/appId.js @@ -38,9 +38,7 @@ const queryToObjectArray = queryStr => { export const oauthLogin = (done = () => 0) => { const queryStr = parseQueryString(); - const tokenObjectList = queryToObjectArray(queryStr); - if (tokenObjectList.length) { $('#main').hide(); addTokenIfValid(tokenObjectList[0].token, tokenObjectList).then(() => { @@ -100,6 +98,11 @@ export const generateWebSocketURL = serverUrl => `wss://${serverUrl}/websockets/ export const getOAuthURL = () => `https://${generateOAuthDomain()}/oauth2/authorize?app_id=${getAppIdFallback()}&l=${getLanguage().toUpperCase()}`; +export const getOAuthURLDeriv = () => + `https://oauth.deriv.com/oauth2/authorize?app_id=31665&l=${getLanguage().toUpperCase()}`; + +// 19111 + const options = { apiUrl : getWebSocketURL(), language: getLanguage().toUpperCase(), diff --git a/src/common/lang.js b/src/common/lang.js index 4a6c62e002..ccca214bba 100644 --- a/src/common/lang.js +++ b/src/common/lang.js @@ -1,9 +1,13 @@ +import React from 'react'; +import { render } from 'react-dom'; import { parseQueryString } from '../common/utils/tools'; -import { set as setStorage, get as getStorage } from '../common/utils/storageManager'; +import { set as setStorage, get as getStorage, remove } from '../common/utils/storageManager'; import { setCookieLanguage } from '../common/utils/cookieManager'; import { supportedLanguages, translate, init } from './i18n'; import { getClientsCountryByIP } from './utils/utility'; +import BotLanding from '../indexPage/react-components/bot-landing'; +const elements = ['#notification-banner', '#main', '#footer', '#header']; export const getLanguage = () => { const queryLang = parseQueryString().l; const lang = queryLang in supportedLanguages ? queryLang : getStorage('lang') || 'en'; @@ -16,7 +20,6 @@ const addUiLang = () => { $('[data-i18n-text]').each(function each() { const el = $(this); const contents = el.contents(); - el.text(translate($(this).attr('data-i18n-text'))).append(contents); }); @@ -31,7 +34,17 @@ export const load = () => { $('#select_language li:not(:first)').click(function click() { const newLang = $(this).attr('class'); - document.location.search = `l=${newLang}`; + if (document.getElementById('bot-landing').classList.contains('hidden') === false) { + remove('setDueDateForBanner'); + render(, document.getElementById('bot-landing')); + elements.map(elem => document.querySelector(elem).classList.add('hidden')); + document.getElementById('bot-landing').classList.remove('hidden'); + document.getElementById('bot-main').classList.remove('hidden'); + $('.barspinner').hide(); + document.location.search = `l=${newLang}`; + } else { + document.location.search = `l=${newLang}`; + } }); $('.language').text( diff --git a/src/indexPage/index.js b/src/indexPage/index.js index 44da8fb6dd..55ac0bdc8a 100644 --- a/src/indexPage/index.js +++ b/src/indexPage/index.js @@ -1,5 +1,5 @@ import React from 'react'; -import ReactDOM from 'react-dom'; +import { render } from 'react-dom'; import endpoint from './endpoint'; import Logo from './react-components/logo.jsx'; import Footer from './react-components/footer.jsx'; @@ -8,32 +8,127 @@ import { isEuCountry, showHideEuElements } from '../common/footer-checks'; import GTM from '../common/gtm'; import { load as loadLang, showBanner } from '../common/lang'; import { moveToDeriv } from '../common/utils/utility'; -import { getTokenList } from '../common/utils/storageManager'; +import { get as getStorage, set as setStorage, remove, getTokenList } from '../common/utils/storageManager'; import { createUrl } from '../common/utils/tools'; import '../common/binary-ui/dropdown'; +import BotLanding from './react-components/bot-landing'; +const today = new Date().getTime(); +// eslint-disable-next-line one-var +const oneMilliSec = 1000; +// twentyOneDays = 21, +// fiveMinutes = 300, +// oneMinute = 60, +// oneDay = 24; + +export const elements = ['#notification-banner', '#main', '#footer', '#header']; +// eslint-disable-next-line one-var +export const bannerToken = getStorage('setDueDateForBanner'); + +// eslint-disable-next-line arrow-body-style +export const expirationDate = () => { + // return today + oneMilliSec * oneMinute * oneMinute * oneDay * twentyOneDays; + return today + oneMilliSec * 120; +}; + +export const calcSetTimeoutValueBanner = expirationDate() - new Date().getTime(); + +// eslint-disable-next-line import/no-mutable-exports +export let timerForBanner; + +const checkifBotRunning = () => { + if (document.getElementById('runButton').style.display === 'none') { + return true; + } + return false; +}; + +export const setTimeOutBanner = route => { + let bannerDisplayed; + // eslint-disable-next-line consistent-return + timerForBanner = setTimeout(() => { + if ( + (route === 'index' && !!bannerDisplayed === false) || + (route === 'views' && checkifBotRunning() === false) + ) { + const getqueryParameter = document.location.search; + const getDefaultPath = window.location.href.replace('/bot.html', getqueryParameter); + window.location.replace(getDefaultPath); + renderBanner(); + } else if ( + (route === 'index' && !!bannerDisplayed === true) || + (route === 'views' && checkifBotRunning() === true) + ) { + remove('setDueDateForBanner'); + setStorage('setDueDateForBanner', expirationDate()); + return false; + } + }, calcSetTimeoutValueBanner); +}; + +const renderBanner = () => { + render(, document.getElementById('bot-landing')); + setStorage('setDueDateForBanner', expirationDate()); + elements.map(elem => document.querySelector(elem).classList.add('hidden')); + document.getElementById('bot-landing').classList.remove('hidden'); + document.getElementById('bot-main').classList.remove('hidden'); + $('.barspinner').hide(); +}; + +// eslint-disable-next-line consistent-return const renderElements = () => { - ReactDOM.render(, document.getElementById('binary-logo')); - ReactDOM.render(