@randy.tarampi/jsx
Version:
Some common JSX components for www.randytarampi.ca
347 lines (325 loc) • 12.8 kB
JavaScript
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
import { Post, POST_ENTITIES, POST_OVERRIDING_TAG_SENTINEL_REGEX } from "@randy.tarampi/js";
import SchemaJsonLdComponent from "@randy.tarampi/schema-dot-org-json-ld-components";
import isHtml from "is-html";
import { DateTime } from "luxon";
import PropTypes from "prop-types";
import React, { Fragment, PureComponent } from "react";
import { Marker } from "react-google-maps";
import { Col, Row } from "react-materialize";
import { connect } from "react-redux";
import { updateMapCreator } from "../actions";
import { CampaignLink, getBrandedLinkForNetwork, InternalLink } from "./link";
import { MapComponent } from "./map";
export class PostComponent extends PureComponent {
get postElement() {
return document.getElementById(this.props.post.uid);
}
get width() {
var postElement = this.postElement;
return postElement ? postElement.clientWidth : this.props.containerHeight;
}
get height() {
var postElement = this.postElement;
return postElement ? postElement.clientHeight : this.props.containerWidth;
}
get metadataWidth() {
var postElement = this.postElement;
var metadataColumnElement = postElement && postElement.querySelector(".post-metadata");
return metadataColumnElement ? metadataColumnElement.clientWidth : this.width;
}
get metadataHeight() {
var postElement = this.postElement;
var metadataColumnElement = postElement && postElement.querySelector(".post-metadata");
return metadataColumnElement ? metadataColumnElement.clientHeight : this.height;
}
get contentHeight() {
var postElement = this.postElement;
var contentColumnElement = postElement && postElement.querySelector(".post-content");
return contentColumnElement ? contentColumnElement.clientHeight : this.height;
}
get containerHeight() {
return this.props.containerHeight;
}
get containerWidth() {
return this.props.containerWidth;
}
get scaledHeight() {
return Math.round(this.containerWidth * this.height / this.width);
}
get title() {
return this.props.post.title || "Untitled";
}
render() {
var {
post
} = this.props;
return /*#__PURE__*/React.createElement(Row, {
className: "post post--words",
id: post.uid
}, /*#__PURE__*/React.createElement(SchemaJsonLdComponent, {
markup: post.toSchema()
}), /*#__PURE__*/React.createElement(Col, {
className: "post-metadata",
s: 12,
l: 4
}, /*#__PURE__*/React.createElement(PostTitleComponent, {
post: post,
title: this.title
}), /*#__PURE__*/React.createElement(PostDatePublishedComponent, {
post: post
}), /*#__PURE__*/React.createElement(PostDateCreatedComponent, {
post: post
}), /*#__PURE__*/React.createElement(PostLocationComponent, {
post: post
}), /*#__PURE__*/React.createElement(PostTagsComponent, {
post: post
})), /*#__PURE__*/React.createElement(Col, {
className: "post-content",
s: 12,
l: 8
}, /*#__PURE__*/React.createElement(PostBodyAsStringComponent, {
post: post
}), /*#__PURE__*/React.createElement(PostBodyAsArrayComponent, {
post: post
})));
}
}
PostComponent.propTypes = {
post: PropTypes.instanceOf(Post).isRequired,
containerWidth: PropTypes.number,
containerHeight: PropTypes.number
};
export var PostTitleComponent = (_ref) => {
var {
post,
title
} = _ref;
return /*#__PURE__*/React.createElement("h1", {
className: "post-title"
}, post.sourceUrl ? /*#__PURE__*/React.createElement(CampaignLink, {
className: "post-title__link",
href: post.sourceUrl,
text: title
}) : /*#__PURE__*/React.createElement("span", {
className: "post-title__text"
}, title));
};
PostTitleComponent.propTypes = {
post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired,
title: PropTypes.string.isRequired
};
export var PostBodyAsStringComponent = (_ref2) => {
var {
post
} = _ref2;
return typeof post.body === "string" && post.body !== "" ? /*#__PURE__*/React.createElement("div", {
className: "post-body"
}, isHtml(post.body) ? /*#__PURE__*/React.createElement("div", {
className: "post-body__html"
}, /*#__PURE__*/React.createElement("div", {
dangerouslySetInnerHTML: {
__html: post.body
}
})) : /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("span", {
className: "post-body__text",
dangerouslySetInnerHTML: {
__html: post.body
}
}))) : null;
};
PostBodyAsStringComponent.propTypes = {
post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired
};
export var PostBodyAsArrayComponent = (_ref3) => {
var {
post
} = _ref3;
return Array.isArray(post.body) ? /*#__PURE__*/React.createElement(Fragment, null, post.body.map((htmlString, index) => {
return /*#__PURE__*/React.createElement("div", {
className: "post-body",
key: "".concat(post.id, ":").concat(post.type, ":body:").concat(index)
}, isHtml(htmlString) ? /*#__PURE__*/React.createElement("div", {
className: "post-body__html"
}, /*#__PURE__*/React.createElement("div", {
dangerouslySetInnerHTML: {
__html: htmlString
}
})) : /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("span", {
className: "post-body__text",
dangerouslySetInnerHTML: {
__html: htmlString
}
})));
})) : null;
};
PostBodyAsArrayComponent.propTypes = {
post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired
};
export var PostDatePublishedComponent = (_ref4) => {
var {
post,
label
} = _ref4;
var postSourceLink = null;
if (post.creator) {
var PostSourceLinkComponent = getBrandedLinkForNetwork(post.source);
var sourceName = post.creator.username || post.creator.name;
var sourceAttribution = "".concat(sourceName, " on ").concat(post.source);
if (PostSourceLinkComponent) {
postSourceLink = /*#__PURE__*/React.createElement(PostSourceLinkComponent, {
className: "post-source__link",
href: post.creator.url,
username: post.creator.username,
text: sourceAttribution
}, sourceName, " on ", /*#__PURE__*/React.createElement("span", {
className: "post-source__source-name"
}, post.source));
} else {
postSourceLink = /*#__PURE__*/React.createElement(CampaignLink, {
className: "post-source__link",
href: post.creator.url,
text: sourceAttribution
});
}
}
return post.datePublished ? /*#__PURE__*/React.createElement("p", {
className: "post-date"
}, /*#__PURE__*/React.createElement("strong", {
className: "post-date__label post-date__label--published"
}, label), /*#__PURE__*/React.createElement("span", {
className: "post-date__date post-date__date--published"
}, post.datePublished.toLocaleString(DateTime.DATE_MED)), postSourceLink) : null;
};
PostDatePublishedComponent.propTypes = {
label: PropTypes.string.isRequired,
post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired
};
PostDatePublishedComponent.defaultProps = {
label: "Posted:"
};
export var PostDateCreatedComponent = (_ref5) => {
var {
post,
label
} = _ref5;
return post.dateCreated && post.dateCreated.valueOf() !== post.datePublished.valueOf() ? /*#__PURE__*/React.createElement("p", {
className: "post-date"
}, /*#__PURE__*/React.createElement("strong", {
className: "post-date__label post-date__label--created"
}, label), /*#__PURE__*/React.createElement("span", {
className: "post-date__date post-date__date--created"
}, post.dateCreated.toLocaleString(DateTime.DATETIME_MED))) : null;
};
PostDateCreatedComponent.propTypes = {
post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired,
label: PropTypes.string.isRequired
};
PostDateCreatedComponent.defaultProps = {
label: "Drafted:"
};
export var PostTagsComponent = (_ref6) => {
var {
post,
tagLinkBase = "/blog".concat("/tags")
} = _ref6;
return post.tags && post.tags.size ? /*#__PURE__*/React.createElement("p", {
className: "post-tags hide-on-med-and-down"
}, /*#__PURE__*/React.createElement("strong", {
className: "post-tags__label"
}, "Tags:"), post.tags.filter(tag => !tag.match(POST_OVERRIDING_TAG_SENTINEL_REGEX)).map(tag => /*#__PURE__*/React.createElement(Fragment, {
key: tag
}, /*#__PURE__*/React.createElement(InternalLink, {
className: "post-tags__tag",
href: "".concat(tagLinkBase, "/").concat(tag)
}, tag), " ") // NOTE-RT: We need this ` ` between the `</InternalLink>` and the `</Fragment>` because Safari (Webkit?) seems to collapse ` ` and not insert line breaks between each `<Fragment>` but doesn't with ` `
)) : null;
};
PostTagsComponent.propTypes = {
tagLinkBase: PropTypes.string,
post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired
};
export var PostMapComponent = (_ref7) => {
var {
post,
mapContainerHeight,
children
} = _ref7,
props = _objectWithoutProperties(_ref7, ["post", "mapContainerHeight", "children"]);
return Number.isFinite(post.lat) && Number.isFinite(post.long) ? /*#__PURE__*/React.createElement("div", {
className: "post-map"
}, /*#__PURE__*/React.createElement(MapComponent, _extends({
mapContainerHeight: mapContainerHeight,
defaultZoom: 17,
defaultCenter: {
lat: post.lat,
lng: post.long
}
}, props), children ? children : /*#__PURE__*/React.createElement(Marker, {
position: {
lat: post.lat,
lng: post.long
}
}))) : null;
};
PostMapComponent.propTypes = {
post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired,
mapContainerHeight: PropTypes.number,
contentHeight: PropTypes.number,
metadataHeight: PropTypes.number
};
var PostLocationComponentInternal = (_ref8) => {
var {
post,
setMapPostsCenter
} = _ref8;
if (post.locationCreated) {
var postCoordinates = post.locationCreated.coordinates ? [post.locationCreated.coordinates.latitude, post.locationCreated.coordinates.longitude].map(dmsCoordinate => {
var dmsArray = dmsCoordinate.dmsArray;
return "".concat(dmsArray[0], "\xB0").concat(dmsArray[1], "\u2032").concat(Number(dmsArray[2]).toFixed(3), "\u2033 ").concat(dmsArray[3]);
}).join(", ") : null;
var postLocationName = post.locationCreated.name;
var postAddress = post.locationCreated.address;
return /*#__PURE__*/React.createElement("p", {
className: "post-location hide-on-med-and-down"
}, /*#__PURE__*/React.createElement(InternalLink, {
className: "link--branded post-location__link",
href: "/map",
onClick: setMapPostsCenter,
serviceName: postLocationName || postAddress || postCoordinates,
serviceType: "map-post"
}));
}
return null;
};
PostLocationComponentInternal.propTypes = {
post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired,
setMapPostsCenter: PropTypes.func.isRequired
};
export var PostLocationComponent = connect(null, (dispatch, _ref9) => {
var {
post,
mapId
} = _ref9;
return {
setMapPostsCenter: () => dispatch(updateMapCreator({
id: mapId,
center: {
lat: post.lat,
lng: post.long
},
bounds: null,
zoom: 18
}))
};
})(PostLocationComponentInternal);
PostLocationComponent.propTypes = {
post: PropTypes.oneOfType(POST_ENTITIES.map(PropTypes.instanceOf)).isRequired,
mapId: PropTypes.string.isRequired
};
PostLocationComponent.defaultProps = {
mapId: "map-posts"
};
export default PostComponent;