React/Redux - publish component #323

Merged
bones7242 merged 80 commits from react-upload into master 2018-01-25 22:43:20 +01:00
9 changed files with 100 additions and 136 deletions
Showing only changes of commit a9d9a88360 - Show all commits

View file

@ -1,4 +0,0 @@
function sendAuthRequest (channelName, password, url) {
const params = `username=${channelName}&password=${password}`;
return postRequest(url, params);
}

View file

@ -20,17 +20,36 @@ function showChannelCreationError(msg) {
} }
function publishNewChannel (event) { function publishNewChannel (event) {
const userName = document.getElementById('new-channel-name').value; const username = document.getElementById('new-channel-name').value;
const password = document.getElementById('new-channel-password').value; const password = document.getElementById('new-channel-password').value;
// prevent default so this script can handle submission // prevent default so this script can handle submission
event.preventDefault(); event.preventDefault();
// validate submission // validate submission
validationFunctions.validateNewChannelSubmission(userName, password) validationFunctions.validateNewChannelSubmission(username, password)
.then(() => { .then(() => {
showChannelCreateInProgressDisplay(); showChannelCreateInProgressDisplay();
return sendAuthRequest(userName, password, '/signup') // post the request // return sendAuthRequest(userName, password, '/signup') // post the request
return fetch('/signup', {
method: 'POST',
body: JSON.stringify({username, password}),
headers: new Headers({
'Content-Type': 'application/json'
}),
credentials: 'include',
}) })
.then(result => { .then(function(response) {
if (response.ok){
return response.json();
} else {
throw response;
}
})
.catch(function(error) {
throw error;
})
})
.then(signupResult => {
console.log('signup success:', signupResult);
showChannelCreateDoneDisplay(); showChannelCreateDoneDisplay();
window.location = '/'; window.location = '/';
}) })
@ -40,7 +59,7 @@ function publishNewChannel (event) {
validationFunctions.showError(channelNameErrorDisplayElement, error.message); validationFunctions.showError(channelNameErrorDisplayElement, error.message);
} else { } else {
console.log('signup failure:', error); console.log('signup failure:', error);
showChannelCreationError('Unfortunately, we encountered an error while creating your channel. Please let us know in slack!'); showChannelCreationError('Unfortunately, we encountered an error while creating your channel. Please let us know in slack!', error);
} }
}) })
} }

View file

