Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { Component, PropTypes } from 'react';
- import {
- View,
- StyleSheet,
- Image,
- Text,
- StatusBar,
- Animated,
- ActivityIndicator,
- ToolbarAndroid,
- TouchableNativeFeedback,
- TouchableWithoutFeedback,
- } from 'react-native';
- import { connect } from 'react-redux';
- import moment from 'moment';
- import * as constants from './utils/constants';
- import * as actions from '../../actions/index';
- const HEADER_MAX_HEIGHT = 160;
- const DELTA = 20;
- const TOOLBAR_HEIGHT = 56;
- const HEADER_SCROLL_DISTANCE = HEADER_MAX_HEIGHT - TOOLBAR_HEIGHT;
- const ic_close_black = require('../../assets/icons/ic_close_black.png');
- const ic_incoming_transaction = require('../../assets/icons/ic_incoming.png');
- const ic_outgoing_transaction = require('../../assets/icons/ic_payment.png');
- const ic_back_white = require('../../assets/icons/ic_back_white.png');
- const ic_settings_white = require('../../assets/icons/ic_settings_white.png');
- const ic_fab = require('../../assets/icons/ic_fab_money.png');
- const ic_empty = require('../../assets/icons/ic_profile_feed.png');
- export class Profile extends Component {
- static propTypes = {
- navigation: PropTypes.shape({
- navigate: PropTypes.func.isRequired,
- dispatch: PropTypes.func.isRequired,
- }),
- };
- offset = 0
- limit = 10
- activity = true
- constructor(props) {
- super(props);
- this.state = {
- scrollY: new Animated.Value(0),
- modalVisibility: false,
- newTransactionModalVisibility: false,
- item: {},
- // TODO get user from props (redux)
- user: {
- id: '1568161709003113564',
- pic: 'http://www.gstatic.com/webp/gallery/2.jpg',
- balance: {
- token: {
- currency: '',
- amount: '',
- },
- price: {
- currency: '',
- amount: '',
- },
- },
- name: 'User',
- surname: 'User1',
- phone: '+1 (234) 567-8901',
- status: 1, // 1 - online, 0 - offline
- password: 'djamik123',
- wallet: '0x123123123123',
- },
- transactions: [],
- showFooter: false,
- arrayChanged: true,
- loading: false,
- refreshing: false,
- };
- }
- componentWillMount() {
- }
- componentDidMount() {
- }
- // animation in order to make collapse effects
- getAnimationType = (type) => {
- switch (type) {
- case constants.HEADER_TRANSLATE:
- return this.state.scrollY.interpolate({
- inputRange: [0, HEADER_SCROLL_DISTANCE],
- outputRange: [0, -HEADER_SCROLL_DISTANCE],
- extrapolate: 'clamp',
- });
- case constants.HEADER_TRANSLATE2:
- return this.state.scrollY.interpolate({
- inputRange: [0, HEADER_SCROLL_DISTANCE],
- outputRange: [0, HEADER_SCROLL_DISTANCE],
- extrapolate: 'clamp',
- });
- case constants.VIEW_TRANSLATE:
- return this.state.scrollY.interpolate({
- inputRange: [0, HEADER_SCROLL_DISTANCE],
- outputRange: [1, 0.7],
- extrapolate: 'clamp',
- });
- case constants.VIEWY_TRANSLATE:
- return this.state.scrollY.interpolate({
- inputRange: [0, HEADER_SCROLL_DISTANCE],
- outputRange: [0, DELTA + (0.7 * DELTA)],
- extrapolate: 'clamp',
- });
- case constants.IMAGE_OPACITY:
- return this.state.scrollY.interpolate({
- inputRange: [0, HEADER_SCROLL_DISTANCE / 2],
- outputRange: [1, 0],
- extrapolate: 'clamp',
- });
- default:
- return '';
- }
- };
- render() {
- const { user } = this.state;
- const { profile } = this.props;
- // break amount into two values to use them separately
- const hmqInt = user && user.balance && user.balance.token && user.balance.token.amount
- ? user.balance.token.amount.toString().split('.')[0] : '0';
- const hmqDec = user && user.balance && user.balance.token && user.balance.token.amount
- ? user.balance.token.amount.toString().split('.')[1] : '00';
- // break amount into two values to use them separately
- const currencyInt = user && user.balance && user.balance.price && user.balance.price.amount
- ? user.balance.price.amount.toString().split('.')[0] : '0';
- const currencyDec = user && user.balance && user.balance.price && user.balance.price.amount
- ? user.balance.price.amount.toString().split('.')[1] : '00';
- return (
- <View style={styles.mainContainer}>
- {/* render status bar */}
- <StatusBar
- backgroundColor="#598FBA"
- />
- {/* render list */}
- {this.state.transactions.length > 0 ? this.renderContent() : this.renderEmptyView()}
- {/* render collapse layout */}
- <Animated.View
- style={[styles.collapseContainer, {
- transform: [{ translateY: this.getAnimationType(constants.HEADER_TRANSLATE) }],
- }]}
- >
- <Animated.View
- style={[styles.bar, {
- transform: [
- { scale: this.getAnimationType(constants.VIEW_TRANSLATE) },
- { translateY: this.getAnimationType(constants.VIEWY_TRANSLATE) },
- ],
- }]}
- >
- <Animated.View
- style={styles.avatarInfoContainer}
- >
- <Animated.Image
- style={styles.avatar}
- source={{ uri: profile.avatar ? profile.avatar.url : this.state.user.pic }}
- />
- <Animated.View style={styles.infoContainer}>
- <Text style={styles.title}>{`${hmqInt}.`}
- <Text style={{ fontSize: 17.5, color: '#DAE5EE' }}>
- {hmqDec || '00'} {user.balance.token.currency}
- </Text>
- </Text>
- <Text style={{ fontSize: 16, color: '#DAE5EE', marginTop: 3 }}>
- {`${currencyInt}.`}{currencyDec || '00'} {user.balance.price.currency}
- </Text>
- </Animated.View>
- </Animated.View>
- </Animated.View>
- {/* render toolbar */}
- <Animated.View style={[{
- transform: [{ translateY: this.getAnimationType(constants.HEADER_TRANSLATE2) }],
- }]}
- >
- <ToolbarAndroid
- onActionSelected={position => this.onActionClick(position)}
- style={styles.toolbar}
- onIconClicked={() => this.backButtonHandle()}
- navIcon={ic_back_white}
- actions={[{
- title: '',
- icon: ic_settings_white,
- show: 'always',
- }]}
- />
- </Animated.View>
- </Animated.View>
- </View>
- );
- }
- backButtonHandle = () => {
- };
- renderHeaderSection = header => (
- <Text style={styles.headerSection}>{header}</Text>
- );
- // render list
- renderScrollViewContent = () => {
- // convert array to map
- let index = 0;
- const categoryMap = {};
- const headerIds = [];
- this.state.transactions.forEach((item) => {
- // sort by category (timestamp)
- const category = moment.unix(item.timestamp).format('DD.MM.YYYY').toString();
- if (!categoryMap[category]) {
- categoryMap[category] = [];
- headerIds[index] = category;
- index += 1;
- }
- categoryMap[category].push(item);
- });
- return (
- <View style={styles.scrollViewContent}>
- {headerIds.map(item => categoryMap[item].map((child, childIndex) => (
- <View>
- {/* render header text */}
- {childIndex === 0 ? this.renderHeaderSection(item) : null}
- {/* render transaction item */}
- <Item
- item={child}
- currentIndex={childIndex}
- size={categoryMap[item].length}
- onClick={() => this.onItemClick(child)}
- />
- </View>
- )))}
- {this.state.showFooter ? this.progressIndicator() : null}
- </View>
- );
- };
- _onRefresh() {
- this.setState({ refreshing: true });
- }
- progressIndicator = () => (
- <Animated.View style={{ padding: 5 }}>
- <ActivityIndicator
- size={30}
- />
- </Animated.View>
- );
- settingsButtonHandle = () => {
- const navState = this.props.navigation.state;
- this.props.navigation.navigate('ProfileSettings', { ...navState.params, user: this.state.user });
- };
- // on fab button click handler
- onFabButtonPress = () => {
- // show newTransactionModal
- this.setState({ newTransactionModalVisibility: true });
- };
- renderContent = () => (
- <Animated.ScrollView
- ref="scrollRef"
- style={{ backgroundColor: '#fff' }}
- scrollEventThrottle={15}
- onScroll={this.onScroll.bind(this)}
- >
- {this.renderScrollViewContent()}
- </Animated.ScrollView>
- );
- isCloseToBottom = ({ layoutMeasurement, contentOffset, contentSize }) => {
- let paddingToBottom = 0;
- paddingToBottom += layoutMeasurement.height;
- return contentOffset.y >= contentSize.height - paddingToBottom;
- };
- // combining two onScroll events (Animated.Event and onScroll event)
- onScroll(event) {
- if (this.props.onScroll) this.props.onScroll(event);
- Animated.event(
- [{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
- { onScroll: this.props.onScroll }, { useNativeDriver: true },
- )(event);
- // detect if scroll reached the end of the list to load more data
- if (this.isCloseToBottom(event.nativeEvent)
- && !this.state.showFooter && this.state.arrayChanged) {
- this.scrollToPosition = event.nativeEvent.contentSize.height;
- this.setState({ showFooter: true });
- setTimeout(() => {
- if (this.activity && this.refs.scrollRef) {
- this.refs.scrollRef._component.scrollTo({ x: 0, y: this.scrollToPosition });
- this.loadMoreData();
- }
- }, 50);
- }
- }
- // render Empty View, if array is empty
- renderEmptyView = () => (
- <View style={styles.emptyViewContainer}>
- <Image
- resizeMode="contain"
- style={styles.emptyImage}
- source={ic_empty}
- />
- </View>
- );
- // on transaction item click handler
- onItemClick = (item) => {
- this.setState({
- item,
- modalVisibility: true,
- });
- };
- // on chat icon click handler
- onChatClick = () => {
- this.setState({
- modalVisibility: false,
- });
- };
- // to load more data
- loadMoreData() {
- this.getTransactions();
- }
- componentWillUnmount() {
- // to prevent null pointers
- this.activity = false;
- // DeviceEventEmitter.removeAllListeners()
- }
- // toolbar action click handler
- onActionClick = (position) => {
- switch (position) {
- case 0:
- return this.settingsButtonHandle();
- default:
- return '';
- }
- };
- onRefresh() {
- // when pull to refresh triggers
- this.setState({ loading: true });
- setTimeout(() => this.setState({ loading: false }));
- }
- dismissModal() {
- this.setState({ newTransactionModalVisibility: false });
- }
- }
- const styles = StyleSheet.create({
- mainContainer: {
- flex: 1,
- },
- collapseContainer: {
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- backgroundColor: '#598fba',
- overflow: 'hidden',
- height: HEADER_MAX_HEIGHT,
- },
- avatarInfoContainer: {
- flexDirection: 'row',
- alignItems: 'center',
- alignSelf: 'flex-start',
- marginLeft: 16,
- },
- avatar: {
- height: 60,
- width: 60,
- borderRadius: 65,
- },
- infoContainer: { marginLeft: 13 },
- bar: {
- backgroundColor: 'transparent',
- justifyContent: 'center',
- alignSelf: 'flex-end',
- position: 'absolute',
- left: 0,
- right: 0,
- bottom: DELTA,
- },
- title: {
- color: 'white',
- fontSize: 28,
- },
- scrollViewContent: {
- marginTop: HEADER_MAX_HEIGHT,
- backgroundColor: '#fff',
- },
- backButton: {
- marginLeft: 16,
- },
- settingsButton: {
- marginRight: 16,
- },
- headerSection: {
- marginLeft: 16.5,
- marginTop: 33,
- marginBottom: 13,
- color: '#2586C6',
- fontSize: 16.5,
- fontWeight: '500',
- },
- back: {
- height: 24,
- width: 24,
- },
- settings: {
- height: 24,
- width: 24,
- },
- toolbar: {
- height: TOOLBAR_HEIGHT,
- backgroundColor: 'transparent',
- },
- emptyViewContainer: {
- marginTop: HEADER_MAX_HEIGHT,
- flex: 1,
- backgroundColor: '#fff',
- alignItems: 'center',
- justifyContent: 'center',
- },
- emptyImage: {},
- priceInt: {
- fontSize: 16,
- color: '#000000',
- },
- priceDecimal: {
- color: '#8B8B8B',
- fontSize: 14,
- },
- rootContainer: {
- justifyContent: 'flex-end',
- flex: 1,
- },
- content: {
- backgroundColor: '#ffffff',
- height: 250,
- justifyContent: 'flex-end',
- },
- closeButtonContainer: {
- padding: 15,
- alignItems: 'center',
- },
- imageContainer: {
- flexDirection: 'row',
- flex: 1,
- },
- transactionImageContainer: {
- padding: 10,
- flex: 1,
- alignItems: 'center',
- justifyContent: 'center',
- },
- });
- export default connect(
- state => ({
- user: state.user,
- profile: state.user.profile || {},
- }),
- dispatch => ({
- setProfile: profile => dispatch(actions.setProfile(profile)),
- }),
- )(Profile);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement