From 7c1a0f2e6602982cff9101d8a90f86f7bf0f2981 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Fri, 28 Jul 2017 14:39:39 -0700 Subject: [PATCH] removed file name verification from front end and updated claim input validation --- public/assets/css/generalStyle.css | 1 + public/assets/js/generalFunctions.js | 6 ++ public/assets/js/publishFunctions.js | 95 +----------------- public/assets/js/validationFunctions.js | 120 +++++++++++++++++++++++ views/index.handlebars | 8 +- views/partials/publish.handlebars | 38 +++++-- views/partials/trendingAssets.handlebars | 7 +- 7 files changed, 165 insertions(+), 110 deletions(-) create mode 100644 public/assets/js/validationFunctions.js diff --git a/public/assets/css/generalStyle.css b/public/assets/css/generalStyle.css index c71a3783..6a3f9dbe 100644 --- a/public/assets/css/generalStyle.css +++ b/public/assets/css/generalStyle.css @@ -123,6 +123,7 @@ table { .input-error { font-weight: bold; color: red; + font-size: small; } @media (max-width: 1250px) { diff --git a/public/assets/js/generalFunctions.js b/public/assets/js/generalFunctions.js index 0556f0c5..129af6fb 100644 --- a/public/assets/js/generalFunctions.js +++ b/public/assets/js/generalFunctions.js @@ -61,6 +61,12 @@ function showError(elementId, errorMsg) { errorDisplay.innerText = errorMsg; } +function clearError(elementId,) { + var errorDisplay = document.getElementById(elementId); + errorDisplay.hidden = true; + errorDisplay.innerText = ''; +} + // Create new error objects, that prototypically inherit from the Error constructor function FileError(message) { this.name = 'FileError'; diff --git a/public/assets/js/publishFunctions.js b/public/assets/js/publishFunctions.js index 58bd51c1..552ecd0d 100644 --- a/public/assets/js/publishFunctions.js +++ b/public/assets/js/publishFunctions.js @@ -2,96 +2,6 @@ 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'); - } - // validate size and type - switch (file.type) { - case 'image/jpeg': - case 'image/jpg': - case 'image/png': - case 'image/gif': - if (file.size > 10000000){ - throw new Error('Sorry, images are limited to 10 megabytes.'); - } - break; - case 'video/mp4': - if (file.size > 50000000){ - throw new Error('Sorry, videos are limited to 50 megabytes.'); - } - break; - default: - 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.'); - }; -} -// 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); - xhttp.responseType = 'json'; - xhttp.onreadystatechange = function() { - if (this.readyState == 4 ) { - if ( this.status == 200) { - if (this.response == true) { - resolve(); - } else { - 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); - }; - } - }; - xhttp.send(); - }); - 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; -} /* publish helper functions */ @@ -115,13 +25,14 @@ function previewAndStageFile(selectedFile){ previewReader.onloadend = function () { dropzone.style.display = 'none'; previewHolder.style.display = 'block'; - previewHolder.innerHTML = 'image preview'; + previewHolder.innerHTML = 'image preview'; }; } // set the name input value to the image name if none is set yet if (nameInput.value === "") { var filename = selectedFile.name.substring(0, selectedFile.name.indexOf('.')) - nameInput.value = filename.replace(/\s+/g, '-');; + nameInput.value = cleanseClaimName(filename); + checkClaimName(nameInput.value); } // store the selected file for upload stagedFiles = [selectedFile]; diff --git a/public/assets/js/validationFunctions.js b/public/assets/js/validationFunctions.js new file mode 100644 index 00000000..92d64aee --- /dev/null +++ b/public/assets/js/validationFunctions.js @@ -0,0 +1,120 @@ + + +// validation function which checks the proposed file's type, size, and name +function validateFile(file) { + if (!file) { + throw new Error('no file provided'); + } + // validate size and type + switch (file.type) { + case 'image/jpeg': + case 'image/jpg': + case 'image/png': + case 'image/gif': + if (file.size > 10000000){ + throw new Error('Sorry, images are limited to 10 megabytes.'); + } + break; + case 'video/mp4': + if (file.size > 50000000){ + throw new Error('Sorry, videos are limited to 50 megabytes.'); + } + break; + default: + throw new Error(file.type + ' is not a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.') + } +} +// validation function that checks to make sure the claim name is not already claimed +function isNameAvailable (name) { + var deferred = new Promise(function(resolve, reject) { + // make sure the claim name is still available + var xhttp; + xhttp = new XMLHttpRequest(); + xhttp.open('GET', '/api/isClaimAvailable/' + name, true); + xhttp.responseType = 'json'; + xhttp.onreadystatechange = function() { + if (this.readyState == 4 ) { + if ( this.status == 200) { + if (this.response == true) { + resolve(); + } else { + reject( new NameError("That name has already been claimed by another user. Please choose a different name.")); + } + } else { + reject("request to check claim name failed with status:" + this.status); + }; + } + }; + xhttp.send(); + }); + return deferred; +} +// validation function that checks to make sure the claim name is valid +function validateClaimName (name) { + // ensure a name was entered + if (name.length < 1) { + throw new NameError("You must enter a name for your claim"); + } + // validate the characters in the 'name' field + const invalidCharacters = /[^A-Za-z0-9,-]/g.exec(name); + if (invalidCharacters) { + throw new NameError('"' + invalidCharacters + '" characters are not allowed in the title.'); + } +} + +function cleanseClaimName(name) { + name = name.replace(/\s+/g, '-'); // replace spaces with dashes + name = name.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-' + return name; +} +// validaiton function to check claim name as the input changes +function checkClaimName(name){ + try { + // check to make sure the characters are valid + validateClaimName(name); + clearError('input-error-claim-name'); + // check to make sure it is availabe + isNameAvailable(name) + .then(function() { + document.getElementById('claim-name-available').hidden = false; + }) + .catch(function(error) { + document.getElementById('claim-name-available').hidden = true; + showError('input-error-claim-name', error.message); + }); + } catch (error) { + showError('input-error-claim-name', error.message); + document.getElementById('claim-name-available').hidden = true; + } +} +// 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 + try { + validateClaimName(name); + } catch (error) { + reject(error); + } + isNameAvailable(name) + .then(function() { + resolve(); + }) + .catch(function(error) { + reject(error); + }); + }); + return deferred; +} \ No newline at end of file diff --git a/views/index.handlebars b/views/index.handlebars index 91f80c88..125deae6 100644 --- a/views/index.handlebars +++ b/views/index.handlebars @@ -11,6 +11,7 @@ + diff --git a/views/partials/publish.handlebars b/views/partials/publish.handlebars index fd18d89b..e878add5 100644 --- a/views/partials/publish.handlebars +++ b/views/partials/publish.handlebars @@ -1,21 +1,19 @@

Publish

-
+

Drag and drop your file here, or choose your file below.

-
- -
+
-
- Spee.ch/ + Spee.ch/ +

@@ -29,10 +27,34 @@

- - + +

By clicking 'Publish' I attest that I have read and agree to the LBRY terms of service.

+ + \ No newline at end of file diff --git a/views/partials/trendingAssets.handlebars b/views/partials/trendingAssets.handlebars index 9532b449..9c7999e5 100644 --- a/views/partials/trendingAssets.handlebars +++ b/views/partials/trendingAssets.handlebars @@ -7,13 +7,13 @@ {{#unless this.nsfw}} {{#ifConditional this.fileType '===' 'video/mp4'}} - {{/unless}} @@ -29,8 +29,7 @@ itemSelector: '.grid-item' }); - function resetLayout() { - console.log('resetting layout'); + function resetTrendingLayout() { msnry.layout(); }