diff --git a/client/build/components/AssetPreview/index.js b/client/build/components/AssetPreview/index.js
index 994b75ce..1d044764 100644
--- a/client/build/components/AssetPreview/index.js
+++ b/client/build/components/AssetPreview/index.js
@@ -19,10 +19,10 @@ var AssetPreview = function AssetPreview(_ref) {
fileExt = _ref$claimData.fileExt,
contentType = _ref$claimData.contentType,
thumbnail = _ref$claimData.thumbnail;
- var directSourceLink = "asset/".concat(name, "/").concat(claimId);
- var showUrlLink = "/".concat(claimId, "/").concat(name);
+ var embedUrl = "/".concat(claimId, "/").concat(name, ".").concat(fileExt);
+ var showUrl = "/".concat(claimId, "/").concat(name);
return _react.default.createElement(_reactRouterDom.Link, {
- to: showUrlLink
+ to: showUrl
}, function () {
switch (contentType) {
case 'image/jpeg':
@@ -31,7 +31,7 @@ var AssetPreview = function AssetPreview(_ref) {
case 'image/gif':
return _react.default.createElement("img", {
className: 'asset-preview-image',
- src: directSourceLink,
+ src: embedUrl,
alt: name
});
diff --git a/client/build/containers/AssetDisplay/view.js b/client/build/containers/AssetDisplay/view.js
index c0d1f013..d8e5620c 100644
--- a/client/build/containers/AssetDisplay/view.js
+++ b/client/build/containers/AssetDisplay/view.js
@@ -60,6 +60,7 @@ function (_React$Component) {
contentType = _this$props$asset$cla2.contentType,
fileExt = _this$props$asset$cla2.fileExt,
thumbnail = _this$props$asset$cla2.thumbnail;
+ var sourceUrl = "/".concat(claimId, "/").concat(name, ".").concat(fileExt);
return _react.default.createElement("div", {
className: 'asset-display'
}, status === _asset_display_states.LOCAL_CHECK && _react.default.createElement("div", null, _react.default.createElement("p", null, "Checking to see if Spee.ch has your asset locally...")), status === _asset_display_states.UNAVAILABLE && _react.default.createElement("div", null, _react.default.createElement("p", null, "Sit tight, we're searching the LBRY blockchain for your asset!"), _react.default.createElement(_ProgressBar.default, {
@@ -82,7 +83,7 @@ function (_React$Component) {
case 'image/gif':
return _react.default.createElement("img", {
className: "asset-image",
- src: "/asset/".concat(name, "/").concat(claimId),
+ src: sourceUrl,
alt: name
});
@@ -92,11 +93,11 @@ function (_React$Component) {
controls: true,
poster: thumbnail
}, _react.default.createElement("source", {
- src: "/asset/".concat(name, "/").concat(claimId)
+ src: sourceUrl
}), _react.default.createElement("p", null, "Your browser does not support the ", _react.default.createElement("code", null, "video"), " element."));
default:
- return _react.default.createElement("p", null, "Unsupported file type");
+ return _react.default.createElement("p", null, "Unsupported content type");
}
}());
}
diff --git a/client/build/containers/AssetInfo/view.js b/client/build/containers/AssetInfo/view.js
index 55eefee1..8a968a42 100644
--- a/client/build/containers/AssetInfo/view.js
+++ b/client/build/containers/AssetInfo/view.js
@@ -89,7 +89,7 @@ function (_React$Component) {
}),
content: _react.default.createElement(_ClickToCopy.default, {
id: 'short-link',
- value: "".concat(host, "/").concat(shortId, "/").concat(name, ".").concat(fileExt)
+ value: "".concat(host, "/").concat(shortId, "/").concat(name)
})
})), _react.default.createElement(_Row.default, null, _react.default.createElement(_RowLabeled.default, {
label: _react.default.createElement(_Label.default, {
@@ -102,9 +102,9 @@ function (_React$Component) {
id: 'embed-text-image',
value: "")
}))
- })), _react.default.createElement(_Row.default, null, _react.default.createElement(_SpaceBetween.default, null, _react.default.createElement(_reactRouterDom.Link, {
+ })), _react.default.createElement(_Row.default, null, _react.default.createElement(_SpaceBetween.default, null, _react.default.createElement("a", {
className: "link--primary",
- to: "/".concat(shortId, "/").concat(name, ".").concat(fileExt)
+ href: "".concat(host, "/").concat(claimId, "/").concat(name, ".").concat(fileExt)
}, "Direct Link"), _react.default.createElement("a", {
className: 'link--primary',
href: "".concat(host, "/").concat(claimId, "/").concat(name, ".").concat(fileExt),
diff --git a/client/build/containers/SEO/index.js b/client/build/containers/SEO/index.js
index 68ed79ed..bbd3c41e 100644
--- a/client/build/containers/SEO/index.js
+++ b/client/build/containers/SEO/index.js
@@ -11,24 +11,6 @@ var _view = _interopRequireDefault(require("./view"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-var mapStateToProps = function mapStateToProps(_ref) {
- var site = _ref.site;
- var defaultDescription = site.defaultDescription,
- defaultThumbnail = site.defaultThumbnail,
- siteDescription = site.description,
- siteHost = site.host,
- siteTitle = site.title,
- siteTwitter = site.twitter;
- return {
- defaultDescription: defaultDescription,
- defaultThumbnail: defaultThumbnail,
- siteDescription: siteDescription,
- siteHost: siteHost,
- siteTitle: siteTitle,
- siteTwitter: siteTwitter
- };
-};
-
-var _default = (0, _reactRedux.connect)(mapStateToProps, null)(_view.default);
+var _default = (0, _reactRedux.connect)(null, null)(_view.default);
exports.default = _default;
\ No newline at end of file
diff --git a/client/build/containers/SEO/view.js b/client/build/containers/SEO/view.js
index 659abd7f..16b25365 100644
--- a/client/build/containers/SEO/view.js
+++ b/client/build/containers/SEO/view.js
@@ -11,11 +11,11 @@ var _reactHelmet = _interopRequireDefault(require("react-helmet"));
var _propTypes = _interopRequireDefault(require("prop-types"));
-var _pageTitle = require("../../utils/pageTitle");
+var _createPageTitle = _interopRequireDefault(require("../../utils/createPageTitle"));
-var _metaTags = require("../../utils/metaTags");
+var _createMetaTags = _interopRequireDefault(require("../../utils/createMetaTags"));
-var _canonicalLink = require("../../utils/canonicalLink");
+var _createCanonicalLink = _interopRequireDefault(require("../../utils/createCanonicalLink"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -49,33 +49,19 @@ function (_React$Component) {
_createClass(SEO, [{
key: "render",
value: function render() {
- // props from state
+ // props from parent
var _this$props = this.props,
- defaultDescription = _this$props.defaultDescription,
- defaultThumbnail = _this$props.defaultThumbnail,
- siteDescription = _this$props.siteDescription,
- siteHost = _this$props.siteHost,
- siteTitle = _this$props.siteTitle,
- siteTwitter = _this$props.siteTwitter; // props from parent
-
- var _this$props2 = this.props,
- asset = _this$props2.asset,
- channel = _this$props2.channel,
- pageUri = _this$props2.pageUri;
+ asset = _this$props.asset,
+ channel = _this$props.channel,
+ pageUri = _this$props.pageUri;
var pageTitle = this.props.pageTitle; // create page title, tags, and canonical link
- pageTitle = (0, _pageTitle.createPageTitle)(siteTitle, pageTitle);
- var metaTags = (0, _metaTags.createMetaTags)({
- siteDescription: siteDescription,
- siteHost: siteHost,
- siteTitle: siteTitle,
- siteTwitter: siteTwitter,
+ pageTitle = (0, _createPageTitle.default)(pageTitle);
+ var metaTags = (0, _createMetaTags.default)({
asset: asset,
- channel: channel,
- defaultDescription: defaultDescription,
- defaultThumbnail: defaultThumbnail
+ channel: channel
});
- var canonicalLink = (0, _canonicalLink.createCanonicalLink)(asset, channel, pageUri, siteHost); // render results
+ var canonicalLink = (0, _createCanonicalLink.default)(asset, channel, pageUri); // render results
return _react.default.createElement(_reactHelmet.default, {
title: pageTitle,
diff --git a/client/build/utils/createAssetMetaTags.js b/client/build/utils/createAssetMetaTags.js
new file mode 100644
index 00000000..3fb2720f
--- /dev/null
+++ b/client/build/utils/createAssetMetaTags.js
@@ -0,0 +1,105 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _siteConfig = _interopRequireDefault(require("@config/siteConfig.json"));
+
+var _determineContentTypeFromExtension = _interopRequireDefault(require("./determineContentTypeFromExtension"));
+
+var _createMetaTagsArray = _interopRequireDefault(require("./createMetaTagsArray"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var _siteConfig$details = _siteConfig.default.details,
+ host = _siteConfig$details.host,
+ siteTitle = _siteConfig$details.title,
+ twitter = _siteConfig$details.twitter,
+ _siteConfig$assetDefa = _siteConfig.default.assetDefaults,
+ defaultDescription = _siteConfig$assetDefa.description,
+ defaultThumbnail = _siteConfig$assetDefa.thumbnail;
+var VIDEO = 'VIDEO';
+var IMAGE = 'IMAGE';
+var GIF = 'GIF';
+
+var determineMediaType = function determineMediaType(contentType) {
+ switch (contentType) {
+ case 'image/jpg':
+ case 'image/jpeg':
+ case 'image/png':
+ return IMAGE;
+
+ case 'image/gif':
+ return GIF;
+
+ case 'video/mp4':
+ case 'video/webm':
+ return VIDEO;
+
+ default:
+ return '';
+ }
+};
+
+var createAssetMetaTags = function createAssetMetaTags(asset) {
+ var claimData = asset.claimData;
+ var contentType = claimData.contentType;
+ var showUrl = "".concat(host, "/").concat(claimData.claimId, "/").concat(claimData.name);
+ var serveUrl = "".concat(host, "/").concat(claimData.claimId, "/").concat(claimData.name, ".").concat(claimData.fileExt);
+ var ogTitle = claimData.title || claimData.name;
+ var ogDescription = claimData.description || defaultDescription;
+ var ogThumbnailContentType = (0, _determineContentTypeFromExtension.default)(claimData.thumbnail);
+ var ogThumbnail = claimData.thumbnail || defaultThumbnail; // {property: 'og:title'] = ogTitle},
+
+ var metaTags = {
+ 'og:title': ogTitle,
+ 'twitter:title': ogTitle,
+ 'og:description': ogDescription,
+ 'twitter:description': ogDescription,
+ 'og:url': showUrl,
+ 'og:site_name': siteTitle,
+ 'twitter:site': twitter,
+ 'fb:app_id': '1371961932852223'
+ };
+
+ if (determineMediaType(contentType) === VIDEO) {
+ var videoEmbedUrl = "".concat(host, "/video-embed/").concat(claimData.name, "/").concat(claimData.claimId); // card type tags
+
+ metaTags['og:type'] = 'video.other';
+ metaTags['twitter:card'] = 'player';
+ metaTags['twitter:player'] = videoEmbedUrl;
+ metaTags['twitter:player:width'] = 600;
+ metaTags['twitter:text:player_width'] = 600;
+ metaTags['twitter:player:height'] = 350;
+ metaTags['twitter:player:stream'] = serveUrl;
+ metaTags['twitter:player:stream:content_type'] = contentType; // video tags
+
+ metaTags['og:video'] = serveUrl;
+ metaTags['og:video:secure_url'] = serveUrl;
+ metaTags['og:video:type'] = contentType; // image tags
+
+ metaTags['og:image'] = ogThumbnail;
+ metaTags['og:image:width'] = 600;
+ metaTags['og:image:height'] = 315;
+ metaTags['og:image:type'] = ogThumbnailContentType;
+ metaTags['twitter:image'] = ogThumbnail;
+ } else {
+ // card type tags
+ metaTags['og:type'] = 'article';
+ metaTags['twitter:card'] = 'summary_large_image'; // image tags
+
+ metaTags['og:image'] = serveUrl;
+ metaTags['og:image'] = serveUrl;
+ metaTags['og:image:width'] = 600;
+ metaTags['og:image:height'] = 315;
+ metaTags['og:image:type'] = contentType;
+ metaTags['twitter:image'] = serveUrl;
+ }
+
+ return (0, _createMetaTagsArray.default)(metaTags);
+};
+
+var _default = createAssetMetaTags;
+exports.default = _default;
\ No newline at end of file
diff --git a/client/build/utils/createBasicMetaTags.js b/client/build/utils/createBasicMetaTags.js
new file mode 100644
index 00000000..0160e74a
--- /dev/null
+++ b/client/build/utils/createBasicMetaTags.js
@@ -0,0 +1,51 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _siteConfig = _interopRequireDefault(require("@config/siteConfig.json"));
+
+var _determineContentTypeFromExtension = _interopRequireDefault(require("./determineContentTypeFromExtension.js"));
+
+var _createMetaTagsArray = _interopRequireDefault(require("./createMetaTagsArray"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var _siteConfig$details = _siteConfig.default.details,
+ description = _siteConfig$details.description,
+ host = _siteConfig$details.host,
+ title = _siteConfig$details.title,
+ twitter = _siteConfig$details.twitter,
+ thumbnail = _siteConfig.default.assetDefaults.thumbnail;
+
+var createBasicMetaTags = function createBasicMetaTags() {
+ var metaTags = {
+ // page details
+ 'og:title': title,
+ 'twitter:title': title,
+ 'og:description': description,
+ 'twitter:description': description,
+ // url
+ 'og:url': host,
+ // site id
+ 'og:site_name': title,
+ 'twitter:site': twitter,
+ 'fb:app_id': '1371961932852223',
+ // card type
+ 'og:type': 'article',
+ 'twitter:card': 'summary_large_image',
+ // image
+ 'og:image': thumbnail,
+ 'og:image:width': 600,
+ 'og:image:height': 315,
+ 'og:image:type': (0, _determineContentTypeFromExtension.default)(thumbnail),
+ 'twitter:image': thumbnail,
+ 'twitter:image:alt': 'Spee.ch Logo'
+ };
+ return (0, _createMetaTagsArray.default)(metaTags);
+};
+
+var _default = createBasicMetaTags;
+exports.default = _default;
\ No newline at end of file
diff --git a/client/build/utils/createCanonicalLink.js b/client/build/utils/createCanonicalLink.js
new file mode 100644
index 00000000..281a68e4
--- /dev/null
+++ b/client/build/utils/createCanonicalLink.js
@@ -0,0 +1,55 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _siteConfig = _interopRequireDefault(require("@config/siteConfig.json"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var host = _siteConfig.default.details.host;
+
+var createBasicCanonicalLink = function createBasicCanonicalLink(page) {
+ return "".concat(host, "/").concat(page);
+};
+
+var createAssetCanonicalLink = function createAssetCanonicalLink(asset) {
+ var channelName, certificateId, name, claimId;
+
+ if (asset.claimData) {
+ var _asset$claimData = asset.claimData;
+ channelName = _asset$claimData.channelName;
+ certificateId = _asset$claimData.certificateId;
+ name = _asset$claimData.name;
+ claimId = _asset$claimData.claimId;
+ }
+
+ if (channelName) {
+ return "".concat(host, "/").concat(channelName, ":").concat(certificateId, "/").concat(name);
+ }
+
+ return "".concat(host, "/").concat(claimId, "/").concat(name);
+};
+
+var createChannelCanonicalLink = function createChannelCanonicalLink(channel) {
+ var name = channel.name,
+ longId = channel.longId;
+ return "".concat(host, "/").concat(name, ":").concat(longId);
+};
+
+var createCanonicalLink = function createCanonicalLink(asset, channel, page) {
+ if (asset) {
+ return createAssetCanonicalLink(asset);
+ }
+
+ if (channel) {
+ return createChannelCanonicalLink(channel);
+ }
+
+ return createBasicCanonicalLink(page);
+};
+
+var _default = createCanonicalLink;
+exports.default = _default;
\ No newline at end of file
diff --git a/client/build/utils/createChannelMetaTags.js b/client/build/utils/createChannelMetaTags.js
new file mode 100644
index 00000000..9abc6902
--- /dev/null
+++ b/client/build/utils/createChannelMetaTags.js
@@ -0,0 +1,53 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = exports.createChannelMetaTags = void 0;
+
+var _siteConfig = _interopRequireDefault(require("@config/siteConfig.json"));
+
+var _determineContentTypeFromExtension = _interopRequireDefault(require("./determineContentTypeFromExtension"));
+
+var _createMetaTagsArray = _interopRequireDefault(require("./createMetaTagsArray"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var _siteConfig$details = _siteConfig.default.details,
+ host = _siteConfig$details.host,
+ siteTitle = _siteConfig$details.title,
+ twitter = _siteConfig$details.twitter,
+ defaultThumbnail = _siteConfig.default.assetDefaults.thumbnail;
+
+var createChannelMetaTags = function createChannelMetaTags(channel) {
+ var name = channel.name,
+ longId = channel.longId;
+ var metaTags = {
+ // page detail tags
+ 'og:title': "".concat(name, " on ").concat(siteTitle),
+ 'twitter:title': "".concat(name, " on ").concat(siteTitle),
+ 'og:description': "".concat(name, ", a channel on ").concat(siteTitle),
+ 'twitter:description': "".concat(name, ", a channel on ").concat(siteTitle),
+ // url
+ 'og:url': "".concat(host, "/").concat(name, ":").concat(longId),
+ // site info
+ 'og:site_name': siteTitle,
+ 'twitter:site': twitter,
+ 'fb:app_id': '1371961932852223',
+ // card type tags
+ 'og:type': 'article',
+ 'twitter:card': 'summary_large_image',
+ // image tags
+ 'og:image': defaultThumbnail,
+ 'og:image:width': 600,
+ 'og:image:height': 315,
+ 'og:image:type': (0, _determineContentTypeFromExtension.default)(defaultThumbnail),
+ 'twitter:image': defaultThumbnail,
+ 'twitter:image:alt': 'Spee.ch Logo'
+ };
+ return (0, _createMetaTagsArray.default)(metaTags);
+};
+
+exports.createChannelMetaTags = createChannelMetaTags;
+var _default = createChannelMetaTags;
+exports.default = _default;
\ No newline at end of file
diff --git a/client/build/utils/createMetaTags.js b/client/build/utils/createMetaTags.js
new file mode 100644
index 00000000..98c33201
--- /dev/null
+++ b/client/build/utils/createMetaTags.js
@@ -0,0 +1,32 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _createAssetMetaTags = _interopRequireDefault(require("./createAssetMetaTags"));
+
+var _createChannelMetaTags = _interopRequireDefault(require("./createChannelMetaTags.js"));
+
+var _createBasicMetaTags = _interopRequireDefault(require("./createBasicMetaTags.js"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var createMetaTags = function createMetaTags(_ref) {
+ var asset = _ref.asset,
+ channel = _ref.channel;
+
+ if (asset) {
+ return (0, _createAssetMetaTags.default)(asset);
+ }
+
+ if (channel) {
+ return (0, _createChannelMetaTags.default)(channel);
+ }
+
+ return (0, _createBasicMetaTags.default)();
+};
+
+var _default = createMetaTags;
+exports.default = _default;
\ No newline at end of file
diff --git a/client/build/utils/createMetaTagsArray.js b/client/build/utils/createMetaTagsArray.js
new file mode 100644
index 00000000..21fa19ef
--- /dev/null
+++ b/client/build/utils/createMetaTagsArray.js
@@ -0,0 +1,24 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var createMetaTagsArray = function createMetaTagsArray(metaTagsObject) {
+ var metaTagsArray = [];
+
+ for (var key in metaTagsObject) {
+ if (metaTagsObject.hasOwnProperty(key)) {
+ metaTagsArray.push({
+ property: key,
+ content: metaTagsObject[key]
+ });
+ }
+ }
+
+ return metaTagsArray;
+};
+
+var _default = createMetaTagsArray;
+exports.default = _default;
\ No newline at end of file
diff --git a/client/build/utils/createPageTitle.js b/client/build/utils/createPageTitle.js
new file mode 100644
index 00000000..72577c0e
--- /dev/null
+++ b/client/build/utils/createPageTitle.js
@@ -0,0 +1,23 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _siteConfig = _interopRequireDefault(require("@config/siteConfig.json"));
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var siteTitle = _siteConfig.default.details.title;
+
+var createPageTitle = function createPageTitle(pageTitle) {
+ if (!pageTitle) {
+ return "".concat(siteTitle);
+ }
+
+ return "".concat(siteTitle, " - ").concat(pageTitle);
+};
+
+var _default = createPageTitle;
+exports.default = _default;
\ No newline at end of file
diff --git a/client/build/utils/determineContentTypeFromExtension.js b/client/build/utils/determineContentTypeFromExtension.js
new file mode 100644
index 00000000..ecaa987e
--- /dev/null
+++ b/client/build/utils/determineContentTypeFromExtension.js
@@ -0,0 +1,35 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var determineContentTypeFromExtension = function determineContentTypeFromExtension(thumbnail) {
+ if (thumbnail) {
+ var fileExt = thumbnail.substring(thumbnail.lastIndexOf('.'));
+
+ switch (fileExt) {
+ case 'jpeg':
+ case 'jpg':
+ return 'image/jpg';
+
+ case 'png':
+ return 'image/png';
+
+ case 'gif':
+ return 'image/gif';
+
+ case 'mp4':
+ return 'video/mp4';
+
+ default:
+ return '';
+ }
+ }
+
+ return '';
+};
+
+var _default = determineContentTypeFromExtension;
+exports.default = _default;
\ No newline at end of file
diff --git a/client/build/utils/metaTags.js b/client/build/utils/metaTags.js
index 418710f7..383a32f0 100644
--- a/client/build/utils/metaTags.js
+++ b/client/build/utils/metaTags.js
@@ -5,270 +5,25 @@ Object.defineProperty(exports, "__esModule", {
});
exports.createMetaTags = void 0;
-var determineOgThumbnailContentType = function determineOgThumbnailContentType(thumbnail) {
- if (thumbnail) {
- var fileExt = thumbnail.substring(thumbnail.lastIndexOf('.'));
+var createAssetMetaTags = require('createAssetMetaTags.js');
- switch (fileExt) {
- case 'jpeg':
- case 'jpg':
- return 'image/jpeg';
+var createChannelMetaTags = require('createChannelMetaTags.js');
- case 'png':
- return 'image/png';
+var createBasicMetaTags = require('createBasicMetaTags.js');
- case 'gif':
- return 'image/gif';
-
- case 'mp4':
- return 'video/mp4';
-
- default:
- return 'image/jpeg';
- }
- }
-
- return '';
-};
-
-var createBasicMetaTags = function createBasicMetaTags(_ref) {
- var siteHost = _ref.siteHost,
- siteDescription = _ref.siteDescription,
- siteTitle = _ref.siteTitle,
- siteTwitter = _ref.siteTwitter,
- defaultThumbnail = _ref.defaultThumbnail;
- return [{
- property: 'og:title',
- content: siteTitle
- }, {
- property: 'twitter:title',
- content: siteTitle
- }, {
- property: 'og:url',
- content: siteHost
- }, {
- property: 'og:site_name',
- content: siteTitle
- }, {
- property: 'og:description',
- content: siteDescription
- }, {
- property: 'twitter:description',
- content: siteDescription
- }, {
- property: 'twitter:site',
- content: siteTwitter
- }, {
- property: 'twitter:card',
- content: 'summary_large_image'
- }, {
- property: 'og:image',
- content: defaultThumbnail
- }, {
- property: 'twitter:image',
- content: defaultThumbnail
- }, {
- property: 'og:image:type',
- content: 'image/jpeg'
- }];
-};
-
-var createChannelMetaTags = function createChannelMetaTags(_ref2) {
- var siteHost = _ref2.siteHost,
- siteTitle = _ref2.siteTitle,
- siteTwitter = _ref2.siteTwitter,
- channel = _ref2.channel;
- var name = channel.name,
- longId = channel.longId;
- return [{
- property: 'og:title',
- content: "".concat(name, " on ").concat(siteTitle)
- }, {
- property: 'twitter:title',
- content: "".concat(name, " on ").concat(siteTitle)
- }, {
- property: 'og:url',
- content: "".concat(siteHost, "/").concat(name, ":").concat(longId)
- }, {
- property: 'og:site_name',
- content: siteTitle
- }, {
- property: 'og:description',
- content: "".concat(name, ", a channel on ").concat(siteTitle)
- }, {
- property: 'twitter:site',
- content: siteTwitter
- }, {
- property: 'twitter:card',
- content: 'summary'
- }];
-};
-
-var createAssetMetaTags = function createAssetMetaTags(_ref3) {
- var siteHost = _ref3.siteHost,
- siteTitle = _ref3.siteTitle,
- siteTwitter = _ref3.siteTwitter,
- asset = _ref3.asset,
- defaultDescription = _ref3.defaultDescription,
- defaultThumbnail = _ref3.defaultThumbnail;
- var claimData = asset.claimData;
- var contentType = claimData.contentType;
- var videoEmbedUrl = "".concat(siteHost, "/video-embed/").concat(claimData.name, "/").concat(claimData.claimId);
- var showUrl = "".concat(siteHost, "/").concat(claimData.claimId, "/").concat(claimData.name);
- var source = "".concat(siteHost, "/asset/").concat(claimData.name, "/").concat(claimData.claimId);
- var ogTitle = claimData.title || claimData.name;
- var ogDescription = claimData.description || defaultDescription;
- var ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail);
- var ogThumbnail = claimData.thumbnail || defaultThumbnail;
- var metaTags = [{
- property: 'og:title',
- content: ogTitle
- }, {
- property: 'twitter:title',
- content: ogTitle
- }, {
- property: 'og:url',
- content: showUrl
- }, {
- property: 'og:site_name',
- content: siteTitle
- }, {
- property: 'og:description',
- content: ogDescription
- }, {
- property: 'twitter:description',
- content: ogDescription
- }, {
- property: 'og:image:width',
- content: 600
- }, {
- property: 'og:image:height',
- content: 315
- }, {
- property: 'twitter:site',
- content: siteTwitter
- }];
-
- if (contentType === 'video/mp4' || contentType === 'video/webm') {
- metaTags.push({
- property: 'og:video',
- content: source
- });
- metaTags.push({
- property: 'og:video:secure_url',
- content: source
- });
- metaTags.push({
- property: 'og:video:type',
- content: contentType
- });
- metaTags.push({
- property: 'og:image',
- content: ogThumbnail
- });
- metaTags.push({
- property: 'twitter:image',
- content: ogThumbnail
- });
- metaTags.push({
- property: 'og:image:type',
- content: ogThumbnailContentType
- });
- metaTags.push({
- property: 'og:type',
- content: 'video.other'
- });
- metaTags.push({
- property: 'twitter:card',
- content: 'player'
- });
- metaTags.push({
- property: 'twitter:player',
- content: videoEmbedUrl
- });
- metaTags.push({
- property: 'twitter:player:width',
- content: 600
- });
- metaTags.push({
- property: 'twitter:text:player_width',
- content: 600
- });
- metaTags.push({
- property: 'twitter:player:height',
- content: 337
- });
- metaTags.push({
- property: 'twitter:player:stream',
- content: source
- });
- metaTags.push({
- property: 'twitter:player:stream:content_type',
- content: contentType
- });
- } else {
- metaTags.push({
- property: 'og:image',
- content: source
- });
- metaTags.push({
- property: 'twitter:image',
- content: source
- });
- metaTags.push({
- property: 'og:image:type',
- content: contentType
- });
- metaTags.push({
- property: 'og:type',
- content: 'article'
- });
- metaTags.push({
- property: 'twitter:card',
- content: 'summary_large_image'
- });
- }
-
- return metaTags;
-};
-
-var createMetaTags = function createMetaTags(_ref4) {
- var siteDescription = _ref4.siteDescription,
- siteHost = _ref4.siteHost,
- siteTitle = _ref4.siteTitle,
- siteTwitter = _ref4.siteTwitter,
- asset = _ref4.asset,
- channel = _ref4.channel,
- defaultDescription = _ref4.defaultDescription,
- defaultThumbnail = _ref4.defaultThumbnail;
+var createMetaTags = function createMetaTags(_ref) {
+ var asset = _ref.asset,
+ channel = _ref.channel;
if (asset) {
- return createAssetMetaTags({
- siteHost: siteHost,
- siteTitle: siteTitle,
- siteTwitter: siteTwitter,
- asset: asset,
- defaultDescription: defaultDescription,
- defaultThumbnail: defaultThumbnail
- });
+ return createAssetMetaTags(asset);
}
if (channel) {
- return createChannelMetaTags({
- siteHost: siteHost,
- siteTitle: siteTitle,
- siteTwitter: siteTwitter,
- channel: channel
- });
+ return createChannelMetaTags(channel);
}
- return createBasicMetaTags({
- siteDescription: siteDescription,
- siteHost: siteHost,
- siteTitle: siteTitle,
- siteTwitter: siteTwitter,
- defaultThumbnail: defaultThumbnail
- });
+ return createBasicMetaTags();
};
exports.createMetaTags = createMetaTags;
\ No newline at end of file
diff --git a/client/src/components/AssetPreview/index.jsx b/client/src/components/AssetPreview/index.jsx
index e9e10cef..be09c200 100644
--- a/client/src/components/AssetPreview/index.jsx
+++ b/client/src/components/AssetPreview/index.jsx
@@ -2,10 +2,10 @@ import React from 'react';
import { Link } from 'react-router-dom';
const AssetPreview = ({ defaultThumbnail, claimData: { name, claimId, fileExt, contentType, thumbnail } }) => {
- const directSourceLink = `asset/${name}/${claimId}`;
- const showUrlLink = `/${claimId}/${name}`;
+ const embedUrl = `/${claimId}/${name}.${fileExt}`;
+ const showUrl = `/${claimId}/${name}`;
return (
-
+
{(() => {
switch (contentType) {
case 'image/jpeg':
@@ -15,7 +15,7 @@ const AssetPreview = ({ defaultThumbnail, claimData: { name, claimId, fileExt, c
return (
);
diff --git a/client/src/containers/AssetDisplay/view.jsx b/client/src/containers/AssetDisplay/view.jsx
index c742c851..e07bfa78 100644
--- a/client/src/containers/AssetDisplay/view.jsx
+++ b/client/src/containers/AssetDisplay/view.jsx
@@ -9,6 +9,7 @@ class AssetDisplay extends React.Component {
}
render () {
const { status, error, asset: { claimData: { name, claimId, contentType, fileExt, thumbnail } } } = this.props;
+ const sourceUrl = `/${claimId}/${name}.${fileExt}`;
return (
{(status === LOCAL_CHECK) &&
@@ -39,7 +40,7 @@ class AssetDisplay extends React.Component {
return (
);
@@ -50,14 +51,14 @@ class AssetDisplay extends React.Component {
controls poster={thumbnail}
>
Your browser does not support the video
element.
);
default:
return (
-
Unsupported file type
+
Unsupported content type
);
}
})()
diff --git a/client/src/containers/AssetInfo/view.jsx b/client/src/containers/AssetInfo/view.jsx
index e251e81d..ccf88fbd 100644
--- a/client/src/containers/AssetInfo/view.jsx
+++ b/client/src/containers/AssetInfo/view.jsx
@@ -50,7 +50,7 @@ class AssetInfo extends React.Component {
content={
}
/>
@@ -81,12 +81,12 @@ class AssetInfo extends React.Component {
-
Direct Link
-
+
{
- 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);
+export default connect(null, null)(View);
diff --git a/client/src/containers/SEO/view.jsx b/client/src/containers/SEO/view.jsx
index 58c12cf3..85574695 100644
--- a/client/src/containers/SEO/view.jsx
+++ b/client/src/containers/SEO/view.jsx
@@ -2,30 +2,22 @@ import React from 'react';
import Helmet from 'react-helmet';
import PropTypes from 'prop-types';
-import { createPageTitle } from '../../utils/pageTitle';
-import { createMetaTags } from '../../utils/metaTags';
-import { createCanonicalLink } from '../../utils/canonicalLink';
+import createPageTitle from '../../utils/createPageTitle';
+import createMetaTags from '../../utils/createMetaTags';
+import createCanonicalLink from '../../utils/createCanonicalLink';
class SEO extends React.Component {
render () {
- // 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);
+ pageTitle = createPageTitle(pageTitle);
const metaTags = createMetaTags({
- siteDescription,
- siteHost,
- siteTitle,
- siteTwitter,
asset,
channel,
- defaultDescription,
- defaultThumbnail,
});
- const canonicalLink = createCanonicalLink(asset, channel, pageUri, siteHost);
+ const canonicalLink = createCanonicalLink(asset, channel, pageUri);
// render results
return (
{
- return `${siteHost}/${page}`;
-};
-
-const createAssetCanonicalLink = (asset, siteHost) => {
- let channelName, certificateId, name, claimId;
- if (asset.claimData) {
- ({ channelName, certificateId, name, claimId } = asset.claimData);
- };
- if (channelName) {
- return `${siteHost}/${channelName}:${certificateId}/${name}`;
- };
- return `${siteHost}/${claimId}/${name}`;
-};
-
-const createChannelCanonicalLink = (channel, siteHost) => {
- const { name, longId } = channel;
- return `${siteHost}/${name}:${longId}`;
-};
-
-export const createCanonicalLink = (asset, channel, page, siteHost) => {
- if (asset) {
- return createAssetCanonicalLink(asset, siteHost);
- }
- if (channel) {
- return createChannelCanonicalLink(channel, siteHost);
- }
- return createBasicCanonicalLink(page, siteHost);
-};
diff --git a/client/src/utils/createAssetMetaTags.js b/client/src/utils/createAssetMetaTags.js
new file mode 100644
index 00000000..531df9e3
--- /dev/null
+++ b/client/src/utils/createAssetMetaTags.js
@@ -0,0 +1,93 @@
+import siteConfig from '@config/siteConfig.json';
+import determineContentTypeFromExtension from './determineContentTypeFromExtension';
+import createMetaTagsArray from './createMetaTagsArray';
+
+const {
+ details: {
+ host,
+ title: siteTitle,
+ twitter,
+ },
+ assetDefaults: {
+ description: defaultDescription,
+ thumbnail: defaultThumbnail,
+ },
+} = siteConfig;
+
+const VIDEO = 'VIDEO';
+const IMAGE = 'IMAGE';
+const GIF = 'GIF';
+
+const determineMediaType = (contentType) => {
+ switch (contentType) {
+ case 'image/jpg':
+ case 'image/jpeg':
+ case 'image/png':
+ return IMAGE;
+ case 'image/gif':
+ return GIF;
+ case 'video/mp4':
+ case 'video/webm':
+ return VIDEO;
+ default:
+ return '';
+ }
+};
+
+const createAssetMetaTags = (asset) => {
+ const { claimData } = asset;
+ const { contentType } = claimData;
+ const showUrl = `${host}/${claimData.claimId}/${claimData.name}`;
+ const serveUrl = `${host}/${claimData.claimId}/${claimData.name}.${claimData.fileExt}`;
+ const ogTitle = claimData.title || claimData.name;
+ const ogDescription = claimData.description || defaultDescription;
+ const ogThumbnailContentType = determineContentTypeFromExtension(claimData.thumbnail);
+ const ogThumbnail = claimData.thumbnail || defaultThumbnail;
+ // {property: 'og:title'] = ogTitle},
+ const metaTags = {
+ 'og:title' : ogTitle,
+ 'twitter:title' : ogTitle,
+ 'og:description' : ogDescription,
+ 'twitter:description': ogDescription,
+ 'og:url' : showUrl,
+ 'og:site_name' : siteTitle,
+ 'twitter:site' : twitter,
+ 'fb:app_id' : '1371961932852223',
+ };
+ if (determineMediaType(contentType) === VIDEO) {
+ const videoEmbedUrl = `${host}/video-embed/${claimData.name}/${claimData.claimId}`;
+ // card type tags
+ metaTags['og:type'] = 'video.other';
+ metaTags['twitter:card'] = 'player';
+ metaTags['twitter:player'] = videoEmbedUrl;
+ metaTags['twitter:player:width'] = 600;
+ metaTags['twitter:text:player_width'] = 600;
+ metaTags['twitter:player:height'] = 350;
+ metaTags['twitter:player:stream'] = serveUrl;
+ metaTags['twitter:player:stream:content_type'] = contentType;
+ // video tags
+ metaTags['og:video'] = serveUrl;
+ metaTags['og:video:secure_url'] = serveUrl;
+ metaTags['og:video:type'] = contentType;
+ // image tags
+ metaTags['og:image'] = ogThumbnail;
+ metaTags['og:image:width'] = 600;
+ metaTags['og:image:height'] = 315;
+ metaTags['og:image:type'] = ogThumbnailContentType;
+ metaTags['twitter:image'] = ogThumbnail;
+ } else {
+ // card type tags
+ metaTags['og:type'] = 'article';
+ metaTags['twitter:card'] = 'summary_large_image';
+ // image tags
+ metaTags['og:image'] = serveUrl;
+ metaTags['og:image'] = serveUrl;
+ metaTags['og:image:width'] = 600;
+ metaTags['og:image:height'] = 315;
+ metaTags['og:image:type'] = contentType;
+ metaTags['twitter:image'] = serveUrl;
+ }
+ return createMetaTagsArray(metaTags);
+};
+
+export default createAssetMetaTags;
diff --git a/client/src/utils/createBasicMetaTags.js b/client/src/utils/createBasicMetaTags.js
new file mode 100644
index 00000000..090d796d
--- /dev/null
+++ b/client/src/utils/createBasicMetaTags.js
@@ -0,0 +1,44 @@
+import siteConfig from '@config/siteConfig.json';
+import determineContentTypeFromExtension from './determineContentTypeFromExtension.js';
+import createMetaTagsArray from './createMetaTagsArray';
+
+const {
+ details: {
+ description,
+ host,
+ title,
+ twitter,
+ },
+ assetDefaults: {
+ thumbnail,
+ },
+} = siteConfig;
+
+const createBasicMetaTags = () => {
+ const metaTags = {
+ // page details
+ 'og:title' : title,
+ 'twitter:title' : title,
+ 'og:description' : description,
+ 'twitter:description': description,
+ // url
+ 'og:url' : host,
+ // site id
+ 'og:site_name' : title,
+ 'twitter:site' : twitter,
+ 'fb:app_id' : '1371961932852223',
+ // card type
+ 'og:type' : 'article',
+ 'twitter:card' : 'summary_large_image',
+ // image
+ 'og:image' : thumbnail,
+ 'og:image:width' : 600,
+ 'og:image:height' : 315,
+ 'og:image:type' : determineContentTypeFromExtension(thumbnail),
+ 'twitter:image' : thumbnail,
+ 'twitter:image:alt' : 'Spee.ch Logo',
+ };
+ return createMetaTagsArray(metaTags);
+};
+
+export default createBasicMetaTags;
diff --git a/client/src/utils/createCanonicalLink.js b/client/src/utils/createCanonicalLink.js
new file mode 100644
index 00000000..d73e183d
--- /dev/null
+++ b/client/src/utils/createCanonicalLink.js
@@ -0,0 +1,39 @@
+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;
diff --git a/client/src/utils/createChannelMetaTags.js b/client/src/utils/createChannelMetaTags.js
new file mode 100644
index 00000000..fea67ec5
--- /dev/null
+++ b/client/src/utils/createChannelMetaTags.js
@@ -0,0 +1,44 @@
+import siteConfig from '@config/siteConfig.json';
+import determineContentTypeFromExtension from './determineContentTypeFromExtension';
+import createMetaTagsArray from './createMetaTagsArray';
+
+const {
+ details: {
+ host,
+ title: siteTitle,
+ twitter,
+ },
+ assetDefaults: {
+ thumbnail: defaultThumbnail,
+ },
+} = siteConfig;
+
+export const createChannelMetaTags = (channel) => {
+ const { name, longId } = channel;
+ const metaTags = {
+ // page detail tags
+ 'og:title' : `${name} on ${siteTitle}`,
+ 'twitter:title' : `${name} on ${siteTitle}`,
+ 'og:description' : `${name}, a channel on ${siteTitle}`,
+ 'twitter:description': `${name}, a channel on ${siteTitle}`,
+ // url
+ 'og:url' : `${host}/${name}:${longId}`,
+ // site info
+ 'og:site_name' : siteTitle,
+ 'twitter:site' : twitter,
+ 'fb:app_id' : '1371961932852223',
+ // card type tags
+ 'og:type' : 'article',
+ 'twitter:card' : 'summary_large_image',
+ // image tags
+ 'og:image' : defaultThumbnail,
+ 'og:image:width' : 600,
+ 'og:image:height' : 315,
+ 'og:image:type' : determineContentTypeFromExtension(defaultThumbnail),
+ 'twitter:image' : defaultThumbnail,
+ 'twitter:image:alt' : 'Spee.ch Logo',
+ };
+ return createMetaTagsArray(metaTags);
+};
+
+export default createChannelMetaTags;
diff --git a/client/src/utils/createMetaTags.js b/client/src/utils/createMetaTags.js
new file mode 100644
index 00000000..19287478
--- /dev/null
+++ b/client/src/utils/createMetaTags.js
@@ -0,0 +1,15 @@
+import createAssetMetaTags from './createAssetMetaTags';
+import createChannelMetaTags from './createChannelMetaTags.js';
+import createBasicMetaTags from './createBasicMetaTags.js';
+
+const createMetaTags = ({ asset, channel }) => {
+ if (asset) {
+ return createAssetMetaTags(asset);
+ }
+ if (channel) {
+ return createChannelMetaTags(channel);
+ }
+ return createBasicMetaTags();
+};
+
+export default createMetaTags;
diff --git a/client/src/utils/createMetaTagsArray.js b/client/src/utils/createMetaTagsArray.js
new file mode 100644
index 00000000..e4052724
--- /dev/null
+++ b/client/src/utils/createMetaTagsArray.js
@@ -0,0 +1,14 @@
+const createMetaTagsArray = (metaTagsObject) => {
+ let metaTagsArray = [];
+ for (let key in metaTagsObject) {
+ if (metaTagsObject.hasOwnProperty(key)) {
+ metaTagsArray.push({
+ property: key,
+ content : metaTagsObject[key],
+ });
+ }
+ }
+ return metaTagsArray;
+};
+
+export default createMetaTagsArray;
diff --git a/client/src/utils/createPageTitle.js b/client/src/utils/createPageTitle.js
new file mode 100644
index 00000000..0093e190
--- /dev/null
+++ b/client/src/utils/createPageTitle.js
@@ -0,0 +1,16 @@
+import siteConfig from '@config/siteConfig.json';
+
+const {
+ details: {
+ title: siteTitle,
+ },
+} = siteConfig;
+
+const createPageTitle = (pageTitle) => {
+ if (!pageTitle) {
+ return `${siteTitle}`;
+ }
+ return `${siteTitle} - ${pageTitle}`;
+};
+
+export default createPageTitle;
diff --git a/client/src/utils/determineContentTypeFromExtension.js b/client/src/utils/determineContentTypeFromExtension.js
new file mode 100644
index 00000000..cd7f85b4
--- /dev/null
+++ b/client/src/utils/determineContentTypeFromExtension.js
@@ -0,0 +1,21 @@
+const determineContentTypeFromExtension = (thumbnail) => {
+ if (thumbnail) {
+ const fileExt = thumbnail.substring(thumbnail.lastIndexOf('.'));
+ switch (fileExt) {
+ case 'jpeg':
+ case 'jpg':
+ return 'image/jpg';
+ case 'png':
+ return 'image/png';
+ case 'gif':
+ return 'image/gif';
+ case 'mp4':
+ return 'video/mp4';
+ default:
+ return '';
+ }
+ }
+ return '';
+};
+
+export default determineContentTypeFromExtension;
diff --git a/client/src/utils/metaTags.js b/client/src/utils/metaTags.js
deleted file mode 100644
index 7f0094e1..00000000
--- a/client/src/utils/metaTags.js
+++ /dev/null
@@ -1,122 +0,0 @@
-const determineOgThumbnailContentType = (thumbnail) => {
- if (thumbnail) {
- const fileExt = thumbnail.substring(thumbnail.lastIndexOf('.'));
- switch (fileExt) {
- case 'jpeg':
- case 'jpg':
- return 'image/jpeg';
- case 'png':
- return 'image/png';
- case 'gif':
- return 'image/gif';
- case 'mp4':
- return 'video/mp4';
- default:
- return 'image/jpeg';
- }
- }
- return '';
-};
-
-const createBasicMetaTags = ({siteHost, siteDescription, siteTitle, siteTwitter, defaultThumbnail}) => {
- return [
- {property: 'og:title', content: siteTitle},
- {property: 'twitter:title', content: siteTitle},
- {property: 'og:url', content: siteHost},
- {property: 'og:site_name', content: siteTitle},
- {property: 'og:description', content: siteDescription},
- {property: 'twitter:description', content: siteDescription},
- {property: 'twitter:site', content: siteTwitter},
- {property: 'twitter:card', content: 'summary_large_image'},
- {property: 'og:image', content: defaultThumbnail},
- {property: 'twitter:image', content: defaultThumbnail},
- {property: 'og:image:type', content: 'image/jpeg'},
- ];
-};
-
-const createChannelMetaTags = ({siteHost, siteTitle, siteTwitter, channel}) => {
- const { name, longId } = channel;
- return [
- {property: 'og:title', content: `${name} on ${siteTitle}`},
- {property: 'twitter: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 = ({siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail}) => {
- const { claimData } = asset;
- const { contentType } = claimData;
- const videoEmbedUrl = `${siteHost}/video-embed/${claimData.name}/${claimData.claimId}`;
- const showUrl = `${siteHost}/${claimData.claimId}/${claimData.name}`;
- const source = `${siteHost}/asset/${claimData.name}/${claimData.claimId}`;
- const ogTitle = claimData.title || claimData.name;
- const ogDescription = claimData.description || defaultDescription;
- const ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail);
- const ogThumbnail = claimData.thumbnail || defaultThumbnail;
- const metaTags = [
- {property: 'og:title', content: ogTitle},
- {property: 'twitter:title', content: ogTitle},
- {property: 'og:url', content: showUrl},
- {property: 'og:site_name', content: siteTitle},
- {property: 'og:description', content: ogDescription},
- {property: 'twitter:description', content: ogDescription},
- {property: 'og:image:width', content: 600},
- {property: 'og:image:height', content: 315},
- {property: 'twitter:site', content: siteTwitter},
- ];
- if (contentType === 'video/mp4' || contentType === 'video/webm') {
- metaTags.push({property: 'og:video', content: source});
- metaTags.push({property: 'og:video:secure_url', content: source});
- metaTags.push({property: 'og:video:type', content: contentType});
- metaTags.push({property: 'og:image', content: ogThumbnail});
- metaTags.push({property: 'twitter:image', content: ogThumbnail});
- metaTags.push({property: 'og:image:type', content: ogThumbnailContentType});
- metaTags.push({property: 'og:type', content: 'video.other'});
- metaTags.push({property: 'twitter:card', content: 'player'});
- metaTags.push({property: 'twitter:player', content: videoEmbedUrl});
- metaTags.push({property: 'twitter:player:width', content: 600});
- metaTags.push({property: 'twitter:text:player_width', content: 600});
- metaTags.push({property: 'twitter:player:height', content: 337});
- metaTags.push({property: 'twitter:player:stream', content: source});
- metaTags.push({property: 'twitter:player:stream:content_type', content: contentType});
- } else {
- metaTags.push({property: 'og:image', content: source});
- metaTags.push({property: 'twitter:image', content: source});
- metaTags.push({property: 'og:image:type', content: contentType});
- metaTags.push({property: 'og:type', content: 'article'});
- metaTags.push({property: 'twitter:card', content: 'summary_large_image'});
- }
- return metaTags;
-};
-
-export const createMetaTags = ({ siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail }) => {
- if (asset) {
- return createAssetMetaTags({
- siteHost,
- siteTitle,
- siteTwitter,
- asset,
- defaultDescription,
- defaultThumbnail,
- });
- }
- if (channel) {
- return createChannelMetaTags({
- siteHost,
- siteTitle,
- siteTwitter,
- channel,
- });
- }
- return createBasicMetaTags({
- siteDescription,
- siteHost,
- siteTitle,
- siteTwitter,
- defaultThumbnail,
- });
-};
diff --git a/client/src/utils/pageTitle.js b/client/src/utils/pageTitle.js
deleted file mode 100644
index 2b577c0b..00000000
--- a/client/src/utils/pageTitle.js
+++ /dev/null
@@ -1,6 +0,0 @@
-export const createPageTitle = (siteTitle, pageTitle) => {
- if (!pageTitle) {
- return `${siteTitle}`;
- }
- return `${siteTitle} - ${pageTitle}`;
-};
diff --git a/server/controllers/api/claim/publish/index.js b/server/controllers/api/claim/publish/index.js
index 51e6e9be..b43995f5 100644
--- a/server/controllers/api/claim/publish/index.js
+++ b/server/controllers/api/claim/publish/index.js
@@ -27,6 +27,7 @@ const claimPublish = ({ body, files, headers, ip, originalUrl, user, tor }, res)
ip,
headers,
body,
+ files,
});
// check for disabled publishing
if (disabled) {
@@ -36,14 +37,14 @@ const claimPublish = ({ body, files, headers, ip, originalUrl, user, tor }, res)
});
}
// define variables
- let channelName, channelId, channelPassword, description, fileName, filePath, fileType, gaStartTime, license, name, nsfw, thumbnail, thumbnailFileName, thumbnailFilePath, thumbnailFileType, title;
+ let channelName, channelId, channelPassword, description, fileName, filePath, fileExtension, fileType, gaStartTime, license, name, nsfw, thumbnail, thumbnailFileName, thumbnailFilePath, thumbnailFileType, title;
// record the start time of the request
gaStartTime = Date.now();
// validate the body and files of the request
try {
// validateApiPublishRequest(body, files);
({name, nsfw, license, title, description, thumbnail} = parsePublishApiRequestBody(body));
- ({fileName, filePath, fileType, thumbnailFileName, thumbnailFilePath, thumbnailFileType} = parsePublishApiRequestFiles(files));
+ ({fileName, filePath, fileExtension, fileType, thumbnailFileName, thumbnailFilePath, thumbnailFileType} = parsePublishApiRequestFiles(files));
({channelName, channelId, channelPassword} = body);
} catch (error) {
return res.status(400).json({success: false, message: error.message});
@@ -76,8 +77,9 @@ const claimPublish = ({ body, files, headers, ip, originalUrl, user, tor }, res)
data : {
name,
claimId : result.claim_id,
- url : `${host}/${result.claim_id}/${name}`,
- embedUrl: `${host}/asset/${name}/${result.claim_id}`,
+ url : `${host}/${result.claim_id}/${name}`, // for backwards compatability with app
+ showUrl : `${host}/${result.claim_id}/${name}`,
+ serveUrl: `${host}/${result.claim_id}/${name}${fileExtension}`,
lbryTx : result,
},
});
diff --git a/server/controllers/api/claim/publish/parsePublishApiRequestFiles.js b/server/controllers/api/claim/publish/parsePublishApiRequestFiles.js
index 66f57be9..3e99ad20 100644
--- a/server/controllers/api/claim/publish/parsePublishApiRequestFiles.js
+++ b/server/controllers/api/claim/publish/parsePublishApiRequestFiles.js
@@ -1,3 +1,4 @@
+const path = require('path');
const validateFileTypeAndSize = require('./validateFileTypeAndSize.js');
const parsePublishApiRequestFiles = ({file, thumbnail}) => {
@@ -33,6 +34,7 @@ const parsePublishApiRequestFiles = ({file, thumbnail}) => {
return {
fileName : file.name,
filePath : file.path,
+ fileExtension : path.extname(file.path),
fileType : file.type,
thumbnailFileName: (thumbnail ? thumbnail.name : null),
thumbnailFilePath: (thumbnail ? thumbnail.path : null),
diff --git a/server/controllers/assets/constants/request_types.js b/server/controllers/assets/constants/request_types.js
index 22f0d0ce..4c32b6f1 100644
--- a/server/controllers/assets/constants/request_types.js
+++ b/server/controllers/assets/constants/request_types.js
@@ -1,9 +1,7 @@
-const EMBED = 'EMBED';
-const BROWSER = 'BROWSER';
-const SOCIAL = 'SOCIAL';
+const SERVE = 'SERVE';
+const SHOW = 'SHOW';
module.exports = {
- EMBED,
- BROWSER,
- SOCIAL,
+ SERVE,
+ SHOW,
};
diff --git a/server/controllers/assets/serveByClaim/index.js b/server/controllers/assets/serveByClaim/index.js
index 6e0e9e40..1ca0be13 100644
--- a/server/controllers/assets/serveByClaim/index.js
+++ b/server/controllers/assets/serveByClaim/index.js
@@ -1,3 +1,5 @@
+const logger = require('winston');
+
const { sendGAServeEvent } = require('../../../utils/googleAnalytics');
const handleShowRender = require('../../../render/build/handleShowRender.js');
@@ -6,7 +8,7 @@ const lbryUri = require('../utils/lbryUri.js');
const determineRequestType = require('../utils/determineRequestType.js');
const getClaimIdAndServeAsset = require('../utils/getClaimIdAndServeAsset.js');
-const { EMBED } = require('../constants/request_types.js');
+const { SHOW } = require('../constants/request_types.js');
/*
@@ -16,29 +18,32 @@ const { EMBED } = require('../constants/request_types.js');
const serveByClaim = (req, res) => {
const { headers, ip, originalUrl, params } = req;
- // decide if this is a show request
- let hasFileExtension;
+
try {
+ let isChannel, hasFileExtension, claimName;
+
+ ({ isChannel } = lbryUri.parseIdentifier(params.claim));
+ if (isChannel) {
+ logger.debug('channel request:', { headers, ip, originalUrl, params });
+ return handleShowRender(req, res);
+ }
+
({ hasFileExtension } = lbryUri.parseModifier(params.claim));
+ if (determineRequestType(hasFileExtension, headers) === SHOW) {
+ logger.debug('show request:', { headers, ip, originalUrl, params });
+ return handleShowRender(req, res);
+ }
+
+ ({ claimName } = lbryUri.parseClaim(params.claim));
+ logger.debug('serve request:', { headers, ip, originalUrl, params });
+ getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res);
+
+ sendGAServeEvent(headers, ip, originalUrl);
+
} catch (error) {
return res.status(400).json({success: false, message: error.message});
}
- // determine request type
- let requestType = determineRequestType(hasFileExtension, headers);
- if (requestType !== EMBED) {
- return handleShowRender(req, res);
- }
- // parse the claim
- let claimName;
- try {
- ({claimName} = lbryUri.parseClaim(params.claim));
- } catch (error) {
- return res.status(400).json({success: false, message: error.message});
- }
- // send google analytics
- sendGAServeEvent(headers, ip, originalUrl);
- // get the claim Id and then serve the asset
- getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res);
+
};
module.exports = serveByClaim;
diff --git a/server/controllers/assets/serveByIdentifierAndClaim/index.js b/server/controllers/assets/serveByIdentifierAndClaim/index.js
index 609a1256..34434f5b 100644
--- a/server/controllers/assets/serveByIdentifierAndClaim/index.js
+++ b/server/controllers/assets/serveByIdentifierAndClaim/index.js
@@ -1,3 +1,5 @@
+const logger = require('winston');
+
const { sendGAServeEvent } = require('../../../utils/googleAnalytics');
const handleShowRender = require('../../../render/build/handleShowRender.js');
@@ -7,7 +9,7 @@ const determineRequestType = require('../utils/determineRequestType.js');
const getClaimIdAndServeAsset = require('../utils/getClaimIdAndServeAsset.js');
const flipClaimNameAndId = require('../utils/flipClaimNameAndId.js');
-const { EMBED } = require('../constants/request_types.js');
+const { SHOW } = require('../constants/request_types.js');
/*
@@ -17,40 +19,32 @@ const { EMBED } = require('../constants/request_types.js');
const serverByIdentifierAndClaim = (req, res) => {
const { headers, ip, originalUrl, params } = req;
- // parse request
- let hasFileExtension;
+
try {
+ let hasFileExtension, claimName, isChannel, channelName, channelClaimId, claimId;
+
({ hasFileExtension } = lbryUri.parseModifier(params.claim));
- } catch (error) {
- return res.status(400).json({success: false, message: error.message});
- }
- // determine request type
- let requestType = determineRequestType(hasFileExtension, headers);
- if (requestType !== EMBED) {
- return handleShowRender(req, res);
- }
- // parse the claim
- let claimName;
- try {
+ if (determineRequestType(hasFileExtension, headers) === SHOW) {
+ logger.debug('show request:', { headers, ip, originalUrl, params });
+ return handleShowRender(req, res);
+ }
+
({ claimName } = lbryUri.parseClaim(params.claim));
- } catch (error) {
- return res.status(400).json({success: false, message: error.message});
- }
- // parse the identifier
- let isChannel, channelName, channelClaimId, claimId;
- try {
({ isChannel, channelName, channelClaimId, claimId } = lbryUri.parseIdentifier(params.identifier));
+
+ if (!isChannel) {
+ [claimId, claimName] = flipClaimNameAndId(claimId, claimName);
+ }
+
+ logger.debug('serve request:', { headers, ip, originalUrl, params });
+ getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res);
+
+ sendGAServeEvent(headers, ip, originalUrl);
+
} catch (error) {
return res.status(400).json({success: false, message: error.message});
}
- // for backwards compatability, flip claim name and claim id if necessary
- if (!isChannel) {
- [claimId, claimName] = flipClaimNameAndId(claimId, claimName);
- }
- // send google analytics
- sendGAServeEvent(headers, ip, originalUrl);
- // get the claim Id and then serve the asset
- getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res);
+
};
module.exports = serverByIdentifierAndClaim;
diff --git a/server/controllers/assets/utils/determineRequestType.js b/server/controllers/assets/utils/determineRequestType.js
index afc5574f..02e08fbc 100644
--- a/server/controllers/assets/utils/determineRequestType.js
+++ b/server/controllers/assets/utils/determineRequestType.js
@@ -1,60 +1,16 @@
-const logger = require('winston');
-const { EMBED, BROWSER, SOCIAL } = require('../constants/request_types.js');
-
-function headersMatchesSocialBotList (headers) {
- const userAgent = headers['user-agent'];
- const socialBotList = [
- 'facebookexternalhit',
- 'Twitterbot',
- ];
- for (let i = 0; i < socialBotList.length; i++) {
- if (userAgent.includes(socialBotList[i])) {
- logger.debug('request is from social bot:', socialBotList[i]);
- return true;
- }
- }
- return false;
-}
-
-function clientAcceptsHtml ({accept}) {
- return accept && accept.match(/text\/html/);
-}
-
-function requestIsFromBrowser (headers) {
- return headers['user-agent'] && headers['user-agent'].match(/Mozilla/);
-}
+const { SERVE, SHOW } = require('../constants/request_types.js');
function clientWantsAsset ({accept, range}) {
- const imageIsWanted = accept && accept.match(/image\/.*/) && !accept.match(/text\/html/) && !accept.match(/text\/\*/);
- const videoIsWanted = accept && range;
+ const imageIsWanted = accept && accept.match(/image\/.*/) && !accept.match(/text\/html/);
+ const videoIsWanted = accept && accept.match(/video\/.*/) && !accept.match(/text\/html/);
return imageIsWanted || videoIsWanted;
}
const determineRequestType = (hasFileExtension, headers) => {
- let responseType;
- logger.debug('headers:', headers);
- // return early with 'show' if headers match the list
- if (headersMatchesSocialBotList(headers)) {
- return SOCIAL;
+ if (hasFileExtension || clientWantsAsset(headers)) {
+ return SERVE;
}
- // if request is not from a social bot...
- if (hasFileExtension) {
- // assume embed,
- responseType = EMBED;
- // but change to browser if client accepts html.
- if (clientAcceptsHtml(headers)) {
- responseType = BROWSER;
- }
- // if request does not have file extentsion...
- } else {
- // assume browser,
- responseType = BROWSER;
- // but change to embed if someone embeded a show url...
- if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) {
- responseType = EMBED;
- }
- }
- return responseType;
+ return SHOW;
};
module.exports = determineRequestType;
diff --git a/server/routes/assets/index.js b/server/routes/assets/index.js
index 5d4f92d1..ef70ea3f 100644
--- a/server/routes/assets/index.js
+++ b/server/routes/assets/index.js
@@ -1,9 +1,7 @@
const serveByClaim = require('../../controllers/assets/serveByClaim');
const serveByIdentifierAndClaim = require('../../controllers/assets/serveByIdentifierAndClaim');
-const serveAsset = require('../../controllers/assets/serveAsset');
module.exports = (app) => {
- app.get('/asset/:claimName/:claimId/', serveAsset);
app.get('/:identifier/:claim', serveByIdentifierAndClaim);
app.get('/:claim', serveByClaim);
};
diff --git a/server/views/embed.handlebars b/server/views/embed.handlebars
index 9cc0d40e..6b1a4ed6 100644
--- a/server/views/embed.handlebars
+++ b/server/views/embed.handlebars
@@ -1,4 +1,4 @@