2020-07-19 17:36:36 +02:00
|
|
|
window.addEventListener('load', (event) => {
|
|
|
|
|
let main = document.getElementsByTagName("main")[0];
|
|
|
|
|
main.addEventListener('click', (event) => {
|
2020-12-15 11:10:10 +01:00
|
|
|
side_content = document.getElementById("side-content")
|
|
|
|
|
if (side_content != null) {
|
|
|
|
|
side_content.classList.remove("active");
|
|
|
|
|
}
|
2020-07-19 17:36:36 +02:00
|
|
|
});
|
|
|
|
|
let menubtn = document.getElementById("menubtn");
|
2020-12-15 11:10:10 +01:00
|
|
|
if (menubtn != null) {
|
|
|
|
|
menubtn.addEventListener('click', (event) => {
|
|
|
|
|
document.getElementById("side-content").classList.add("active");
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-07-19 17:36:36 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
document.addEventListener("errormsg", (e)=>{
|
|
|
|
|
if(!("timeout" in e.detail)){
|
|
|
|
|
e.detail.timeout = 0;
|
|
|
|
|
}
|
|
|
|
|
showError(e.detail.message, e.detail.timeout);
|
|
|
|
|
});
|
|
|
|
|
document.addEventListener("notification", (e)=>{
|
|
|
|
|
if(!("timeout" in e.detail)){
|
|
|
|
|
e.detail.timeout = 3000;
|
|
|
|
|
}
|
|
|
|
|
showNotification(e.detail.message, e.detail.timeout);
|
|
|
|
|
});
|
2020-12-15 15:01:17 +02:00
|
|
|
|
|
|
|
|
document.addEventListener("updateAddressLabel", function (e) {
|
|
|
|
|
document.querySelectorAll('address-label').forEach(el => {
|
|
|
|
|
let event = new CustomEvent('updateAddressLabel', { detail: e.detail });
|
|
|
|
|
return el.dispatchEvent(event);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// TODO: Needed currently for all custom elements containing <address-label>
|
|
|
|
|
// Find an alternative which would work regardless of shadowRoot
|
2021-01-30 11:34:23 +02:00
|
|
|
if (document.querySelector('tx-table')) {
|
|
|
|
|
document.querySelector('tx-table').shadowRoot.querySelectorAll('tx-row').forEach(el => {
|
|
|
|
|
el.shadowRoot.querySelectorAll('address-label').forEach(el => {
|
|
|
|
|
let event = new CustomEvent('updateAddressLabel', { detail: e.detail });
|
|
|
|
|
return el.dispatchEvent(event);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (document.querySelector('addresses-table')) {
|
|
|
|
|
document.querySelector('addresses-table').shadowRoot.querySelectorAll('address-row').forEach(el => {
|
|
|
|
|
el.shadowRoot.querySelectorAll('address-label').forEach(el => {
|
|
|
|
|
let event = new CustomEvent('updateAddressLabel', { detail: e.detail });
|
|
|
|
|
return el.dispatchEvent(event);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (document.querySelector('address-data')) {
|
|
|
|
|
document.querySelector('address-data').shadowRoot.querySelectorAll('address-label').forEach(el => {
|
2020-12-15 15:01:17 +02:00
|
|
|
let event = new CustomEvent('updateAddressLabel', { detail: e.detail });
|
|
|
|
|
return el.dispatchEvent(event);
|
|
|
|
|
});
|
2021-01-30 11:34:23 +02:00
|
|
|
}
|
2020-12-15 15:01:17 +02:00
|
|
|
});
|
2022-08-10 08:57:43 +02:00
|
|
|
|
2022-12-16 10:59:41 -08:00
|
|
|
// Clicking somewhere else than on the edit label section cancels the label editing
|
|
|
|
|
document.addEventListener("click", (e) => {
|
|
|
|
|
addressesTableComponent = document.querySelector('addresses-table')
|
|
|
|
|
txTableComponent = document.querySelector('tx-table')
|
|
|
|
|
addressDataComponent = document.querySelector('address-data')
|
|
|
|
|
const path = e.composedPath()
|
|
|
|
|
const clickedElement = path[0]
|
|
|
|
|
const parentElement = path[1]
|
|
|
|
|
if (addressesTableComponent) {
|
|
|
|
|
addressesTableComponent.shadowRoot.querySelectorAll('address-row').forEach(addressRow => {
|
|
|
|
|
const addressLabel = addressRow.shadowRoot.querySelector('address-label')
|
|
|
|
|
if (addressLabel.isEditing) {
|
|
|
|
|
console.log("Clicking somewhere else on the screen. Canceling editing.")
|
|
|
|
|
addressLabel.cancelEditing()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
else if (txTableComponent) {
|
|
|
|
|
txTableComponent.shadowRoot.querySelectorAll('tx-row').forEach(txRow => {
|
|
|
|
|
const addressLabel = txRow.shadowRoot.querySelector('address-label')
|
|
|
|
|
// In the tx labeling there also "labels" ("X Recipients") which aren't label components
|
|
|
|
|
if (addressLabel !== null && addressLabel.isEditing) {
|
|
|
|
|
console.log("Clicking somewhere else on the screen. Canceling editing.")
|
|
|
|
|
addressLabel.cancelEditing()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
// Can't use else if here: Address data is a pop-up so addresses or tx table are still in the DOM
|
|
|
|
|
if (addressDataComponent) {
|
|
|
|
|
addressDataComponent.shadowRoot.querySelectorAll('address-label').forEach(addressLabel => {
|
|
|
|
|
if (addressLabel.isEditing) {
|
|
|
|
|
console.log("Clicking somewhere else on the screen. Canceling editing.")
|
|
|
|
|
addressLabel.cancelEditing()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
2022-08-10 08:57:43 +02:00
|
|
|
document.documentElement.style.setProperty('--mobileDistanceElementBottomHeight', `${Math.max(0, window.outerHeight - window.innerHeight)}px`);
|
|
|
|
|
|
2020-07-19 17:36:36 +02:00
|
|
|
function showError(msg, timeout=0) {
|
|
|
|
|
return showNotification(msg, timeout, "error");
|
|
|
|
|
}
|
|
|
|
|
function showNotification(msg, timeout=3000, type="primary") {
|
|
|
|
|
let el = document.createElement("message-box");
|
|
|
|
|
el.setAttribute("type", type);
|
|
|
|
|
el.setAttribute("timeout", timeout);
|
|
|
|
|
el.innerHTML = msg;
|
|
|
|
|
document.getElementById("messages").appendChild(el);
|
|
|
|
|
el.addEventListener('click', (e)=>{
|
|
|
|
|
document.getElementById("messages").removeChild(el);
|
|
|
|
|
});
|
|
|
|
|
return el;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function copyText(value, msg) {
|
|
|
|
|
try {
|
|
|
|
|
var element = document.createElement("p");
|
|
|
|
|
document.getElementsByTagName("body")[0].appendChild(element);
|
2021-07-11 20:56:18 +02:00
|
|
|
element.textContent = value;
|
2020-07-19 17:36:36 +02:00
|
|
|
var selection = document.getSelection();
|
|
|
|
|
var range = document.createRange();
|
2021-07-11 20:56:18 +02:00
|
|
|
range.selectNodeContents(element);
|
2020-07-19 17:36:36 +02:00
|
|
|
selection.removeAllRanges();
|
|
|
|
|
selection.addRange(range);
|
|
|
|
|
document.execCommand("copy");
|
|
|
|
|
selection.removeAllRanges();
|
|
|
|
|
document.getElementsByTagName("body")[0].removeChild(element);
|
|
|
|
|
showNotification(msg);
|
|
|
|
|
}
|
|
|
|
|
catch (err) {
|
|
|
|
|
showError('Unable to copy text');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
async function wait(ms){
|
|
|
|
|
return new Promise(resolve => {
|
|
|
|
|
setTimeout(resolve, ms);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
function capitalize(str){
|
|
|
|
|
return str.charAt(0).toUpperCase()+str.substring(1);
|
2020-10-22 15:57:41 +02:00
|
|
|
}
|
|
|
|
|
|
2020-10-22 20:24:06 +02:00
|
|
|
// Enable navigation loader
|
2020-10-22 15:57:41 +02:00
|
|
|
window.addEventListener('beforeunload', function (e) {
|
2020-10-22 20:24:06 +02:00
|
|
|
// half a second delay before we show it
|
|
|
|
|
window.setTimeout(()=>{
|
2020-10-22 15:57:41 +02:00
|
|
|
document.getElementById("pageloader").style.display = 'block';
|
2020-10-22 20:24:06 +02:00
|
|
|
}, 200);
|
2020-12-04 16:53:17 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// toggle a navbar on mobile view
|
|
|
|
|
function toggleMobileNav(btn, openImg, collapseImg) {
|
|
|
|
|
var x = btn.parentNode;
|
|
|
|
|
if (x.className === "row collapse-on-mobile") {
|
|
|
|
|
x.className += " responsive";
|
|
|
|
|
btn.children[0].src = collapseImg;
|
|
|
|
|
} else {
|
|
|
|
|
x.className = "row collapse-on-mobile";
|
|
|
|
|
btn.children[0].src = openImg;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-12-15 15:01:17 +02:00
|
|
|
|
|
|
|
|
function numberWithCommas(x) {
|
|
|
|
|
x = parseFloat(x).toString();
|
|
|
|
|
if (x.split(".").length > 1) {
|
|
|
|
|
return x.split(".")[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",") + '.' + x.split(".")[1];
|
|
|
|
|
}
|
|
|
|
|
return x.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
|
|
|
}
|
2022-08-02 09:15:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
async function send_request(url, method_str, csrf_token, formData) {
|
|
|
|
|
if (!formData) {
|
|
|
|
|
formData = new FormData();
|
|
|
|
|
}
|
2022-12-13 14:23:04 +01:00
|
|
|
const headers = new Headers();
|
|
|
|
|
headers.append('Accept', 'application/json');
|
2022-08-02 09:15:32 +02:00
|
|
|
formData.append("csrf_token", csrf_token)
|
|
|
|
|
d = {
|
|
|
|
|
method: method_str,
|
2022-12-13 14:23:04 +01:00
|
|
|
headers: headers
|
2022-08-02 09:15:32 +02:00
|
|
|
}
|
|
|
|
|
if (method_str == 'POST') {
|
|
|
|
|
d['body'] = formData;
|
|
|
|
|
}
|
2022-12-13 14:23:04 +01:00
|
|
|
try {
|
|
|
|
|
const response = await fetch(url, d);
|
|
|
|
|
if(response.status != 200){
|
|
|
|
|
showError(await response.text());
|
|
|
|
|
console.log(`Error while calling ${url} with ${method_str} ${formData}`)
|
|
|
|
|
return {"error": `Error while calling ${url} with ${method_str} ${formData}` }
|
|
|
|
|
}
|
|
|
|
|
let jsonResponse = await response.json();
|
2022-12-19 21:30:17 +01:00
|
|
|
console.log(`${method_str} call response:`)
|
2022-12-13 14:23:04 +01:00
|
|
|
console.log(jsonResponse)
|
|
|
|
|
if (typeof(jsonResponse) === 'boolean') {
|
|
|
|
|
return {}
|
|
|
|
|
}
|
|
|
|
|
else if (jsonResponse !== null && 'error' in jsonResponse) {
|
|
|
|
|
showError(`${jsonResponse["error"]}`)
|
|
|
|
|
return jsonResponse
|
|
|
|
|
}
|
|
|
|
|
return jsonResponse
|
|
|
|
|
}
|
|
|
|
|
catch(error) {
|
|
|
|
|
showError(`Failed to fetch transactions list: ${error}`)
|
|
|
|
|
return { 'error': error}
|
2022-08-02 09:15:32 +02:00
|
|
|
}
|
|
|
|
|
}
|