diff --git a/css/styles.css b/css/styles.css index af322c6..e50dc5f 100644 --- a/css/styles.css +++ b/css/styles.css @@ -267,10 +267,10 @@ input[type=number] { color: #FFF; } -.reset-button { +.button { + color: #686868; font-family: inherit; font-weight: bold; - color: #FFBABA; padding: 8px 16px; border-width: 0px; border-radius: 40px; @@ -281,13 +281,16 @@ input[type=number] { margin: 16px auto; } -.reset-button:hover { +.button:hover { transform: scale(1.1); cursor: pointer; opacity: 1; box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05), 0 3px 6px rgba(0, 0, 0, 0.09); } +.button.button--reset { + color: #E45B5B; +} .table-wrapper { display: inline-block; @@ -378,7 +381,6 @@ input[type=number] { justify-content: center; } - .waves { position: relative; width: 100%; @@ -388,6 +390,74 @@ input[type=number] { max-height: 150px; } +#permalink-input { + display: none; + position: fixed; +} + +.permalink { + display: none; + white-space: nowrap; + font-size: 18px; + user-select: none; + cursor: pointer; +} + +.permalink .fa-copy { + margin: 0 8px; + height: 20px; + color: #0AB5CD; +} + +/* The snackbar - position it at the bottom and in the middle of the screen */ +#snackbar { + visibility: hidden; /* Hidden by default. Visible on click */ + min-width: 250px; /* Set a default minimum width */ + background-color: #FFFAE5; /* Black background color */ + font-family: 'Raleway', sans-serif; + font-weight: 800; + font-size: 1rem; + color: #837865; + letter-spacing: 0.2px; + line-height: 1.8rem; + text-align: center; /* Centered text */ + border-radius: 40px; /* Rounded borders */ + padding: 16px 24px; /* Padding */ + position: fixed; /* Sit on top of the screen */ + z-index: 1; /* Add a z-index if needed */ + bottom: 30px; /* 30px from the bottom */ + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 1px 2px rgba(0, 0, 0, 0.08); +} + +/* Show the snackbar when clicking on a button (class added with JavaScript) */ +#snackbar.show { + visibility: visible; /* Show the snackbar */ + /* Add animation: Take 0.5 seconds to fade in and out the snackbar. + However, delay the fade out process for 2.5 seconds */ + -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s; + animation: fadein 0.5s, fadeout 0.5s 2.5s; +} + +/* Animations to fade the snackbar in and out */ +@-webkit-keyframes fadein { + from {bottom: 0; opacity: 0;} + to {bottom: 30px; opacity: 1;} +} + +@keyframes fadein { + from {bottom: 0; opacity: 0;} + to {bottom: 30px; opacity: 1;} +} + +@-webkit-keyframes fadeout { + from {bottom: 30px; opacity: 1;} + to {bottom: 0; opacity: 0;} +} + +@keyframes fadeout { + from {bottom: 30px; opacity: 1;} + to {bottom: 0; opacity: 0;} +} /* Animation */ .parallax>use { diff --git a/index.html b/index.html index 4f664e7..4e72a73 100644 --- a/index.html +++ b/index.html @@ -194,7 +194,14 @@ - @@ -309,6 +316,8 @@

+
Some text some message...
+ diff --git a/js/scripts.js b/js/scripts.js index 65cf904..3438a3a 100644 --- a/js/scripts.js +++ b/js/scripts.js @@ -40,6 +40,9 @@ const sell_inputs = getSellFields() const buy_input = $("#buy") const first_buy_radios = getFirstBuyRadios() const previous_pattern_radios = getPreviousPatternRadios() +const permalink_input = $('#permalink-input') +const permalink_button = $('#permalink-btn') +const snackbar = $('#snackbar') //Functions const fillFields = function (prices, first_buy, previous_pattern) { @@ -79,6 +82,8 @@ const initialize = function () { console.error(e); } + $("#permalink-btn").on("click", copyPermalink) + $("#reset").on("click", function () { sell_inputs.forEach(input => input.value = '') fillFields([], false, -1) @@ -267,6 +272,53 @@ const calculateOutput = function (data, first_buy, previous_pattern) { update_chart(data, analyzed_possibilities); } +const generatePermalink = function (buy_price, sell_prices, first_buy, previous_pattern) { + let searchParams = new URLSearchParams(); + let pricesParam = buy_price ? buy_price.toString() : ''; + + if (!isEmpty(sell_prices)) { + const filtered = sell_prices.map(price => isNaN(price) ? '' : price).join('.'); + pricesParam = pricesParam.concat('.', filtered); + } + + if (pricesParam) { + searchParams.append('prices', pricesParam); + } + + if (first_buy) { + searchParams.append('first', true); + } + + if (previous_pattern !== -1) { + searchParams.append('pattern', previous_pattern); + } + + return searchParams.toString() && window.location.origin.concat('?', searchParams.toString()); +} + +const copyPermalink = function () { + let text = permalink_input[0]; + + permalink_input.show(); + text.select(); + text.setSelectionRange(0, 99999); /* for mobile devices */ + + document.execCommand('copy'); + permalink_input.hide(); + + flashMessage("Permalink copied!"); +} + +const flashMessage = function(message) { + snackbar.text(message); + snackbar.addClass('show'); + + setTimeout(function () { + snackbar.removeClass('show') + snackbar.text(''); + }, 3000); +} + const update = function () { const sell_prices = getSellPrices(); const buy_price = parseInt(buy_input.val()); @@ -276,6 +328,14 @@ const update = function () { buy_input[0].disabled = first_buy; buy_input[0].placeholder = first_buy ? '—' : '...' + const permalink = generatePermalink(buy_price, sell_prices, first_buy, previous_pattern); + if (permalink) { + permalink_button.show(); + } else { + permalink_button.hide(); + } + permalink_input.val(permalink); + const prices = [buy_price, buy_price, ...sell_prices]; if (!window.populated_from_query) {