diff --git a/src/botPage/bot/Interpreter.js b/src/botPage/bot/Interpreter.js index 57854d4428..1f0959e5a1 100644 --- a/src/botPage/bot/Interpreter.js +++ b/src/botPage/bot/Interpreter.js @@ -149,8 +149,10 @@ export default class Interpreter { } terminateSession() { this.$scope.api.disconnect(); - globalObserver.emit('bot.stop'); this.stopped = true; + + globalObserver.emit('bot.stop'); + globalObserver.setState({ isRunning: false }); } stop() { if (this.bot.tradeEngine.isSold === false && !this.isErrorTriggered) { diff --git a/src/botPage/bot/TradeEngine/index.js b/src/botPage/bot/TradeEngine/index.js index aaec4f3c65..8ad3f62180 100644 --- a/src/botPage/bot/TradeEngine/index.js +++ b/src/botPage/bot/TradeEngine/index.js @@ -92,6 +92,7 @@ export default class TradeEngine extends Balance(Purchase(Sell(OpenContract(Prop } globalObserver.emit('bot.running'); + globalObserver.setState({ isRunning: true }); this.tradeOptions = expectTradeOptions(tradeOptions); diff --git a/src/botPage/view/View.js b/src/botPage/view/View.js index 690a9552ae..3000071b5f 100644 --- a/src/botPage/view/View.js +++ b/src/botPage/view/View.js @@ -511,11 +511,19 @@ export default class View { }); const startBot = limitations => { - const $runButtons = $('#runButton, #summaryRunButton'); - const $stopButtons = $('#stopButton, #summaryStopButton'); - $stopButtons.show(); - $runButtons.hide(); - $runButtons.prop('disabled', true); + const elRunButtons = document.querySelectorAll('#runButton, #summaryRunButton'); + const elStopButtons = document.querySelectorAll('#stopButton, #summaryStopButton'); + + elRunButtons.forEach(el => { + const elRunButton = el; + elRunButton.style.display = 'none'; + elRunButton.setAttributeNode(document.createAttribute('disabled')); + }); + elStopButtons.forEach(el => { + const elStopButton = el; + elStopButton.style.display = 'inline-block'; + }); + globalObserver.emit('summary.disable_clear'); showSummary(); this.blockly.run(limitations); @@ -627,6 +635,9 @@ export default class View { this.blockly.stop(); } addEventHandlers() { + const getRunButtonElements = () => document.querySelectorAll('#runButton, #summaryRunButton'); + const getStopButtonElements = () => document.querySelectorAll('#stopButton, #summaryStopButton'); + window.addEventListener('storage', e => { window.onbeforeunload = null; if (e.key === 'activeToken' && !e.newValue) window.location.reload(); @@ -634,7 +645,11 @@ export default class View { }); globalObserver.register('Error', error => { - $('#runButton, #summaryRunButton').prop('disabled', false); + getRunButtonElements().forEach(el => { + const elRunButton = el; + elRunButton.removeAttribute('disabled'); + }); + if (error.error && error.error.error.code === 'InvalidToken') { removeAllTokens(); updateTokenList(); @@ -642,16 +657,32 @@ export default class View { } }); + globalObserver.register('bot.running', () => { + getRunButtonElements().forEach(el => { + const elRunButton = el; + elRunButton.style.display = 'none'; + elRunButton.setAttributeNode(document.createAttribute('disabled')); + }); + getStopButtonElements().forEach(el => { + const elStopButton = el; + elStopButton.style.display = 'inline-block'; + elStopButton.removeAttribute('disabled'); + }); + }); + globalObserver.register('bot.stop', () => { - const $runButtons = $('#runButton, #summaryRunButton'); - const $stopButtons = $('#stopButton, #summaryStopButton'); - if ($runButtons.is(':visible') || $stopButtons.is(':visible')) { - $runButtons.show(); - $stopButtons.hide(); - - $stopButtons.prop('disabled', false); - $runButtons.prop('disabled', false); - } + // Enable run button, this event is emitted after the interpreter + // killed the API connection. + getStopButtonElements().forEach(el => { + const elStopButton = el; + elStopButton.style.display = null; + elStopButton.removeAttribute('disabled'); + }); + getRunButtonElements().forEach(el => { + const elRunButton = el; + elRunButton.style.display = null; + elRunButton.removeAttribute('disabled'); + }); }); globalObserver.register('bot.info', info => { diff --git a/src/botPage/view/blockly/blocks/shared.js b/src/botPage/view/blockly/blocks/shared.js index 80406ad6e2..7e5ed841fe 100644 --- a/src/botPage/view/blockly/blocks/shared.js +++ b/src/botPage/view/blockly/blocks/shared.js @@ -410,6 +410,21 @@ export const getPredictionForContracts = (contracts, selectedContractType) => { return predictionRange; }; -export const disableRunButton = isDisabled => { - $('#runButton, #summaryRunButton').attr('disabled', isDisabled); +export const disableRunButton = shouldDisable => { + const elRunButtons = document.querySelectorAll('#runButton, #summaryRunButton'); + const isRunning = globalObserver.getState('isRunning'); + + elRunButtons.forEach(elRunButton => { + if (isRunning) { + if (shouldDisable) { + elRunButton.setAttributeNode(document.createAttribute('disabled')); + } else { + // Do not enable. The bot is running. + } + } else if (shouldDisable) { + elRunButton.setAttributeNode(document.createAttribute('disabled')); + } else { + elRunButton.removeAttribute('disabled'); + } + }); }; diff --git a/src/botPage/view/blockly/index.js b/src/botPage/view/blockly/index.js index f5d9c60fd4..cf92dd5e2c 100644 --- a/src/botPage/view/blockly/index.js +++ b/src/botPage/view/blockly/index.js @@ -440,7 +440,17 @@ while(true) { } stop(stopBeforeStart) { if (!stopBeforeStart) { - $('#stopButton, #summaryStopButton').prop('disabled', true); + const elRunButtons = document.querySelectorAll('#runButton, #summaryRunButton'); + const elStopButtons = document.querySelectorAll('#stopButton, #summaryStopButton'); + + elRunButtons.forEach(el => { + const elRunButton = el; + elRunButton.style.display = 'initial'; + }); + elStopButtons.forEach(el => { + const elStopButton = el; + elStopButton.style.display = null; + }); } if (this.interpreter) { this.interpreter.stop(); diff --git a/src/common/utils/observer.js b/src/common/utils/observer.js index 9fded6642a..d0f06d51f6 100644 --- a/src/common/utils/observer.js +++ b/src/common/utils/observer.js @@ -3,6 +3,7 @@ import { Map, List } from 'immutable'; export default class Observer { constructor() { this.eam = new Map(); // event action map + this.state = {}; } register(event, _action, once, unregisterIfError, unregisterAllBefore) { if (unregisterAllBefore) { @@ -53,6 +54,12 @@ export default class Observer { this.eam.get(event).forEach(action => action.action(data)); } } + setState(state = {}) { + this.state = Object.assign({}, this.state, state); + } + getState(key) { + return this.state[key]; + } } export const observer = new Observer(); diff --git a/static/css/bot.scss b/static/css/bot.scss index a4a2063f26..76111ace27 100644 --- a/static/css/bot.scss +++ b/static/css/bot.scss @@ -169,7 +169,7 @@ body { background: black; } -#stopButton { +#stopButton, #summaryStopButton { display: none; }