diff --git a/helpers/libraries/publishHelpers.js b/helpers/libraries/publishHelpers.js index 460aab09..7652fa1f 100644 --- a/helpers/libraries/publishHelpers.js +++ b/helpers/libraries/publishHelpers.js @@ -24,11 +24,10 @@ module.exports = { default: throw new Error('The ' + file.Type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.'); } - - // validate name + // validate claim name const invalidCharacters = /[^A-Za-z0-9,-]/.exec(name); if (invalidCharacters) { - throw new Error('The name you provided is not allowed. Please use A-Z, a-z, 0-9, and "-" only.'); + throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and "-"'); } // validate license if ((license.indexOf('Public Domain') === -1) && (license.indexOf('Creative Commons') === -1)) { diff --git a/public/assets/js/index.js b/public/assets/js/index.js deleted file mode 100644 index e7e99d5e..00000000 --- a/public/assets/js/index.js +++ /dev/null @@ -1,75 +0,0 @@ -// define variables -var socket = io(); -var uploader = new SocketIOFileUpload(socket); -var stagedFiles = null; - -/* configure the submit button */ -function publishSelectedImage(event) { - event.preventDefault(); - // validate inputs - var name = document.getElementById('publish-name').value; - try { - validateSubmission(stagedFiles, name); - } catch (error) { - if (error.name === 'FileError'){ - showError('input-error-file-selection', error.message); - } else if (error.name === 'NameError') { - showError('input-error-claim-name', error.message); - } else { - showError('input-error-publish-submit', error.message); - } - return; - } - // make sure the name is available then start the upload - validateClaimName(name) - .then(function() { - uploader.submitFiles(stagedFiles); //note: must pass the file as part of an array. - }) - .catch(function(error) { - showError('input-error-claim-name', error); - }) -}; - -/* socketio-file-upload listeners */ -uploader.addEventListener('start', function(event){ - var name = document.getElementById('publish-name').value; - var license = document.getElementById('publish-license').value; - var nsfw = document.getElementById('publish-nsfw').checked; - event.file.meta.name = name; - event.file.meta.license = license; - event.file.meta.nsfw = nsfw; - event.file.meta.type = stagedFiles[0].type; - // re-set the html in the publish area - document.getElementById('publish-active-area').innerHTML = '
'; - // start a progress animation - createProgressBar(document.getElementById('progress-bar'), 12); - // google analytics - ga('send', { - hitType: 'event', - eventCategory: 'publish', - eventAction: name - }); -}); -uploader.addEventListener('progress', function(event){ - var percent = event.bytesLoaded / event.file.size * 100; - updatePublishStatus('File is ' + percent.toFixed(2) + '% loaded to the server'); -}); - -/* socket.io message listeners */ -socket.on('publish-status', function(msg){ - updatePublishStatus(msg); -}); -socket.on('publish-failure', function(msg){ - document.getElementById('publish-active-area').innerHTML = '--(✖╭╮✖)→
' + JSON.stringify(msg) + '
For help, post the above error text in the #speech channel on the lbry slack'; -}); - -socket.on('publish-complete', function(msg){ - var publishResults; - var showUrl = '/show/' + msg.name + '/' + msg.result.claim_id; - // build new publish area - publishResults = 'Your publish is complete! You are being redirected to it now.
'; - publishResults += ''; - // update publish area - document.getElementById('publish-active-area').innerHTML = publishResults; - window.location.href = showUrl; -}); \ No newline at end of file diff --git a/public/assets/js/publishFunctions.js b/public/assets/js/publishFunctions.js index b93a4f55..88e7fc38 100644 --- a/public/assets/js/publishFunctions.js +++ b/public/assets/js/publishFunctions.js @@ -2,7 +2,7 @@ function updatePublishStatus(msg){ document.getElementById('publish-status').innerHTML = msg; } - +// validation function which checks the proposed file's type, size, and name function validateFile(file) { if (!file) { throw new Error('no file provided'); @@ -22,28 +22,28 @@ function validateFile(file) { } break; default: - throw new Error('The ' + file.Type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.') + throw new Error(file.type + ' is not supported a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.') } + // validate the file name (note: different from the lbry claim name) + var invalidCharacter = /[^\w.-\s()]/g.exec(file.name); + if (invalidCharacter) { + throw new Error('Special characters, such as "' + invalidCharacter + '", are not allowed in the file name.'); + }; } - -function validateSubmission(stagedFiles, name){ - // make sure only 1 file was selected - if (!stagedFiles) { - throw new FileError("Please select a file"); - } else if (stagedFiles.length > 1) { - throw new FileError("Only one file is allowed at a time"); - } - // validate 'name' field - var invalidCharacters = /[^A-Za-z0-9,-]/.exec(name); - if (invalidCharacters) { - throw new NameError(invalidCharacters + ' is not allowed. A-Z, a-z, 0-9, and "-" only.'); - } else if (name.length < 1) { - throw new NameError("You must enter a name for your claim"); - } -} - +// validation function that checks to make sure the claim name is not already claimed function validateClaimName (name) { var deferred = new Promise(function(resolve, reject) { + // validate the characters in the 'name' field + if (name.length < 1) { + reject(new NameError("You must enter a name for your claim")); + return; + } + var invalidCharacters = /[^A-Za-z0-9,-]/g.exec(name); + if (invalidCharacters) { + reject(new NameError('"' + invalidCharacters + '" is not allowed. Use only the following characters: A-Z, a-z, 0-9, and "-"')); + return; + } + // make sure the claim name is still available var xhttp; xhttp = new XMLHttpRequest(); xhttp.open('GET', '/api/isClaimAvailable/' + name, true); @@ -54,7 +54,7 @@ function validateClaimName (name) { if (this.response == true) { resolve(); } else { - reject("That name has already been claimed by spee.ch. Please choose a different name."); + reject( new NameError("That name has already been claimed by spee.ch. Please choose a different name.")); } } else { reject("request to check claim name failed with status:" + this.status); @@ -65,41 +65,87 @@ function validateClaimName (name) { }); return deferred; } +// validation function which checks all aspects of the publish submission +function validateSubmission(stagedFiles, name){ + var deferred = new Promise(function (resolve, reject) { + // make sure only 1 file was selected + if (!stagedFiles) { + reject(new FileError("Please select a file")); + } else if (stagedFiles.length > 1) { + reject(new FileError("Only one file is allowed at a time")); + } + // validate the file's name, type, and size + try { + validateFile(stagedFiles[0]); + } catch (error) { + reject(error); + } + // make sure the claim name has not already been used + validateClaimName(name) + .then(function() { + resolve(); + }) + .catch(function(error) { + reject(error); + }) + }); + return deferred; +} -/* regular publish helper functions */ +/* publish helper functions */ +// When a file is selected for publish, validate that file and +// stage it so it will be ready when the publish button is clicked. function previewAndStageFile(selectedFile){ var previewHolder = document.getElementById('asset-preview-holder'); var dropzone = document.getElementById('drop-zone'); var previewReader = new FileReader(); var nameInput = document.getElementById('publish-name'); - // validate the file + // validate the file's name, type, and size try { validateFile(selectedFile); } catch (error) { showError('input-error-file-selection', error.message); return; } - // set the preview - if (selectedFile.type === 'video/mp4') { - - } else { + // set the image preview, if a preview was provided + if (selectedFile.type !== 'video/mp4') { previewReader.readAsDataURL(selectedFile); previewReader.onloadend = function () { dropzone.style.display = 'none'; previewHolder.style.display = 'block'; - previewHolder.innerHTML = ''; - + previewHolder.innerHTML = ''; }; } // set the name input value to the image name if none is set yet if (nameInput.value === "") { - nameInput.value = selectedFile.name.substring(0, selectedFile.name.indexOf('.')); + var filename = selectedFile.name.substring(0, selectedFile.name.indexOf('.')) + nameInput.value = filename.replace(/\s+/g, '-');; } // store the selected file for upload stagedFiles = [selectedFile]; } +// Validate the publish submission and then trigger publishing. +function publishSelectedImage(event) { + event.preventDefault(); + var name = document.getElementById('publish-name').value; + validateSubmission(stagedFiles, name) + .then(function() { + uploader.submitFiles(stagedFiles); + }) + .catch(function(error) { + if (error.name === 'FileError'){ + showError('input-error-file-selection', error.message); + } else if (error.name === 'NameError') { + showError('input-error-claim-name', error.message); + } else { + showError('input-error-publish-submit', error.message); + } + return; + }) +}; + /* drop zone functions */ function drop_handler(ev) { @@ -127,52 +173,4 @@ function dragend_handler(ev) { } else { ev.dataTransfer.clearData(); } -} - -/* meme publish functions */ - -function startPublish() { - //download the image - var dataUrl = canvas.toDataURL('image/jpeg'); // canvas defined in memeDraw.js - var blob = dataURItoBlob(dataUrl) - var fileName = nameInput.value + ".jpeg"; //note: need to dynamically grab type - var file = new File([blob], fileName, {type: 'image/jpeg', lastModified: Date.now()}); - stageAndPublish(file); -}; - -function stageAndPublish(file) { - var name = nameInput.value; - var invalidCharacters = /[^A-Za-z0-9,-]/.exec(name); - // validate 'name' - if (invalidCharacters) { - showError('input-error-claim-name', invalidCharacters + ' is not allowed. A-Z, a-z, 0-9, "_" and "-" only.'); - return; - } else if (name.length < 1) { - showError('input-error-claim-name', 'You must enter a name for your claim'); - return; - } - // stage files - stagedFiles = [file]; // stores the selected file for - // make sure a file was selected - if (stagedFiles) { - // make sure only 1 file was selected - if (stagedFiles.length < 1) { - showError('input-error-file-selection', 'A file is needed'); - return; - } - // make sure the content type is acceptable - switch (stagedFiles[0].type) { - case "image/png": - case "image/jpeg": - case "image/gif": - case "video/mp4": - uploader.submitFiles(stagedFiles); - break; - default: - showError('input-error-publish-submit', 'Only .png, .jpeg, .gif, and .mp4 files are currently supported'); - break; - } - } else { - showError('input-error-file-selection', 'Please select a file'); - } } \ No newline at end of file diff --git a/views/index.handlebars b/views/index.handlebars index 233e19ae..4456fd4c 100644 --- a/views/index.handlebars +++ b/views/index.handlebars @@ -10,7 +10,58 @@ - - + diff --git a/views/partials/trendingAssets.handlebars b/views/partials/trendingAssets.handlebars index 538c31d4..8c9a7043 100644 --- a/views/partials/trendingAssets.handlebars +++ b/views/partials/trendingAssets.handlebars @@ -26,7 +26,6 @@