Skip to content

Commit

Permalink
examples: cache images;
Browse files Browse the repository at this point in the history
also started the react-router example
  • Loading branch information
jossmac committed Feb 14, 2018
1 parent 54707d3 commit ab8a3d7
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 27 deletions.
30 changes: 25 additions & 5 deletions examples/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import glam from 'glam';
import React, { Component } from 'react';
import { BrowserRouter, Link, Route, Switch } from 'react-router-dom';

import { Home, NoMatch } from './pages';
import { Home, NoMatch, ReactRouter } from './pages';
import ImageRoute from './ImageRoute';
import withImages, { type ProviderProps } from './ImageProvider';

const borderColor = 'hsl(0, 0%, 88%)';
const navWidth = 180;
Expand Down Expand Up @@ -37,9 +39,13 @@ const AppContainer = props => (
const PageContent = props => (
<div
css={{
marginLeft: 'auto',
marginRight: 'auto',
maxWidth: 640,
paddingBottom: contentGutter,
paddingLeft: 20,
paddingRight: 20,
paddingTop: contentGutter,
paddingRight: navWidth / 2,

[smallDevice]: {
paddingTop: contentGutter * 2,
Expand Down Expand Up @@ -137,10 +143,15 @@ const NavItem = ({ selected, ...props }) => (
{...props}
/>
);
const links = [{ label: 'Home', value: '/' }];
const links = [
{ label: 'Home', value: '/' },
{ label: 'React Router', value: '/react-router' },
];

export default class App extends Component<*> {
class App extends Component<*> {
routeProps: ProviderProps;
render() {
const routeProps = (this.routeProps = this.props);
return (
<BrowserRouter>
<Route>
Expand All @@ -162,7 +173,14 @@ export default class App extends Component<*> {
<AppContent>
<PageContent>
<Switch>
<Route exact path="/" component={Home} />
<ImageRoute exact path="/" component={Home} {...routeProps} />
<BrowserRouter basename="/react-router">
<ImageRoute
path="/:activeIndices"
component={ReactRouter}
{...routeProps}
/>
</BrowserRouter>
<Route component={NoMatch} />
</Switch>
</PageContent>
Expand All @@ -173,3 +191,5 @@ export default class App extends Component<*> {
);
}
}

export default withImages(App);
27 changes: 20 additions & 7 deletions examples/ImageProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,19 @@

import React, { Component, type ComponentType } from 'react';

type Props = {};
type State = { images: Array<Object> | null };
type Images = Array<{
description: string,
photographer: string,
urls: {
regular: string,
thumb: string,
},
}>;
export type ProviderProps = {
images: Images,
isLoading: boolean,
};
type State = { images: Images | null, isLoading: boolean };

function formatImages(arr) {
return arr.map(img => ({
Expand All @@ -15,8 +26,8 @@ function formatImages(arr) {
}

export default function withImages(WrappedComponent: ComponentType<*>) {
return class ImageProvider extends Component<Props, State> {
state = { images: null };
return class ImageProvider extends Component<{}, State> {
state = { images: null, isLoading: true };
componentDidMount() {
const query = 'wildlife,animal';
const url =
Expand All @@ -27,18 +38,20 @@ export default function withImages(WrappedComponent: ComponentType<*>) {
fetch(`${url}${query}&client_id=${process.env.UNSPLASH_API_KEY}`)
.then(res => res.json())
.then(data => {
this.setState({ images: data.results });
this.setState({ images: data.results, isLoading: false });
})
.catch(err => {
console.error('Error occured when fetching images', err);
});
}
render() {
const { images } = this.state;
const { images, isLoading } = this.state;

return (
<WrappedComponent
images={images ? formatImages(images) : []}
isLoading={!images}
isLoading={isLoading}
{...this.props}
/>
);
}
Expand Down
26 changes: 26 additions & 0 deletions examples/ImageRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// @flow

import React, { type ComponentType } from 'react';
import { Route } from 'react-router-dom';
import { type ProviderProps } from './ImageProvider';

type Props = ProviderProps & {
component: ComponentType<*>,
exact?: boolean,
path: string,
};

const ImageRoute = (props: Props) => {
const { component: Component, images, isLoading, ...rest } = props;

return (
<Route
{...rest}
children={routeProps => (
<Component images={images} isLoading={isLoading} {...routeProps} />
)}
/>
);
};

export default ImageRoute;
15 changes: 2 additions & 13 deletions examples/pages/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import glam from 'glam';
import React, { Component } from 'react';

import Carousel, { Modal, ModalGateway } from '../../src/components';
import withImages from '../ImageProvider';

const flow = (
<a href="https://flow.org" target="_blank">
Expand Down Expand Up @@ -49,7 +48,7 @@ type State = {
lightboxIsOpen: boolean,
};

class Home extends Component<Props, State> {
export default class Home extends Component<Props, State> {
state = {
currentView: undefined,
lightboxIsOpen: false,
Expand All @@ -65,15 +64,7 @@ class Home extends Component<Props, State> {
const { currentView, lightboxIsOpen } = this.state;

return (
<div
css={{
maxWidth: 640,
marginLeft: 'auto',
marginRight: 'auto',
paddingLeft: 20,
paddingRight: 20,
}}
>
<div>
<h1>
React Images v1{' '}
<small css={{ color: '#999', fontWeight: 500 }}>(alpha)</small>
Expand Down Expand Up @@ -154,5 +145,3 @@ class Home extends Component<Props, State> {
);
}
}

export default withImages(Home);
41 changes: 41 additions & 0 deletions examples/pages/ReactRouter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// @flow
// @jsx glam
import glam from 'glam';
import React, { Component } from 'react';

import Carousel from '../../src/components';
import { type ProviderProps } from '../ImageProvider';

export default class ReactRouter extends Component<ProviderProps> {
static defaultProps = {
activeIndices: [0],
};
handleViewChange = activeIndices => {
const { history, location } = this.props;
history.push(`${activeIndices}`);
console.log('activeIndices', activeIndices);
};
render() {
const { activeIndices, images, isLoading } = this.props;

console.log('router example', this.props);

return (
<div>
<h1>React Router Example</h1>
{!isLoading ? (
<Carousel
frameProps={{ autoSize: 'height' }}
trackProps={{
infinite: true,
currentView: activeIndices,
onViewChange: this.handleViewChange,
}}
views={images}
components={{ Header: null }}
/>
) : null}
</div>
);
}
}
1 change: 1 addition & 0 deletions examples/pages/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as Home } from './Home';
export { default as NoMatch } from './NoMatch';
export { default as ReactRouter } from './ReactRouter';
4 changes: 2 additions & 2 deletions src/components/Carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const defaultProps = {
hideControlsWhenIdle: true,
styles: {},
trackProps: {
currentView: 0,
currentView: [0],
instant: !isTouch(),
swipe: 'touch',
},
Expand All @@ -102,7 +102,7 @@ class Carousel extends Component<CarouselProps, CarouselState> {
const trackProps = this.getTrackProps(props);

this.state = {
activeIndices: [trackProps.currentView],
activeIndices: trackProps.currentView,
footerHeight: 0,
headerHeight: 0,
mouseIsIdle: isTouch(),
Expand Down

0 comments on commit ab8a3d7

Please sign in to comment.