const currentDomain = window.location.hostname; const currentPort = window.location.port let apiDomain function init() { if(currentPort) { apiDomain = "http://"+currentDomain+":"+currentPort } else { apiDomain = "https://"+currentDomain } logAnalytic('LOAD', 'LOAD', '/'); setupListeners(); } function setupListeners() { let analyticElements = document.querySelectorAll('[ana]') for(let element of analyticElements) { element.addEventListener("click", ()=>{ let details = element.attributes['ana-name'] ? element.attributes['ana-name'].value : null; let location = element.attributes['ana-location'] ? element.attributes['ana-location'].value : null; logAnalytic('CLICK', details, location); }) } let contactForums = document.querySelectorAll('[form-group]') for(let element of contactForums) { let items = element.querySelectorAll('[form-input]'); let successElement = element.querySelector('[form-success]'); let failureElement = element.querySelector('[form-failure]'); let submit = element.querySelector('[form-submit]'); successElement.style.display='none'; failureElement.style.display='none'; let addImageLink = element.querySelector('[form-upload]') let addImageInput = element.querySelector('[form-upload-input]'); let forumImages = element.querySelector('[form-images]') let originalButtonText = submit.innerHTML; addImageLink.addEventListener("click", (e)=>{ e.preventDefault(); if(!uploadingImages) { addImageInput.click(); } }); addImageInput.addEventListener("change", (e)=>{ this.uploadImages(e, addImageLink, forumImages); addImageLink.innerHTML='Uploading Images'; }) submit.addEventListener("click", ()=> { this.submitContactForum(items, successElement, failureElement, submit, originalButtonText, forumImages, addImageLink); }); } } let images = []; let uploadingImages = false; let maxImageUpload = 15; let totalUploaded = 0; let uploadedCount = 0; let targetCount = 0; function uploadImages(e, addImageLink, uploadedImagesElement) { let maxImageSize = 1500; if(e.target.files.length === 0) { return; } addImageLink.innerHTML = 'Uploading Images...'; addImageLink.disabled = true; uploadingImages = true; uploadedCount = 0; targetCount = e.target.files.length; for(let i = 0; i < e.target.files.length && i < maxImageUpload-totalUploaded; i++) { let fileName = e.target.files[i].name.split(".")[e.target.files[i].name.split(".").length-1] + ".webp"; let desiredReduction = 1; if(e.target.files[i].size/1000 > maxImageSize) { //reduce image size desiredReduction = 1-(e.target.files[i].size/1000-maxImageSize)/(e.target.files[i].size/1000); } let image = new Image(); image.src= URL.createObjectURL(e.target.files[i]); image.decode().then(()=>{ let canvas = document.createElement('canvas'); let ctx = canvas.getContext('2d'); let width = image.naturalWidth*desiredReduction, height = image.naturalHeight*desiredReduction; canvas.width = width; canvas.height = height; // @ts-ignore ctx.drawImage(image, 0, 0, width, height); var dataUrl = canvas.toDataURL('image/webp'); var resizedImage = this.dataURLToBlob(dataUrl); let newFile = new File([resizedImage], fileName, { type: "image/webp" }); uploadImageFile(newFile, addImageLink, uploadedImagesElement); }); } } function uploadImageFile(file, addImageLink, uploadedImagesElement) { let formData = new FormData(); formData.append("file", file); let http = new XMLHttpRequest(); http.open("POST", apiDomain+"/upload", true); http.send(formData); http.onreadystatechange = (response) => { if (http.readyState === XMLHttpRequest.DONE) { if(http.status === 200) { let response = JSON.parse(http.response); let imageLocation = response.imageUrl; let imageWrapper = document.createElement("div"); imageWrapper.style.display='flex'; imageWrapper.style.flexDirection='column'; imageWrapper.style.alignItems='center'; imageWrapper.setAttribute("id", imageLocation); let removeButton = document.createElement("a"); removeButton.style.color='red'; removeButton.innerText = "X"; removeButton.onclick = function () { removeImage(imageLocation); }; let imageThumbnail = document.createElement("img"); imageThumbnail.setAttribute("src", imageLocation); imageThumbnail.setAttribute("width", "125px"); imageThumbnail.setAttribute("height", "125px"); imageWrapper.appendChild(removeButton); imageWrapper.appendChild(imageThumbnail); uploadedImagesElement.append(imageWrapper); images.push(imageLocation); totalUploaded++; } uploadedCount++; if(uploadedCount === targetCount) { uploadingImages = false; addImageLink.disabled=false; addImageLink.innerHTML='Upload Images (up to ' + maxImageUpload+')'; } } } } /* Utility function to convert a canvas to a BLOB */ function dataURLToBlob(dataURL) { var BASE64_MARKER = ';base64,'; if (dataURL.indexOf(BASE64_MARKER) == -1) { var parts = dataURL.split(','); var contentType = parts[0].split(':')[1]; var raw = parts[1]; return new Blob([raw], {type: contentType}); } var parts = dataURL.split(BASE64_MARKER); var contentType = parts[0].split(':')[1]; var raw2 = window.atob(parts[1]); var rawLength = raw2.length; var uInt8Array = new Uint8Array(rawLength); for (var i = 0; i < rawLength; ++i) { uInt8Array[i] = raw2.charCodeAt(i); } return new Blob([uInt8Array], {type: contentType}); } /* End Utility function to convert a canvas to a BLOB */ function removeImage(id) { document.getElementById(id).remove(); let index = -1; for(let i = 0; i < images.length; i++) { if(images[i] === id) { index=i; } } if(index != -1) { images = images.splice(index, 1); totalUploaded--; } } function submitContactForum(items, successElement, failureElement, submitButton, submitButtonText, forumImages, forumImageLink) { successElement.innerHTML=''; failureElement.innerHTML=''; successElement.style.display='none'; failureElement.style.display='none'; submitButton.innerHTML='Submitting...'; let contactData = {} let missingInfo = false; let failReason = ""; for(let item of items) { contactData[item.attributes['form-input'].value] = item.value; if(item.attributes['form-required']) { if(item.value.trim() === '') { missingInfo = true; failReason = 'Please include a ' + item.attributes['form-input'].value; } } } if(missingInfo) { failureElement.style.display='block'; failureElement.innerHTML = failReason; submitButton.innerHTML = submitButtonText; submitButton.disabled = false; return; } var http = new XMLHttpRequest(); http.open("POST", apiDomain+"/contact", true); http.setRequestHeader("Content-Type", "application/json"); http.setRequestHeader("sessionId", getOrCreateSession()); let request = { contactData: contactData, images: images, domain: window.location.origin } submitButton.disabled = true; http.send(JSON.stringify(request)); http.onreadystatechange = (response) => { if (http.readyState === XMLHttpRequest.DONE) { if(http.status === 200) { successElement.innerHTML='Forum Submitted!'; submitButton.innerHTML = 'Submitted.'; forumImageLink.innerHTML = ''; forumImages.remove(); successElement.style.display='block'; } else if(http.status === 400) { failureElement.innerHTML = failReason; submitButton.innerHTML = submitButtonText; submitButton.disabled = false; failureElement.innerHTML=JSON.parse(http.responseText).message; failureElement.style.display='block'; } } } } //contact forum function logAnalytic(eventType, eventDetails, eventLocation) { var http = new XMLHttpRequest(); http.open("POST", apiDomain+"/analytics", true); http.setRequestHeader("Content-Type", "application/json"); http.setRequestHeader("sessionId", getOrCreateSession()) let request = { domain: window.location.hostname, page: window.location.pathname, eventType: eventType, eventLocation: eventLocation, eventDetails: eventDetails, screenSize: window.innerWidth+"x"+window.innerHeight } http.send(JSON.stringify(request)); http.onreadystatechange = (response) => { if (http.readyState === XMLHttpRequest.DONE) {} } } //session handling function getOrCreateSession() { if(!tokenExist()) { localStorage.setItem('sessionId', createUUID()); localStorage.setItem('sessionStart', new Date(Date.now() + 4 * (60 * 60 * 1000)).toString()) } return localStorage.getItem('sessionId'); } function tokenExist() { if(localStorage.getItem('sessionId')) { if(localStorage.getItem('sessionStart')) { try { let createDate = Date.parse(localStorage.getItem('sessionStart')); if(Number(createDate) > Number(new Date().getTime())) { return true; } } catch(e) { } } } return false; } function createUUID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } //session handling init()