From 08f6ab2c508287d7d55f3e7185c89c02a111d7f7 Mon Sep 17 00:00:00 2001 From: Splash Date: Sun, 26 Apr 2020 20:43:08 +0800 Subject: [PATCH 1/2] Adding multi-island support --- css/styles.css | 173 +++++++++++++++++++++-- index.html | 17 ++- js/islands.js | 135 ++++++++++++++++++ js/scripts.js | 342 +++++++++++++++++++++++++++------------------ js/translations.js | 3 +- locales/en.json | 6 + locales/zh-CN.json | 6 + locales/zh-TW.json | 6 + 8 files changed, 531 insertions(+), 157 deletions(-) create mode 100644 js/islands.js diff --git a/css/styles.css b/css/styles.css index fa575e3d..a3a46738 100644 --- a/css/styles.css +++ b/css/styles.css @@ -210,42 +210,58 @@ input { margin: 8px 0px; } -input[type=number]:placeholder-shown { +input[type=number]:placeholder-shown, +input[type=text]:placeholder-shown { background: #f3f3f3; } -input[type=number]:not(:placeholder-shown) { +input[type=number]:not(:placeholder-shown), +input[type=text]:not(:placeholder-shown) { background: transparent; color: #0AB5CD; } -input[type=number]:placeholder-shown:hover { +input[type=number]:placeholder-shown:hover, +input[type=text]:placeholder-shown:hover { cursor: pointer; transform: scale(1.1); box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05), 0 3px 6px rgba(0, 0, 0, 0.09); } -input[type=number]:focus { +input[type=number]:focus, +input[type=text]:focus { outline: none; transform: scale(1.1); background: white; box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05), 0 3px 6px rgba(0, 0, 0, 0.09); } -input[type=number]:focus::placeholder { +input[type=number]:focus::placeholder, +input[type=text]:focus::placeholder { opacity: 0; } input[type=number] { width: 60px; - text-align: center; } -input[type=number]:disabled { +input[type=text] { + width: 150px; +} + +input[type=number]:disabled, +input[type=text]:disabled { background: inherit; } +input[type=number]:disabled, +input[type=text]:disabled, +input[type=radio]:disabled+label, +.button.button--reset:disabled { + cursor: not-allowed !important; +} -input[type=number]:disabled:hover { +input[type=number]:disabled:hover, +input[type=text]:disabled:hover { box-shadow: none; transform: none; cursor: default; @@ -257,8 +273,10 @@ input::-webkit-inner-spin-button { margin: 0; } -input[type=number] { +input[type=number], +input[type=text] { -moz-appearance: textfield; + text-align: center; } .input__radio-buttons { @@ -555,7 +573,8 @@ input[type=number] { } /*Darkmodjs*/ -.darkmode-layer, .darkmode-toggle { +.darkmode-layer, +.darkmode-toggle { z-index: 1; } @@ -597,8 +616,7 @@ body.darkmode--activated{ body.darkmode--activated div[class^="dialog-box"], body.darkmode--activated div[class^="nook-phone"], -body.darkmode--activated form[class^="input__form"], -{ +body.darkmode--activated form[class^="input__form"] { background: #fee0c4; color: #010F1D; } @@ -609,13 +627,15 @@ body.darkmode--activated svg[class^="waves"]{ body.darkmode--activated a, body.darkmode--activated b, -body.darkmode--activated input[type=number]:not(:placeholder-shown){ +body.darkmode--activated input[type=number]:not(:placeholder-shown), +body.darkmode--activated input[type=text]:not(:placeholder-shown) { color: #586472; } body.darkmode--activated input[type="radio"]+label, -body.darkmode--activated input[type=number]:placeholder-shown{ +body.darkmode--activated input[type=number]:placeholder-shown, +body.darkmode--activated input[type=text]:placeholder-shown { background: #bda284; } @@ -626,3 +646,128 @@ body.darkmode--activated input[type="radio"]:checked+label{ body.darkmode--activated i{ color: #7b6955; } + +.island-menu { + display: flex; + flex-direction: column-reverse; + align-items: flex-end; + position: fixed; + right: 32px; + bottom: 85px; + z-index: 1; + user-select: none; +} + +.island-toggle { + display: flex; + opacity: 0.7; + border-radius: 50%; +} + +.island-toggle, +.island-selector { + background-color: #bcdada; + z-index: 1; + width: 3rem; + height: 3rem; + border: none; + left: unset; + cursor: pointer; + transition: all 0.5s ease; + justify-content: center; + align-items: center; +} + +.island-group { + display: flex; + align-items: flex-end; + flex-direction: column-reverse; +} + +.island-group .island-selector { + width: 12rem; + height: 2rem; + line-height: 2rem; + position: relative; + margin-bottom: 8px; + padding: 5px; + border-radius: 5px; + font-weight: bold; + font-size: 1.25rem; + color: #768bc5; + text-align: center; + opacity: 0.7; +} + +.island-group .island-selector.island-selected { + background-color: #f7d379; +} + +.island-group .island-selector-add { + position: relative; + margin-bottom: 8px; + background-color: #92e4ef; + z-index: 1; + width: 3rem; + height: 3rem; + border: none; + left: unset; + cursor: pointer; + transition: all 0.5s ease; + justify-content: center; + align-items: center; + display: inherit; + opacity: 0.7; + border-radius: 50%; +} + +.island-group .island-selector-add.shared-data { + background-color: #76e472 +} + +.island-toggle:hover { + opacity: 0.9; +} + +.island-group .island-selector:hover { + background-color: #bce6ff; +} + +.island-group .island-selector.island-selected:hover { + background-color: #ffe299; +} + +.island-group .island-selector:active { + background-color: #74cafc; +} + +.island-group .island-selector.island-selected:active { + background-color: #ffc42d; +} + +.island-group .island-selector-add:hover { + background-color: #a0f2fd; +} + +.island-group .island-selector-add:active { + background-color: #65e9fa; +} + +.island-group .island-selector-add.shared-data:hover { + background-color: #98ff94 +} + +.island-group .island-selector-add.shared-data:active { + background-color: #5af155 +} + +.island-toggle:active { + transition: opacity 0s; + opacity: 1; +} + +.island-toggle:focus, +.island-selector:focus, +.island-selector-add:focus { + outline: none; +} \ No newline at end of file diff --git a/index.html b/index.html index 46763b43..db02b8df 100644 --- a/index.html +++ b/index.html @@ -43,7 +43,10 @@ - +
+
🏝️
+ +

@@ -71,7 +74,14 @@

Turnip Prophet

- +
+
+
+
+ + +
+
@@ -111,7 +121,6 @@
-
@@ -196,6 +205,7 @@
+ @@ -312,6 +322,7 @@

+ diff --git a/js/islands.js b/js/islands.js new file mode 100644 index 00000000..d87a03ee --- /dev/null +++ b/js/islands.js @@ -0,0 +1,135 @@ +class MultiIsland { + constructor(data, index = 0) { + let islandsData, + islandIndex = index; + if (!data) { + islandsData = JSON.parse(localStorage.getItem('islands_Data')); + islandIndex = JSON.parse(localStorage.getItem('islands_Index')); + } else { + switch (typeof data) { + case 'object': + if (Array.isArray(data)) { + // [{prices: Array, isfirst: Boolean, pattern: Int, name: String}, {...}] + islandsData = data; + } else { + // {prices: Array, isfirst: Boolean, pattern: Int, name: String} + islandsData = [data]; + } + break; + case 'string': + islandsData = JSON.parse(data); + break; + default: + console.error('Data Type Error!'); + } + } + if (!islandsData || !islandsData.length) { + islandsData = []; + //Compatible with older versions + let prices = localStorage.getItem('sell_prices'), + first = localStorage.getItem('first_buy'), + pattern = localStorage.getItem('previous_pattern'); + islandsData[0] = new Island(prices, first, pattern); + } + this.islandIndex = islandIndex != null ? islandIndex : 0; + islandsData = islandsData.filter((e) => e != null); + this.islandsData = islandsData.map((island) => new Island(island.prices, island.isfirst, island.pattern, island.name)); + this.saveData(); + } + + getIslandData(index) { + let islandIndex = index != null ? index : this.islandIndex; + if (this.islandsData.length < islandIndex + 1) + islandIndex = 0; + return this.islandsData[islandIndex]; + } + + getIslandCount() { + return this.islandsData.length; + } + + setIslandData(prices, isfirst, pattern, name, index) { + let islandIndex = index != null ? index : this.islandIndex; + if (this.islandsData.length < islandIndex + 1) { + addIslandData(prices, isfirst, pattern, name); + } else { + this.islandsData[islandIndex].setIslandData(prices, isfirst, pattern, name) + this.saveData(1); + } + } + + addIsland(island) { + this.islandsData[this.islandsData.length] = island; + this.saveData(1); + } + + addIslandData(prices, isfirst, pattern, name) { + this.islandsData[this.islandsData.length] = new Island(prices, isfirst, pattern, name); + this.saveData(1); + } + + removeIslandData(index) { + if (index == null || this.islandsData.length < index + 1) { + console.warn('Missing island index!'); + return; + } + this.islandsData.splice(index, 1); + this.islandIndex >= index && this.islandIndex !== 0 && this.islandIndex--; + if (!this.islandsData.length) { + this.islandsData = [new Island()]; + this.islandIndex = 0; + } + this.saveData(); + } + + removeIslandDataAll() { + this.islandsData = [new Island()]; + this.islandIndex = 0; + this.saveData(); + } + + setCurrentIsland(index) { + let islandIndex = 1 * (index != null ? index : 0); + if (this.islandsData.length < islandIndex + 1) + islandIndex = 0; + this.islandIndex = islandIndex; + this.saveData(2); + } + + /** + * @param {Int} saveFlag - 1: islands_Data; 2: islands_Index; Others: Full save + */ + saveData(saveFlag) { + if (saveFlag !== 1) + localStorage.setItem('islands_Index', JSON.stringify(this.islandIndex)); + if (saveFlag !== 2) + localStorage.setItem('islands_Data', JSON.stringify(this.islandsData)); + } + + resetData() { + this.islandsData = []; + this.islandIndex = 0; + clearLocalStorage(); + } + + clearLocalStorage() { + localStorage.removeItem('islands_Index'); + localStorage.removeItem('islands_Data'); + } +} + +class Island { + constructor(prices = [], isfirst = false, pattern = -1, name = '') { + this.prices = typeof prices == 'string' ? JSON.parse(prices) : prices; + this.isfirst = typeof isfirst == 'string' ? JSON.parse(isfirst) : isfirst; + this.pattern = 1 * pattern; + this.name = name; + } + + setIslandData(prices, isfirst, pattern, name) { + this.prices = prices != null ? prices : this.prices; + this.isfirst = isfirst != null ? isfirst : this.isfirst; + this.pattern = pattern != null ? pattern : this.pattern; + this.name = name != null ? name : this.name; + } +} diff --git a/js/scripts.js b/js/scripts.js index 6e7c3844..8974f1c7 100644 --- a/js/scripts.js +++ b/js/scripts.js @@ -1,18 +1,18 @@ //Reusable Fields const getSellFields = function () { - let fields = [] + let fields = []; for (var i = 2; i < 14; i++) { - fields.push($("#sell_" + i)[0]) + fields.push($("#sell_" + i)[0]); } - return fields -} + return fields; +}; const getFirstBuyRadios = function () { return [ $("#first-time-radio-no")[0], $("#first-time-radio-yes")[0] ]; -} +}; const getPreviousPatternRadios = function () { return [ @@ -22,11 +22,11 @@ const getPreviousPatternRadios = function () { $("#pattern-radio-large-spike")[0], $("#pattern-radio-decreasing")[0] ]; -} +}; const getCheckedRadio = function (radio_array) { return radio_array.find(radio => radio.checked === true).value; -} +}; const checkRadioByValue = function (radio_array, value) { if (value === null) { @@ -34,81 +34,160 @@ const checkRadioByValue = function (radio_array, value) { } value = value.toString(); radio_array.find(radio => radio.value == value).checked = true; -} - -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') +}; +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'); +const islandname_input = $('#island'), +multiIsland = new MultiIsland(); //Functions -const fillFields = function (prices, first_buy, previous_pattern) { +const fillFields = function (prices, first_buy, previous_pattern, island_name) { checkRadioByValue(first_buy_radios, first_buy); checkRadioByValue(previous_pattern_radios, previous_pattern); buy_input.focus(); - buy_input.val(prices[0] || '') + buy_input.val(prices[0] || ''); buy_input.blur(); - const sell_prices = prices.slice(2) - - sell_prices.forEach((price, index) => { - if (!price) { - return + islandname_input.val(island_name || ''); + const sell_prices = prices.slice(2); + sell_inputs.forEach((sell_input, index) => { + if (!sell_prices[index]) { + sell_input.value = ''; } else { - const element = $("#sell_" + (index + 2)); - element.focus(); - element.val(price); - element.blur(); + sell_input.value = sell_prices[index]; } - }) + }); +}; + +const fillFieldsByIsland = function (island) { + fillFields(island.prices, island.isfirst, island.pattern, island.name); +}; + +const updateMultiIslandSelector = function () { + const islandGroup = $('.island-group'), + maxIslandNum = 5, + islandCount = multiIsland.getIslandCount(); + islandGroup.empty(); + if (multiIsland.islandIndex > maxIslandNum - 1 || multiIsland.islandIndex > islandCount - 1) { + multiIsland.setCurrentIsland(); + } + for (let i = 0; i < islandCount; i++) { + if (i > maxIslandNum - 1) + break; + let islandName = multiIsland.getIslandData(i).name; + islandGroup.append(`
${islandName != '' ? islandName : i + 1}
`); + if (i >= islandCount - 1 && islandCount < maxIslandNum) { + islandGroup.append(`
`); + } + } } const initialize = function () { try { - const previous = getPrevious(); - const first_buy = previous[0]; - const previous_pattern = previous[1]; - const prices = previous[2]; - if (prices === null) { - fillFields([], first_buy, previous_pattern) - } else { - fillFields(prices, first_buy, previous_pattern) - } + fillFieldsByIsland(getPrevious()); } catch (e) { console.error(e); } - $(document).trigger("input"); + updateContent(); + if (window.populated_from_query) { + $('input').prop('disabled', true); + $('.button--reset').prop('disabled', true); + } + updateMultiIslandSelector(); - $("#permalink-btn").on("click", copyPermalink) + $("#permalink-btn").on("click", copyPermalink); - $("#reset").on("click", function () { + $("#reset").on("click", () => { if (window.confirm(i18next.t("prices.reset-warning"))) { - sell_inputs.forEach(input => input.value = '') - fillFields([], false, -1) - update() + multiIsland.removeIslandDataAll(); + fillFieldsByIsland(multiIsland.getIslandData()); + update(); + updateMultiIslandSelector(); } + }); + + $("#delete").on("click", () => { + if (window.confirm(i18next.t("islands.delete-warning"))) { + multiIsland.removeIslandData(multiIsland.islandIndex); + fillFieldsByIsland(multiIsland.getIslandData()); + update(); + updateMultiIslandSelector(); + } + }); + + islandname_input.on('change', () => { + update(true); + updateMultiIslandSelector(); + }); + + $('.island-group').on('click', '.island-selector', (event) => { + if (window.populated_from_query) { + history.pushState(null, null, window.location.origin.concat(window.location.pathname)); + window.populated_from_query = false; + $('input').prop('disabled', false); + $('.button--reset').prop('disabled', false); + $('.island-selector-add.shared-data').removeClass('shared-data'); + } + let islandBtn = $(event.currentTarget); + multiIsland.setCurrentIsland(islandBtn.attr('data-index')); + $('.island-group .island-selector').removeClass('island-selected'); + islandBtn.addClass('island-selected'); + fillFieldsByIsland(multiIsland.getIslandData()); + update(); + }).on('click', '.island-selector-add', () => { + if (!window.populated_from_query) { + multiIsland.addIslandData(); + } else { + multiIsland.addIsland(getPreviousFromQuery()); + history.pushState(null, null, window.location.origin.concat(window.location.pathname)); + window.populated_from_query = false; + $('input').prop('disabled', false); + $('.button--reset').prop('disabled', false); + } + multiIsland.setCurrentIsland(multiIsland.getIslandCount() - 1); + fillFieldsByIsland(multiIsland.getIslandData()); + update(); + updateMultiIslandSelector(); + }); + + let istap; + $('.island-toggle').on({ + 'mouseenter': () => { + $('.island-group').stop().slideDown(100); + }, + 'touchstart': () => { + istap = true; + }, + 'touchmove': () => { + istap = false; + }, + 'touchend': (e) => { + if (istap) { + if ($('.island-group').is(':visible')) { + $('.island-group').stop().slideUp(100); + } else { + $('.island-group').stop().slideDown(100); + } + } + e.cancelable && e.preventDefault(); + } + }); + $('.island-menu').on( + 'mouseleave', () => { + $('.island-group').stop().slideUp(100); }) -} - -const updateLocalStorage = function (prices, first_buy, previous_pattern) { - try { - if (prices.length !== 14) throw "The data array needs exactly 14 elements to be valid" - localStorage.setItem("sell_prices", JSON.stringify(prices)) - localStorage.setItem("first_buy", JSON.stringify(first_buy)); - localStorage.setItem("previous_pattern", JSON.stringify(previous_pattern)); - } catch (e) { - console.error(e) - } -} +}; const isEmpty = function (arr) { const filtered = arr.filter(value => value !== null && value !== '' && !isNaN(value)) - return filtered.length == 0 -} + return filtered.length == 0; +}; const getFirstBuyStateFromQuery = function (param) { try { @@ -131,15 +210,18 @@ const getFirstBuyStateFromQuery = function (param) { } catch (e) { return null; } -} - -const getFirstBuyStateFromLocalstorage = function () { - return JSON.parse(localStorage.getItem('first_buy')) -} +}; -const getPreviousPatternStateFromLocalstorage = function () { - return JSON.parse(localStorage.getItem('previous_pattern')) -} +const getIslandNameFromQuery = function () { + try { + let islandName = new URLSearchParams(window.location.search.substr(1)).get('island'); + if (!islandName) + return null; + return $.trim(decodeURIComponent(islandName)); + } catch (e) { + return null; + } +}; const getPreviousPatternStateFromQuery = function (param) { try { @@ -167,20 +249,6 @@ const getPreviousPatternStateFromQuery = function (param) { } catch (e) { return null; } -} - -const getPricesFromLocalstorage = function () { - try { - const sell_prices = JSON.parse(localStorage.getItem("sell_prices")); - - if (!Array.isArray(sell_prices) || sell_prices.length !== 14) { - return null; - } - - return sell_prices; - } catch (e) { - return null; - } }; const getPricesFromQuery = function (param) { @@ -216,29 +284,20 @@ const getPreviousFromQuery = function () { console.log("Using data from query."); window.populated_from_query = true; - return [ + return new Island( + prices, getFirstBuyStateFromQuery("first"), getPreviousPatternStateFromQuery("pattern"), - prices - ]; + getIslandNameFromQuery()); }; -const getPreviousFromLocalstorage = function () { - return [ - getFirstBuyStateFromLocalstorage(), - getPreviousPatternStateFromLocalstorage(), - getPricesFromLocalstorage() - ]; -}; - - /** * Gets previous values. First tries to parse parameters, * if none of them match then it looks in local storage. - * @return {[first time, previous pattern, prices]} + * @return {first time, previous pattern, prices ,island name} */ const getPrevious = function () { - return getPreviousFromQuery() || getPreviousFromLocalstorage(); + return getPreviousFromQuery() || multiIsland.getIslandData(); }; const getSellPrices = function () { @@ -246,18 +305,18 @@ const getSellPrices = function () { return res = sell_inputs.map(function (input) { return parseInt(input.value || ''); }) -} +}; -const getPriceClass = function(buy_price, max) { +const getPriceClass = function (buy_price, max) { const priceBrackets = [200, 30, 0, -30, -99]; let diff = max - buy_price; - for(var i=0; i= priceBrackets[i]) { + for (var i = 0; i < priceBrackets.length; i++) { + if (diff >= priceBrackets[i]) { return "range" + i; } } return ""; -} +}; const calculateOutput = function (data, first_buy, previous_pattern) { if (isEmpty(data)) { @@ -269,40 +328,41 @@ const calculateOutput = function (data, first_buy, previous_pattern) { let analyzed_possibilities = predictor.analyze_possibilities(); let buy_price = parseInt(buy_input.val()); previous_pattern_number = "" - for (let poss of analyzed_possibilities) { - var out_line = "" + poss.pattern_description + "" - if (previous_pattern_number != poss.pattern_number) { - previous_pattern_number = poss.pattern_number - pattern_count = analyzed_possibilities - .filter(val => val.pattern_number == poss.pattern_number) - .length - percentage_display = percent => Number.isFinite(percent) ? ((percent * 100).toPrecision(3) + '%') : '—' - out_line += `${percentage_display(poss.category_total_probability)}`; - } - out_line += `${percentage_display(poss.probability)}`; - for (let day of poss.prices.slice(1)) { - let price_class = getPriceClass(buy_price, day.max); - if (day.min !== day.max) { - out_line += `${day.min} ${i18next.t("output.to")} ${day.max}`; - } else { - out_line += `${day.min}`; + for (let poss of analyzed_possibilities) { + var out_line = "" + poss.pattern_description + "" + if (previous_pattern_number != poss.pattern_number) { + previous_pattern_number = poss.pattern_number + pattern_count = analyzed_possibilities + .filter(val => val.pattern_number == poss.pattern_number) + .length + percentage_display = percent => Number.isFinite(percent) ? ((percent * 100).toPrecision(3) + '%') : '—' + out_line += `${percentage_display(poss.category_total_probability)}`; + } + out_line += `${percentage_display(poss.probability)}`; + for (let day of poss.prices.slice(1)) { + let price_class = getPriceClass(buy_price, day.max); + if (day.min !== day.max) { + out_line += `${day.min} ${i18next.t("output.to")} ${day.max}`; + } else { + out_line += `${day.min}`; + } } - } - var min_class = getPriceClass(buy_price, poss.weekGuaranteedMinimum); - var max_class = getPriceClass(buy_price, poss.weekMax); - out_line += `${poss.weekGuaranteedMinimum}${poss.weekMax}`; - output_possibilities += out_line - } + var min_class = getPriceClass(buy_price, poss.weekGuaranteedMinimum); + var max_class = getPriceClass(buy_price, poss.weekMax); + out_line += `${poss.weekGuaranteedMinimum}${poss.weekMax}`; + output_possibilities += out_line + } - $("#output").html(output_possibilities) + $("#output").html(output_possibilities) - update_chart(data, analyzed_possibilities); -} + 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() : ''; +const generatePermalink = function (buy_price, sell_prices, first_buy, previous_pattern, island_name) { + let searchParams = new URLSearchParams(), + pricesParam = buy_price ? buy_price.toString() : '', + islandName = encodeURIComponent($.trim(island_name)); if (!isEmpty(sell_prices)) { const filtered = sell_prices.map(price => isNaN(price) ? '' : price).join('.'); @@ -321,8 +381,12 @@ const generatePermalink = function (buy_price, sell_prices, first_buy, previous_ searchParams.append('pattern', previous_pattern); } - return searchParams.toString() && window.location.origin.concat('?', searchParams.toString()); -} + if (islandName != '') { + searchParams.append('island', islandName); + } + + return searchParams.toString() && window.location.origin.concat(window.location.pathname, '?', searchParams.toString()); +}; const copyPermalink = function () { let text = permalink_input[0]; @@ -335,9 +399,9 @@ const copyPermalink = function () { permalink_input.hide(); flashMessage(i18next.t("prices.permalink-copied")); -} +}; -const flashMessage = function(message) { +const flashMessage = function (message) { snackbar.text(message); snackbar.addClass('show'); @@ -345,18 +409,19 @@ const flashMessage = function(message) { snackbar.removeClass('show') snackbar.text(''); }, 3000); -} +}; -const update = function () { +const update = function (skipCalc) { const sell_prices = getSellPrices(); const buy_price = parseInt(buy_input.val()); const first_buy = getCheckedRadio(first_buy_radios) == 'true'; const previous_pattern = parseInt(getCheckedRadio(previous_pattern_radios)); + const island_name = islandname_input.val(); buy_input[0].disabled = first_buy; - buy_input[0].placeholder = first_buy ? '—' : '...' + buy_input[0].placeholder = first_buy ? '—' : '...'; - const permalink = generatePermalink(buy_price, sell_prices, first_buy, previous_pattern); + const permalink = generatePermalink(buy_price, sell_prices, first_buy, previous_pattern, island_name); if (permalink) { permalink_button.show(); } else { @@ -367,8 +432,9 @@ const update = function () { const prices = [buy_price, buy_price, ...sell_prices]; if (!window.populated_from_query) { - updateLocalStorage(prices, first_buy, previous_pattern); + multiIsland.setIslandData(prices, first_buy, previous_pattern, island_name); } - + if (skipCalc) + return; calculateOutput(prices, first_buy, previous_pattern); -} +}; diff --git a/js/translations.js b/js/translations.js index b3b1db35..60747532 100644 --- a/js/translations.js +++ b/js/translations.js @@ -50,6 +50,5 @@ i18next }); // init set content $(document).ready(initialize); - $(document).on('input', updateContent); - $('input[type = radio]').on('change', updateContent); + $('input:not([type=text])').on('change', () => update()); }); diff --git a/locales/en.json b/locales/en.json index ff51f41c..7ae31dd6 100644 --- a/locales/en.json +++ b/locales/en.json @@ -7,6 +7,12 @@ "description": "This app lets you track your island's turnip prices daily, but you'll have to put the prices in yourself!", "conclusion": "After that, the Turnip Prophet app will magically predict the turnip prices you'll have for the rest of the week." }, + "islands": { + "title": "Island Name", + "description": "If you have multiple islands, fill in this field to distinguish them.(It doesn't affect your pattern.)", + "delete": "Delete Island", + "delete-warning": "Are you sure you want to delete this island's data?\n\nThis cannot be undone!" + }, "first-time": { "title": "First-Time Buyer", "description": "Is this your first time buying turnips from Daisy Mae on your island?(This affects your pattern)", diff --git a/locales/zh-CN.json b/locales/zh-CN.json index d0d85baa..a20e7e41 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -7,6 +7,12 @@ "description": "这个APP可以让你每天跟踪自己岛上大头菜的价格,但你得自己把价格填写进去!", "conclusion": "之后,大头菜预测工具会神奇地预测出本周剩余时间的大头菜价格。" }, + "islands": { + "title": "岛名", + "description": "如果你有多个无人岛,请填写这个字段。(不会影响趋势)", + "delete": "删除无人岛", + "delete-warning": "你确定要删除这个无人岛的数据吗?\n\n此操作不可撤销!" + }, "first-time": { "title": "首次购买", "description": "你是第一次在自己岛上购买大头菜吗?(将影响预测趋势)", diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 0d5b7b5e..5eea62ff 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -7,6 +7,12 @@ "description": "這個工具可以讓你每天追蹤自己島上的大頭菜價格,但你必須自己輸入價格!", "conclusion": "接下來,Turnip Prophet 將 神奇地 預測本週剩餘時間的大頭菜價格。" }, + "islands": { + "title": "島名", + "description": "如果你有多個無人島,請填冩這個欄位。(不会影響模型)", + "delete": "刪除無人島", + "delete-warning": "是否確定要刪除這個無人島的資料?\n\n此動作無法復原!" + }, "first-time": { "title": "首次購買", "description": "這是你第一次從自己島上和曹賣購買大頭菜嗎?(將影響這次的模型)", From e0c96dcb55cef9ffe179f213bd628d54b29abfb2 Mon Sep 17 00:00:00 2001 From: Splash Date: Sun, 26 Apr 2020 20:51:13 +0800 Subject: [PATCH 2/2] Update styles.css --- css/styles.css | 1 + 1 file changed, 1 insertion(+) diff --git a/css/styles.css b/css/styles.css index a3a46738..9ca2832c 100644 --- a/css/styles.css +++ b/css/styles.css @@ -682,6 +682,7 @@ body.darkmode--activated i{ display: flex; align-items: flex-end; flex-direction: column-reverse; + height: auto; } .island-group .island-selector {