commit
e46533046f
13 changed files with 158 additions and 80 deletions
|
@ -1,9 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import createCanonicalLink from '../../../../utils/createCanonicalLink';
|
||||||
|
|
||||||
const AssetPreview = ({ defaultThumbnail, claimData: { name, claimId, fileExt, contentType, thumbnail, title } }) => {
|
const AssetPreview = ({ defaultThumbnail, claimData }) => {
|
||||||
const embedUrl = `/${claimId}/${name}.${fileExt}`;
|
const { name, fileExt, contentType, thumbnail, title } = claimData;
|
||||||
const showUrl = `/${claimId}/${name}`;
|
const showUrl = createCanonicalLink({ asset: { ...claimData }});
|
||||||
|
const embedUrl = `${showUrl}.${fileExt}`;
|
||||||
return (
|
return (
|
||||||
<Link to={showUrl} className='asset-preview'>
|
<Link to={showUrl} className='asset-preview'>
|
||||||
{(() => {
|
{(() => {
|
||||||
|
|
|
@ -1,48 +1,48 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import SocialShareLink from '@components/SocialShareLink';
|
import SocialShareLink from '@components/SocialShareLink';
|
||||||
|
|
||||||
const AssetShareButtons = ({ host, name, shortId }) => {
|
const AssetShareButtons = ({ assetUrl, name }) => {
|
||||||
return (
|
return (
|
||||||
<SocialShareLink >
|
<SocialShareLink >
|
||||||
<a
|
<a
|
||||||
className='link--primary'
|
className='link--primary'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
href={`https://twitter.com/intent/tweet?text=${host}/${shortId}/${name}`}
|
href={`https://twitter.com/intent/tweet?text=${assetUrl}`}
|
||||||
>
|
>
|
||||||
twitter
|
twitter
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
className='link--primary'
|
className='link--primary'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
href={`https://www.facebook.com/sharer/sharer.php?u=${host}/${shortId}/${name}`}
|
href={`https://www.facebook.com/sharer/sharer.php?u=${assetUrl}`}
|
||||||
>
|
>
|
||||||
facebook
|
facebook
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
className='link--primary'
|
className='link--primary'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
href={`https://tumblr.com/widgets/share/tool?canonicalUrl=${host}/${shortId}/${name}`}
|
href={`https://tumblr.com/widgets/share/tool?canonicalUrl=${assetUrl}`}
|
||||||
>
|
>
|
||||||
tumblr
|
tumblr
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
className='link--primary'
|
className='link--primary'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
href={`https://www.reddit.com/submit?url=${host}/${shortId}/${name}&title=${name}`}
|
href={`https://www.reddit.com/submit?url=${assetUrl}&title=${name}`}
|
||||||
>
|
>
|
||||||
reddit
|
reddit
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
className='link--primary'
|
className='link--primary'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
href={`https://sharetomastodon.github.io/?title=${name}&url=${host}/${shortId}/${name}`}
|
href={`https://sharetomastodon.github.io/?title=${name}&url=${assetUrl}`}
|
||||||
>
|
>
|
||||||
mastodon
|
mastodon
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
className='link--primary'
|
className='link--primary'
|
||||||
target='_blank'
|
target='_blank'
|
||||||
href={`https://share.diasporafoundation.org/?title=${name}&url=${host}/${shortId}/${name}`}
|
href={`https://share.diasporafoundation.org/?title=${name}&url=${assetUrl}`}
|
||||||
>
|
>
|
||||||
diaspora
|
diaspora
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -7,18 +7,26 @@ import SpaceBetween from '@components/SpaceBetween';
|
||||||
import AssetShareButtons from '@components/AssetShareButtons';
|
import AssetShareButtons from '@components/AssetShareButtons';
|
||||||
import ClickToCopy from '@components/ClickToCopy';
|
import ClickToCopy from '@components/ClickToCopy';
|
||||||
|
|
||||||
|
import siteConfig from '@config/siteConfig.json';
|
||||||
|
const { details: { host } } = siteConfig;
|
||||||
|
import createCanonicalLink from '../../../../utils/createCanonicalLink';
|
||||||
|
|
||||||
class AssetInfo extends React.Component {
|
class AssetInfo extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
const {
|
const { asset } = this.props;
|
||||||
asset: {
|
const { claimViews, claimData: { channelName, channelShortId, description, name, fileExt, contentType, thumbnail, host } } = asset;
|
||||||
shortId,
|
|
||||||
claimData : {
|
|
||||||
channelName, certificateId, description, name, claimId, fileExt, contentType, thumbnail, host
|
|
||||||
},
|
|
||||||
claimViews,
|
|
||||||
}
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
|
const canonicalUrl = createCanonicalLink({ asset: { ...asset.claimData, shortId: asset.shortId }});
|
||||||
|
const assetCanonicalUrl = `${host}${canonicalUrl}`;
|
||||||
|
|
||||||
|
let channelCanonicalUrl;
|
||||||
|
if (channelName) {
|
||||||
|
const channel = {
|
||||||
|
name: channelName,
|
||||||
|
shortId: channelShortId,
|
||||||
|
};
|
||||||
|
channelCanonicalUrl = `${createCanonicalLink({channel})}`;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{channelName && (
|
{channelName && (
|
||||||
|
@ -29,7 +37,7 @@ class AssetInfo extends React.Component {
|
||||||
}
|
}
|
||||||
content={
|
content={
|
||||||
<span className='text'>
|
<span className='text'>
|
||||||
<Link to={`/${channelName}:${certificateId}`}>{channelName}</Link>
|
<Link to={channelCanonicalUrl}>{channelName}</Link>
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -58,9 +66,8 @@ class AssetInfo extends React.Component {
|
||||||
}
|
}
|
||||||
content={
|
content={
|
||||||
<AssetShareButtons
|
<AssetShareButtons
|
||||||
host={host}
|
|
||||||
name={name}
|
name={name}
|
||||||
shortId={shortId}
|
assetUrl={assetCanonicalUrl}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -74,7 +81,7 @@ class AssetInfo extends React.Component {
|
||||||
content={
|
content={
|
||||||
<ClickToCopy
|
<ClickToCopy
|
||||||
id={'short-link'}
|
id={'short-link'}
|
||||||
value={`${host}/${shortId}/${name}`}
|
value={assetCanonicalUrl}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -90,12 +97,12 @@ class AssetInfo extends React.Component {
|
||||||
{(contentType === 'video/mp4') ? (
|
{(contentType === 'video/mp4') ? (
|
||||||
<ClickToCopy
|
<ClickToCopy
|
||||||
id={'embed-text-video'}
|
id={'embed-text-video'}
|
||||||
value={`<iframe src="${host}/video-embed/${name}/${claimId}" allowfullscreen="true" style="border:0" /></iframe>`}
|
value={`<iframe src="${host}/video-embed${canonicalUrl}" allowfullscreen="true" style="border:0" /></iframe>`}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ClickToCopy
|
<ClickToCopy
|
||||||
id={'embed-text-image'}
|
id={'embed-text-image'}
|
||||||
value={`<img src="${host}/${claimId}/${name}.${fileExt}"/>`}
|
value={`<img src="${assetCanonicalUrl}.${fileExt}"/>`}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -107,13 +114,13 @@ class AssetInfo extends React.Component {
|
||||||
<SpaceBetween>
|
<SpaceBetween>
|
||||||
<a
|
<a
|
||||||
className='link--primary'
|
className='link--primary'
|
||||||
href={`${host}/${claimId}/${name}.${fileExt}`}
|
href={`${assetCanonicalUrl}.${fileExt}`}
|
||||||
>
|
>
|
||||||
Direct Link
|
Direct Link
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
className={'link--primary'}
|
className={'link--primary'}
|
||||||
href={`${host}/${claimId}/${name}.${fileExt}`}
|
href={`${assetCanonicalUrl}.${fileExt}`}
|
||||||
download={name}
|
download={name}
|
||||||
>
|
>
|
||||||
Download
|
Download
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NavLink, withRouter } from 'react-router-dom';
|
import { NavLink, withRouter } from 'react-router-dom';
|
||||||
import NavBarChannelOptionsDropdown from '@components/NavBarChannelOptionsDropdown';
|
import NavBarChannelOptionsDropdown from '@components/NavBarChannelOptionsDropdown';
|
||||||
|
import createCanonicalLink from '../../../../utils/createCanonicalLink';
|
||||||
|
|
||||||
const VIEW = 'VIEW';
|
const VIEW = 'VIEW';
|
||||||
const LOGOUT = 'LOGOUT';
|
const LOGOUT = 'LOGOUT';
|
||||||
|
@ -14,6 +15,7 @@ class NavigationLinks extends React.Component {
|
||||||
this.props.checkForLoggedInChannel();
|
this.props.checkForLoggedInChannel();
|
||||||
}
|
}
|
||||||
handleSelection (event) {
|
handleSelection (event) {
|
||||||
|
const { history, channelName: name, channelShortId: shortId } = this.props;
|
||||||
const value = event.target.selectedOptions[0].value;
|
const value = event.target.selectedOptions[0].value;
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case LOGOUT:
|
case LOGOUT:
|
||||||
|
@ -21,7 +23,7 @@ class NavigationLinks extends React.Component {
|
||||||
break;
|
break;
|
||||||
case VIEW:
|
case VIEW:
|
||||||
// redirect to channel page
|
// redirect to channel page
|
||||||
this.props.history.push(`/${this.props.channelName}:${this.props.channelLongId}`);
|
history.push(createCanonicalLink({ channel: { name, shortId } }));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2,12 +2,12 @@ import React from 'react';
|
||||||
import Helmet from 'react-helmet';
|
import Helmet from 'react-helmet';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import siteConfig from '@config/siteConfig.json';
|
|
||||||
import createPageTitle from '../../utils/createPageTitle';
|
import createPageTitle from '../../utils/createPageTitle';
|
||||||
import createMetaTags from '../../utils/createMetaTags';
|
import createMetaTags from '../../utils/createMetaTags';
|
||||||
import oEmbed from '../../utils/oEmbed.js';
|
import oEmbed from '../../utils/oEmbed.js';
|
||||||
import createCanonicalLink from '../../utils/createCanonicalLink';
|
import createCanonicalLink from '../../../../utils/createCanonicalLink';
|
||||||
|
|
||||||
|
import siteConfig from '@config/siteConfig.json';
|
||||||
const { details: { host } } = siteConfig;
|
const { details: { host } } = siteConfig;
|
||||||
|
|
||||||
class SEO extends React.Component {
|
class SEO extends React.Component {
|
||||||
|
@ -21,7 +21,11 @@ class SEO extends React.Component {
|
||||||
asset,
|
asset,
|
||||||
channel,
|
channel,
|
||||||
});
|
});
|
||||||
const cannonicalLink = createCanonicalLink(asset, channel, pageUri);
|
const canonicalLink = `${host}${createCanonicalLink({
|
||||||
|
asset: asset ? { ...asset.claimData, shortId: asset.shortId } : undefined,
|
||||||
|
channel,
|
||||||
|
page: pageUri,
|
||||||
|
})}`;
|
||||||
// render results
|
// render results
|
||||||
return (
|
return (
|
||||||
<Helmet
|
<Helmet
|
||||||
|
@ -30,9 +34,9 @@ class SEO extends React.Component {
|
||||||
link={[
|
link={[
|
||||||
{
|
{
|
||||||
rel : 'canonical',
|
rel : 'canonical',
|
||||||
href: cannonicalLink,
|
href: canonicalLink,
|
||||||
},
|
},
|
||||||
oEmbed.json(host, cannonicalLink),
|
oEmbed.json(host, canonicalLink),
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import siteConfig from '@config/siteConfig.json';
|
import siteConfig from '@config/siteConfig.json';
|
||||||
import determineContentTypeFromExtension from './determineContentTypeFromExtension';
|
import determineContentTypeFromExtension from './determineContentTypeFromExtension';
|
||||||
import createMetaTagsArray from './createMetaTagsArray';
|
import createMetaTagsArray from './createMetaTagsArray';
|
||||||
|
import createCanonicalLink from '../../../utils/createCanonicalLink';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
details: {
|
details: {
|
||||||
|
@ -37,8 +38,10 @@ const determineMediaType = (contentType) => {
|
||||||
const createAssetMetaTags = (asset) => {
|
const createAssetMetaTags = (asset) => {
|
||||||
const { claimData } = asset;
|
const { claimData } = asset;
|
||||||
const { contentType } = claimData;
|
const { contentType } = claimData;
|
||||||
const showUrl = `${host}/${claimData.claimId}/${claimData.name}`;
|
const canonicalLink = createCanonicalLink({ asset: { ...asset.claimData, shortId: asset.shortId }});
|
||||||
const serveUrl = `${host}/${claimData.claimId}/${claimData.name}.${claimData.fileExt}`;
|
const showUrl = `${host}${canonicalLink}`;
|
||||||
|
const serveUrl = `${showUrl}.${claimData.fileExt}`;
|
||||||
|
|
||||||
const ogTitle = claimData.title || claimData.name;
|
const ogTitle = claimData.title || claimData.name;
|
||||||
const ogDescription = claimData.description || defaultDescription;
|
const ogDescription = claimData.description || defaultDescription;
|
||||||
const ogThumbnailContentType = determineContentTypeFromExtension(claimData.thumbnail);
|
const ogThumbnailContentType = determineContentTypeFromExtension(claimData.thumbnail);
|
||||||
|
@ -55,7 +58,7 @@ const createAssetMetaTags = (asset) => {
|
||||||
'fb:app_id' : '1371961932852223',
|
'fb:app_id' : '1371961932852223',
|
||||||
};
|
};
|
||||||
if (determineMediaType(contentType) === VIDEO) {
|
if (determineMediaType(contentType) === VIDEO) {
|
||||||
const videoEmbedUrl = `${host}/video-embed/${claimData.name}/${claimData.claimId}`;
|
const videoEmbedUrl = `${host}/video-embed${canonicalLink}`;
|
||||||
// card type tags
|
// card type tags
|
||||||
metaTags['og:type'] = 'video.other';
|
metaTags['og:type'] = 'video.other';
|
||||||
metaTags['twitter:card'] = 'player';
|
metaTags['twitter:card'] = 'player';
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
import siteConfig from '@config/siteConfig.json';
|
|
||||||
|
|
||||||
const {
|
|
||||||
details: {
|
|
||||||
host,
|
|
||||||
},
|
|
||||||
} = siteConfig;
|
|
||||||
|
|
||||||
const createBasicCanonicalLink = (page) => {
|
|
||||||
return `${host}/${page}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const createAssetCanonicalLink = (asset) => {
|
|
||||||
let channelName, certificateId, name, claimId;
|
|
||||||
if (asset.claimData) {
|
|
||||||
({ channelName, certificateId, name, claimId } = asset.claimData);
|
|
||||||
}
|
|
||||||
if (channelName) {
|
|
||||||
return `${host}/${channelName}:${certificateId}/${name}`;
|
|
||||||
}
|
|
||||||
return `${host}/${claimId}/${name}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const createChannelCanonicalLink = (channel) => {
|
|
||||||
const { name, longId } = channel;
|
|
||||||
return `${host}/${name}:${longId}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const createCanonicalLink = (asset, channel, page) => {
|
|
||||||
if (asset) {
|
|
||||||
return createAssetCanonicalLink(asset);
|
|
||||||
}
|
|
||||||
if (channel) {
|
|
||||||
return createChannelCanonicalLink(channel);
|
|
||||||
}
|
|
||||||
return createBasicCanonicalLink(page);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createCanonicalLink;
|
|
|
@ -1,6 +1,7 @@
|
||||||
import siteConfig from '@config/siteConfig.json';
|
import siteConfig from '@config/siteConfig.json';
|
||||||
import determineContentTypeFromExtension from './determineContentTypeFromExtension';
|
import determineContentTypeFromExtension from './determineContentTypeFromExtension';
|
||||||
import createMetaTagsArray from './createMetaTagsArray';
|
import createMetaTagsArray from './createMetaTagsArray';
|
||||||
|
import createCanonicalLink from '../../../utils/createCanonicalLink';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
details: {
|
details: {
|
||||||
|
@ -14,7 +15,7 @@ const {
|
||||||
} = siteConfig;
|
} = siteConfig;
|
||||||
|
|
||||||
export const createChannelMetaTags = (channel) => {
|
export const createChannelMetaTags = (channel) => {
|
||||||
const { name, longId } = channel;
|
const { name, shortId } = channel;
|
||||||
const metaTags = {
|
const metaTags = {
|
||||||
// page detail tags
|
// page detail tags
|
||||||
'og:title' : `${name} on ${siteTitle}`,
|
'og:title' : `${name} on ${siteTitle}`,
|
||||||
|
@ -22,7 +23,7 @@ export const createChannelMetaTags = (channel) => {
|
||||||
'og:description' : `${name}, a channel on ${siteTitle}`,
|
'og:description' : `${name}, a channel on ${siteTitle}`,
|
||||||
'twitter:description': `${name}, a channel on ${siteTitle}`,
|
'twitter:description': `${name}, a channel on ${siteTitle}`,
|
||||||
// url
|
// url
|
||||||
'og:url' : `${host}/${name}:${longId}`,
|
'og:url' : `${host}/${createCanonicalLink({ channel })}`,
|
||||||
// site info
|
// site info
|
||||||
'og:site_name' : siteTitle,
|
'og:site_name' : siteTitle,
|
||||||
'twitter:site' : twitter,
|
'twitter:site' : twitter,
|
||||||
|
|
|
@ -69,12 +69,19 @@ const parseLogoConfigParam = async (rawConfig) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const sendVideoEmbedPage = async ({ params }, res) => {
|
const sendVideoEmbedPage = async ({ params }, res) => {
|
||||||
const {
|
let {
|
||||||
claimId,
|
claimId,
|
||||||
config,
|
config,
|
||||||
name,
|
name,
|
||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
|
// if channel then swap name and claimId for order
|
||||||
|
if (name[0] === '@' && name.includes(':')) {
|
||||||
|
const temp = name;
|
||||||
|
name = claimId;
|
||||||
|
claimId = temp;
|
||||||
|
}
|
||||||
|
|
||||||
const logoConfig = await parseLogoConfigParam(config);
|
const logoConfig = await parseLogoConfigParam(config);
|
||||||
|
|
||||||
// test setting response headers
|
// test setting response headers
|
||||||
|
|
|
@ -34,6 +34,35 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
|
||||||
|
|
||||||
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||||
|
|
||||||
|
var createCanonicalLink = require('../../../utils/createCanonicalLink');
|
||||||
|
|
||||||
|
var getCanonicalUrlFromShow = function getCanonicalUrlFromShow(show) {
|
||||||
|
var requestId = show.requestList[show.request.id];
|
||||||
|
var requestType = show.request.type;
|
||||||
|
|
||||||
|
switch (requestType) {
|
||||||
|
case 'ASSET_DETAILS':
|
||||||
|
var asset = show.assetList[requestId.key];
|
||||||
|
return createCanonicalLink({
|
||||||
|
asset: _objectSpread({}, asset.claimData, {
|
||||||
|
shortId: asset.shortId
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
case 'CHANNEL':
|
||||||
|
return createCanonicalLink({
|
||||||
|
channel: show.channelList[requestId.key]
|
||||||
|
});
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var returnSagaWithParams = function returnSagaWithParams(saga, params) {
|
var returnSagaWithParams = function returnSagaWithParams(saga, params) {
|
||||||
return (
|
return (
|
||||||
/*#__PURE__*/
|
/*#__PURE__*/
|
||||||
|
@ -115,6 +144,14 @@ module.exports = function (req, res) {
|
||||||
var boundSaga = returnSagaWithParams(saga, boundAction); // run the saga middleware with the saga call
|
var boundSaga = returnSagaWithParams(saga, boundAction); // run the saga middleware with the saga call
|
||||||
|
|
||||||
sagaMiddleware.run(boundSaga).done.then(function () {
|
sagaMiddleware.run(boundSaga).done.then(function () {
|
||||||
|
// redirect if request does not use canonical url
|
||||||
|
var canonicalUrl = getCanonicalUrlFromShow(store.getState().show);
|
||||||
|
|
||||||
|
if (canonicalUrl && canonicalUrl !== req.originalUrl) {
|
||||||
|
console.log("redirecting ".concat(req.originalUrl, " to ").concat(canonicalUrl));
|
||||||
|
res.redirect(canonicalUrl);
|
||||||
|
}
|
||||||
|
|
||||||
return renderPage(store);
|
return renderPage(store);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,12 +15,27 @@ import App from '@app';
|
||||||
import Sagas from '@sagas';
|
import Sagas from '@sagas';
|
||||||
import Actions from '@actions';
|
import Actions from '@actions';
|
||||||
|
|
||||||
|
const createCanonicalLink = require('../../../utils/createCanonicalLink');
|
||||||
|
|
||||||
|
const getCanonicalUrlFromShow = show => {
|
||||||
|
const requestId = show.requestList[show.request.id];
|
||||||
|
const requestType = show.request.type;
|
||||||
|
switch (requestType) {
|
||||||
|
case 'ASSET_DETAILS':
|
||||||
|
const asset = show.assetList[requestId.key];
|
||||||
|
return createCanonicalLink({ asset: { ...asset.claimData, shortId: asset.shortId }});
|
||||||
|
case 'CHANNEL':
|
||||||
|
return createCanonicalLink({ channel: show.channelList[requestId.key] });
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const returnSagaWithParams = (saga, params) => {
|
const returnSagaWithParams = (saga, params) => {
|
||||||
return function * () {
|
return function * () {
|
||||||
yield call(saga, params);
|
yield call(saga, params);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = (req, res) => {
|
module.exports = (req, res) => {
|
||||||
let context = {};
|
let context = {};
|
||||||
|
|
||||||
|
@ -90,7 +105,15 @@ module.exports = (req, res) => {
|
||||||
sagaMiddleware
|
sagaMiddleware
|
||||||
.run(boundSaga)
|
.run(boundSaga)
|
||||||
.done
|
.done
|
||||||
.then(() => renderPage(store) );
|
.then(() => {
|
||||||
|
// redirect if request does not use canonical url
|
||||||
|
const canonicalUrl = getCanonicalUrlFromShow(store.getState().show);
|
||||||
|
if (canonicalUrl && canonicalUrl !== req.originalUrl) {
|
||||||
|
console.log(`redirecting ${req.originalUrl} to ${canonicalUrl}`);
|
||||||
|
res.redirect(canonicalUrl);
|
||||||
|
}
|
||||||
|
return renderPage(store)
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
const store = createStore(Reducers);
|
const store = createStore(Reducers);
|
||||||
renderPage(store);
|
renderPage(store);
|
||||||
|
|
|
@ -10,11 +10,17 @@ module.exports = async (data) => {
|
||||||
channelName = await chainquery.claim.queries.getClaimChannelName(certificateId).catch(()=>{});
|
channelName = await chainquery.claim.queries.getClaimChannelName(certificateId).catch(()=>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let channelShortId = null;
|
||||||
|
if (certificateId && channelName) {
|
||||||
|
channelShortId = await chainquery.claim.queries.getShortClaimIdFromLongClaimId(certificateId, channelName).catch(() => null);
|
||||||
|
}
|
||||||
|
|
||||||
return ({
|
return ({
|
||||||
name: data.name,
|
name: data.name,
|
||||||
title: data.title,
|
title: data.title,
|
||||||
certificateId,
|
certificateId,
|
||||||
channelName,
|
channelName,
|
||||||
|
channelShortId,
|
||||||
contentType: data.content_type || data.contentType,
|
contentType: data.content_type || data.contentType,
|
||||||
claimId: data.claim_id || data.claimId,
|
claimId: data.claim_id || data.claimId,
|
||||||
fileExt: data.generated_extension || data.fileExt,
|
fileExt: data.generated_extension || data.fileExt,
|
||||||
|
|
25
utils/createCanonicalLink.js
Normal file
25
utils/createCanonicalLink.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
const createBasicCanonicalLink = (page) => {
|
||||||
|
return `/${page}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const createAssetCanonicalLink = (asset) => {
|
||||||
|
const { channelName, channelShortId, name, claimId, shortId } = asset;
|
||||||
|
return channelName ? `/${channelName}:${channelShortId}/${name}` : `/${shortId || claimId}/${name}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const createChannelCanonicalLink = (channel) => {
|
||||||
|
const { name, shortId } = channel;
|
||||||
|
return `/${name}:${shortId}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const createCanonicalLink = ({asset, channel, page}) => {
|
||||||
|
if (asset) {
|
||||||
|
return createAssetCanonicalLink(asset);
|
||||||
|
}
|
||||||
|
if (channel) {
|
||||||
|
return createChannelCanonicalLink(channel);
|
||||||
|
}
|
||||||
|
return createBasicCanonicalLink(page);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = createCanonicalLink;
|
Loading…
Add table
Reference in a new issue