Commit 5cc5cf9f authored by Jason Salyers's avatar Jason Salyers

Merge branch '114-post-image-preview-selection' into 'develop'

Resolve "Allow selecting post preview image"

Closes #114

See merge request !190
parents 65612ae0 85087a0d
......@@ -14,6 +14,7 @@ import SlateEditor, {
deserializeHtml,
getDemoState,
} from 'app/components/elements/SlateEditor';
import { extractRtags } from 'app/utils/ExtractContent';
import LoadingIndicator from 'app/components/elements/LoadingIndicator';
import PostCategoryBanner from 'app/components/elements/PostCategoryBanner';
import shouldComponentUpdate from 'app/utils/shouldComponentUpdate';
......@@ -657,6 +658,14 @@ class ReplyEditor extends React.Component {
const disabled = submitting || !valid;
const loading = submitting || this.state.loading;
// Generate an array of images used in the post body.
// This will be used to display the cover image selector.
let selectedCoverImage = '';
let rtags;
if (isStory) {
rtags = extractRtags(body.value);
}
const errorCallback = estr => {
this.setState({ postError: estr, loading: false });
};
......@@ -724,6 +733,23 @@ class ReplyEditor extends React.Component {
});
};
const onSelectCoverImage = event => {
const { target } = event;
const postImages = document.getElementsByClassName(
'ReplyEditor__options__image_selector__image_container'
);
for (let pi = 0; pi < postImages.length; pi += 1) {
const postImage = postImages[pi];
postImage.classList.remove('selected');
}
target.classList.add('selected');
selectedCoverImage = target.style.backgroundImage
.slice(4, -1)
.replace(/"/g, '');
};
return (
<div
className={classnames({
......@@ -771,6 +797,7 @@ class ReplyEditor extends React.Component {
...data,
...replyParams,
startLoadingIndicator,
selectedCoverImage,
};
reply(replyPayload);
})}
......@@ -1016,6 +1043,36 @@ class ReplyEditor extends React.Component {
</span>
)}
</div>
{Array.from(rtags.images).length >
0 && (
<div className="ReplyEditor__options__cover_image_selector">
<h6>
{tt(
'reply_editor.select_cover_image'
)}
:
</h6>
<div className="ReplyEditor__options__image_selector">
{Array.from(
rtags.images
).map(image => {
return (
<div
className="ReplyEditor__options__image_selector__image_container"
style={{
backgroundImage: `url(${
image
})`,
}}
onClick={
onSelectCoverImage
}
/>
);
})}
</div>
</div>
)}
<a
href="#"
onClick={
......@@ -1369,6 +1426,7 @@ export default formId =>
successCallback,
errorCallback,
startLoadingIndicator,
selectedCoverImage,
}) => {
const isEdit = type === 'edit';
const isNew = /^submit_/.test(type);
......@@ -1426,16 +1484,40 @@ export default formId =>
// merge
const meta = isEdit ? jsonMetadata : {};
if (metaTags.size) meta.tags = metaTags.toJS();
else delete meta.tags;
if (rtags.usertags.size) meta.users = Array.from(rtags.usertags);
else delete meta.users;
if (rtags.images.size)
meta.image = Array.from(rtags.images).slice(0, 1);
else delete meta.image;
if (rtags.links.size)
if (metaTags.size) {
meta.tags = metaTags.toJS();
} else {
delete meta.tags;
}
if (rtags.usertags.size) {
meta.users = Array.from(rtags.usertags);
} else {
delete meta.users;
}
if (rtags.images.size) {
const moveToFirst = (array, first) => {
array.sort((x, y) => {
return x === first ? -1 : y === first ? 1 : 0;
});
};
meta.image = Array.from(rtags.images);
// If a cover image has been manually selected,
// move it to the first element of the image array.
if (selectedCoverImage) {
moveToFirst(meta.image, selectedCoverImage);
}
} else {
delete meta.image;
}
if (rtags.links.size) {
meta.links = Array.from(rtags.links).slice(0, 1);
else delete meta.links;
} else {
delete meta.links;
}
meta.app = 'hiveblog/0.1';
if (isStory) {
......
......@@ -156,3 +156,35 @@
.Dropdown__root___1B9ta {
color: black!important;
}
.ReplyEditor__options__cover_image_selector {
margin-top: 10px;
}
.ReplyEditor__options__image_selector {
.ReplyEditor__options__image_selector__image_container {
width: 60px;
height: 60px;
margin-right: 5px;
margin-bottom: 5px;
border: 1px solid grey;
background-size: cover;
display: inline-block;
transition: width 0.5s, height 0.5s;
vertical-align: top;
opacity: 0.5;
&.selected {
opacity: 1;
@include themify($themes) {
border: 3px solid $color-hive-red;
}
}
&:hover {
opacity: 1;
width: 120px;
height: 120px;
}
}
}
......@@ -361,7 +361,8 @@
"tags_input": "Enter your tags separated by a space",
"enable_sidebyside": "Enable side-by-side editor",
"disable_sidebyside": "Disable side-by-side editor",
"post_options": "Post options"
"post_options": "Post options",
"select_cover_image": "Select your cover image"
},
"beneficiary_selector_jsx": {
"header": "Who should receive any rewards?",
......
......@@ -15,8 +15,26 @@ const getValidImage = array => {
: null;
};
export function extractRtags(body = null) {
let rtags;
{
const isHtml = /^<html>([\S\s]*)<\/html>$/.test(body);
const htmlText = isHtml
? body
: remarkable.render(
body.replace(
/<!--([\s\S]+?)(-->|$)/g,
'(html comment removed: $1)'
)
);
rtags = HtmlReady(htmlText, { mutate: false });
}
return rtags;
}
export function extractImageLink(json_metadata, body = null) {
let json = json_metadata || {};
const json = json_metadata || {};
let image_link;
try {
......@@ -25,19 +43,7 @@ export function extractImageLink(json_metadata, body = null) {
// If nothing found in json metadata, parse body and check images/links
if (!image_link) {
let rtags;
{
const isHtml = /^<html>([\S\s]*)<\/html>$/.test(body);
const htmlText = isHtml
? body
: remarkable.render(
body.replace(
/<!--([\s\S]+?)(-->|$)/g,
'(html comment removed: $1)'
)
);
rtags = HtmlReady(htmlText, { mutate: false });
}
const rtags = extractRtags(body);
if (rtags.images) {
[image_link] = Array.from(rtags.images);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment