diff --git a/Services/Interfaces/web_interface/advanced_templates/advanced_layout.html b/Services/Interfaces/web_interface/advanced_templates/advanced_layout.html index 4af30475b..a4294c235 100644 --- a/Services/Interfaces/web_interface/advanced_templates/advanced_layout.html +++ b/Services/Interfaces/web_interface/advanced_templates/advanced_layout.html @@ -47,7 +47,7 @@ {% if IS_DEMO or IS_CLOUD or IS_ALLOWING_TRACKING%} {% endif %} diff --git a/Services/Interfaces/web_interface/controllers/home.py b/Services/Interfaces/web_interface/controllers/home.py index 2a015ff59..00e0c09a6 100644 --- a/Services/Interfaces/web_interface/controllers/home.py +++ b/Services/Interfaces/web_interface/controllers/home.py @@ -87,6 +87,9 @@ def home(): sandbox_exchanges=sandbox_exchanges, display_ph_launch=display_ph_launch, is_launching=is_launching, + latest_release_url=f"{octobot_commons.constants.GITHUB_BASE_URL}/" + f"{octobot_commons.constants.GITHUB_ORGANISATION}/" + f"{constants.PROJECT_NAME}/releases/latest", ) else: return flask.redirect(flask.url_for("terms")) diff --git a/Services/Interfaces/web_interface/models/dashboard.py b/Services/Interfaces/web_interface/models/dashboard.py index 4258a4757..3a227aa80 100644 --- a/Services/Interfaces/web_interface/models/dashboard.py +++ b/Services/Interfaces/web_interface/models/dashboard.py @@ -71,7 +71,10 @@ def format_trades(dict_trade_history): float(dict_trade[trading_enums.ExchangeConstantsOrderColumns.PRICE.value])) trades[trade_description_key].append( f"{trade_type.name.replace('_', ' ')}: " - f"{dict_trade[trading_enums.ExchangeConstantsOrderColumns.AMOUNT.value]}") + f"{dict_trade[trading_enums.ExchangeConstantsOrderColumns.AMOUNT.value]} " + f"{dict_trade[trading_enums.ExchangeConstantsOrderColumns.QUANTITY_CURRENCY.value]} " + f"at {dict_trade[trading_enums.ExchangeConstantsOrderColumns.PRICE.value]} " + f"{dict_trade[trading_enums.ExchangeConstantsOrderColumns.MARKET.value]}") trades[trade_order_side_key].append(trade_side.value) return trades diff --git a/Services/Interfaces/web_interface/models/trading.py b/Services/Interfaces/web_interface/models/trading.py index 63c027455..9bfed793a 100644 --- a/Services/Interfaces/web_interface/models/trading.py +++ b/Services/Interfaces/web_interface/models/trading.py @@ -87,7 +87,8 @@ def get_exchanges_load(): "load": trading_api.get_currently_handled_pair_with_time_frame(exchange_manager), "max_load": trading_api.get_max_handled_pair_with_time_frame(exchange_manager), "overloaded": trading_api.is_overloaded(exchange_manager), - "has_websocket": trading_api.get_has_websocket(exchange_manager) + "has_websocket": trading_api.get_has_websocket(exchange_manager), + "has_reached_websocket_limit": trading_api.get_has_reached_websocket_limit(exchange_manager) } for exchange_manager in interfaces_util.get_exchange_managers() } diff --git a/Services/Interfaces/web_interface/static/css/style.css b/Services/Interfaces/web_interface/static/css/style.css index 6cd7a1b75..3a1eab767 100644 --- a/Services/Interfaces/web_interface/static/css/style.css +++ b/Services/Interfaces/web_interface/static/css/style.css @@ -21,6 +21,8 @@ :root { --mdb-body-font-family: DM Sans, sans-serif; --local-secondary-bg-text-color: #0f1237; /* same as dark mdb-primary */ + --local-price-chart-sell-color: #F65A33; + --local-price-chart-stop-color: #FFA500; } :root[data-mdb-theme=light] { @@ -72,14 +74,22 @@ --mdb-card-long-border-color: var(--mdb-secondary); --mdb-card-short-border-color: var(--mdb-orange); --mdb-card-very-short-border-color: var(--mdb-red); + --mdb-card-bg: var(--mdb-bg); + --mdb-card-color: var(--mdb-primary); + --mdb-surface-bg: var(--mdb-bg); /* navbar */ --mdb-navbar-bg: var(--mdb-bg); --mdb-navbar-brand-color: var(--mdb-primary); - --mdb-card-bg: var(--mdb-bg); - --mdb-card-color: var(--mdb-primary); - --mdb-surface-bg: var(--mdb-bg); + /* local */ + /* config cards */ + --local-config-card--border-width: 0px; + + /* price charts */ + --local-price-chart-buy-color: #6cb596; + --local-price-chart-candle-sell-color: var(--local-price-chart-sell-color); + --local-price-chart-candle-buy-color: #6cb596; } :root[data-mdb-theme=dark] { @@ -130,14 +140,22 @@ --mdb-card-long-border-color: var(--mdb-secondary); --mdb-card-short-border-color: var(--mdb-orange); --mdb-card-very-short-border-color: var(--mdb-red); + --mdb-card-bg: var(--mdb-secondary); + --mdb-card-color: var(--mdb-primary); + --mdb-surface-bg: var(--mdb-bg-500); /* navbar */ --mdb-navbar-bg: var(--mdb-bg); --mdb-navbar-brand-color: var(--mdb-primary); - --mdb-card-bg: var(--mdb-secondary); - --mdb-card-color: var(--mdb-primary); - --mdb-surface-bg: var(--mdb-bg-500); + /* local */ + /* config cards */ + --local-config-card--border-width: 1px; + + /* price charts */ + --local-price-chart-buy-color: #6cb596; + --local-price-chart-candle-sell-color: var(--local-price-chart-sell-color); + --local-price-chart-candle-buy-color: #65e7cf; } /* Fix incompatibility with bootstrap 4 */ @@ -459,6 +477,10 @@ footer.page-footer { flex-basis: inherit !important; } +.config-card { + border: var(--local-config-card--border-width) solid rgba(var(--mdb-primary-rgb), 0.3); +} + .community-bot-stats-label { font-weight: bold; font-size: x-large; @@ -563,7 +585,7 @@ footer.page-footer { /* Theme */ /* Elegant */ .card-body.candle-graph { - min-height: 30.625rem; + height: 30.625rem; background-color: inherit; } diff --git a/Services/Interfaces/web_interface/static/js/common/candlesticks.js b/Services/Interfaces/web_interface/static/js/common/candlesticks.js index 38913487d..0fe75b880 100644 --- a/Services/Interfaces/web_interface/static/js/common/candlesticks.js +++ b/Services/Interfaces/web_interface/static/js/common/candlesticks.js @@ -118,9 +118,11 @@ function get_watched_symbol_price_graph(element, callback=undefined, no_data_cal }); } -const stop_color = "#FFA500"; -const sell_color = "#F65A33"; -const buy_color = isDarkTheme() ? '#299a39' : "#009900"; +const stop_color = getComputedStyle(document.body).getPropertyValue('--local-price-chart-stop-color'); +const sell_color = getComputedStyle(document.body).getPropertyValue('--local-price-chart-sell-color'); +const buy_color = getComputedStyle(document.body).getPropertyValue('--local-price-chart-buy-color'); +const candle_sell_color = getComputedStyle(document.body).getPropertyValue('----local-price-chart-candle-sell-color'); +const candle_buy_color = getComputedStyle(document.body).getPropertyValue('--local-price-chart-candle-buy-color'); function create_candlesticks(candles){ const data_time = candles["time"]; @@ -132,9 +134,9 @@ function create_candlesticks(candles){ return { x: data_time, close: data_close, - decreasing: {line: {color: sell_color}}, + decreasing: {line: {color: candle_sell_color}}, high: data_high, - increasing: {line: {color: buy_color}}, + increasing: {line: {color: candle_buy_color}}, line: {color: 'rgba(31,119,180,1)'}, low: data_low, open: data_open, @@ -187,22 +189,23 @@ function create_trades(trades, trader){ const data_trade_description = trades["trade_description"]; const data_order_side = trades["order_side"]; - const marker_size = trader === "Simulator" ? 14 : 16; - const marker_opacity = trader === "Simulator" ? 0.5 : 0.65; - const border_line_color = "#b6b8c3"; + const marker_size = 16; + const marker_opacity = 0.9; + const border_line_color = getTextColor(); const colors = []; $.each(data_order_side, function (index, value) { colors.push(_getOrderColor(trades["trade_description"][index], value)); }); - const line_with = trader === "Simulator" ? 0 : 1; + const line_with = isDarkTheme() ? 1 : 0.2; return { x: data_time, y: data_price, mode: 'markers', - name: trader, + name: "", text: data_trade_description, + hovertemplate: `%{text}
%{x}`, marker: { color: colors, size: marker_size, diff --git a/Services/Interfaces/web_interface/static/js/common/exchange_accounts.js b/Services/Interfaces/web_interface/static/js/common/exchange_accounts.js index 5ac82f499..9554a72bb 100644 --- a/Services/Interfaces/web_interface/static/js/common/exchange_accounts.js +++ b/Services/Interfaces/web_interface/static/js/common/exchange_accounts.js @@ -93,7 +93,7 @@ function register_exchanges_checks(check_existing_accounts){ const check_account = (exchangeCard, source, newValue) => { const exchange = exchangeCard.find(".card-body").attr("name"); - if(exchange !== config_default_value){ + if(exchange !== config_default_value && exchangeCard.find("#exchange_api-key").length > 0){ const apiKey = source.attr("id") === "exchange_api-key" ? newValue : exchangeCard.find("#exchange_api-key").editable('getValue', true).trim(); const apiSecret = source.attr("id") === "exchange_api-secret" ? newValue : exchangeCard.find("#exchange_api-secret").editable('getValue', true).trim(); const apiPassword = source.attr("id") === "exchange_api-password" ? newValue : exchangeCard.find("#exchange_api-password").editable('getValue', true).trim(); diff --git a/Services/Interfaces/web_interface/static/js/common/tracking.js b/Services/Interfaces/web_interface/static/js/common/tracking.js index 91210b00e..6e8419e96 100644 --- a/Services/Interfaces/web_interface/static/js/common/tracking.js +++ b/Services/Interfaces/web_interface/static/js/common/tracking.js @@ -2,17 +2,20 @@ $(document).ready(function() { const getUserEmail = () => { - return getUserDetails().email + return getUserDetails().email || ""; } const getUserDetails = () => { + if (_USER_DETAILS.email === ""){ + // do not erase email if unset + delete _USER_DETAILS.email; + } return _USER_DETAILS } const updateUserDetails = () => { posthog.capture( - getUserEmail(), - event='update_user_details', + 'up_user_details', properties={ '$set': getUserDetails(), } @@ -21,11 +24,19 @@ $(document).ready(function() { const shouldUpdateUserDetails = () => { const currentProperties = posthog.get_property('$stored_person_properties'); - return ( - getUserEmail() !== "" - && isDefined(currentProperties) - && JSON.stringify(currentProperties) !== JSON.stringify(getUserDetails()) - ) + if(currentProperties === undefined){ + return true; + } + if(isDefined(currentProperties)){ + const currentDetails = getUserDetails(); + if(currentDetails.email === undefined){ + // compare without email (otherwise result is always different as no email is currently set) + const localProperties = JSON.parse(JSON.stringify(currentProperties)); + delete localProperties.email + return JSON.stringify(localProperties) !== JSON.stringify(getUserDetails()); + } + } + return JSON.stringify(currentProperties) !== JSON.stringify(getUserDetails()); } const shouldReset = (newEmail) => { diff --git a/Services/Interfaces/web_interface/templates/components/config/currency_card.html b/Services/Interfaces/web_interface/templates/components/config/currency_card.html index ea9be644c..b497bf012 100644 --- a/Services/Interfaces/web_interface/templates/components/config/currency_card.html +++ b/Services/Interfaces/web_interface/templates/components/config/currency_card.html @@ -8,7 +8,7 @@
- {{ crypto_currency }}
-

+

{{ m_editable_config.editable_key( config_symbols, crypto_currency, "crypto-currencies_" + crypto_currency, diff --git a/Services/Interfaces/web_interface/templates/components/config/exchange_card.html b/Services/Interfaces/web_interface/templates/components/config/exchange_card.html index 58a885fb9..20fe60fe5 100644 --- a/Services/Interfaces/web_interface/templates/components/config/exchange_card.html +++ b/Services/Interfaces/web_interface/templates/components/config/exchange_card.html @@ -6,7 +6,7 @@

-
+

{{exchange}} diff --git a/Services/Interfaces/web_interface/templates/components/config/service_card.html b/Services/Interfaces/web_interface/templates/components/config/service_card.html index 01c37edbb..4e7a5b9e5 100644 --- a/Services/Interfaces/web_interface/templates/components/config/service_card.html +++ b/Services/Interfaces/web_interface/templates/components/config/service_card.html @@ -5,7 +5,7 @@
-
+

diff --git a/Services/Interfaces/web_interface/templates/index.html b/Services/Interfaces/web_interface/templates/index.html index 4b0682451..839ae6c88 100644 --- a/Services/Interfaces/web_interface/templates/index.html +++ b/Services/Interfaces/web_interface/templates/index.html @@ -25,7 +25,14 @@

{% endif %} {% if not IS_CLOUD %} {% endif %} diff --git a/Services/Interfaces/web_interface/templates/layout.html b/Services/Interfaces/web_interface/templates/layout.html index 840702896..58816a23e 100644 --- a/Services/Interfaces/web_interface/templates/layout.html +++ b/Services/Interfaces/web_interface/templates/layout.html @@ -61,7 +61,7 @@ {% if IS_DEMO or IS_CLOUD or IS_ALLOWING_TRACKING%} {% endif %} diff --git a/Services/Interfaces/web_interface/templates/trading.html b/Services/Interfaces/web_interface/templates/trading.html index a738a0d8a..39f93af8f 100644 --- a/Services/Interfaces/web_interface/templates/trading.html +++ b/Services/Interfaces/web_interface/templates/trading.html @@ -8,7 +8,13 @@ {% set vars = {'exchange_overload': False} %} {% macro exchange_overload_warning(exchange, load) -%} - {% if load["overloaded"] %} + {% if load["has_reached_websocket_limit"] %} + + {% elif load["overloaded"] %}