1
0
mirror of https://github.com/trambarhq/relaks-wordpress-example.git synced 2025-09-02 20:52:33 +02:00

Implemented image dialog box (issue #17).

This commit is contained in:
Chung Leong
2019-01-29 21:26:49 +01:00
parent fee7616378
commit d24cc2cc1a
6 changed files with 166 additions and 8 deletions

View File

@@ -47,6 +47,7 @@ class FrontEnd extends PureComponent {
<div className="page-container">
<PageComponent route={route} wp={wp} key={key} />
</div>
<div id="overlay" />
</div>
);
}

View File

@@ -52,14 +52,15 @@ class PostPage extends AsyncComponent {
}
// see how recently a category was visited
let historyIndex = (c) => {
return _.findLastIndex(route.history, { params: { categorySlug: c.slug }});
let historyIndex = (category) => {
let predicate = { params: { categorySlug: category.slug }};
return _.findLastIndex(route.history, predicate);
};
// see how deep a category is
let depth = (c) => {
if (c.parent) {
let parent = _.find(allCategories, { id: c.parent });
let depth = (category) => {
if (category.parent) {
let predicate = { id: category.parent };
let parent = _.find(allCategories, predicate);
if (parent) {
return depth(parent) + 1;
}
@@ -97,7 +98,7 @@ class PostPageSync extends PureComponent {
let { route, categories, post, author, tags, comments } = this.props;
let trail = [ { label: 'Categories' } ];
for (let category of categories) {
let label = _.get(c, 'name', '');
let label = _.get(category, 'name', '');
let url = route.prefetchObjectURL(category);
trail.push({ label, url });
}

View File

@@ -190,6 +190,9 @@ class Route {
node.attribs.target = '_blank';
}
}
if (_.startsWith(node.attribs.href, '/wp-content/')) {
node.attribs.href = siteURL + node.attribs.href;
}
if (_.startsWith(node.attribs.href, '/')) {
// strip off page number
node.attribs.href = node.attribs.href.replace(/\/\d+\/?$/, '');

View File

@@ -320,6 +320,65 @@ A {
}
}
.overlay {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.image-dialog {
.background, .foreground {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.background {
background-color: #ffffff;
opacity: 0.5;
}
.foreground {
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
.box {
position: relative;
pointer-events: auto;
background: #66023c;
border-color: 1px solid black;
padding: 1em 1em 1em 1em;
box-shadow: 2px 2px 10px #000000;
max-width: 90%;
color: #cccccc;
.image {
display: block;
border: 1px solid #000000;
max-width: 100%;
max-height: 80vh;
height: auto;
}
.close-button {
position: absolute;
font-size: 0.75em;
padding: 0.25em 0.25em 0.25em 0.25em;
margin: -0.25em -0.25em -0.25em -0.25em;
right: 0.35em;
top: 0.35em;
cursor: pointer;
}
}
}
}
@media only screen and (max-width: 800px) {
.page-container {
transition: margin-left 0.3s;

View File

@@ -0,0 +1,57 @@
import _ from 'lodash';
import React, { PureComponent } from 'react';
import ReactDOM from 'react-dom';
class ImageDialog extends PureComponent {
render() {
let { imageURL } = this.props;
if (!imageURL) {
return null;
}
let container = document.getElementById('overlay');
let dialog = this.renderDialog();
return ReactDOM.createPortal(dialog, container);
}
renderDialog() {
let { imageURL } = this.props;
return (
<div className="image-dialog">
<div className="background" onClick={this.handleCloseClick}/>
<div className="foreground">
<div className="box">
<div className="close-button" onClick={this.handleCloseClick}>
<i className="fa fa-times" />
</div>
<img className="image" src={imageURL} />
</div>
</div>
</div>
);
}
handleCloseClick = (evt) => {
let { onClose } = this.props;
if (onClose) {
onClose({
type: 'close',
target: this,
});
}
}
}
if (process.env.NODE_ENV !== 'production') {
const PropTypes = require('prop-types');
ImageDialog.propTypes = {
imageURL: PropTypes.string,
onClose: PropTypes.func,
};
}
export {
ImageDialog as default,
ImageDialog,
};

View File

@@ -3,10 +3,18 @@ import Moment from 'moment';
import React, { PureComponent } from 'react';
import HTML from 'widgets/html';
import ImageDialog from 'widgets/image-dialog';
class PostView extends PureComponent {
static displayName = 'PostView';
constructor(props) {
super(props);
this.state = {
imageURL: null,
};
}
render() {
let { post, author, transform } = this.props;
let title = _.get(post, 'title.rendered', '');
@@ -23,12 +31,41 @@ class PostView extends PureComponent {
<div className="author">{name}</div>
</div>
<h1><HTML text={title} /></h1>
<div className="content">
<div className="content" onClick={this.handleClick}>
<HTML text={content} transform={transform} />
</div>
{this.renderImageDialog()}
</div>
);
}
renderImageDialog() {
let { imageURL } = this.state;
return <ImageDialog imageURL={imageURL} onClose={this.handleDialogClose} />;
}
handleClick = (evt) => {
let target = evt.target;
let container = evt.currentTarget;
if (target.tagName === 'IMG') {
let link;
for (let p = target; p && p !== container; p = p.parentNode) {
if (p.tagName === 'A') {
link = p;
break;
}
}
if (link) {
let imageURL = link.href;
this.setState({ imageURL });
evt.preventDefault();
}
}
}
handleDialogClose = (evt) => {
this.setState({ imageURL: null });
}
}
if (process.env.NODE_ENV !== 'production') {