added templates for show pages and channel page
This commit is contained in:
parent
caee8bb835
commit
fa5c811dab
13 changed files with 322 additions and 26 deletions
|
@ -16,10 +16,10 @@ module.exports = {
|
|||
},
|
||||
showFile (claimInfo, shortId, res) {
|
||||
logger.verbose(`showing claim: ${claimInfo.name}#${claimInfo.claimId}`);
|
||||
res.status(200).render('show', { layout: 'show', claimInfo, shortId });
|
||||
res.status(200).render('index');
|
||||
},
|
||||
showFileLite (claimInfo, shortId, res) {
|
||||
logger.verbose(`showlite claim: ${claimInfo.name}#${claimInfo.claimId}`);
|
||||
res.status(200).render('showLite', { layout: 'showlite', claimInfo, shortId });
|
||||
res.status(200).render('index');
|
||||
},
|
||||
};
|
||||
|
|
11
react/components/AssetDisplay/index.js
Normal file
11
react/components/AssetDisplay/index.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import React from 'react';
|
||||
|
||||
const AssetDisplay = () => {
|
||||
return (
|
||||
<div>
|
||||
<p>display asset here</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AssetDisplay;
|
11
react/components/AssetInfo/index.js
Normal file
11
react/components/AssetInfo/index.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import React from 'react';
|
||||
|
||||
const AssetTitle = () => {
|
||||
return (
|
||||
<div>
|
||||
<p>Show asset info here</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AssetTitle;
|
11
react/components/AssetTitle/index.js
Normal file
11
react/components/AssetTitle/index.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import React from 'react';
|
||||
|
||||
const AssetTitle = ({title}) => {
|
||||
return (
|
||||
<div>
|
||||
<span className="text--large">{title}</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AssetTitle;
|
47
react/components/ShowChannel/index.js
Normal file
47
react/components/ShowChannel/index.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
import React from 'react';
|
||||
import NavBar from 'containers/NavBar';
|
||||
|
||||
class ShowChannel extends React.Component {
|
||||
componentDidMount () {
|
||||
console.log(this.props);
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<NavBar/>
|
||||
<div className="row row--tall row--padded">
|
||||
<div className="column column--10">
|
||||
<h2>channelName: {this.props.channelName}</h2>
|
||||
<h2>channelClaimId: {this.props.channelClaimId}</h2>
|
||||
</div>
|
||||
<div class="row row--padded">
|
||||
<div class="row">
|
||||
|
||||
{((this.props.totalPages === 0) &&
|
||||
<p>There is no content in {this.props.channelName}:{this.props.longChannelClaimId} yet. Upload some!
|
||||
</p>)}
|
||||
|
||||
{((this.props.totalPages >= 1) &&
|
||||
<div>
|
||||
<p>Below are the contents for {this.channelName}:{this.longChannelClaimId}</p>
|
||||
<div>
|
||||
{/* claims here */}
|
||||
</div>
|
||||
</div>)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// required props
|
||||
// channelName
|
||||
// channelLongClaimId
|
||||
// channelShortClaimId
|
||||
// totalPages
|
||||
// claims
|
||||
|
||||
export default ShowChannel;
|
34
react/components/ShowDetails/index.js
Normal file
34
react/components/ShowDetails/index.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
import React from 'react';
|
||||
import NavBar from 'containers/NavBar';
|
||||
import AssetTitle from 'components/AssetTitle';
|
||||
import AssetDisplay from 'components/AssetDisplay';
|
||||
import AssetInfo from 'components/AssetInfo';
|
||||
|
||||
class ShowDetailsPage extends React.Component {
|
||||
componentDidMount () {
|
||||
console.log(this.props);
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<NavBar/>
|
||||
<div className="row row--tall row--padded">
|
||||
<div className="column column--10">
|
||||
<AssetTitle title={'test title'}/>
|
||||
</div>
|
||||
<div className="column column--5 column--sml-10 align-content-top">
|
||||
<div className="row row--padded">
|
||||
<AssetDisplay/>
|
||||
</div>
|
||||
</div><div className="column column--5 column--sml-10 align-content-top">
|
||||
<div className="row row--padded">
|
||||
<AssetInfo />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ShowDetailsPage;
|
14
react/components/ShowLite/index.js
Normal file
14
react/components/ShowLite/index.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
import React from 'react';
|
||||
import AssetDisplay from 'components/AssetDisplay';
|
||||
|
||||
class ShowLitePage extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<div className="row row--tall flex-container--column flex-container--center-center">
|
||||
<AssetDisplay />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ShowLitePage;
|
94
react/components/ShowPage/index.js
Normal file
94
react/components/ShowPage/index.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
import React from 'react';
|
||||
import ShowLite from 'components/ShowLite';
|
||||
import ShowDetails from 'components/ShowDetails';
|
||||
import ShowChannel from 'components/ShowChannel';
|
||||
import lbryUri from 'utils/lbryUri';
|
||||
|
||||
class ShowPage extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isChannel : null,
|
||||
channelName : null,
|
||||
channelClaimId: null,
|
||||
claimId : null,
|
||||
claimName : null,
|
||||
isServeRequest: null,
|
||||
};
|
||||
}
|
||||
componentDidMount () {
|
||||
const identifier = this.props.match.params.identifier;
|
||||
const claim = this.props.match.params.claim;
|
||||
// handle case of identifier and claim
|
||||
if (identifier) {
|
||||
let isChannel, channelName, channelClaimId, claimId, claimName, isServeRequest;
|
||||
try {
|
||||
({ isChannel, channelName, channelClaimId, claimId } = lbryUri.parseIdentifier(identifier));
|
||||
({ claimName, isServeRequest } = lbryUri.parseName(claim));
|
||||
} catch (error) {
|
||||
return console.log('error:', error);
|
||||
}
|
||||
// set state
|
||||
return this.setState({
|
||||
isChannel,
|
||||
channelName,
|
||||
channelClaimId,
|
||||
claimId,
|
||||
claimName,
|
||||
isServeRequest,
|
||||
});
|
||||
}
|
||||
// handle case of just claim (asset or channel)
|
||||
let isChannel, channelName, channelClaimId;
|
||||
try {
|
||||
({ isChannel, channelName, channelClaimId } = lbryUri.parseIdentifier(claim));
|
||||
} catch (error) {
|
||||
console.log('error:', error);
|
||||
}
|
||||
if (isChannel) {
|
||||
return this.setState({
|
||||
isChannel,
|
||||
channelName,
|
||||
channelClaimId,
|
||||
});
|
||||
}
|
||||
let claimName, isServeRequest;
|
||||
try {
|
||||
({claimName, isServeRequest} = lbryUri.parseName(claim));
|
||||
} catch (error) {
|
||||
console.log('error:', error);
|
||||
}
|
||||
this.setState({
|
||||
claimName,
|
||||
isServeRequest,
|
||||
});
|
||||
}
|
||||
render () {
|
||||
const identifier = this.props.match.params.identifier;
|
||||
console.log('rendering component');
|
||||
if (!identifier && this.state.isChannel) {
|
||||
return (
|
||||
<ShowChannel
|
||||
channelName={this.state.channelName}
|
||||
channelClaimId={this.state.channelClaimId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (this.state.isServeRequest) {
|
||||
return (
|
||||
<ShowLite
|
||||
claimId={this.state.claimId}
|
||||
claimName={this.state.claimName}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<ShowDetails
|
||||
claimId={this.state.claimId}
|
||||
claimName={this.state.claimName}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default ShowPage;
|
|
@ -6,6 +6,7 @@ import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
|||
import PublishPage from 'components/PublishPage';
|
||||
import AboutPage from 'components/AboutPage';
|
||||
import LoginPage from 'components/LoginPage';
|
||||
import ShowPage from 'components/ShowPage';
|
||||
|
||||
const Root = ({ store }) => (
|
||||
<Provider store={store}>
|
||||
|
@ -14,6 +15,8 @@ const Root = ({ store }) => (
|
|||
<Route exact path="/" component={PublishPage} />
|
||||
<Route exact path="/about" component={AboutPage} />
|
||||
<Route exact path="/login" component={LoginPage} />
|
||||
<Route exact path="/:identifier/:claim" component={ShowPage} />
|
||||
<Route exact path="/:claim/" component={ShowPage} />
|
||||
</Switch>
|
||||
</BrowserRouter>
|
||||
</Provider>
|
||||
|
|
91
react/utils/lbryUri.js
Normal file
91
react/utils/lbryUri.js
Normal file
|
@ -0,0 +1,91 @@
|
|||
module.exports = {
|
||||
REGEXP_INVALID_CLAIM : /[^A-Za-z0-9-]/g,
|
||||
REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,
|
||||
REGEXP_ADDRESS : /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,
|
||||
CHANNEL_CHAR : '@',
|
||||
parseIdentifier : function (identifier) {
|
||||
console.log('parsing identifier:', identifier);
|
||||
const componentsRegex = new RegExp(
|
||||
'([^:$#/]*)' + // value (stops at the first separator or end)
|
||||
'([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
|
||||
);
|
||||
const [proto, value, modifierSeperator, modifier] = componentsRegex
|
||||
.exec(identifier)
|
||||
.map(match => match || null);
|
||||
console.log(`${proto}, ${value}, ${modifierSeperator}, ${modifier}`);
|
||||
|
||||
// Validate and process name
|
||||
if (!value) {
|
||||
throw new Error(`Check your url. No channel name provided before "${modifierSeperator}"`);
|
||||
}
|
||||
const isChannel = value.startsWith(module.exports.CHANNEL_CHAR);
|
||||
const channelName = isChannel ? value : null;
|
||||
let claimId;
|
||||
if (isChannel) {
|
||||
if (!channelName) {
|
||||
throw new Error('No channel name after @.');
|
||||
}
|
||||
const nameBadChars = (channelName).match(module.exports.REGEXP_INVALID_CHANNEL);
|
||||
if (nameBadChars) {
|
||||
throw new Error(`Invalid characters in channel name: ${nameBadChars.join(', ')}.`);
|
||||
}
|
||||
} else {
|
||||
claimId = value;
|
||||
}
|
||||
|
||||
// Validate and process modifier
|
||||
let channelClaimId;
|
||||
if (modifierSeperator) {
|
||||
if (!modifier) {
|
||||
throw new Error(`No modifier provided after separator "${modifierSeperator}"`);
|
||||
}
|
||||
|
||||
if (modifierSeperator === ':') {
|
||||
channelClaimId = modifier;
|
||||
} else {
|
||||
throw new Error(`The "${modifierSeperator}" modifier is not currently supported`);
|
||||
}
|
||||
}
|
||||
return {
|
||||
isChannel,
|
||||
channelName,
|
||||
channelClaimId,
|
||||
claimId,
|
||||
};
|
||||
},
|
||||
parseName: function (name) {
|
||||
console.log('parsing name:', name);
|
||||
const componentsRegex = new RegExp(
|
||||
'([^:$#/.]*)' + // name (stops at the first modifier)
|
||||
'([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
|
||||
);
|
||||
const [proto, claimName, modifierSeperator, modifier] = componentsRegex
|
||||
.exec(name)
|
||||
.map(match => match || null);
|
||||
console.log(`${proto}, ${claimName}, ${modifierSeperator}, ${modifier}`);
|
||||
|
||||
// Validate and process name
|
||||
if (!claimName) {
|
||||
throw new Error('No claim name provided before .');
|
||||
}
|
||||
const nameBadChars = (claimName).match(module.exports.REGEXP_INVALID_CLAIM);
|
||||
if (nameBadChars) {
|
||||
throw new Error(`Invalid characters in claim name: ${nameBadChars.join(', ')}.`);
|
||||
}
|
||||
// Validate and process modifier
|
||||
let isServeRequest = false;
|
||||
if (modifierSeperator) {
|
||||
if (!modifier) {
|
||||
throw new Error(`No file extension provided after separator ${modifierSeperator}.`);
|
||||
}
|
||||
if (modifierSeperator !== '.') {
|
||||
throw new Error(`The ${modifierSeperator} modifier is not supported in the claim name`);
|
||||
}
|
||||
isServeRequest = true;
|
||||
}
|
||||
return {
|
||||
claimName,
|
||||
isServeRequest,
|
||||
};
|
||||
},
|
||||
};
|
|
@ -10,15 +10,10 @@ module.exports = (app) => {
|
|||
});
|
||||
// route to display login page
|
||||
app.get('/login', (req, res) => {
|
||||
if (req.user) {
|
||||
res.status(200).redirect(`/${req.user.channelName}`);
|
||||
} else {
|
||||
res.status(200).render('index');
|
||||
}
|
||||
res.status(200).render('index');
|
||||
});
|
||||
// route to show 'about' page
|
||||
app.get('/about', (req, res) => {
|
||||
// get and render the content
|
||||
res.status(200).render('index');
|
||||
});
|
||||
// route to display a list of the trending images
|
||||
|
|
|
@ -188,7 +188,8 @@ module.exports = (app) => {
|
|||
// log the request data for debugging
|
||||
logRequestData(null, null, channelName, null);
|
||||
// handle showing the channel page
|
||||
showChannelPageToClient(channelName, channelClaimId, originalUrl, ip, query, res);
|
||||
// showChannelPageToClient(channelName, channelClaimId, originalUrl, ip, query, res);
|
||||
return res.status(200).render('index');
|
||||
} else {
|
||||
let claimName, isServeRequest;
|
||||
try {
|
||||
|
@ -203,7 +204,7 @@ module.exports = (app) => {
|
|||
getClaimId(null, null, claimName, null)
|
||||
.then(fullClaimId => {
|
||||
if (fullClaimId === NO_CLAIM) {
|
||||
return res.status(200).render('noClaim');
|
||||
return res.status(200).render('index');
|
||||
}
|
||||
showOrServeAsset(responseType, fullClaimId, claimName, res);
|
||||
postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
{{> navBar}}
|
||||
<div class="row row--padded">
|
||||
<div class="column column--5 column--med-10 align-content-top">
|
||||
<div class="column column--8 column--med-10">
|
||||
<p>Channels allow you to publish and group content under an identity. You can create a channel for yourself, or share one with like-minded friends. You can create 1 channel, or 100, so whether you're <a class="link--primary" target="_blank" href="/@catalonia2017:43dcf47163caa21d8404d9fe9b30f78ef3e146a8">documenting important events</a>, or making a public repository for <a class="link--primary" target="_blank" href="/@catGifs">cat gifs</a> (password: '1234'), try creating a channel for it!</p>
|
||||
</div>
|
||||
</div><div class="column column--5 column--med-10 align-content-top">
|
||||
<div class="column column--8 column--med-10">
|
||||
<h3 class="h3--no-bottom">Log in to an existing channel:</h3>
|
||||
{{>channelLoginForm}}
|
||||
<h3 class="h3--no-bottom">Create a brand new channel:</h3>
|
||||
{{>channelCreationForm}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in a new issue