Merge pull request #395 from lbryio/speech-as-a-package-site-info-in-state

Speech as a package site info in state
This commit is contained in:
Bill Bittner 2018-03-15 17:40:43 -07:00 committed by GitHub
commit 4bde1c6f3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 156 additions and 96 deletions

View file

@ -3,18 +3,19 @@ function SiteConfig () {
googleId: 'default',
};
this.assetDefaults = {
title : 'Spee.ch',
description: 'An asset published on Spee.ch',
thumbnail : 'https://spee.ch/assets/img/video_thumb_default.png',
description: 'Open-source, decentralized image and video sharing.',
title : 'Spee.ch',
};
this.auth = {
sessionKey: 'default',
};
this.details = {
description: 'Open-source, decentralized image and video sharing.',
host : 'default',
port : 3000,
title : 'Spee.ch',
host : 'default',
description: 'Open-source, decentralized image and video sharing.',
twitter : '@spee_ch',
};
this.publishing = {
additionalClaimAddresses: [],

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,6 @@
import Request from 'utils/request';
const { details: { host } } = require('../../config/siteConfig.js');
export function getLongClaimId (name, modifier) {
export function getLongClaimId (host, name, modifier) {
let body = {};
// create request params
if (modifier) {
@ -24,12 +23,12 @@ export function getLongClaimId (name, modifier) {
return Request(url, params);
};
export function getShortId (name, claimId) {
export function getShortId (host, name, claimId) {
const url = `${host}/api/claim/short-id/${claimId}/${name}`;
return Request(url);
};
export function getClaimData (name, claimId) {
export function getClaimData (host, name, claimId) {
const url = `${host}/api/claim/data/${name}/${claimId}`;
return Request(url);
};

View file

@ -1,13 +1,12 @@
import Request from 'utils/request';
const { details: { host } } = require('../../config/siteConfig.js');
export function getChannelData (name, id) {
export function getChannelData (host, id, name) {
if (!id) id = 'none';
const url = `${host}/api/channel/data/${name}/${id}`;
return Request(url);
};
export function getChannelClaims (name, longId, page) {
export function getChannelClaims (host, longId, name, page) {
if (!page) page = 1;
const url = `${host}/api/channel/claims/${name}/${longId}/${page}`;
return Request(url);

View file

@ -1,12 +1,11 @@
import Request from 'utils/request';
const { details: { host } } = require('../../config/siteConfig.js');
export function checkFileAvailability (name, claimId) {
export function checkFileAvailability (claimId, host, name) {
const url = `${host}/api/file/availability/${name}/${claimId}`;
return Request(url);
}
export function triggerClaimGet (name, claimId) {
export function triggerClaimGet (claimId, host, name) {
const url = `${host}/api/claim/get/${name}/${claimId}`;
return Request(url);
}

View file

@ -4,7 +4,7 @@ import HomePage from 'components/HomePage';
import AboutPage from 'components/AboutPage';
import LoginPage from 'containers/LoginPage';
import ShowPage from 'containers/ShowPage';
import FourOhFourPage from 'components/FourOhFourPage';
import FourOhFourPage from 'containers/FourOhFourPage';
const App = () => {
return (

View file

@ -0,0 +1,10 @@
import { connect } from 'react-redux';
import View from './view';
const mapStateToProps = ({site: {defaults: { defaultThumbnail }}}) => {
return {
defaultThumbnail,
};
};
export default connect(mapStateToProps, null)(View);

View file

@ -1,8 +1,7 @@
import React from 'react';
import { Link } from 'react-router-dom';
const { assetDefaults: { thumbnail: defaultThumbnail } } = require('../../../config/siteConfig.js');
const AssetPreview = ({ claimData: { name, claimId, fileExt, contentType, thumbnail } }) => {
const AssetPreview = ({ defaultThumbnail, claimData: { name, claimId, fileExt, contentType, thumbnail } }) => {
const directSourceLink = `${claimId}/${name}.${fileExt}`;
const showUrlLink = `/${claimId}/${name}`;
return (

View file

@ -1,7 +1,7 @@
import React from 'react';
import GoogleAnalytics from 'react-ga';
import { withRouter } from 'react-router-dom';
const {analytics: googleId} = require('../../../config/siteConfig.js');
const { analytics: { googleId } } = require('../../../config/siteConfig.js');
GoogleAnalytics.initialize(googleId);

View file

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
class Preview extends React.Component {
class PublishPreview extends React.Component {
constructor (props) {
super(props);
this.state = {
@ -53,10 +53,10 @@ class Preview extends React.Component {
}
};
Preview.propTypes = {
PublishPreview.propTypes = {
dimPreview: PropTypes.bool.isRequired,
file : PropTypes.object.isRequired,
thumbnail : PropTypes.object,
};
export default Preview;
export default PublishPreview;

View file

@ -0,0 +1,16 @@
import { connect } from 'react-redux';
import View from './view';
const mapStateToProps = ({ site }) => {
const { defaultDescription, defaultThumbnail, description: siteDescription, host: siteHost, title: siteTitle, twitter: siteTwitter } = site;
return {
defaultDescription,
defaultThumbnail,
siteDescription,
siteHost,
siteTitle,
siteTwitter,
};
};
export default connect(mapStateToProps, null)(View);

View file

@ -8,10 +8,16 @@ import { createCanonicalLink } from 'utils/canonicalLink';
class SEO extends React.Component {
render () {
let { pageTitle, asset, channel, pageUri } = this.props;
pageTitle = createPageTitle(pageTitle);
const metaTags = createMetaTags(asset, channel);
const canonicalLink = createCanonicalLink(asset, channel, pageUri);
// props from state
const { defaultDescription, defaultThumbnail, siteDescription, siteHost, siteTitle, siteTwitter } = this.props;
// props from parent
const { asset, channel, pageUri } = this.props;
let { pageTitle } = this.props;
// create page title, tags, and canonical link
pageTitle = createPageTitle(siteTitle, pageTitle);
const metaTags = createMetaTags(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail);
const canonicalLink = createCanonicalLink(asset, channel, pageUri, siteHost);
// render results
return (
<Helmet
title={pageTitle}

View file

@ -1,6 +1,6 @@
import React from 'react';
import { validateFile } from 'utils/file';
import Preview from 'components/Preview';
import PublishPreview from 'components/PublishPreview';
class Dropzone extends React.Component {
constructor (props) {
@ -87,7 +87,7 @@ class Dropzone extends React.Component {
<div id='preview-dropzone' className={'row row--padded row--tall dropzone' + (this.state.dragOver ? ' dropzone--drag-over' : '')} onDrop={this.handleDrop} onDragOver={this.handleDragOver} onDragEnd={this.handleDragEnd} onDragEnter={this.handleDragEnter} onDragLeave={this.handleDragLeave} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} onClick={this.handleClick}>
{this.props.file ? (
<div>
<Preview
<PublishPreview
dimPreview={this.state.dimPreview}
file={this.props.file}
thumbnail={this.props.thumbnail}

View file

@ -0,0 +1,11 @@
import { connect } from 'react-redux';
import View from './view';
const mapStateToProps = ({ site: { host, title } }) => {
return {
host,
title,
};
};
export default connect(mapStateToProps, null)(View);

View file

@ -1,10 +1,10 @@
import React from 'react';
import NavBar from 'containers/NavBar';
import Helmet from 'react-helmet';
const { details: { title, host } } = require('../../../config/siteConfig.js');
class FourOhForPage extends React.Component {
render () {
const {title, host} = this.props;
return (
<div>
<Helmet>

View file

@ -1,7 +1,29 @@
const { details: { host } } = require('../../config/siteConfig.js');
const siteConfig = require('../../config/siteConfig.js');
const {
analytics: {
googleId: googleAnalyticsId,
},
assetDefaults: {
thumbnail: defaultThumbnail,
description: defaultDescription,
},
details: {
description,
host,
title,
twitter,
},
} = siteConfig;
const initialState = {
host: host,
description,
googleAnalyticsId,
host,
title,
twitter,
defaultDescription,
defaultThumbnail,
};
export default function (state = initialState, action) {

View file

@ -1,16 +1,18 @@
import { call, put, takeLatest } from 'redux-saga/effects';
import {call, put, select, takeLatest} from 'redux-saga/effects';
import * as actions from 'constants/show_action_types';
import { updateFileAvailability, updateDisplayAssetError } from 'actions/show';
import { UNAVAILABLE, AVAILABLE } from 'constants/asset_display_states';
import { checkFileAvailability, triggerClaimGet } from 'api/fileApi';
import { selectSiteHost } from 'selectors/site';
function * retrieveFile (action) {
const name = action.data.name;
const claimId = action.data.claimId;
const host = yield select(selectSiteHost);
// see if the file is available
let isAvailable;
try {
({ data: isAvailable } = yield call(checkFileAvailability, name, claimId));
({ data: isAvailable } = yield call(checkFileAvailability, claimId, host, name));
} catch (error) {
return yield put(updateDisplayAssetError(error.message));
};
@ -21,7 +23,7 @@ function * retrieveFile (action) {
yield put(updateFileAvailability(UNAVAILABLE));
// initiate get request for the file
try {
yield call(triggerClaimGet, name, claimId);
yield call(triggerClaimGet, claimId, host, name);
} catch (error) {
return yield put(updateDisplayAssetError(error.message));
};

View file

@ -3,6 +3,7 @@ import * as actions from 'constants/show_action_types';
import { addRequestToRequestList, onRequestError, onRequestUpdate, addAssetToAssetList } from 'actions/show';
import { getLongClaimId, getShortId, getClaimData } from 'api/assetApi';
import { selectShowState } from 'selectors/show';
import { selectSiteHost } from 'selectors/site';
export function * newAssetRequest (action) {
const { requestType, requestId, name, modifier } = action.data;
@ -11,13 +12,14 @@ export function * newAssetRequest (action) {
// is this an existing request?
// If this uri is in the request list, it's already been fetched
const state = yield select(selectShowState);
const host = yield select(selectSiteHost);
if (state.requestList[requestId]) {
return null;
}
// get long id && add request to request list
let longId;
try {
({data: longId} = yield call(getLongClaimId, name, modifier));
({data: longId} = yield call(getLongClaimId, host, name, modifier));
} catch (error) {
return yield put(onRequestError(error.message));
}
@ -31,14 +33,14 @@ export function * newAssetRequest (action) {
// get short Id
let shortId;
try {
({data: shortId} = yield call(getShortId, name, longId));
({data: shortId} = yield call(getShortId, host, name, longId));
} catch (error) {
return yield put(onRequestError(error.message));
}
// get asset claim data
let claimData;
try {
({data: claimData} = yield call(getClaimData, name, longId));
({data: claimData} = yield call(getClaimData, host, name, longId));
} catch (error) {
return yield put(onRequestError(error.message));
}

View file

@ -3,6 +3,7 @@ import * as actions from 'constants/show_action_types';
import { addNewChannelToChannelList, addRequestToRequestList, onRequestError, onRequestUpdate, updateChannelClaims } from 'actions/show';
import { getChannelClaims, getChannelData } from 'api/channelApi';
import { selectShowState } from 'selectors/show';
import { selectSiteHost } from 'selectors/site';
export function * newChannelRequest (action) {
const { requestType, requestId, channelName, channelId } = action.data;
@ -11,13 +12,14 @@ export function * newChannelRequest (action) {
// is this an existing request?
// If this uri is in the request list, it's already been fetched
const state = yield select(selectShowState);
const host = yield select(selectSiteHost);
if (state.requestList[requestId]) {
return null;
}
// get channel long id
let longId, shortId;
try {
({ data: {longChannelClaimId: longId, shortChannelClaimId: shortId} } = yield call(getChannelData, channelName, channelId));
({ data: {longChannelClaimId: longId, shortChannelClaimId: shortId} } = yield call(getChannelData, host, channelName, channelId));
} catch (error) {
return yield put(onRequestError(error.message));
}
@ -32,7 +34,7 @@ export function * newChannelRequest (action) {
// get channel claims data
let claimsData;
try {
({ data: claimsData } = yield call(getChannelClaims, channelName, longId, 1));
({ data: claimsData } = yield call(getChannelClaims, host, longId, channelName, 1));
} catch (error) {
return yield put(onRequestError(error.message));
}
@ -48,9 +50,10 @@ export function * watchNewChannelRequest () {
function * getNewClaimsAndUpdateChannel (action) {
const { channelKey, name, longId, page } = action.data;
const host = yield select(selectSiteHost);
let claimsData;
try {
({ data: claimsData } = yield call(getChannelClaims, name, longId, page));
({ data: claimsData } = yield call(getChannelClaims, host, longId, name, page));
} catch (error) {
return yield put(onRequestError(error.message));
}

View file

@ -1,3 +1,7 @@
export const selectSiteState = (state) => {
return state.site;
};
export const selectSiteHost = (state) => {
return state.site.host;
};

View file

@ -1,37 +1,29 @@
const { details: { host } } = require('../../config/siteConfig.js');
const createBasicCanonicalLink = (page) => {
if (!page) {
return `${host}`;
};
return `${host}/${page}`;
const createBasicCanonicalLink = (page, siteHost) => {
return `${siteHost}/${page}`;
};
const createAssetCanonicalLink = (asset) => {
const createAssetCanonicalLink = (asset, siteHost) => {
let channelName, certificateId, name, claimId;
if (asset.claimData) {
({ channelName, certificateId, name, claimId } = asset.claimData);
};
if (channelName) {
return `${host}/${channelName}:${certificateId}/${name}`;
return `${siteHost}/${channelName}:${certificateId}/${name}`;
};
return `${host}/${claimId}/${name}`;
return `${siteHost}/${claimId}/${name}`;
};
const createChannelCanonicalLink = (channel) => {
const createChannelCanonicalLink = (channel, siteHost) => {
const { name, longId } = channel;
return `${host}/${name}:${longId}`;
return `${siteHost}/${name}:${longId}`;
};
export const createCanonicalLink = (asset, channel, page) => {
export const createCanonicalLink = (asset, channel, page, siteHost) => {
if (asset) {
return createAssetCanonicalLink(asset);
return createAssetCanonicalLink(asset, siteHost);
}
if (channel) {
return createChannelCanonicalLink(channel);
return createChannelCanonicalLink(channel, siteHost);
}
if (page) {
return createBasicCanonicalLink(page);
}
return createBasicCanonicalLink();
return createBasicCanonicalLink(page, siteHost);
};

View file

@ -1,5 +1,3 @@
const { details: { title, host, description }, assetDefaults: { thumbnail: defaultThumbnail, description: defaultDescription } } = require('../../config/siteConfig.js');
const determineOgThumbnailContentType = (thumbnail) => {
if (thumbnail) {
const fileExt = thumbnail.substring(thumbnail.lastIndexOf('.'));
@ -20,35 +18,35 @@ const determineOgThumbnailContentType = (thumbnail) => {
return '';
};
const createBasicMetaTags = () => {
const createBasicMetaTags = (siteHost, siteDescription, siteTitle, siteTwitter) => {
return [
{property: 'og:title', content: title},
{property: 'og:url', content: host},
{property: 'og:site_name', content: title},
{property: 'og:description', content: description},
{property: 'twitter:site', content: '@spee_ch'},
{property: 'og:title', content: siteTitle},
{property: 'og:url', content: siteHost},
{property: 'og:site_name', content: siteTitle},
{property: 'og:description', content: siteDescription},
{property: 'twitter:site', content: siteTwitter},
{property: 'twitter:card', content: 'summary'},
];
};
const createChannelMetaTags = (channel) => {
const createChannelMetaTags = (siteTitle, siteHost, siteTwitter, channel) => {
const { name, longId } = channel;
return [
{property: 'og:title', content: `${name} on ${title}`},
{property: 'og:url', content: `${host}/${name}:${longId}`},
{property: 'og:site_name', content: title},
{property: 'og:description', content: `${name}, a channel on ${title}`},
{property: 'twitter:site', content: '@spee_ch'},
{property: 'og:title', content: `${name} on ${siteTitle}`},
{property: 'og:url', content: `${siteHost}/${name}:${longId}`},
{property: 'og:site_name', content: siteTitle},
{property: 'og:description', content: `${name}, a channel on ${siteTitle}`},
{property: 'twitter:site', content: siteTwitter},
{property: 'twitter:card', content: 'summary'},
];
};
const createAssetMetaTags = (asset) => {
const createAssetMetaTags = (siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail) => {
const { claimData } = asset;
const { contentType } = claimData;
const embedUrl = `${host}/${claimData.claimId}/${claimData.name}`;
const showUrl = `${host}/${claimData.claimId}/${claimData.name}`;
const source = `${host}/${claimData.claimId}/${claimData.name}.${claimData.fileExt}`;
const embedUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`;
const showUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`;
const source = `${siteHost}/${claimData.claimId}/${claimData.name}.${claimData.fileExt}`;
const ogTitle = claimData.title || claimData.name;
const ogDescription = claimData.description || defaultDescription;
const ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail);
@ -56,11 +54,11 @@ const createAssetMetaTags = (asset) => {
const metaTags = [
{property: 'og:title', content: ogTitle},
{property: 'og:url', content: showUrl},
{property: 'og:site_name', content: title},
{property: 'og:site_name', content: siteTitle},
{property: 'og:description', content: ogDescription},
{property: 'og:image:width', content: 600},
{property: 'og:image:height', content: 315},
{property: 'twitter:site', content: '@spee_ch'},
{property: 'twitter:site', content: siteTwitter},
];
if (contentType === 'video/mp4' || contentType === 'video/webm') {
metaTags.push({property: 'og:video', content: source});
@ -85,12 +83,12 @@ const createAssetMetaTags = (asset) => {
return metaTags;
};
export const createMetaTags = (asset, channel) => {
export const createMetaTags = (siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail) => {
if (asset) {
return createAssetMetaTags(asset);
return createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail);
};
if (channel) {
return createChannelMetaTags(channel);
return createChannelMetaTags(siteHost, siteTitle, siteTwitter, channel);
};
return createBasicMetaTags();
return createBasicMetaTags(siteDescription, siteHost, siteTitle, siteTwitter);
};

View file

@ -1,8 +1,6 @@
const { details: { title } } = require('../../config/siteConfig.js');
export const createPageTitle = (pageTitle) => {
export const createPageTitle = (siteTitle, pageTitle) => {
if (!pageTitle) {
return `${title}`;
return `${siteTitle}`;
}
return `${title} - ${pageTitle}`;
return `${siteTitle} - ${pageTitle}`;
};

View file

@ -15,7 +15,6 @@ module.exports = (app) => {
// route for log in
app.post('/login', (req, res, next) => {
passport.authenticate('local-login', (err, user, info) => {
logger.debug('info:', info);
if (err) {
return next(err);
}