Skip to content

Instantly share code, notes, and snippets.

@SoHotSoup
Created April 18, 2017 15:23
Show Gist options
  • Select an option

  • Save SoHotSoup/1354dfaf64f8dc1ef8b110aa860bea34 to your computer and use it in GitHub Desktop.

Select an option

Save SoHotSoup/1354dfaf64f8dc1ef8b110aa860bea34 to your computer and use it in GitHub Desktop.
Article Details Screen with declarative animations
import React from 'react';
import { ScrollView } from 'react-native';
import { connectStyle } from '@shoutem/theme';
import {
Screen,
Title,
Caption,
Icon,
Image,
Overlay,
RichMedia,
} from '@shoutem/ui';
import {
HeroHeader,
FadeOut,
FadeIn,
ZoomOut,
ScrollDriver,
Parallax,
} from '@shoutem/animation';
import * as _ from 'lodash';
import moment from 'moment';
import { connect } from 'react-redux';
import { getCollection } from '@shoutem/redux-io';
import { ext } from '../const';
import NextArticle from '../components/NextArticle';
class ArticleDetailsScreen extends React.Component {
static propTypes = {
// The news article to display
article: React.PropTypes.object.isRequired,
// News articles collection being displayed
articles: React.PropTypes.array,
// A function for configuring the navigation bar
setNavBarProps: React.PropTypes.func,
// Whether the next article view should be displayed at
// the bottom of the screen
showNext: React.PropTypes.bool,
};
shouldRenderNextArticle() {
return this.props.articles && this.props.showNext;
}
renderUpNext() {
const { article: { id }, articles } = this.props;
const currentArticleIndex = _.findIndex(articles, { id });
const nextArticle = articles[currentArticleIndex + 1];
if (nextArticle) {
return (
<NextArticle article={nextArticle} />
);
}
return null;
}
render() {
const { article, setNavBarProps } = this.props;
const driver = new ScrollDriver();
setNavBarProps({
styleName: 'clear',
share: {
title: article.title,
text: article.summary,
link: article.link,
},
});
/* eslint-disable no-multi-spaces */
return (
<Screen styleName="full-screen">
<ScrollView {...driver.scrollViewProps}>
<HeroHeader driver={driver}>
<Image styleName="large-portrait" source={{ uri: _.get(article, 'image.url') }}>
<Overlay styleName="dark">
<Parallax driver={driver} scrollSpeed={1.2}>
<FadeIn driver={driver} inputRange={[-70, -50]}>
<FadeOut driver={driver} inputRange={[50, 200]}>
<Title styleName="centered">{article.title.toUpperCase()}</Title>
<Caption>
{article.newsAuthor} {moment(article.timeUpdated).fromNow()}
</Caption>
</FadeOut>
</FadeIn>
</Parallax>
<Icon name="down-arrow" styleName="scroll-indicator" />
</Overlay>
</Image>
</HeroHeader>
<Screen>
<RichMedia
body={article.body}
attachments={article.attachments}
/>
{this.shouldRenderNextArticle() && this.renderUpNext()}
</Screen>
</ScrollView>
</Screen>
);
}
}
export default connect((state) => ({
articles: getCollection(state[ext()].latestNews, state),
}))(connectStyle(ext('ArticleDetailsScreen'), {})(ArticleDetailsScreen));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment