Skip to content

Commit 15ac8eb

Browse files
lstkzgondzo
authored andcommitted
cloudinary
1 parent 41c4dbd commit 15ac8eb

File tree

20 files changed

+462
-285
lines changed

20 files changed

+462
-285
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ REACT_APP_API_BASE_PATH=http://localhost:3500
33
REACT_APP_AUTH0_CLIENT_ID=3CGKzjS2nVSqHxHHE64RhvvKY6e0TYpK
44
REACT_APP_AUTH0_CLIENT_DOMAIN=dronetest.auth0.com
55
REACT_APP_SOCKET_URL=http://localhost:3500
6+
CLOUDINARY_ACCOUNT_NAME=dsp

.env.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ GOOGLE_API_KEY=AIzaSyCrL-O319wNJK8kk8J_JAYsWgu6yo5YsDI
22
REACT_APP_API_BASE_PATH=http://localhost:3500
33
REACT_APP_AUTH0_CLIENT_ID=3CGKzjS2nVSqHxHHE64RhvvKY6e0TYpK
44
REACT_APP_AUTH0_CLIENT_DOMAIN=dronetest.auth0.com
5-
REACT_APP_SOCKET_URL=http://localhost:3500
5+
REACT_APP_SOCKET_URL=http://localhost:3500
6+
CLOUDINARY_ACCOUNT_NAME=dsp

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ See Guild https://github.com/lorenwest/node-config/wiki/Configuration-Files
1818
|`PORT`| The port to listen|
1919
|`GOOGLE_API_KEY`| The google api key see (https://developers.google.com/maps/documentation/javascript/get-api-key#key)|
2020
|`API_BASE_URL`| The base URL for Drone API |
21-
|`REACT_APP_API_BASE_PATH`| The React app api base path`|
22-
|`REACT_APP_SOCKET_URL`| The React app app socket url`|
23-
|`REACT_APP_AUTH0_CLIEND_ID`| The React app auth0 client id`|
24-
|`REACT_APP_AUTH0_DOMAIN`| The React app auth0 domain`|
21+
|`REACT_APP_API_BASE_PATH`| The React app api base path|
22+
|`REACT_APP_SOCKET_URL`| The React app app socket url|
23+
|`REACT_APP_AUTH0_CLIEND_ID`| The React app auth0 client id|
24+
|`REACT_APP_AUTH0_DOMAIN`| The React app auth0 domain|
25+
|`CLOUDINARY_ACCOUNT_NAME`| Your `Cloud name` from https://cloudinary.com/console|
2526

2627
Environment variables will be loaded from the .env file during build. Create the .env file based on the provided env.example
2728
### Auth0 setup

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
"dependencies": {
2626
"auth0-js": "^7.6.0",
2727
"autoprefixer": "^6.5.0",
28+
"aws-sdk": "^2.7.21",
29+
"aws-sdk-promise": "0.0.2",
2830
"axios": "^0.15.3",
2931
"babel-core": "^6.17.0",
3032
"babel-eslint": "^7.0.0",
@@ -78,7 +80,9 @@
7880
"react-google-maps": "^6.0.1",
7981
"react-highcharts": "^11.0.0",
8082
"react-icheck": "^0.3.6",
83+
"react-image-lightbox": "^3.4.1",
8184
"react-input-range": "^0.9.3",
85+
"react-measure": "^1.4.5",
8286
"react-modal": "^1.5.2",
8387
"react-portal": "^3.0.0",
8488
"react-redux": "^4.0.0",
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React, {PropTypes} from 'react';
2+
3+
/**
4+
* Fires onClick only when cursor doesn't move
5+
* Used in react-slick because slick always fires onClick when dragging the slider
6+
*/
7+
8+
class ClickWithoutDrag extends React.Component {
9+
constructor(props) {
10+
super(props);
11+
this.isClick = false;
12+
13+
this.onMouseUp = (e) => {
14+
if (this.isClick) {
15+
this.props.onClick(e);
16+
}
17+
};
18+
this.onMouseMove = () => {
19+
this.isClick = false;
20+
};
21+
this.onMouseDown = () => {
22+
this.isClick = true;
23+
};
24+
}
25+
26+
render() {
27+
return (
28+
<a href="javascript:" onMouseUp={this.onMouseUp} onMouseMove={this.onMouseMove} onMouseDown={this.onMouseDown}>
29+
{this.props.children}
30+
</a>
31+
);
32+
}
33+
}
34+
35+
ClickWithoutDrag.propTypes = {
36+
children: PropTypes.any.isRequired,
37+
onClick: PropTypes.func.isRequired,
38+
};
39+
40+
export default ClickWithoutDrag;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import ClickWithoutDrag from './ClickWithoutDrag';
2+
3+
export default ClickWithoutDrag;
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import React, {PropTypes} from 'react';
2+
import CSSModules from 'react-css-modules';
3+
import Slider from 'react-slick';
4+
import _ from 'lodash';
5+
import Measure from 'react-measure';
6+
import Lightbox from 'react-image-lightbox';
7+
import config from '../../config';
8+
import styles from './CloudinaryGallery.scss';
9+
import CloudinaryGalleryItem from './CloudinaryGalleryItem';
10+
11+
const CLOUDINARY_PREFIX = `http://res.cloudinary.com/${config.CLOUDINARY_ACCOUNT_NAME}/image/fetch/`;
12+
13+
const sliderProps = {
14+
infinite: false,
15+
dots: true,
16+
speed: 500,
17+
slidesToShow: 1,
18+
slidesToScroll: 1,
19+
vertical: false,
20+
variableWidth: false,
21+
};
22+
23+
// css margin
24+
const MARGIN = 8;
25+
26+
class CloudinaryGallery extends React.Component {
27+
constructor(props) {
28+
super(props);
29+
this.state = {
30+
photoIndex: 0,
31+
isOpen: false,
32+
};
33+
}
34+
35+
render() {
36+
const {items, width, count, height, noItemsText} = this.props;
37+
const {isOpen, photoIndex} = this.state;
38+
39+
if (!items || !items.length) {
40+
return (
41+
<p styleName="no-items">{noItemsText}</p>
42+
);
43+
}
44+
const itemWidth = Math.floor(width / count) - 2 * MARGIN;
45+
const resizedItems = items.map((item) => ({
46+
...item,
47+
// c_fill = crop with retaining original proportions
48+
// g_auto = auto detect point of interests
49+
// see http://cloudinary.com/blog/introducing_smart_cropping_intelligent_quality_selection_and_automated_responsive_images#automatic_content_aware_cropping_g_auto
50+
src: `${CLOUDINARY_PREFIX}w_${itemWidth},h_${height},c_fill,g_auto/${item.src}`,
51+
}));
52+
return (
53+
<div styleName="cloudinary-gallery">
54+
{isOpen &&
55+
<Lightbox
56+
mainSrc={items[photoIndex].src}
57+
nextSrc={items[(photoIndex + 1) % items.length].src}
58+
prevSrc={items[(photoIndex + items.length - 1) % items.length].src}
59+
onCloseRequest={() => this.setState({isOpen: false})}
60+
onMovePrevRequest={() => this.setState({
61+
photoIndex: (photoIndex + items.length - 1) % items.length,
62+
})}
63+
onMoveNextRequest={() => this.setState({
64+
photoIndex: (photoIndex + 1) % items.length,
65+
})}
66+
/>
67+
}
68+
<Slider {...sliderProps}>
69+
{_.chunk(resizedItems, count).map((slideItems, slideIndex) => (
70+
<div key={slideIndex} styleName="slide">
71+
<div styleName="slide-inner">
72+
{slideItems.map((item, itemIndex) => (
73+
<div key={itemIndex} styleName="item">
74+
<CloudinaryGalleryItem
75+
{...item}
76+
onClick={() => {
77+
this.setState({
78+
isOpen: true,
79+
photoIndex: slideIndex * count + itemIndex,
80+
});
81+
}}
82+
/>
83+
</div>
84+
))}
85+
</div>
86+
</div>
87+
))}
88+
</Slider>
89+
</div>
90+
);
91+
}
92+
}
93+
94+
CloudinaryGallery.propTypes = {
95+
items: PropTypes.array.isRequired,
96+
width: PropTypes.number,
97+
count: PropTypes.number.isRequired,
98+
height: PropTypes.number.isRequired,
99+
noItemsText: PropTypes.string.isRequired,
100+
};
101+
102+
// HOC wrapping
103+
104+
const CloudinaryGalleryWithStyles = CSSModules(CloudinaryGallery, styles);
105+
106+
const CloudinaryGalleryWithMeasure = (props) => (
107+
<Measure>
108+
{
109+
({width}) => <CloudinaryGalleryWithStyles {...props} width={width} />
110+
}
111+
</Measure>
112+
);
113+
export default CloudinaryGalleryWithMeasure;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy