/** * @author Usman Naeem */ const home_form_id = "home_form"; var homeEventsSet = false; const resetSnapshotReload = false; function enableHomePage() { if (!homeEventsSet) { setHomeEventListeners(); } addLoader(); setPage("home_page"); addHeader(true); addFooter(); preventDefaultFormSubmit(home_form_id); const messageboxElement = getElement("home_message_box"); messageboxElement.innerHTML = ""; load_home_page().then(() => { set_home_page().catch((error) => { console.log(error); handleError(error, "home_message_box", true); return; }); }).catch(error => { console.log(error); handleError(error, "home_message_box", true); return; }); //initCollapsable(); } function setHomeEventListeners() { homeEventsSet = true; const itemListElement = getElement('item_list'); const itemTextElement = getElement('item_text'); document.addEventListener('click', function (e) { e = e || window.event; if (e.target === itemTextElement) { if (itemListElement.style.display === "block") { closeItemList(); } else { openItemList(); } return; } else { itemListElement.style.display = 'none'; } if (e.target.name === 'list_item') { const list_item_value = e.target.innerHTML; if (itemTextElement.value.toLowerCase().includes(list_item_value.toLowerCase)) { return; } itemTextElement.value = itemTextElement.value.trim(); if (itemTextElement.value !== "") { if (itemTextElement.value.endsWith(",")) { itemTextElement.value = itemTextElement.value + " "; } else { itemTextElement.value = itemTextElement.value + ", "; } } itemTextElement.value = itemTextElement.value + list_item_value; const itemDropdownElement = getElement("item_list"); itemDropdownElement.style.display = 'none'; } }); itemTextElement.addEventListener('dblclick', () => { //itemTextElement.select(); itemTextElement.value = ""; itemTextElement.blur(); itemTextElement.focus(); openItemList(); }); itemTextElement.addEventListener("input", (e) => { e = e || window.event; const allow0 = "[A-Za-z]+"; const allow = /^\+?[A-Za-z \,/]+$/; var itemTextValue = itemTextElement.value; var i = 0; var itemTextValue = ""; if (itemTextElement.value.length > 0) { for (i = 0; i < itemTextElement.value.length; i++) { const ch = itemTextElement.value.charAt(i); if (i === 0) { if (ch.match(allow0) !== null) { itemTextValue += ch; } } else { if (ch.match(allow) !== null) { itemTextValue += ch; } } } } itemTextValue = itemTextValue.toUpperCase(); itemTextElement.value = itemTextValue; openItemList(); }); document.addEventListener("keyup", (e) => { if (document.activeElement !== itemTextElement) { closeItemList(); } }); document.addEventListener("keydown", (e) => { e = e || window.event; //console.log(e.ctrlKey + " : " + e.altKey + " : " + e.metaKey + " : " + e.shiftKey); if (e.code === "Escape") { closeMenu(); closeItemList(); return; } if (e.altKey) { if (e.shiftKey) { if (e.code === 'KeyS') { e.preventDefault(); const preferredItemsOnlyElement = getElement('preferred_items_only'); preferredItemsOnlyElement.click(); const itemTextElement = getElement('item_text'); itemTextElement.focus(); itemTextElement.click(); return; } if (e.code === 'KeyT') { e.preventDefault(); const preferredTimeframesOnlyElement = getElement('preferred_timeframes_only'); preferredTimeframesOnlyElement.click(); return; } } else { if (e.code === 'KeyS') { e.preventDefault(); const itemTextElement = getElement('item_text'); itemTextElement.focus(); itemTextElement.click(); return; } if (e.code === 'KeyT') { e.preventDefault(); const timeframeElement = getElement('timeframe'); timeframeElement.focus(); return; } } } }); } function openItemList() { const itemListElement = getElement('item_list'); const itemTextElement = getElement('item_text'); const itemValue = itemTextElement.value.toLowerCase(); const list_items = itemListElement.querySelectorAll('div'); list_items.forEach(listItemValue => { if (itemValue.includes(listItemValue.innerHTML.toLowerCase())) { listItemValue.style.display = 'none'; } else { listItemValue.style.display = 'block'; } }); itemListElement.style.display = 'block'; } function closeItemList() { const itemListElement = getElement('item_list'); itemListElement.style.display = 'none'; } async function load_home_page() { try { const messageboxElement = getElement("home_message_box"); messageboxElement.innerHTML = ""; const url = "HomePage"; const json = await callWebserviceGET(url, messageboxElement, null); if (json.code !== 200) { messageboxElement.innerHTML = json.message; throw new Error("Failed to get data"); } else { user_json = json.user; await set_user(); await set_preferred_items(json.user_item_preferences); await set_analyzed_items(json.analyzed_items); await set_timeframes(json.timeframes, true); await set_preferred_timeframes(json.user_timeframe_preferences); } return json; } catch (error) { throw new Error("Failed to load homepage. " + error.message); } } async function set_home_page() { await load_timezones("timezone", user_json.timezone, false, true).catch((error) => { handleError(error, "home_message_box", true); return; }); removeLoader(); const prefferedItemsOnlyElement = getElement("preferred_items_only"); if (preferred_items.length === 0) { prefferedItemsOnlyElement.checked = false; prefferedItemsOnlyElement.disabled = true; } else { prefferedItemsOnlyElement.disabled = false; } if (analyzed_items.length === 0) { const messageboxElement = getElement("home_message_box"); messageboxElement.innerHTML = "No symbol is beaing analyzed at this moment"; } load_items_element("item_list", "item_text", analyzed_items, preferred_items, analyzed_items, true, true, false); const prefferedTimeframesOnlyElement = getElement("preferred_timeframes_only"); if (preferred_timeframe_name_map.size === 0) { prefferedTimeframesOnlyElement.checked = false; prefferedTimeframesOnlyElement.disabled = true; } else { prefferedTimeframesOnlyElement.disabled = false; } load_timeframes_element("timeframe", timeframe_name_map, preferred_timeframe_name_map, true, 60, true); load_snapshot_reload_delay_element("reload_delay", -1); load_format_element(); } function set_all_timeframes_elements() { load_timeframes_element("trendlinesForMinimumTimeframe", timeframe_name_map, null, false, -1, false); load_timeframes_element("trendlinesForMaximumTimeframe", timeframe_name_map, null, false, -1, false); load_timeframes_element("levelsForMinimumTimeframe", timeframe_name_map, null, false, -1, false); load_timeframes_element("levelsForMaximumTimeframe", timeframe_name_map, null, false, -1, false); load_timeframes_element("fibonacciForMinimumTimeframe", timeframe_name_map, null, false, -1, false); load_timeframes_element("fibonacciForMaximumTimeframe", timeframe_name_map, null, false, -1, false); load_timeframes_element("smcZonesForMinimumTimeframe", timeframe_name_map, null, false, -1, false); load_timeframes_element("smcZonesForMaximumTimeframe", timeframe_name_map, null, false, -1, false); } function initCollapsable() { var collapsBorderSize = 2; var collapsButtons = document.getElementsByClassName("collaps-button"); for (var i = 0; i < collapsButtons.length; i++) { collapsButtons[i].addEventListener("click", function (e) { this.classList.toggle("active"); // this.classList or e.target.classList var collapsContent = this.nextElementSibling; if (collapsContent.style.maxHeight) { collapsContent.style.maxHeight = null; collapsContent.style.borderBottomColor = null; collapsContent.style.borderBottomWidth = null; } else { const borderColor = getComputedStyle(this).getPropertyValue("background-color"); collapsContent.style.borderBottomColor = borderColor; collapsContent.style.borderBottomWidth = collapsBorderSize + "px"; collapsContent.style.maxHeight = collapsContent.scrollHeight + "px"; } }); } } function resetCollapsable() { var collapsButtons = document.getElementsByClassName("collaps-button"); for (var i = 0; i < collapsButtons.length; i++) { var collapsContent = collapsButtons[i].nextElementSibling; if (collapsContent.style.maxHeight) { //collapsContent.style.maxHeight = collapsContent.scrollHeight + "px"; collapsContent.style.maxHeight = "1000000px"; } } } function load_items_element(select_id, select_text, all_items, preferred_items, analyzed_items, analyzed_only, cleanup, default_select) { const prefferedItemsOnlyElement = getElement("preferred_items_only"); const itemListElement = getElement(select_id); const itemTextElement = getElement(select_text); if (cleanup) { itemListElement.innerHTML = ""; itemTextElement.value = ""; } var items_array; if (prefferedItemsOnlyElement && prefferedItemsOnlyElement.checked && preferred_items && preferred_items.length > 0) { items_array = new Array(...preferred_items); } else { items_array = new Array(...all_items); } items_array.sort(); var items_filter; if (analyzed_only) { items_filter = new Array(...analyzed_items); } else { items_filter = new Array(...all_items); } const options = new Array(); var first = true; items_array.forEach(function (id, index) { if (items_filter.includes(id)) { const listItemElement = document.createElement('div'); listItemElement.name = "list_item"; listItemElement.innerHTML = id; if (!first) { listItemElement.style.borderWidth = "1px 0px 0px 0px"; } itemListElement.appendChild(listItemElement); first = false; options.push(id); } }); } function load_timeframes_element(select_id, all_timeframe_name_map, preferred_timeframe_name_map, cleanup, selected_max_timeframe, multi_secect) { const prefferedTimeframesOnlyElement = getElement("preferred_timeframes_only"); const timeframeElement = getElement(select_id); if (cleanup) { timeframeElement.innerHTML = ""; } var timeframe_name_map; if (prefferedTimeframesOnlyElement && prefferedTimeframesOnlyElement.checked && preferred_timeframe_name_map && preferred_timeframe_name_map.size > 0) { timeframe_name_map = new Map([...preferred_timeframe_name_map.entries()].sort(function (a, b) { return a - b; })); } else { timeframe_name_map = new Map([...all_timeframe_name_map.entries()].sort(function (a, b) { return a - b; })); } var selectedDone = false; timeframe_name_map.forEach(function (value, key) { var optionElement = document.createElement('option'); optionElement.value = key; optionElement.innerHTML = value.name; if (!selectedDone && selected_max_timeframe > 0) { optionElement.selected = true; if (key === selected_max_timeframe) { selectedDone = true; } } timeframeElement.appendChild(optionElement); }); // if (multi_secect && timeframe_name_map.size > 1) { if (timeframe_name_map.size === 2) { let timeframes = Array.from(timeframe_name_map.keys()); create_multi_timeframe_option(timeframe_name_map, [timeframes.at(1), timeframes.at(0)], timeframeElement); } else if (timeframe_name_map.size === 3) { let timeframes = Array.from(timeframe_name_map.keys()); create_multi_timeframe_option(timeframe_name_map, [timeframes.at(1), timeframes.at(0)], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [timeframes.at(2), timeframes.at(0)], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [timeframes.at(2), timeframes.at(1)], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [timeframes.at(2), timeframes.at(1), timeframes.at(0)], timeframeElement); } else { create_multi_timeframe_option(timeframe_name_map, [5, 1], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [15, 5], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [15, 5, 1], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [60, 15], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [60, 15, 5], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [60, 15, 5, 1], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [240, 60], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [240, 60, 15], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [240, 60, 15, 5], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [240, 60, 15, 5, 1], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [1440, 240], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [1440, 240, 60], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [1440, 240, 60, 15], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [1440, 240, 60, 15, 5], timeframeElement); create_multi_timeframe_option(timeframe_name_map, [1440, 240, 60, 15, 5, 1], timeframeElement); } } } function create_multi_timeframe_option(timeframe_name_map, timeframes, select_element) { var missing = false; timeframes.forEach(timeframe => { if (!timeframe_name_map.has(timeframe)) { missing = true; } }); if (missing) { return; } var value = ""; var html = "[ "; var i; for (i = 0; i < timeframes.length; i++) { const timeframe = timeframes.at(i); if (i > 0) { value += ","; html += " - "; } if (timeframe === 1440) { value += "1440"; html += "1D"; } else if (timeframe >= 60) { var hours = timeframe / 60; value += hours * 60; html += hours + "H"; } else { var minutes = timeframe; value += minutes; html += minutes + "M"; } } html += " ]"; var optionElement = document.createElement('option'); optionElement.value = value; optionElement.innerHTML = html; optionElement.selected = false; select_element.appendChild(optionElement); } function load_format_element() { const formatElement = getElement("format"); if (formatElement.length === 0) { add_format_option(formatElement, "[ PNG ]  Low Quality", "svg.png", !isCompressionSupported()); add_format_option(formatElement, "[ SVG ]  High Quality", "svg", isCompressionSupported()); add_format_option(formatElement, "[ HTM ]  Interactive", "svg.html", false); } } function add_format_option(format_element, name, value, selected) { var optionElement = document.createElement('option'); optionElement.innerHTML = name; optionElement.value = value; optionElement.selected = selected; format_element.appendChild(optionElement); } function checkSnapshotInput(messageboxElement) { const itemTextElement = getElement("item_text"); if (!itemTextElement.value) { messageboxElement.innerHTML = "Symbol is not selected"; sleep(3000).then(() => { messageboxElement.innerHTML = ""; }); return false; } const timeframeElement = getElement("timeframe"); if (!timeframeElement.value) { messageboxElement.innerHTML = "Timeframe is not selected"; sleep(3000).then(() => { messageboxElement.innerHTML = ""; }); return false; } const timezoneElement = getElement("timezone"); if (!timezoneElement.value) { messageboxElement.innerHTML = "Timezone is not selected"; sleep(3000).then(() => { messageboxElement.innerHTML = ""; }); return false; } const formatElement = getElement("format"); if (!formatElement.value) { messageboxElement.innerHTML = "Format is not selected"; sleep(3000).then(() => { messageboxElement.innerHTML = ""; }); return false; } else { if (formatElement.value === "svg" || formatElement.value === "svg.html") { if (!isCompressionSupported()) { messageboxElement.innerHTML = "Your device or browser is not compatible with this format"; sleep(3000).then(() => { messageboxElement.innerHTML = ""; }); return false; } } } return true; } function closeAddToWatchListBox(explicit) { const id = event && event.target ? event.target.id : null; if (explicit === true || !id || !id.startsWith("watchlist_")) { const watchlist_entry_div = getElement("watchlist_entry_div"); watchlist_entry_div.style.display = 'none'; } } function openAddToWatchListBox() { const itemTextElement = getElement("item_text"); if (!itemTextElement.value) { const messageboxElement = getElement("home_message_box"); messageboxElement.innerHTML = "Symbol is not selected"; sleep(2000).then(() => { messageboxElement.innerHTML = ""; }); return; } const watchListMessageboxElement = getElement("watchlist_add_message_box"); watchListMessageboxElement.innerHTML = ""; const watch_list_record_name = getElement("watchlist_record_name"); watch_list_record_name.value = ""; const watch_list_record_description = getElement("watchlist_record_description"); watch_list_record_description.value = ""; const watchlist_entry_div = getElement("watchlist_entry_div"); watchlist_entry_div.style.display = 'block'; watch_list_record_name.focus(); } async function addToWatchList() { try { const watchListMessageboxElement = getElement("watchlist_add_message_box"); watchListMessageboxElement.innerHTML = ""; if (!checkSnapshotInput(watchListMessageboxElement)) { return; } const watchListRecordNameElement = getElement("watchlist_record_name"); const watchListRecordName = watchListRecordNameElement.value.trim(); if (watchListRecordName === '') { watchListMessageboxElement.innerHTML = "Name of watch list entry is required"; return; } const watchListRecordDescriptionElement = getElement("watchlist_record_description"); const watchListRecordDescription = watchListRecordDescriptionElement.value ? watchListRecordDescriptionElement.value.trim() : ""; const reloadDelayElement = getElement("reload_delay"); const reloadDelay = reloadDelayElement.value; var wait_text = "Please Wait"; const buttonElement = getElement("watchlist_save_btn"); if (buttonElement.textContent === wait_text) { return; } const buttonText = buttonElement.textContent; buttonElement.textContent = wait_text; const formData = getFormData(home_form_id); disableOrEnableForm(home_form_id, true); const url = "AddSnapshotWatchListRecord?name=" + encodeURIComponent(watchListRecordName) + "&description=" + encodeURIComponent(watchListRecordDescription) + "&reload_delay=" + reloadDelay; await callWebservicePOST(url, formData, watchListMessageboxElement, null).then((json) => { disableOrEnableForm(home_form_id, false); buttonElement.textContent = buttonText; if (json) { if (json.code !== 200) { watchListMessageboxElement.innerHTML = getErrorMessage(json.message); } else { closeAddToWatchListBox(true); const messageboxElement = getElement("home_message_box"); messageboxElement.innerHTML = "Added to your watch list"; sleep(2000).then(() => { messageboxElement.innerHTML = ""; }); } } }).catch((error) => { disableOrEnableForm(home_form_id, false); buttonElement.textContent = buttonText; handleError("Failed to add to watch list " + error, "home_message_box", false); console.log(error); }); } catch (error) { console.log(error); handleError("Failed to add to watch list " + error, "home_message_box", false); } } async function takeSnapshot() { try { const messageboxElement = getElement("home_message_box"); messageboxElement.innerHTML = ""; if (!checkSnapshotInput(messageboxElement)) { return; } const reloadDelayElement = getElement("reload_delay"); const reloadDelay = reloadDelayElement.value; // var wait_text = "Please Wait"; const buttonElement = getElement("take_snapshot"); if (buttonElement.textContent === wait_text) { return; } const snapshotWindow = openSnapshotWindow(); if (snapshotWindow && !snapshotWindow.closed) { const buttonText = buttonElement.textContent; buttonElement.textContent = wait_text; const closeSnapshotWindow = closeSnapshotWindowFunction(snapshotWindow); const formData = getFormData(home_form_id); await take_snapshot(snapshotWindow, formData, messageboxElement, buttonElement, buttonText, closeSnapshotWindow, false).then(() => { if (snapshotWindow && !snapshotWindow.closed) { if (reloadDelay > 1000) { var startTime = Number(Date.now()); var nextReload = startTime + Number(reloadDelay); var reloadCheckDelay = 1000; var takingSnapshot = false; const reloader = window.setInterval(function () { if (snapshotWindow.closed) { clearInterval(reloader); return; } if (!takingSnapshot) { if (nextReload < Date.now()) { if (!takingSnapshot) { takingSnapshot = true; take_snapshot(snapshotWindow, formData, null, null, null, null, true).then(() => { startTime = Number(Date.now()); nextReload = Number(Date.now()) + Number(reloadDelay); takingSnapshot = false; }); } } } }, reloadCheckDelay); if (include_time_elapsed_in_title || include_reload_time_in_title) { var title = snapshotWindow.document.title; const titler = window.setInterval(function () { if (snapshotWindow.closed) { clearInterval(titler); return; } var remaining; if (include_reload_time_in_title) { var remainingTime = (include_time_elapsed_in_title ? nextReload - startTime : nextReload - Number(Date.now())); if (remainingTime < 0) { remainingTime = 0; } var minutes = Math.floor(remainingTime / 60000); var seconds = ((remainingTime % 60000) / 1000).toFixed(0); remaining = " [" + minutes + ":" + (seconds < 10 ? '0' : '') + seconds + "] "; } var timePssed; if (include_time_elapsed_in_title) { const timeElapsed = Number(Date.now() - startTime); minutes = Math.floor(timeElapsed / 60000); seconds = ((timeElapsed % 60000) / 1000).toFixed(0); timePssed = " [" + minutes + ":" + (seconds < 10 ? '0' : '') + seconds + "] "; } snapshotWindow.document.title = title + (timePssed ? timePssed : "") + (remaining ? (timePssed ? "/" : "") + remaining : ""); }, 1000); } } else { if (include_time_elapsed_in_title) { var title = snapshotWindow.document.title; const startTime = Number(Date.now()); const titler = window.setInterval(function () { if (snapshotWindow.closed) { clearInterval(titler); return; } const timeElapsed = Number(Date.now() - startTime); var minutes = Math.floor(timeElapsed / 60000); var seconds = ((timeElapsed % 60000) / 1000).toFixed(0); const timePassed = " [" + minutes + ":" + (seconds < 10 ? '0' : '') + seconds + "]"; snapshotWindow.document.title = title + timePassed; }, 1000); } } } }); } else { messageboxElement.innerHTML = "Failed to open snapshot popup"; } } catch (error) { console.log(error); handleError("Failed to take snapshot " + error, "home_message_box", false); } } async function take_snapshot(snapshot_window, form_data, messagebox_element, button_element, button_text, close_snapshot_window, reloading) { if (snapshot_window.closed) { return; } if (!reloading || clear_snapshot_before_reload) { snapshot_window.document.body.innerHTML = createSnapshotAltContent(snapshot_wait_content); } if (!reloading) { disableOrEnableForm(home_form_id, true); } const url = "TakeSnapshot"; await callWebservicePOST(url, form_data, messagebox_element, close_snapshot_window).then((json) => { if (!reloading) { disableOrEnableForm(home_form_id, false); button_element.textContent = button_text; } if (json) { if (json.code !== 200) { if (!reloading) { messagebox_element.innerHTML = getErrorMessage(json.message); } if (snapshot_window && !snapshot_window.closed) { snapshot_window.close(); } } else { if (!reloading) { messagebox_element.innerHTML = ""; } if (snapshot_window && !snapshot_window.closed) { if (!reloading) { snapshot_window.focus(); if (resetSnapshotReload) { const reloadDelayElement = getElement("reload_delay"); reloadDelayElement.value = -1; } } const snapshots = json.snapshots; setSnapshots(snapshot_window, snapshots, "home_message_box"); } } } }).catch((error) => { if (!reloading) { disableOrEnableForm(home_form_id, false); button_element.textContent = button_text; if (!snapshot_window.closed) { try { snapshot_window.close(); } catch (error) { } } if (!reloading) { handleError("Failed to take snapshot " + error, "home_message_box", false); } } else { if (!snapshot_window.closed) { snapshot_window.document.body.innerHTML = createSnapshotAltContent(error); } } console.log(error); }); }