@ -1,94 +1,3 @@
function getRequest (url) {
return new Promise((resolve, reject) => {
let xhttp = new XMLHttpRequest();
xhttp.open('GET', url, true);
xhttp.responseType = 'json';
xhttp.onreadystatechange = () => {
if (xhttp.readyState === 4 ) {
if ( xhttp.status === 200) {
resolve(xhttp.response);
} else if (xhttp.status === 403) {
reject('Wrong channel name or password');
} else {
reject('request failed with status:' + xhttp.status);
};
}
};
xhttp.send();
})
}
function postRequest (url, params) {
return new Promise((resolve, reject) => {
let xhttp = new XMLHttpRequest();
xhttp.open('POST', url, true);
xhttp.responseType = 'json';
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.onreadystatechange = () => {
if (xhttp.readyState === 4 ) {
if ( xhttp.status === 200) {
resolve(xhttp.response);
} else if (xhttp.status === 401) {
reject( new AuthenticationError('Wrong channel name or password'));
} else {
reject('request failed with status:' + xhttp.status);
};
}
};
xhttp.send(params);
})
}
function createProgressBar(element, size){
var x = 0;
var adder = 1;
// create the bar holder & place it
var barHolder = document.createElement('p');
for (var i = 0; i < size; i++) {
const bar = document.createElement('span');
bar.innerText = '| ';
bar.setAttribute('class', 'progress-bar progress-bar--inactive');
barHolder.appendChild(bar);
}
element.appendChild(barHolder);
// get the bars
const bars = document.getElementsByClassName('progress-bar');
// function to update the bars' classes
function updateOneBar(){
// update the appropriate bar
if (x > -1 && x < size){
if (adder === 1){
bars[x].setAttribute('class', 'progress-bar progress-bar--active');
} else {
bars[x].setAttribute('class', 'progress-bar progress-bar--inactive');
}
}
// set x
if (x === size){
adder = -1;
} else if ( x === -1){
adder = 1;
}
// update the adder
x += adder;
};
// start updater
setInterval(updateOneBar, 300);
}
function copyToClipboard(event){
var elementToCopy = event.target.dataset.elementtocopy;
var element = document.getElementById(elementToCopy);
var errorElement = 'input-error-copy-text' + elementToCopy;
element.select();
try {
document.execCommand('copy');
} catch (err) {
validationFunctions.showError(errorElement, 'Oops, unable to copy');
}
}
// Create new error objects, that prototypically inherit from the Error constructor // Create new error objects, that prototypically inherit from the Error constructor
function FileError(message) { function FileError(message) {
this.name = 'FileError'; this.name = 'FileError';

View file

@ -1,11 +1,28 @@
function loginToChannel (event) { function loginToChannel (event) {
const userName = document.getElementById('channel-login-name-input').value; const username = document.getElementById('channel-login-name-input').value;
const password = document.getElementById('channel-login-password-input').value; const password = document.getElementById('channel-login-password-input').value;
// prevent default // prevent default
event.preventDefault() event.preventDefault()
validationFunctions.validateNewChannelLogin(userName, password) validationFunctions.validateNewChannelLogin(username, password)
.then(() => { .then(() => {
return sendAuthRequest(userName, password, '/login') return fetch('/login', {
method: 'POST',
body: JSON.stringify({username, password}),
headers: new Headers({
'Content-Type': 'application/json'
}),
credentials: 'include',
})
.then(function(response) {
if (response.ok){
return response.json();
} else {
throw response;
}
})
.catch(function(error) {
throw error;
})
}) })
.then(result => { .then(result => {
window.location = '/'; window.location = '/';

View file

@ -18,9 +18,23 @@ const validationFunctions = {
} }
}, },
// validation functions to check claim & channel name eligibility as the inputs change // validation functions to check claim & channel name eligibility as the inputs change
isChannelNameAvailable: function (name) {
return this.isNameAvailable(name, '/api/channel-is-available/');
},
isClaimNameAvailable: function (name) {
return this.isNameAvailable(name, '/api/claim-is-available/')
},
isNameAvailable: function (name, apiUrl) { isNameAvailable: function (name, apiUrl) {
console.log('isNameAvailable?', name);
const url = apiUrl + name; const url = apiUrl + name;
return getRequest(url) return fetch(url)
.then(function (response) {
return response.json();
})
.catch(error => {
console.log('isNameAvailable error', error);
throw error;
})
}, },
showError: function (errorDisplay, errorMsg) { showError: function (errorDisplay, errorMsg) {
errorDisplay.hidden = false; errorDisplay.hidden = false;
@ -38,20 +52,24 @@ const validationFunctions = {
successElement.hidden = true; successElement.hidden = true;
successElement.innerHTML = ""; successElement.innerHTML = "";
}, },
checkAvailability: function (name, successDisplayElement, errorDisplayElement, validateName, errorMessage, apiUrl) { checkChannelName: function (name) {
var successDisplayElement = document.getElementById('input-success-channel-name');
var errorDisplayElement = document.getElementById('input-error-channel-name');
var channelName = `@${name}`;
var that = this; var that = this;
try { try {
// check to make sure the characters are valid // check to make sure the characters are valid
validateName(name); that.validateChannelName(channelName);
// check to make sure it is available // check to make sure it is available
that.isNameAvailable(name, apiUrl) that.isChannelNameAvailable(channelName)
.then(function (result) { .then(function(isAvailable){
if (result === true) { console.log('isChannelNameAvailable:', isAvailable);
if (isAvailable) {
that.hideError(errorDisplayElement); that.hideError(errorDisplayElement);
that.showSuccess(successDisplayElement) that.showSuccess(successDisplayElement)
} else { } else {
that.hideSuccess(successDisplayElement); that.hideSuccess(successDisplayElement);
that.showError(errorDisplayElement, errorMessage); that.showError(errorDisplayElement, 'Sorry, that name is already taken');
} }
}) })
.catch(error => { .catch(error => {
@ -63,12 +81,6 @@ const validationFunctions = {
that.showError(errorDisplayElement, error.message); that.showError(errorDisplayElement, error.message);
} }
}, },
checkChannelName: function (name) {
const successDisplayElement = document.getElementById('input-success-channel-name');
const errorDisplayElement = document.getElementById('input-error-channel-name');
name = `@${name}`;
this.checkAvailability(name, successDisplayElement, errorDisplayElement, this.validateChannelName, 'Sorry, that name is already taken', '/api/channel-is-available/');
},
// validation function which checks all aspects of a new channel submission // validation function which checks all aspects of a new channel submission
validateNewChannelSubmission: function (userName, password) { validateNewChannelSubmission: function (userName, password) {
const channelName = `@${userName}`; const channelName = `@${userName}`;
@ -87,16 +99,15 @@ const validationFunctions = {
return reject(error); return reject(error);
} }
// 3. if all validation passes, check availability of the name // 3. if all validation passes, check availability of the name
that.isNameAvailable(channelName, '/api/channel-is-available/') // validate the availability that.isChannelNameAvailable(channelName)
.then(function(result) { .then(function(isAvailable) {
if (result) { if (isAvailable) {
resolve(); resolve();
} else { } else {
reject(new ChannelNameError('Sorry, that name is already taken')); reject(new ChannelNameError('Sorry, that name is already taken'));
} }
}) })
.catch(function(error) { .catch(function(error) {
console.log('error evaluating channel name availability', error);
reject(error); reject(error);
}); });
}); });

View file

@ -18,9 +18,6 @@
<body id="main-body"> <body id="main-body">
<script src="/assets/js/generalFunctions.js"></script> <script src="/assets/js/generalFunctions.js"></script>
<script src="/assets/js/validationFunctions.js"></script> <script src="/assets/js/validationFunctions.js"></script>
<script src="/assets/js/authFunctions.js"></script>
<script src="/assets/js/loginFunctions.js"></script>
<script src="/assets/js/createChannelFunctions.js"></script>
{{{ body }}} {{{ body }}}
</body> </body>
</html> </html>

View file

@ -113,4 +113,15 @@
toggle.dataset.status = "closed"; toggle.dataset.status = "closed";
} }
} }
function copyToClipboard(event){
var elementToCopy = event.target.dataset.elementtocopy;
var element = document.getElementById(elementToCopy);
var errorElement = 'input-error-copy-text' + elementToCopy;
element.select();
try {
document.execCommand('copy');
} catch (err) {
validationFunctions.showError(errorElement, 'Oops, unable to copy');
}
}
</script> </script>

View file

@ -29,9 +29,11 @@
<div id="channel-publish-in-progress" hidden="true"> <div id="channel-publish-in-progress" hidden="true">
<p>Creating your new channel. This may take a few seconds...</p> <p>Creating your new channel. This may take a few seconds...</p>
<div id="create-channel-progress-bar"></div> {{> progressBar}}
</div> </div>
<div id="channel-publish-done" hidden="true"> <div id="channel-publish-done" hidden="true">
<p>Your channel has been successfully created!</p> <p>Your channel has been successfully created!</p>
</div> </div>
<script src="/assets/js/createChannelFunctions.js"></script>

View file

@ -24,3 +24,5 @@
<button class="button--primary" onclick="loginToChannel(event)">Authenticate</button> <button class="button--primary" onclick="loginToChannel(event)">Authenticate</button>
</div> </div>
</form> </form>
<script src="/assets/js/loginFunctions.js"></script>