set up basic AssetDisplay functionality and removed unnecessary handlebars/js
This commit is contained in:
parent
bfa623ec17
commit
97a6254370
21 changed files with 238 additions and 651 deletions
|
@ -1,139 +0,0 @@
|
|||
const Asset = function () {
|
||||
this.data = {};
|
||||
this.addPlayPauseToVideo = function () {
|
||||
const that = this;
|
||||
const video = document.getElementById('video-asset');
|
||||
if (video) {
|
||||
// add event listener for click
|
||||
video.addEventListener('click', ()=> {
|
||||
that.playOrPause(video);
|
||||
});
|
||||
// add event listener for space bar
|
||||
document.body.onkeyup = (event) => {
|
||||
if (event.keyCode == 32) {
|
||||
that.playOrPause(video);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
this.playOrPause = function(video){
|
||||
if (video.paused == true) {
|
||||
video.play();
|
||||
}
|
||||
else{
|
||||
video.pause();
|
||||
}
|
||||
};
|
||||
this.showAsset = function () {
|
||||
this.hideAssetStatus();
|
||||
this.showAssetHolder();
|
||||
if (!this.data.src) {
|
||||
return console.log('error: src is not set')
|
||||
}
|
||||
if (!this.data.contentType) {
|
||||
return console.log('error: contentType is not set')
|
||||
}
|
||||
if (this.data.contentType === 'video/mp4') {
|
||||
this.showVideo();
|
||||
} else {
|
||||
this.showImage();
|
||||
}
|
||||
};
|
||||
this.showVideo = function () {
|
||||
console.log('showing video', this.data.src);
|
||||
const video = document.getElementById('video-asset');
|
||||
const source = document.createElement('source');
|
||||
source.setAttribute('src', this.data.src);
|
||||
video.appendChild(source);
|
||||
video.play();
|
||||
};
|
||||
this.showImage = function () {
|
||||
console.log('showing image', this.data.src);
|
||||
const asset = document.getElementById('image-asset');
|
||||
asset.setAttribute('src', this.data.src);
|
||||
};
|
||||
this.hideAssetStatus = function () {
|
||||
const assetStatus = document.getElementById('asset-status');
|
||||
assetStatus.hidden = true;
|
||||
};
|
||||
this.showAssetHolder =function () {
|
||||
const assetHolder = document.getElementById('asset-holder');
|
||||
assetHolder.hidden = false;
|
||||
};
|
||||
this.showSearchMessage = function () {
|
||||
const searchMessage = document.getElementById('searching-message');
|
||||
searchMessage.hidden = false;
|
||||
};
|
||||
this.showFailureMessage = function (msg) {
|
||||
console.log(msg);
|
||||
const searchMessage = document.getElementById('searching-message');
|
||||
const failureMessage = document.getElementById('failure-message');
|
||||
const errorMessage = document.getElementById('error-message');
|
||||
searchMessage.hidden = true;
|
||||
failureMessage.hidden = false;
|
||||
errorMessage.innerText = msg;
|
||||
};
|
||||
this.checkFileAndRenderAsset = function () {
|
||||
const that = this;
|
||||
this.isFileAvailable()
|
||||
.then(isAvailable => {
|
||||
if (!isAvailable) {
|
||||
console.log('file is not yet available');
|
||||
that.showSearchMessage();
|
||||
return that.getAssetOnSpeech();
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
that.showAsset();
|
||||
})
|
||||
.catch(error => {
|
||||
that.showFailureMessage(error);
|
||||
})
|
||||
};
|
||||
this.isFileAvailable = function () {
|
||||
console.log(`checking if file is available for ${this.data.claimName}#${this.data.claimId}`)
|
||||
const uri = `/api/file-is-available/${this.data.claimName}/${this.data.claimId}`;
|
||||
const xhr = new XMLHttpRequest();
|
||||
return new Promise((resolve, reject) => {
|
||||
xhr.open("GET", uri, true);
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == 4) {
|
||||
const response = JSON.parse(xhr.response);
|
||||
if (xhr.status == 200) {
|
||||
console.log('isFileAvailable succeeded:', response);
|
||||
if (response.message === true) {
|
||||
resolve(true);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
} else {
|
||||
console.log('isFileAvailable failed:', response);
|
||||
reject('Well this sucks, but we can\'t seem to phone home');
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
})
|
||||
};
|
||||
this.getAssetOnSpeech = function() {
|
||||
console.log(`getting claim for ${this.data.claimName}#${this.data.claimId}`)
|
||||
const uri = `/api/claim-get/${this.data.claimName}/${this.data.claimId}`;
|
||||
const xhr = new XMLHttpRequest();
|
||||
return new Promise((resolve, reject) => {
|
||||
xhr.open("GET", uri, true);
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == 4) {
|
||||
const response = JSON.parse(xhr.response);
|
||||
if (xhr.status == 200) {
|
||||
console.log('getAssetOnSpeech succeeded:', response)
|
||||
resolve(true);
|
||||
} else {
|
||||
console.log('getAssetOnSpeech failed:', response);
|
||||
reject(response.message);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
})
|
||||
};
|
||||
};
|
|
@ -1,65 +0,0 @@
|
|||
// display the content that shows channel creation has started
|
||||
function showChannelCreateInProgressDisplay () {
|
||||
const publishChannelForm = document.getElementById('publish-channel-form');
|
||||
const inProgress = document.getElementById('channel-publish-in-progress');
|
||||
publishChannelForm.hidden = true;
|
||||
inProgress.hidden = false;
|
||||
}
|
||||
|
||||
// display the content that shows channel creation is done
|
||||
function showChannelCreateDoneDisplay() {
|
||||
const inProgress = document.getElementById('channel-publish-in-progress');
|
||||
inProgress.hidden=true;
|
||||
const done = document.getElementById('channel-publish-done');
|
||||
done.hidden = false;
|
||||
}
|
||||
|
||||
function showChannelCreationError(msg) {
|
||||
const inProgress = document.getElementById('channel-publish-in-progress');
|
||||
inProgress.innerText = msg;
|
||||
}
|
||||
|
||||
function publishNewChannel (event) {
|
||||
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)
|
||||
.then(() => {
|
||||
showChannelCreateInProgressDisplay();
|
||||
// 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(signupResult => {
|
||||
console.log('signup success:', signupResult);
|
||||
showChannelCreateDoneDisplay();
|
||||
window.location = '/';
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.name === 'ChannelNameError' || error.name === 'ChannelPasswordError'){
|
||||
const channelNameErrorDisplayElement = document.getElementById('input-error-channel-name');
|
||||
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!', error);
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
function loginToChannel (event) {
|
||||
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)
|
||||
.then(() => {
|
||||
return fetch('/login', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({username, password}),
|
||||
headers: new Headers({
|
||||
'Content-Type': 'application/json'
|
||||
}),
|
||||
credentials: 'include',
|
||||
})
|
||||
.then(function(response) {
|
||||
console.log(response);
|
||||
if (response.ok){
|
||||
return response.json();
|
||||
} else {
|
||||
throw response;
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
throw error;
|
||||
})
|
||||
})
|
||||
.then(function({success, message}) {
|
||||
if (success) {
|
||||
window.location = '/';
|
||||
} else {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
const loginErrorDisplayElement = document.getElementById('login-error-display-element');
|
||||
if (error.message){
|
||||
validationFunctions.showError(loginErrorDisplayElement, error.message);
|
||||
} else {
|
||||
validationFunctions.showError(loginErrorDisplayElement, 'There was an error logging into your channel');
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
const ProgressBar = function() {
|
||||
this.data = {
|
||||
x: 0,
|
||||
adder: 1,
|
||||
bars: [],
|
||||
};
|
||||
this.barHolder = document.getElementById('bar-holder');
|
||||
this.createProgressBar = function (size) {
|
||||
this.data['size'] = size;
|
||||
for (var i = 0; i < size; i++) {
|
||||
const bar = document.createElement('span');
|
||||
bar.innerText = '| ';
|
||||
bar.setAttribute('class', 'progress-bar progress-bar--inactive');
|
||||
this.barHolder.appendChild(bar);
|
||||
this.data.bars.push(bar);
|
||||
}
|
||||
};
|
||||
this.startProgressBar = function () {
|
||||
this.updateInterval = setInterval(this.updateProgressBar.bind(this), 300);
|
||||
};
|
||||
this.updateProgressBar = function () {
|
||||
const x = this.data.x;
|
||||
const adder = this.data.adder;
|
||||
const size = this.data.size;
|
||||
// update the appropriate bar
|
||||
if (x > -1 && x < size){
|
||||
if (adder === 1){
|
||||
this.data.bars[x].setAttribute('class', 'progress-bar progress-bar--active');
|
||||
} else {
|
||||
this.data.bars[x].setAttribute('class', 'progress-bar progress-bar--inactive');
|
||||
}
|
||||
}
|
||||
// update adder
|
||||
if (x === size){
|
||||
this.data['adder'] = -1;
|
||||
} else if ( x === -1){
|
||||
this.data['adder'] = 1;
|
||||
}
|
||||
// update x
|
||||
this.data['x'] = x + adder;
|
||||
};
|
||||
this.stopProgressBar = function () {
|
||||
clearInterval(this.updateInterval);
|
||||
};
|
||||
};
|
|
@ -1,132 +0,0 @@
|
|||
// validation function which checks the proposed file's type, size, and name
|
||||
const validationFunctions = {
|
||||
validateChannelName: function (name) {
|
||||
name = name.substring(name.indexOf('@') + 1);
|
||||
// ensure a name was entered
|
||||
if (name.length < 1) {
|
||||
throw new ChannelNameError("You must enter a name for your channel");
|
||||
}
|
||||
// validate the characters in the 'name' field
|
||||
const invalidCharacters = /[^A-Za-z0-9,-,@]/g.exec(name);
|
||||
if (invalidCharacters) {
|
||||
throw new ChannelNameError('"' + invalidCharacters + '" characters are not allowed');
|
||||
}
|
||||
},
|
||||
validatePassword: function (password) {
|
||||
if (password.length < 1) {
|
||||
throw new ChannelPasswordError("You must enter a password for you channel");
|
||||
}
|
||||
},
|
||||
// validation functions to check claim & channel name eligibility as the inputs change
|
||||
isChannelNameAvailable: function (name) {
|
||||
return this.isNameAvailable(name, '/api/channel-is-available/');
|
||||
},
|
||||
isNameAvailable: function (name, apiUrl) {
|
||||
console.log('isNameAvailable?', name);
|
||||
const url = apiUrl + name;
|
||||
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;
|
||||
errorDisplay.innerText = errorMsg;
|
||||
},
|
||||
hideError: function (errorDisplay) {
|
||||
errorDisplay.hidden = true;
|
||||
errorDisplay.innerText = '';
|
||||
},
|
||||
showSuccess: function (successElement) {
|
||||
successElement.hidden = false;
|
||||
successElement.innerHTML = "✔";
|
||||
},
|
||||
hideSuccess: function (successElement) {
|
||||
successElement.hidden = true;
|
||||
successElement.innerHTML = "";
|
||||
},
|
||||
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
|
||||
that.validateChannelName(channelName);
|
||||
// check to make sure it is available
|
||||
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);
|
||||
}
|
||||
},
|
||||
// validation function which checks all aspects of a new channel submission
|
||||
validateNewChannelSubmission: function (userName, password) {
|
||||
const channelName = `@${userName}`;
|
||||
var that = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
// 1. validate name
|
||||
try {
|
||||
that.validateChannelName(channelName);
|
||||
} catch (error) {
|
||||
return reject(error);
|
||||
}
|
||||
// 2. validate password
|
||||
try {
|
||||
that.validatePassword(password);
|
||||
} catch (error) {
|
||||
return reject(error);
|
||||
}
|
||||
// 3. if all validation passes, check availability of the name
|
||||
that.isChannelNameAvailable(channelName)
|
||||
.then(function(isAvailable) {
|
||||
if (isAvailable) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new ChannelNameError('Sorry, that name is already taken'));
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
// validation function which checks all aspects of a new channel login
|
||||
validateNewChannelLogin: function (userName, password) {
|
||||
const channelName = `@${userName}`;
|
||||
var that = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
// 1. validate name
|
||||
try {
|
||||
that.validateChannelName(channelName);
|
||||
} catch (error) {
|
||||
return reject(error);
|
||||
}
|
||||
// 2. validate password
|
||||
try {
|
||||
that.validatePassword(password);
|
||||
} catch (error) {
|
||||
return reject(error);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
};
|
|
@ -1,11 +1,153 @@
|
|||
import React from 'react';
|
||||
import ProgressBar from 'components/ProgressBar';
|
||||
import Request from 'utils/request';
|
||||
|
||||
const AssetDisplay = ({ name, claimId }) => {
|
||||
const LOCAL_CHECK = 'LOCAL_CHECK';
|
||||
const SEARCHING = 'SEARCHING';
|
||||
const UNAVAILABLE = 'UNAVAILABLE';
|
||||
const AVAILABLE = 'AVAILABLE';
|
||||
|
||||
class AssetDisplay extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
error : null,
|
||||
status : LOCAL_CHECK,
|
||||
thumbnail : this.props.thumbnail,
|
||||
src : `/${this.props.claimId}}/${this.props.name}.${this.props.fileExt}`,
|
||||
name : this.props.name,
|
||||
claimId : this.props.claimId,
|
||||
fileExt : this.props.fileExt,
|
||||
contentType: this.props.contentType,
|
||||
};
|
||||
this.checkIfLocalFileAvailable = this.checkIfLocalFileAvailable.bind(this);
|
||||
this.triggerGetAssetOnSpeech = this.triggerGetAssetOnSpeech.bind(this);
|
||||
}
|
||||
componentDidMount () {
|
||||
const that = this;
|
||||
this.checkIfLocalFileAvailable()
|
||||
.then(isAvailable => {
|
||||
if (!isAvailable) {
|
||||
console.log('file is not yet available');
|
||||
that.setState({status: SEARCHING});
|
||||
return that.triggerGetAssetOnSpeech();
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
that.setState({status: AVAILABLE});
|
||||
that.addPlayPauseToVideoToBody();
|
||||
})
|
||||
.catch(error => {
|
||||
that.setState({
|
||||
status: UNAVAILABLE,
|
||||
error : error.message,
|
||||
});
|
||||
});
|
||||
}
|
||||
checkIfLocalFileAvailable () {
|
||||
console.log(`checking if file is available for ${this.props.name}#${this.props.claimId}`);
|
||||
const url = `/api/file-is-available/${this.props.name}/${this.props.claimId}`;
|
||||
return new Promise((resolve, reject) => {
|
||||
Request(url)
|
||||
.then(isAvailable => {
|
||||
console.log('/api/file-is-available response:', isAvailable);
|
||||
resolve(isAvailable);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
triggerGetAssetOnSpeech () {
|
||||
console.log(`getting claim for ${this.props.name}#${this.props.claimId}`)
|
||||
const url = `/api/claim-get/${this.props.name}/${this.props.claimId}`;
|
||||
return new Promise((resolve, reject) => {
|
||||
Request(url)
|
||||
.then(response => {
|
||||
console.log('/api/claim-get response:', response);
|
||||
resolve(true);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
addPlayPauseToVideoToBody () {
|
||||
const that = this;
|
||||
const video = document.getElementById('video');
|
||||
if (video) {
|
||||
// add event listener for click
|
||||
video.addEventListener('click', () => {
|
||||
that.playOrPause(video);
|
||||
});
|
||||
// add event listener for space bar
|
||||
document.body.onkeyup = (event) => {
|
||||
if (event.keyCode === 32) {
|
||||
that.playOrPause(video);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
playOrPause (video) {
|
||||
if (video.paused === true) {
|
||||
video.play();
|
||||
} else {
|
||||
video.pause();
|
||||
}
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
<div id="asset-display-component">
|
||||
{(this.state.status === SEARCHING) &&
|
||||
<div>
|
||||
<p>display {name}#{claimId} here</p>
|
||||
<p>Sit tight, we're searching the LBRY blockchain for your asset!</p>
|
||||
<ProgressBar size={12}/>
|
||||
<p>Curious what magic is happening here? <a className="link--primary" target="blank" href="https://lbry.io/faq/what-is-lbry">Learn more.</a></p>
|
||||
</div>
|
||||
}
|
||||
{(this.state.status === UNAVAILABLE) &&
|
||||
<div>
|
||||
<p>Unfortunately, we couldn't download your asset from LBRY. You can help us out by sharing the below error message in the <a className="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">LBRY discord</a>.</p>
|
||||
<i><p id="error-message">{this.state.error}</p></i>
|
||||
</div>
|
||||
}
|
||||
{(this.state.status === AVAILABLE) &&
|
||||
(() => {
|
||||
switch (this.state.contentType) {
|
||||
case 'image/jpeg':
|
||||
case 'image/jpg':
|
||||
case 'image/png':
|
||||
return (
|
||||
<img className="asset" src={this.state.src} alt={this.state.name}/>
|
||||
);
|
||||
case 'image/gif':
|
||||
return (
|
||||
<img className="asset" src={this.state.src} alt={this.state.name}/>
|
||||
);
|
||||
case 'video/mp4':
|
||||
return (
|
||||
<video id="video" className="asset" controls poster={this.state.thumbnail}>
|
||||
<source src={this.state.src}/>
|
||||
<p>Your browser does not support the <code>video</code> element.</p>
|
||||
</video>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<p>unsupported file type</p>
|
||||
);
|
||||
}
|
||||
})()
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// required props
|
||||
// name
|
||||
// claimId
|
||||
// thumbnail
|
||||
// contentType
|
||||
// file extension
|
||||
|
||||
export default AssetDisplay;
|
||||
|
|
|
@ -3,23 +3,17 @@ import React from 'react';
|
|||
class AssetInfo extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.toggleSection = this.toggleSection.bind(this);
|
||||
this.state = {
|
||||
showDetails: false,
|
||||
}
|
||||
this.toggleDetails = this.toggleDetails.bind(this);
|
||||
this.copyToClipboard = this.copyToClipboard.bind(this);
|
||||
}
|
||||
toggleSection (event) {
|
||||
var dataSet = event.target.dataset;
|
||||
var status = dataSet.status;
|
||||
var toggle = document.getElementById('show-details-toggle');
|
||||
var details = document.getElementById('show-details');
|
||||
if (status === 'closed') {
|
||||
details.hidden = false;
|
||||
toggle.innerText = '[less]';
|
||||
toggle.dataset.status = 'open';
|
||||
} else {
|
||||
details.hidden = true;
|
||||
toggle.innerText = '[more]';
|
||||
toggle.dataset.status = 'closed';
|
||||
toggleDetails () {
|
||||
if (this.state.showDetails) {
|
||||
return this.setState({showDetails: false});
|
||||
}
|
||||
this.setState({showDetails: true});
|
||||
}
|
||||
copyToClipboard (event) {
|
||||
var elementToCopy = event.target.dataset.elementtocopy;
|
||||
|
@ -126,41 +120,40 @@ class AssetInfo extends React.Component {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="show-details" className="row--padded row--wide row--no-top" hidden="true">
|
||||
<div id="show-claim-name">
|
||||
{ this.state.showDetails &&
|
||||
<div>
|
||||
<div className="row--padded row--wide row--no-top">
|
||||
<div>
|
||||
<div className="column column--2 column--med-10">
|
||||
<span className="text">Claim Name:</span>
|
||||
</div>
|
||||
<div className="column column--8 column--med-10">
|
||||
</div><div className="column column--8 column--med-10">
|
||||
{this.props.name}
|
||||
</div>
|
||||
</div>
|
||||
<div id="show-claim-id">
|
||||
<div>
|
||||
<div className="column column--2 column--med-10">
|
||||
<span className="text">Claim Id:</span>
|
||||
</div>
|
||||
<div className="column column--8 column--med-10">
|
||||
</div><div className="column column--8 column--med-10">
|
||||
{this.props.claimId}
|
||||
</div>
|
||||
</div>
|
||||
<div id="show-claim-id">
|
||||
<div>
|
||||
<div className="column column--2 column--med-10">
|
||||
<span className="text">File Type:</span>
|
||||
</div>
|
||||
<div className="column column--8 column--med-10">
|
||||
</div><div className="column column--8 column--med-10">
|
||||
{this.props.contentType ? `${this.props.contentType}` : 'unknown'}
|
||||
</div>
|
||||
</div>
|
||||
<div id="show-claim-id">
|
||||
</div>
|
||||
<div className="row--padded row--wide row--no-top">
|
||||
<div className="column column--10">
|
||||
<a target="_blank" href="https://lbry.io/dmca">Report</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
<div className="row row--wide">
|
||||
<a className="text link--primary" id="show-details-toggle" href="#" onClick={this.toggleSection}
|
||||
data-status="closed">[more]</a>
|
||||
<a className="text link--primary" id="show-details-toggle" href="#" onClick={this.toggleDetails}>{this.state.showDetails ? '[less]' : '[more]'}</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -50,7 +50,6 @@ class ChannelClaimsDisplay extends React.Component {
|
|||
</div>
|
||||
) : (
|
||||
<div className="row row--tall">
|
||||
<p># of claims in channel: {this.state.totalResults >= 0 ? this.state.totalResults : 'loading...' }</p>
|
||||
{this.state.claims && this.state.claims.map((claim, index) => <AssetPreview
|
||||
name={claim.name}
|
||||
claimId={claim.claimId}
|
||||
|
|
|
@ -27,6 +27,9 @@ class ShowDetails extends React.Component {
|
|||
<AssetDisplay
|
||||
name={this.props.claimData.name}
|
||||
claimId={this.props.claimData.claimId}
|
||||
thumbnail={this.props.claimData.thumbnail}
|
||||
contentType={this.props.claimData.contentType}
|
||||
fileExt={this.props.claimData.fileExt}
|
||||
/>
|
||||
</div>
|
||||
</div><div className="column column--5 column--sml-10 align-content-top">
|
||||
|
|
|
@ -6,6 +6,6 @@ module.exports = app => {
|
|||
// a catch-all route if someone visits a page that does not exist
|
||||
app.use('*', ({ originalUrl, ip }, res) => {
|
||||
// send response
|
||||
res.status(404).render('index');
|
||||
res.status(404).render('404');
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{{> navBar}}
|
||||
<div class="row row--padded">
|
||||
<div class="row row--tall flex-container--column flex-container--center-center">
|
||||
<h3>404: Not Found</h3>
|
||||
<p>That page does not exist. Return <a class="link--primary" href="/">home</a>.</p>
|
||||
</div>
|
|
@ -1,55 +0,0 @@
|
|||
{{> navBar}}
|
||||
<div class="row row--padded">
|
||||
<div class="row">
|
||||
{{#ifConditional this.totalPages '===' 0}}
|
||||
<p>There is no content in {{this.channelName}}:{{this.longChannelClaimId}} yet. Upload some!</p>
|
||||
{{/ifConditional}}
|
||||
{{#ifConditional this.totalPages '>=' 1}}
|
||||
<p>Below are the contents for {{this.channelName}}:{{this.longChannelClaimId}}</p>
|
||||
<div class="grid">
|
||||
{{#each this.claims}}
|
||||
{{> gridItem}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/ifConditional}}
|
||||
{{#ifConditional this.totalPages '>' 1}}
|
||||
<div class="row">
|
||||
<div class="column column--3 align-content--left">
|
||||
<a class="link--primary" href="/{{this.channelName}}:{{this.longChannelClaimId}}?p=1">First [1]</a>
|
||||
</div><div class="column column--4 align-content-center">
|
||||
{{#if this.previousPage}}
|
||||
<a class="link--primary" href="/{{this.channelName}}:{{this.longChannelClaimId}}?p={{this.previousPage}}">Previous</a>
|
||||
{{else}}
|
||||
<a disabled>Previous</a>
|
||||
{{/if}}
|
||||
|
|
||||
{{#if this.nextPage}}
|
||||
<a class="link--primary" href="/{{this.channelName}}:{{this.longChannelClaimId}}?p={{this.nextPage}}">Next</a>
|
||||
{{else}}
|
||||
<a disabled>Next</a>
|
||||
{{/if}}
|
||||
</div><div class="column column--3 align-content-right">
|
||||
<a class="link--primary" href="/{{this.channelName}}:{{this.longChannelClaimId}}?p={{this.totalPages}}">Last [{{this.totalPages}}]</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/ifConditional}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/assets/vendors/masonry/masonry.pkgd.min.js"></script>
|
||||
<script src="/assets/vendors/imagesloaded/imagesloaded.pkgd.min.js"></script>
|
||||
<script>
|
||||
// init masonry with element
|
||||
var grid = document.querySelector('.grid');
|
||||
var msnry;
|
||||
|
||||
imagesLoaded( grid, function() {
|
||||
msnry = new Masonry( grid, {
|
||||
itemSelector: '.grid-item',
|
||||
columnWidth: 3,
|
||||
percentPosition: true
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
|
||||
<head>
|
||||
{{ placeCommonHeaderTags }}
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@spee_ch" />
|
||||
<meta property="og:title" content="{{this.channelName}} on Spee.ch" />
|
||||
<meta property="og:site_name" content="Spee.ch" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="https://spee.ch/assets/img/Speech_Logo_Main@OG-02.jpg" />
|
||||
<meta property="og:url" content="http://spee.ch/{{this.channelName}}:{{this.longChannelId}}" />
|
||||
<meta property="og:description" content="View images and videos from {{this.channelName}}" />
|
||||
<!--google font-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet">
|
||||
<!-- google analytics -->
|
||||
{{ googleAnalytics }}
|
||||
</head>
|
||||
<body id="channel-body">
|
||||
<script src="/assets/js/generalFunctions.js"></script>
|
||||
{{{ body }}}
|
||||
</body>
|
||||
</html>
|
|
@ -16,8 +16,6 @@
|
|||
{{ googleAnalytics }}
|
||||
</head>
|
||||
<body id="main-body">
|
||||
<script src="/assets/js/generalFunctions.js"></script>
|
||||
<script src="/assets/js/validationFunctions.js"></script>
|
||||
{{{ body }}}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
|
||||
<head>
|
||||
{{ placeCommonHeaderTags }}
|
||||
<meta property="fb:app_id" content="1371961932852223">
|
||||
{{#unless claimInfo.nsfw}}
|
||||
{{{addTwitterCard claimInfo }}}
|
||||
{{{addOpenGraph claimInfo }}}
|
||||
{{/unless}}
|
||||
<!--google font-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet">
|
||||
<!-- google analytics -->
|
||||
{{ googleAnalytics }}
|
||||
</head>
|
||||
<body id="show-body">
|
||||
<script src="/assets/js/generalFunctions.js"></script>
|
||||
<script src="/assets/js/assetConstructor.js"></script>
|
||||
{{{ body }}}
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
{{> navBar}}
|
||||
<div class="row row--padded">
|
||||
<h3>No Channel</h3>
|
||||
<p>There are no published channels matching your url</p>
|
||||
<p>If you think this message is an error, contact us in the <a class="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">LBRY Discord!</a></p>
|
||||
</div>
|
|
@ -1,6 +0,0 @@
|
|||
{{> navBar}}
|
||||
<div class="row row--padded">
|
||||
<h3>No Claims</h3>
|
||||
<p>There are no free assets at that claim. You should publish one at <a class="link--primary" href="/">spee.ch</a>.</p>
|
||||
<p>NOTE: it is possible your claim was published, but it is still being processed by the blockchain</p>
|
||||
</div>
|
|
@ -1,7 +1,52 @@
|
|||
<p id="bar-holder"></p>
|
||||
|
||||
<script src="/assets/js/progressBarConstructor.js"></script>
|
||||
<script type="text/javascript">
|
||||
const ProgressBar = function() {
|
||||
this.data = {
|
||||
x: 0,
|
||||
adder: 1,
|
||||
bars: [],
|
||||
};
|
||||
this.barHolder = document.getElementById('bar-holder');
|
||||
this.createProgressBar = function (size) {
|
||||
this.data['size'] = size;
|
||||
for (var i = 0; i < size; i++) {
|
||||
const bar = document.createElement('span');
|
||||
bar.innerText = '| ';
|
||||
bar.setAttribute('class', 'progress-bar progress-bar--inactive');
|
||||
this.barHolder.appendChild(bar);
|
||||
this.data.bars.push(bar);
|
||||
}
|
||||
};
|
||||
this.startProgressBar = function () {
|
||||
this.updateInterval = setInterval(this.updateProgressBar.bind(this), 300);
|
||||
};
|
||||
this.updateProgressBar = function () {
|
||||
const x = this.data.x;
|
||||
const adder = this.data.adder;
|
||||
const size = this.data.size;
|
||||
// update the appropriate bar
|
||||
if (x > -1 && x < size){
|
||||
if (adder === 1){
|
||||
this.data.bars[x].setAttribute('class', 'progress-bar progress-bar--active');
|
||||
} else {
|
||||
this.data.bars[x].setAttribute('class', 'progress-bar progress-bar--inactive');
|
||||
}
|
||||
}
|
||||
// update adder
|
||||
if (x === size){
|
||||
this.data['adder'] = -1;
|
||||
} else if ( x === -1){
|
||||
this.data['adder'] = 1;
|
||||
}
|
||||
// update x
|
||||
this.data['x'] = x + adder;
|
||||
};
|
||||
this.stopProgressBar = function () {
|
||||
clearInterval(this.updateInterval);
|
||||
};
|
||||
};
|
||||
|
||||
const progressBar = new ProgressBar();
|
||||
progressBar.createProgressBar(10);
|
||||
progressBar.startProgressBar();
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
{{> navBar}}
|
||||
<div class="row row--padded">
|
||||
<h3>Error</h3>
|
||||
<p>Unfortnately, Spee.ch encountered an error. You can help us out, by reporting the below error message in the #speech channel on <a class="link--primary" href="https://discord.gg/YjYbwhS" target="_blank">LBRY Discord</a>!</p>
|
||||
<p>status: {{status}}</p>
|
||||
<p>message: {{message}}</p>
|
||||
</div>
|
|
@ -1,18 +0,0 @@
|
|||
{{> navBar}}
|
||||
<div class="row row--tall row--padded">
|
||||
<div class="column column--10">
|
||||
<!-- title -->
|
||||
<span class="text--large">{{claimInfo.title}}</span>
|
||||
</div>
|
||||
<div class="column column--5 column--sml-10 align-content-top">
|
||||
<!-- asset -->
|
||||
<div class="row row--padded">
|
||||
{{> asset}}
|
||||
</div>
|
||||
</div><div class="column column--5 column--sml-10 align-content-top">
|
||||
<!-- details -->
|
||||
<div class="row row--padded">
|
||||
{{> assetInfo}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,32 +0,0 @@
|
|||
<div>
|
||||
<h3>Site Statistics</h3>
|
||||
<p>Serve: {{ totals.totalServe }}</p>
|
||||
<p>Publish: {{ totals.totalPublish }}</p>
|
||||
<p>Show: {{ totals.totalShow }}</p>
|
||||
<p>Percent Success: {{ percentSuccess}}%</p>
|
||||
<table>
|
||||
<tr>
|
||||
<th>action</th>
|
||||
<th >url</th>
|
||||
<th class="">count</th>
|
||||
<th class="">success</th>
|
||||
<th class="">failure</th>
|
||||
</tr>
|
||||
{{#each records}}
|
||||
<tr>
|
||||
<td>{{ this.action }}</td>
|
||||
<td class="stats-table-url">{{ this.url }}</td>
|
||||
<td class="">{{ this.count }}</td>
|
||||
<td class="">{{ this.success }}</td>
|
||||
<td class="">{{ this.failure }}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="">{{ totals.totalCount }}</td>
|
||||
<td class="">{{ totals.totalSuccess }}</td>
|
||||
<td class="">{{ totals.totalFailure }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
Loading…
Reference in a new issue