added templates for show pages and channel page

This commit is contained in:
bill bittner 2018-01-30 09:00:02 -08:00
parent caee8bb835
commit fa5c811dab
13 changed files with 322 additions and 26 deletions

View file

@ -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');
},
};

View file

@ -0,0 +1,11 @@
import React from 'react';
const AssetDisplay = () => {
return (
<div>
<p>display asset here</p>
</div>
);
};
export default AssetDisplay;

View file

@ -0,0 +1,11 @@
import React from 'react';
const AssetTitle = () => {
return (
<div>
<p>Show asset info here</p>
</div>
);
};
export default AssetTitle;

View file

@ -0,0 +1,11 @@
import React from 'react';
const AssetTitle = ({title}) => {
return (
<div>
<span className="text--large">{title}</span>
</div>
);
};
export default AssetTitle;

View 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;

View 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;

View 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;

View 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;

View file

@ -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
View 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,
};
},
};

View file

@ -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

View file

@ -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');

View file

@ -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>