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) {
const userName = document.getElementById('new-channel-name').value;
const username = document.getElementById('new-channel-name').value;
const password = document.getElementById('new-channel-password').value;
// prevent default so this script can handle submission
event.preventDefault();
// validate submission
validationFunctions.validateNewChannelSubmission(userName, password)
validationFunctions.validateNewChannelSubmission(username, password)
.then(() => {
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(function(response) {
if (response.ok){
return response.json();
} else {
throw response;
}
})
.catch(function(error) {
throw error;
})
})
.then(result => {
.then(signupResult => {
console.log('signup success:', signupResult);
showChannelCreateDoneDisplay();
window.location = '/';
})
@ -40,7 +59,7 @@ function publishNewChannel (event) {
validationFunctions.showError(channelNameErrorDisplayElement, error.message);
} else {
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
function FileError(message) {
this.name = 'FileError';

View file

@ -1,11 +1,28 @@
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;
// prevent default
event.preventDefault()
validationFunctions.validateNewChannelLogin(userName, password)
validationFunctions.validateNewChannelLogin(username, password)
.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 => {
window.location = '/';

View file

@ -18,9 +18,23 @@ const validationFunctions = {
}
},
// 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) {
console.log('isNameAvailable?', 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) {
errorDisplay.hidden = false;
@ -38,37 +52,35 @@ const validationFunctions = {
successElement.hidden = true;
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;
try {
// check to make sure the characters are valid
validateName(name);
that.validateChannelName(channelName);
// check to make sure it is available
that.isNameAvailable(name, apiUrl)
.then(function (result) {
if (result === true) {
that.hideError(errorDisplayElement);
that.showSuccess(successDisplayElement)
} else {
that.hideSuccess(successDisplayElement);
that.showError(errorDisplayElement, errorMessage);
}
})
.catch(error => {
that.hideSuccess(successDisplayElement);
that.showError(errorDisplayElement, error.message);
});
that.isChannelNameAvailable(channelName)
.then(function(isAvailable){
console.log('isChannelNameAvailable:', isAvailable);
if (isAvailable) {
that.hideError(errorDisplayElement);
that.showSuccess(successDisplayElement)
} else {
that.hideSuccess(successDisplayElement);
that.showError(errorDisplayElement, 'Sorry, that name is already taken');
}
})
.catch(error => {
that.hideSuccess(successDisplayElement);
that.showError(errorDisplayElement, error.message);
});
} catch (error) {
that.hideSuccess(successDisplayElement);
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
validateNewChannelSubmission: function (userName, password) {
const channelName = `@${userName}`;
@ -87,16 +99,15 @@ const validationFunctions = {
return reject(error);
}
// 3. if all validation passes, check availability of the name
that.isNameAvailable(channelName, '/api/channel-is-available/') // validate the availability
.then(function(result) {
if (result) {
that.isChannelNameAvailable(channelName)
.then(function(isAvailable) {
if (isAvailable) {
resolve();
} else {
reject(new ChannelNameError('Sorry, that name is already taken'));
}
})
.catch(function(error) {
console.log('error evaluating channel name availability', error);
reject(error);
});
});

View file

@ -18,9 +18,6 @@
<body id="main-body">
<script src="/assets/js/generalFunctions.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>
</html>

View file

@ -113,4 +113,15 @@
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>

View file

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

View file

@ -23,4 +23,6 @@
<div class="row row--wide">
<button class="button--primary" onclick="loginToChannel(event)">Authenticate</button>
</div>
</form>
</form>
<script src="/assets/js/loginFunctions.js"></script>