filesafe/dist/js/home.js.map

1 line
64 KiB
Plaintext

{"version":3,"sources":["home.js"],"names":["const","lsKeys","token","chunkSize","parallelUploads","uploadsHistoryOrder","previewImages","fileLength","uploadAge","stripTags","page","localStorage","apiChecked","private","enableUserAccounts","maxSize","chunkSizeConfig","temporaryUploadAges","defaultTemporaryUploadAge","fileIdentifierLength","stripTagsConfig","album","maxSizeBytes","urlMaxSize","urlMaxSizeBytes","tabs","activeTab","albumSelect","albumSelectOnChange","previewTemplate","dropzone","clipboardJS","lazyLoad","urlsQueue","activeUrlsQueue","imageExts","videoExts","albumTitleMaxLength","albumDescMaxLength","cloudflareErrors","error","document","querySelector","classList","add","querySelectorAll","forEach","element","uploadButton","innerText","remove","addEventListener","window","location","reload","response","onAxiosError","onError","console","content","createElement","innerHTML","toString","swal","title","icon","statusText","status","description","data","success","apiVersion","match","src","text","buttons","confirm","closeModal","then","axios","get","onDownloadProgress","render","done","do","newsfeed","version","checkClientVersion","parseInt","getPrettyBytes","max","default","preparePage","catch","onInitError","verifyToken","prepareUpload","button","href","post","Array","isArray","retentionPeriods","defaultRetentionPeriod","code","removeItem","authLink","setAttribute","value","prepareShareX","fetchAlbums","prepareUploadConfig","prepareDropzone","uploadUrls","event","addUrlsToQueue","tabsContainer","loop","i","id","dataset","tabContent","setActiveTab","push","tab","length","index","let","headers","simple","albums","option","name","appendChild","previewNode","parentNode","removeChild","tabDiv","div","className","previewsContainer","Dropzone","body","url","paramName","clickable","maxFilesize","uploadMultiple","createImageThumbnails","autoProcessQueue","chunking","Boolean","parallelChunkUploads","timeout","init","this","on","file","previewElement","xhr","ontimeout","instances","getUploadingFiles","filter","instance","_handleUploadError","_uplSpeedCalc","lastSent","timestamp","Date","now","bytes","upload","chunked","setRequestHeader","chunks","progress","prettyBytesPerSec","total","Math","size","percentage","bytesSent","toFixed","upl","prefix","skipProgress","last","totalChunkCount","chunkIndex","elapsed","bytesPerSec","fullSec","splice","excessDuration","duration","files","updateTemplate","err","formatAxiosError","Error","test","updateTemplateIcon","chunksUploaded","uuid","original","type","albumid","filelength","age","striptags","urls","split","trim","firstChild","processUrlsQueue","shiftQueue","initUrlUpload","finishedUrlUpload","shift","templateElement","iconClass","iconElement","link","a","clipboard","clipboardText","parentElement","exec","extname","toLowerCase","includes","img","onerror","currentTarget","update","expirydate","expiryDate","getPrettyDate","createAlbum","cancel","download","checked","public","selected","fallback","min","config","siBytes","label","select","help","valueHandler","ampmTime","display","number","round","undefined","disabled","force","video","suffix","uploadFields","_default","stored","parseFloat","String","getPrettyUploadAge","isNaN","form","preventDefault","configKeys","Object","keys","key","conf","field","parsed","find","sel","control","opts","j","opt","join","tmp","submit","checkValidity","elements","hours","minutes","days","items","clipboardData","originalEvent","item","kind","blob","getAsFile","File","addFile","cookieconsent","initialise","cookie","path","pathname","expiryDays","secure","protocol","palette","popup","background","theme","position","message","dismiss","checkIfPublic","ClipboardJS","timer","LazyLoad","elements_selector"],"mappings":"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","file":"home.js","sourcesContent":["/* global swal, axios, Dropzone, ClipboardJS, LazyLoad */\n\nconst lsKeys = {\n token: 'token',\n chunkSize: 'chunkSize',\n parallelUploads: 'parallelUploads',\n uploadsHistoryOrder: 'uploadsHistoryOrder',\n previewImages: 'previewImages',\n fileLength: 'fileLength',\n uploadAge: 'uploadAge',\n stripTags: 'stripTags'\n}\n\nconst page = {\n // user token\n token: localStorage[lsKeys.token],\n\n // configs from api/check\n apiChecked: false,\n private: null,\n enableUserAccounts: null,\n maxSize: null,\n chunkSizeConfig: null,\n temporaryUploadAges: null,\n defaultTemporaryUploadAge: null,\n fileIdentifierLength: null,\n stripTagsConfig: null,\n\n // store album id that will be used with upload requests\n album: null,\n\n parallelUploads: null,\n previewImages: null,\n fileLength: null,\n uploadAge: null,\n stripTags: null,\n\n maxSizeBytes: null,\n urlMaxSize: null,\n urlMaxSizeBytes: null,\n chunkSize: null,\n\n tabs: [],\n activeTab: null,\n albumSelect: null,\n albumSelectOnChange: null,\n previewTemplate: null,\n\n dropzone: null,\n clipboardJS: null,\n lazyLoad: null,\n\n // additional vars for url uploads\n urlsQueue: [],\n activeUrlsQueue: 0,\n\n // Include BMP for uploads preview only, cause the real images will be used\n // Sharp isn't capable of making their thumbnails for dashboard and album public pages\n imageExts: ['.gif', '.jpeg', '.jpg', '.png', '.svg', '.tif', '.tiff', '.webp', '.bmp'],\n videoExts: ['.avi', '.m2ts', '.m4v', '.mkv', '.mov', '.mp4', '.webm', '.wmv'],\n\n albumTitleMaxLength: 70,\n albumDescMaxLength: 4000,\n\n // Better Cloudflare errors\n cloudflareErrors: {\n 520: 'Unknown Error',\n 521: 'Web Server Is Down',\n 522: 'Connection Timed Out',\n 523: 'Origin Is Unreachable',\n 524: 'A Timeout Occurred',\n 525: 'SSL Handshake Failed',\n 526: 'Invalid SSL Certificate',\n 527: 'Railgun Error',\n 530: 'Origin DNS Error'\n }\n}\n\n// Handler for errors during initialization\npage.onInitError = error => {\n // Hide these elements\n document.querySelector('#albumDiv').classList.add('is-hidden')\n document.querySelector('#tabs').classList.add('is-hidden')\n document.querySelectorAll('.tab-content').forEach(element => {\n return element.classList.add('is-hidden')\n })\n\n // Update upload button\n const uploadButton = document.querySelector('#loginToUpload')\n uploadButton.innerText = 'An error occurred. Try to reload?'\n uploadButton.classList.remove('is-loading')\n uploadButton.classList.remove('is-hidden')\n\n uploadButton.addEventListener('click', () => {\n window.location.reload()\n })\n\n if (!error) return\n if (error.response) page.onAxiosError(error)\n else page.onError(error)\n}\n\n// Handler for regular JS errors\npage.onError = error => {\n console.error(error)\n\n const content = document.createElement('div')\n content.innerHTML = `\n <p><code>${error.toString()}</code></p>\n <p>Please check your console for more information.</p>\n `\n return swal({\n title: 'An error occurred!',\n icon: 'error',\n content\n })\n}\n\n// Handler for Axios errors\npage.onAxiosError = error => {\n if (!error.response) {\n return page.onError(error)\n }\n\n const statusText = page.cloudflareErrors[error.response.status] || error.response.statusText\n const description = error.response.data && error.response.data.description\n ? error.response.data.description\n : 'There was an error with the request.\\nPlease check the console for more information.'\n\n return swal(`${error.response.status} ${statusText}`, description, 'error')\n}\n\npage.formatAxiosError = error => {\n const statusText = page.cloudflareErrors[error.response.status] || error.response.statusText\n\n if (error.response.data && error.response.data.description) {\n return error.response\n } else {\n const description = error.response\n ? `${error.response.status} ${statusText}`\n : error.toString()\n return { data: { success: false, description } }\n }\n}\n\npage.checkClientVersion = apiVersion => {\n const self = document.querySelector('#mainScript')\n const match = self.src.match(/\\?_=(\\d+)$/)\n if (match && match[1] && match[1] !== apiVersion) {\n return swal({\n title: 'Update detected!',\n text: 'Client assets have been updated. Reload to display the latest version?',\n icon: 'info',\n buttons: {\n confirm: {\n text: 'Reload',\n closeModal: false\n }\n }\n }).then(() => {\n window.location.reload()\n })\n }\n}\n\npage.checkIfPublic = () => {\n return axios.get('api/check', {\n onDownloadProgress: () => {\n // Only do render and/or newsfeed after this request has been initiated to avoid blocking\n /* global render */\n if (typeof render !== 'undefined' && !render.done) render.do()\n /* global newsfeed */\n if (typeof newsfeed !== 'undefined' && !newsfeed.done) newsfeed.do()\n if (!page.apiChecked) page.apiChecked = true\n }\n }).then(response => {\n if (response.data.version) {\n page.checkClientVersion(response.data.version)\n }\n\n page.private = response.data.private\n page.enableUserAccounts = response.data.enableUserAccounts\n\n page.maxSize = parseInt(response.data.maxSize)\n page.maxSizeBytes = page.maxSize * 1e6\n document.querySelector('#maxSize > span').innerHTML = page.getPrettyBytes(page.maxSizeBytes)\n\n page.chunkSizeConfig = {\n max: (response.data.chunkSize && parseInt(response.data.chunkSize.max)) || 95,\n default: response.data.chunkSize && parseInt(response.data.chunkSize.default)\n }\n\n page.temporaryUploadAges = response.data.temporaryUploadAges\n page.defaultTemporaryUploadAge = response.data.defaultTemporaryUploadAge || null\n page.fileIdentifierLength = response.data.fileIdentifierLength\n page.stripTagsConfig = response.data.stripTags\n\n return page.preparePage()\n }).catch(page.onInitError)\n}\n\npage.preparePage = () => {\n if (page.token) {\n return page.verifyToken(page.token)\n } else if (page.private) {\n const button = document.querySelector('#loginToUpload')\n button.href = 'auth'\n button.classList.remove('is-loading')\n if (page.enableUserAccounts) {\n button.innerText = 'Anonymous upload is disabled.\\nLog in or register to upload.'\n } else {\n button.innerText = 'Running in private mode.\\nLog in to upload.'\n }\n } else {\n return page.prepareUpload()\n }\n}\n\npage.verifyToken = token => {\n return axios.post('api/tokens/verify', { token }).then(response => {\n localStorage[lsKeys.token] = token\n page.token = token\n\n // If user has its own retention periods array, override defaults\n if (Array.isArray(response.data.retentionPeriods)) {\n page.temporaryUploadAges = response.data.retentionPeriods\n page.defaultTemporaryUploadAge = response.data.defaultRetentionPeriod\n }\n\n return page.prepareUpload()\n }).catch(error => {\n return page.onAxiosError(error).then(() => {\n if (error.response.data && error.response.data.code === 10001) {\n localStorage.removeItem(lsKeys.token)\n window.location.reload()\n } else {\n page.onInitError()\n }\n })\n })\n}\n\npage.prepareUpload = () => {\n // I think this fits best here because we need to check for a valid token before we can get the albums\n if (page.token) {\n // Change /auth link to /dashboard\n const authLink = document.querySelector('#linksColumn a[href=\"auth\"]')\n if (authLink) authLink.setAttribute('href', 'dashboard')\n\n // Display the album selection\n document.querySelector('#albumDiv').classList.remove('is-hidden')\n\n page.albumSelect = document.querySelector('#albumSelect')\n page.albumSelectOnChange = () => {\n page.album = parseInt(page.albumSelect.value)\n // Re-generate ShareX config file\n if (typeof page.prepareShareX === 'function') page.prepareShareX()\n }\n page.albumSelect.addEventListener('change', page.albumSelectOnChange)\n\n // Fetch albums\n page.fetchAlbums()\n } else if (page.enableUserAccounts) {\n document.querySelector('#loginLinkText').innerHTML = 'Create an account and keep track of your uploads'\n }\n\n // Prepare & generate config tab\n page.prepareUploadConfig()\n\n // Hide login button\n document.querySelector('#loginToUpload').classList.add('is-hidden')\n\n // Prepare & generate files upload tab\n page.prepareDropzone()\n\n // Generate ShareX config file\n if (typeof page.prepareShareX === 'function') page.prepareShareX()\n\n // Prepare urls upload tab\n const urlMaxSize = document.querySelector('#urlMaxSize')\n if (urlMaxSize) {\n page.urlMaxSize = parseInt(urlMaxSize.innerHTML)\n page.urlMaxSizeBytes = page.urlMaxSize * 1e6\n urlMaxSize.innerHTML = page.getPrettyBytes(page.urlMaxSizeBytes)\n }\n\n const uploadUrls = document.querySelector('#uploadUrls')\n if (uploadUrls) {\n uploadUrls.addEventListener('click', event => {\n page.addUrlsToQueue()\n })\n }\n\n // Get all tabs\n const tabsContainer = document.querySelector('#tabs')\n const tabs = tabsContainer.querySelectorAll('li')\n for (let i = 0; i < tabs.length; i++) {\n const id = tabs[i].dataset.id\n const tabContent = document.querySelector(`#${id}`)\n if (!tabContent) continue\n\n tabs[i].addEventListener('click', () => {\n page.setActiveTab(i)\n })\n page.tabs.push({ tab: tabs[i], content: tabContent })\n }\n\n // Set first valid tab as the default active tab\n if (page.tabs.length) {\n page.setActiveTab(0)\n tabsContainer.classList.remove('is-hidden')\n }\n}\n\npage.setActiveTab = index => {\n for (let i = 0; i < page.tabs.length; i++) {\n if (i === index) {\n page.tabs[i].tab.classList.add('is-active')\n page.tabs[i].content.classList.remove('is-hidden')\n page.activeTab = index\n } else {\n page.tabs[i].tab.classList.remove('is-active')\n page.tabs[i].content.classList.add('is-hidden')\n }\n }\n}\n\npage.fetchAlbums = () => {\n return axios.get('api/albums', {\n headers: {\n simple: '1',\n token: page.token\n }\n }).then(response => {\n if (response.data.success === false) {\n return swal('An error occurred!', response.data.description, 'error')\n }\n\n // Create an option for each album\n if (Array.isArray(response.data.albums) && response.data.albums.length) {\n for (let i = 0; i < response.data.albums.length; i++) {\n const album = response.data.albums[i]\n const option = document.createElement('option')\n option.value = album.id\n option.innerHTML = album.name\n page.albumSelect.appendChild(option)\n }\n }\n }).catch(page.onInitError)\n}\n\npage.prepareDropzone = () => {\n // Parse template element\n const previewNode = document.querySelector('#tpl')\n page.previewTemplate = previewNode.innerHTML\n previewNode.parentNode.removeChild(previewNode)\n\n // Generate files upload tab\n const tabDiv = document.querySelector('#tab-files')\n const div = document.createElement('div')\n div.className = 'control is-expanded'\n div.innerHTML = `\n <div id=\"dropzone\" class=\"button is-danger is-outlined is-fullwidth is-unselectable\">\n <span class=\"icon\">\n <i class=\"icon-upload-cloud\"></i>\n </span>\n <span>Click here or drag & drop files</span>\n </div>\n `\n tabDiv.querySelector('.dz-container').appendChild(div)\n\n const previewsContainer = tabDiv.querySelector('#tab-files .field.uploads')\n\n page.dropzone = new Dropzone(document.body, {\n url: 'api/upload',\n paramName: 'files[]',\n clickable: tabDiv.querySelector('#dropzone'),\n maxFilesize: page.maxSizeBytes / 1024 / 1024, // this option expects MiB\n parallelUploads: page.parallelUploads,\n uploadMultiple: false,\n previewsContainer,\n previewTemplate: page.previewTemplate,\n createImageThumbnails: false,\n autoProcessQueue: true,\n headers: { token: page.token },\n chunking: Boolean(page.chunkSize),\n chunkSize: page.chunkSize * 1e6, // this option expects Bytes\n // Lolisafe cannot handle parallel chunked uploads\n // due to technical reasons involving how we optimize I/O performance\n parallelChunkUploads: false,\n timeout: 0,\n\n init () {\n this.on('addedfile', file => {\n // Set active tab to file uploads, if necessary\n if (page.activeTab !== 0) page.setActiveTab(0)\n\n // Add file entry\n tabDiv.querySelector('.uploads').classList.remove('is-hidden')\n\n file.previewElement.querySelector('.name').innerHTML = file.name\n file.previewElement.querySelector('.descriptive-progress').innerHTML = 'Waiting in queue\\u2026'\n })\n\n this.on('sending', (file, xhr) => {\n // Add timeout listener (hacky method due to lack of built-in timeout handler)\n if (!xhr.ontimeout) {\n xhr.ontimeout = () => {\n const instances = page.dropzone.getUploadingFiles()\n .filter(instance => instance.xhr === xhr)\n page.dropzone._handleUploadError(instances, xhr, 'Connection timed out. Try to reduce upload chunk size.')\n }\n }\n\n // Attach necessary data for initial upload speed calculation\n if (typeof xhr._uplSpeedCalc === 'undefined') {\n xhr._uplSpeedCalc = {\n lastSent: 0,\n data: [{ timestamp: Date.now(), bytes: 0 }]\n }\n }\n\n // If not chunked uploads, add extra headers\n if (!file.upload.chunked) {\n if (page.album !== null) xhr.setRequestHeader('albumid', page.album)\n if (page.fileLength !== null) xhr.setRequestHeader('filelength', page.fileLength)\n if (page.uploadAge !== null) xhr.setRequestHeader('age', page.uploadAge)\n if (page.stripTags !== null) xhr.setRequestHeader('striptags', page.stripTags)\n }\n\n if (!file.upload.chunked) {\n file.previewElement.querySelector('.descriptive-progress').innerHTML = 'Uploading\\u2026'\n } else if (file.upload.chunks.length === 1) {\n file.previewElement.querySelector('.descriptive-progress').innerHTML = `Uploading chunk 1/${file.upload.totalChunkCount}\\u2026`\n }\n })\n\n // Update descriptive progress\n this.on('uploadprogress', (file, progress) => {\n // Total bytes will eventually be bigger than file size when chunked\n const total = Math.max(file.size, file.upload.total)\n const percentage = (file.upload.bytesSent / total * 100).toFixed(0)\n\n const upl = file.upload.chunked\n ? file.upload.chunks[file.upload.chunks.length - 1]\n : file.upload\n const xhr = upl.xhr || file.xhr\n\n let prefix = 'Uploading\\u2026'\n let skipProgress = false\n if (file.upload.chunked) {\n const done = upl.bytesSent === upl.total\n const last = file.upload.chunks.length === file.upload.totalChunkCount\n let chunkIndex = file.upload.chunks.length\n if (done && !last) {\n chunkIndex++\n skipProgress = true\n }\n prefix = `Uploading chunk ${chunkIndex}/${file.upload.totalChunkCount}\\u2026`\n }\n\n // Real-time upload speed calculation\n let prettyBytesPerSec\n if (!skipProgress) {\n const now = Date.now()\n const bytesSent = upl.bytesSent - xhr._uplSpeedCalc.lastSent\n\n // Push data of current iteration\n xhr._uplSpeedCalc.lastSent = upl.bytesSent\n xhr._uplSpeedCalc.data.push({ timestamp: now, bytes: bytesSent })\n\n // Wait till at least the 2nd iteration (3 data including initial data)\n const length = xhr._uplSpeedCalc.data.length\n if (length > 2) {\n // Calculate using data from all iterations\n let elapsed = 0\n let bytesPerSec = 0\n let fullSec = false\n let i = length - 1 // Always start with 2nd from last item\n while (i--) {\n // Splice data of unrequired iterations\n if (fullSec) {\n xhr._uplSpeedCalc.data.splice(i, 1)\n continue\n }\n // Sum data\n elapsed = now - xhr._uplSpeedCalc.data[i].timestamp\n if (elapsed > 1000) {\n const excessDuration = elapsed - 1000\n const newerIterationElapsed = now - xhr._uplSpeedCalc.data[i + 1].timestamp\n const duration = elapsed - newerIterationElapsed\n const fragment = (duration - excessDuration) / duration * xhr._uplSpeedCalc.data[i + 1].bytes\n bytesPerSec += fragment\n fullSec = true\n } else {\n bytesPerSec += xhr._uplSpeedCalc.data[i + 1].bytes\n }\n }\n\n // If not enough data\n if (!fullSec) bytesPerSec = 1000 / elapsed * bytesPerSec\n\n // Get pretty bytes\n prettyBytesPerSec = page.getPrettyBytes(bytesPerSec)\n }\n }\n\n file.previewElement.querySelector('.descriptive-progress').innerHTML =\n `${prefix} ${percentage}%${prettyBytesPerSec ? ` at ${prettyBytesPerSec}/s` : ''}`\n })\n\n this.on('success', (file, data) => {\n if (!data) return\n file.previewElement.querySelector('.descriptive-progress').classList.add('is-hidden')\n\n if (data.success === false) {\n file.previewElement.querySelector('.error').innerHTML = data.description\n file.previewElement.querySelector('.error').classList.remove('is-hidden')\n }\n\n if (Array.isArray(data.files) && data.files[0]) {\n page.updateTemplate(file, data.files[0])\n }\n })\n\n this.on('error', (file, error, xhr) => {\n let err = error\n if (typeof error === 'object' && error.description) {\n err = error.description\n } else if (xhr) {\n const formatted = page.formatAxiosError({\n response: {\n status: xhr.status,\n statusText: xhr.statusText\n }\n })\n err = formatted.data.description\n } else if (error instanceof Error) {\n err = error.toString()\n }\n\n // Clean up file size errors\n if (/^File is too big/.test(err) || /File too large/.test(err)) {\n err = `File too large (${page.getPrettyBytes(file.size)}).`\n }\n\n file.previewElement.querySelector('.descriptive-progress').classList.add('is-hidden')\n\n file.previewElement.querySelector('.error').innerHTML = err\n file.previewElement.querySelector('.error').classList.remove('is-hidden')\n\n page.updateTemplateIcon(file.previewElement, 'icon-block')\n })\n },\n\n chunksUploaded (file, done) {\n file.previewElement.querySelector('.descriptive-progress').innerHTML =\n `Rebuilding ${file.upload.totalChunkCount} chunks\\u2026`\n\n axios.post('api/upload/finishchunks', {\n // This API supports an array of multiple files\n files: [{\n uuid: file.upload.uuid,\n original: file.name,\n type: file.type,\n size: file.size,\n albumid: page.album,\n filelength: page.fileLength,\n age: page.uploadAge\n }]\n }, {\n headers: {\n token: page.token,\n // Unlike the options above (e.g. albumid, filelength, etc.),\n // strip tags cannot yet be configured per file with this API\n striptags: page.stripTags\n }\n }).catch(error => page.formatAxiosError(error)).then(response => {\n file.previewElement.querySelector('.descriptive-progress').classList.add('is-hidden')\n\n if (response.data.success === false) {\n file.previewElement.querySelector('.error').innerHTML = response.data.description\n file.previewElement.querySelector('.error').classList.remove('is-hidden')\n\n page.updateTemplateIcon(file.previewElement, 'icon-block')\n }\n\n if (response.data.files && response.data.files[0]) {\n page.updateTemplate(file, response.data.files[0])\n }\n\n done()\n })\n }\n })\n}\n\npage.addUrlsToQueue = () => {\n const urls = document.querySelector('#urls').value\n .split(/\\r?\\n/)\n .filter(url => {\n return url.trim().length\n })\n\n if (!urls.length) {\n return swal('An error occurred!', 'You have not entered any URLs.', 'error')\n }\n\n const tabDiv = document.querySelector('#tab-urls')\n tabDiv.querySelector('.uploads').classList.remove('is-hidden')\n\n for (let i = 0; i < urls.length; i++) {\n const previewTemplate = document.createElement('template')\n previewTemplate.innerHTML = page.previewTemplate.trim()\n\n const previewElement = previewTemplate.content.firstChild\n previewElement.querySelector('.name').innerHTML = urls[i]\n previewElement.querySelector('.descriptive-progress').innerHTML = 'Waiting in queue\\u2026'\n\n const previewsContainer = tabDiv.querySelector('.uploads')\n previewsContainer.appendChild(previewElement)\n\n page.urlsQueue.push({\n url: urls[i],\n previewElement\n })\n }\n\n page.processUrlsQueue()\n document.querySelector('#urls').value = ''\n}\n\npage.processUrlsQueue = () => {\n if (!page.urlsQueue.length) return\n\n function finishedUrlUpload (file, data) {\n file.previewElement.querySelector('.descriptive-progress').classList.add('is-hidden')\n\n if (data.success === false) {\n const match = data.description.match(/ over limit: (\\d+)$/)\n if (match && match[1]) {\n data.description = `File exceeded limit of ${page.getPrettyBytes(match[1])}.`\n }\n\n file.previewElement.querySelector('.error').innerHTML = data.description\n file.previewElement.querySelector('.error').classList.remove('is-hidden')\n\n page.updateTemplateIcon(file.previewElement, 'icon-block')\n }\n\n if (Array.isArray(data.files) && data.files[0]) {\n page.updateTemplate(file, data.files[0])\n }\n\n page.activeUrlsQueue--\n return shiftQueue()\n }\n\n function initUrlUpload (file) {\n file.previewElement.querySelector('.descriptive-progress').innerHTML =\n 'Waiting for server to fetch URL\\u2026'\n\n return axios.post('api/upload', {\n urls: [file.url]\n }, {\n headers: {\n token: page.token,\n albumid: page.album,\n age: page.uploadAge,\n filelength: page.fileLength\n }\n }).catch(error => page.formatAxiosError(error)).then(response => {\n return finishedUrlUpload(file, response.data)\n })\n }\n\n function shiftQueue () {\n while (page.urlsQueue.length && (page.activeUrlsQueue < page.parallelUploads)) {\n page.activeUrlsQueue++\n initUrlUpload(page.urlsQueue.shift())\n }\n }\n\n return shiftQueue()\n}\n\npage.updateTemplateIcon = (templateElement, iconClass) => {\n const iconElement = templateElement.querySelector('.icon')\n if (!iconElement) return\n\n iconElement.classList.add(iconClass)\n iconElement.classList.remove('is-hidden')\n}\n\npage.updateTemplate = (file, response) => {\n if (!response.url) return\n\n const link = file.previewElement.querySelector('.link')\n const a = link.querySelector('a')\n const clipboard = file.previewElement.querySelector('.clipboard-mobile > .clipboard-js')\n let url = response.url\n if (!/^https?:\\/\\//i.test(url)) {\n url = `${window.location.origin}/${url}`\n }\n a.href = a.innerHTML = clipboard.dataset.clipboardText = url\n\n link.classList.remove('is-hidden')\n clipboard.parentElement.classList.remove('is-hidden')\n\n const exec = /.[\\w]+$/.exec(response.url)\n const extname = exec && exec[0]\n ? exec[0].toLowerCase()\n : null\n\n if (page.imageExts.includes(extname)) {\n if (page.previewImages) {\n const img = file.previewElement.querySelector('img')\n img.setAttribute('alt', response.name || '')\n img.dataset.src = response.url\n img.classList.remove('is-hidden')\n img.onerror = event => {\n // Hide image elements that fail to load\n // Consequently include WEBP in browsers that do not have WEBP support (e.g. IE)\n event.currentTarget.classList.add('is-hidden')\n page.updateTemplateIcon(file.previewElement, 'icon-picture')\n }\n page.lazyLoad.update(file.previewElement.querySelectorAll('img'))\n } else {\n page.updateTemplateIcon(file.previewElement, 'icon-picture')\n }\n } else if (page.videoExts.includes(extname)) {\n page.updateTemplateIcon(file.previewElement, 'icon-video')\n } else {\n page.updateTemplateIcon(file.previewElement, 'icon-doc-inv')\n }\n\n if (response.expirydate) {\n const expiryDate = file.previewElement.querySelector('.expiry-date')\n expiryDate.dataset.timestamp = response.expirydate\n expiryDate.innerHTML = `EXP: ${page.getPrettyDate(new Date(response.expirydate * 1000))}`\n expiryDate.classList.remove('is-hidden')\n }\n}\n\npage.createAlbum = () => {\n const div = document.createElement('div')\n div.innerHTML = `\n <div class=\"field\">\n <div class=\"controls\">\n <input id=\"swalName\" class=\"input\" type=\"text\" placeholder=\"Name\" maxlength=\"${page.albumTitleMaxLength}\">\n </div>\n <p class=\"help\">Max length is ${page.albumTitleMaxLength} characters.</p>\n </div>\n <div class=\"field\">\n <div class=\"control\">\n <textarea id=\"swalDescription\" class=\"textarea\" placeholder=\"Description\" rows=\"2\" maxlength=\"${page.albumDescMaxLength}\"></textarea>\n </div>\n <p class=\"help\">Max length is ${page.albumDescMaxLength} characters.</p>\n </div>\n <div class=\"field\">\n <div class=\"control\">\n <label class=\"checkbox\">\n <input id=\"swalDownload\" type=\"checkbox\" checked>\n Enable download\n </label>\n </div>\n </div>\n <div class=\"field\">\n <div class=\"control\">\n <label class=\"checkbox\">\n <input id=\"swalPublic\" type=\"checkbox\" checked>\n Enable public link\n </label>\n </div>\n </div>\n `\n\n swal({\n title: 'Create new album',\n icon: 'info',\n content: div,\n buttons: {\n cancel: true,\n confirm: {\n closeModal: false\n }\n }\n }).then(value => {\n if (!value) return\n\n const name = document.querySelector('#swalName').value.trim()\n axios.post('api/albums', {\n name,\n description: document.querySelector('#swalDescription').value.trim(),\n download: document.querySelector('#swalDownload').checked,\n public: document.querySelector('#swalPublic').checked\n }, {\n headers: {\n token: page.token\n }\n }).then(response => {\n if (response.data.success === false) {\n return swal('An error occurred!', response.data.description, 'error')\n }\n\n const option = document.createElement('option')\n page.albumSelect.appendChild(option)\n option.value = response.data.id\n option.innerHTML = name\n option.selected = true\n page.albumSelectOnChange()\n\n swal('Woohoo!', 'Album was created successfully.', 'success')\n }).catch(page.onError)\n })\n}\n\npage.prepareUploadConfig = () => {\n // This object should only be used to set fallback values for page[key]\n // (essentially for page[key] properties that explicitly need to be set as something)\n // As for default values in the Config tab (which will not set page[key]),\n // check out number.default property of each config\n const fallback = {\n chunkSize: page.chunkSizeConfig.default,\n parallelUploads: 2\n }\n\n const temporaryUploadAges = Array.isArray(page.temporaryUploadAges) &&\n page.temporaryUploadAges.length\n const fileIdentifierLength = page.fileIdentifierLength &&\n typeof page.fileIdentifierLength.min === 'number' &&\n typeof page.fileIdentifierLength.max === 'number'\n\n const config = {\n siBytes: {\n label: 'File size display',\n select: [\n { value: 'default', text: '1000 B = 1 kB = 1 Kilobyte' },\n { value: '0', text: '1024 B = 1 KiB = 1 Kibibyte' }\n ],\n help: 'This will be used in our homepage, dashboard, and album public pages.',\n valueHandler () {} // Do nothing\n },\n ampmTime: {\n label: 'Show AM/PM on date',\n select: [\n { value: 'default', text: 'No' },\n { value: '1', text: 'Yes' }\n ],\n help: 'This will be used in our homepage and dashboard.',\n valueHandler () {} // Do nothing\n },\n fileLength: {\n display: fileIdentifierLength,\n label: 'File identifier length',\n number: fileIdentifierLength\n ? {\n min: page.fileIdentifierLength.min,\n max: page.fileIdentifierLength.max,\n default: page.fileIdentifierLength.default,\n round: true\n }\n : undefined,\n help: true, // true means auto-generated, for number-based configs only\n disabled: fileIdentifierLength && page.fileIdentifierLength.force\n },\n uploadAge: {\n display: temporaryUploadAges,\n label: 'Upload age',\n select: [],\n help: 'Whether to automatically delete your uploads after a certain amount of time.'\n },\n stripTags: {\n display: page.stripTagsConfig,\n label: 'Strip tags',\n select: page.stripTagsConfig\n ? [\n { value: page.stripTagsConfig.default ? 'default' : '1', text: 'Yes' },\n { value: page.stripTagsConfig.default ? '0' : 'default', text: 'No' }\n ]\n : null,\n help: `Whether to strip tags (e.g. EXIF) from your uploads.<br>\n This only applies to regular image${page.stripTagsConfig && page.stripTagsConfig.video ? ' and video' : ''} uploads (i.e. not URL uploads).`,\n disabled: page.stripTagsConfig && page.stripTagsConfig.force\n },\n chunkSize: {\n display: Boolean(page.chunkSizeConfig.default),\n label: 'Upload chunk size (MB)',\n number: {\n min: 1,\n max: page.chunkSizeConfig.max,\n default: fallback.chunkSize,\n suffix: ' MB',\n round: true\n },\n help: true\n },\n parallelUploads: {\n label: 'Parallel uploads',\n number: {\n min: 1,\n max: 10,\n default: fallback.parallelUploads,\n round: true\n },\n help: true\n },\n uploadsHistoryOrder: {\n label: 'Uploads history order',\n select: [\n { value: 'default', text: 'Older files on top' },\n { value: '0', text: 'Newer files on top' }\n ],\n help: `\"Newer files on top\" will use a CSS technique, which unfortunately come with <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction#Accessibility_concerns\" target=\"_blank\" rel=\"noopener\">some undesirable side effects</a>.<br>\n This also affects text selection, such as when trying to select text from top to bottom will result in them being selected from bottom to top instead, and vice versa.`,\n valueHandler (value) {\n if (value === '0') {\n const uploadFields = document.querySelectorAll('.tab-content > .uploads')\n for (let i = 0; i < uploadFields.length; i++) {\n uploadFields[i].classList.add('is-reversed')\n }\n }\n }\n },\n previewImages: {\n label: 'Load images for preview',\n select: [\n { value: 'default', text: 'Yes' },\n { value: '0', text: 'No' }\n ],\n help: 'By default, uploaded images will be loaded as their previews.',\n valueHandler (value) {\n page.previewImages = value !== '0'\n }\n }\n }\n\n if (temporaryUploadAges) {\n const _default = page.defaultTemporaryUploadAge === null\n ? page.temporaryUploadAges[0]\n : page.defaultTemporaryUploadAge\n const stored = parseFloat(localStorage[lsKeys.uploadAge])\n for (let i = 0; i < page.temporaryUploadAges.length; i++) {\n const age = page.temporaryUploadAges[i]\n config.uploadAge.select.push({\n value: age === _default ? 'default' : String(age),\n text: page.getPrettyUploadAge(age)\n })\n if (age === stored) {\n config.uploadAge.value = stored\n }\n }\n }\n\n if (fileIdentifierLength) {\n const stored = parseInt(localStorage[lsKeys.fileLength])\n if (!page.fileIdentifierLength.force &&\n !isNaN(stored) &&\n stored >= page.fileIdentifierLength.min &&\n stored <= page.fileIdentifierLength.max) {\n config.fileLength.value = stored\n }\n }\n\n const tabContent = document.querySelector('#tab-config')\n const form = document.createElement('form')\n form.addEventListener('submit', event => event.preventDefault())\n\n const configKeys = Object.keys(config)\n for (let i = 0; i < configKeys.length; i++) {\n const key = configKeys[i]\n const conf = config[key]\n\n // Skip only if display attribute is explicitly set to false\n if (conf.display === false) continue\n\n const field = document.createElement('div')\n field.className = 'field'\n\n let value\n if (!conf.disabled) {\n if (typeof conf.value !== 'undefined') {\n value = conf.value\n } else if (typeof conf.number !== 'undefined') {\n const parsed = parseInt(localStorage[lsKeys[key]])\n if (!isNaN(parsed) && parsed <= conf.number.max && parsed >= conf.number.min) {\n value = parsed\n }\n } else {\n const stored = localStorage[lsKeys[key]]\n if (Array.isArray(conf.select)) {\n value = conf.select.find(sel => sel.value === stored)\n ? stored\n : undefined\n } else {\n value = stored\n }\n }\n\n // If valueHandler function exists, defer to the function,\n // otherwise pass value to global page object\n if (typeof conf.valueHandler === 'function') {\n conf.valueHandler(value)\n } else if (typeof value !== 'undefined') {\n page[key] = value\n } else if (typeof fallback[key] !== 'undefined') {\n page[key] = fallback[key]\n }\n }\n\n let control\n if (Array.isArray(conf.select)) {\n control = document.createElement('div')\n control.className = 'select is-fullwidth'\n\n const opts = []\n for (let j = 0; j < conf.select.length; j++) {\n const opt = conf.select[j]\n const selected = (value && (opt.value === String(value))) ||\n (typeof value === 'undefined' && opt.value === 'default')\n opts.push(`\n <option value=\"${opt.value}\"${selected ? ' selected' : ''}>\n ${opt.text}${opt.value === 'default' ? ' (default)' : ''}\n </option>\n `)\n }\n\n control.innerHTML = `\n <select id=\"${key}\">\n ${opts.join('\\n')}\n </select>\n `\n } else if (conf.number) {\n control = document.createElement('input')\n control.id = control.name = key\n control.className = 'input is-fullwidth'\n control.type = 'number'\n\n if (typeof conf.number.min !== 'undefined') control.min = conf.number.min\n if (typeof conf.number.max !== 'undefined') control.max = conf.number.max\n if (typeof value === 'number') control.value = value\n else if (typeof conf.number.default !== 'undefined') control.value = conf.number.default\n }\n\n let help\n if (conf.disabled) {\n if (Array.isArray(conf.select)) {\n control.querySelector('select').disabled = conf.disabled\n } else {\n control.disabled = conf.disabled\n }\n help = 'This option is currently not configurable.'\n } else if (typeof conf.help === 'string') {\n help = conf.help\n } else if (conf.help === true && typeof conf.number !== 'undefined') {\n const tmp = []\n\n if (typeof conf.number.default !== 'undefined') {\n tmp.push(`Default is ${conf.number.default}${conf.number.suffix || ''}.`)\n }\n if (typeof conf.number.min !== 'undefined') {\n tmp.push(`Min is ${conf.number.min}${conf.number.suffix || ''}.`)\n }\n if (typeof conf.number.max !== 'undefined') {\n tmp.push(`Max is ${conf.number.max}${conf.number.suffix || ''}.`)\n }\n\n help = tmp.join(' ')\n }\n\n field.innerHTML = `\n <label class=\"label\">${conf.label}</label>\n <div class=\"control\"></div>\n ${help ? `<p class=\"help\">${help}</p>` : ''}\n `\n field.querySelector('div.control').appendChild(control)\n\n form.appendChild(field)\n }\n\n const submit = document.createElement('div')\n submit.className = 'field'\n submit.innerHTML = `\n <p class=\"control\">\n <button id=\"saveConfig\" type=\"submit\" class=\"button is-danger is-outlined is-fullwidth\">\n <span class=\"icon\">\n <i class=\"icon-floppy\"></i>\n </span>\n <span>Save & reload</span>\n </button>\n </p>\n <p class=\"help\">\n This configuration will only be used in this browser.<br>\n After reloading the page, some of them will also be applied to the ShareX config that you can download by clicking on the ShareX icon below.\n </p>\n `\n\n form.appendChild(submit)\n form.querySelector('#saveConfig').addEventListener('click', () => {\n if (!form.checkValidity()) return\n\n const keys = Object.keys(config)\n .filter(key => config[key].display !== false && config[key].disabled !== true)\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i]\n\n let value\n if (typeof config[key].select !== 'undefined') {\n if (form.elements[key].value !== 'default') {\n value = form.elements[key].value\n }\n } else if (typeof config[key].number !== 'undefined') {\n const parsed = parseInt(form.elements[key].value)\n if (!isNaN(parsed) && parsed !== config[key].number.default) {\n value = Math.min(Math.max(parsed, config[key].number.min), config[key].number.max)\n }\n }\n\n if (typeof value !== 'undefined') localStorage[lsKeys[key]] = value\n else localStorage.removeItem(lsKeys[key])\n }\n\n swal({\n title: 'Woohoo!',\n text: 'Configuration saved into this browser.',\n icon: 'success'\n }).then(() => {\n window.location.reload()\n })\n })\n\n tabContent.appendChild(form)\n}\n\npage.getPrettyUploadAge = hours => {\n if (hours === 0) {\n return 'Permanent'\n } else if (hours < 1) {\n const minutes = hours * 60\n return `${minutes} minute${minutes === 1 ? '' : 's'}`\n } else if (hours >= 24) {\n const days = hours / 24\n return `${days} day${days === 1 ? '' : 's'}`\n } else {\n return `${hours} hour${hours === 1 ? '' : 's'}`\n }\n}\n\n// Handle image paste event\nwindow.addEventListener('paste', event => {\n const items = (event.clipboardData || event.originalEvent.clipboardData).items\n const index = Object.keys(items)\n for (let i = 0; i < index.length; i++) {\n const item = items[index[i]]\n if (item.kind === 'file') {\n const blob = item.getAsFile()\n /* eslint-disable-next-line compat/compat */\n const file = new File([blob], `pasted-image.${blob.type.match(/(?:[^/]*\\/)([^;]*)/)[1]}`, {\n type: blob.type\n })\n page.dropzone.addFile(file)\n }\n }\n})\n\nwindow.addEventListener('DOMContentLoaded', () => {\n if (window.cookieconsent) {\n window.cookieconsent.initialise({\n cookie: {\n name: 'cookieconsent_status',\n path: window.location.pathname,\n expiryDays: 730,\n secure: window.location.protocol === 'https:'\n },\n palette: {\n popup: {\n background: '#282828',\n text: '#eff0f1'\n },\n button: {\n background: '#209cee',\n text: '#ffffff'\n }\n },\n theme: 'classic',\n position: 'bottom-left',\n content: {\n message: 'We use cookies to offer you a better browsing experience and to analyze our traffic. You consent to our cookies if you continue to use this website.',\n dismiss: 'Got it!',\n link: 'Details in our Cookie Policy',\n href: 'cookiepolicy'\n }\n })\n }\n\n page.checkIfPublic()\n\n page.clipboardJS = new ClipboardJS('.clipboard-js')\n\n page.clipboardJS.on('success', () => {\n return swal('', 'The link has been copied to clipboard.', 'success', {\n buttons: false,\n timer: 1500\n })\n })\n\n page.clipboardJS.on('error', page.onError)\n\n page.lazyLoad = new LazyLoad({\n elements_selector: '.field.uploads img'\n })\n\n document.querySelector('#createAlbum').addEventListener('click', () => {\n page.createAlbum()\n })\n})\n"]}