diff --git a/css/styles.css b/css/styles.css
index fa575e3d..9ca2832c 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,129 @@ 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;
+ height: auto;
+}
+
+.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
+
@@ -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": "這是你第一次從自己島上和曹賣購買大頭菜嗎?(將影響這次的模型)",