User.js 13.8 KB
'use strict';

import React from 'react';
import ReactNative from 'react-native';
import ScrollableTabView, {DefaultTabBar} from 'react-native-scrollable-tab-view';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ParallaxScrollView from '../CommonComp/ParallaxScrollView';

import UserCenterTop from './UserCenterTop';
import CommunityList from '../CommonComp/CommunityList';
import ReplyList from './ReplyList';
import ParallaxView from '../CommonComp/ParallaxView';
import SectionTabBar from '../section/SectionTabBar';
import LoadMoreIndicator from '../../../common/components/LoadMoreIndicator';
import UserNavBar from './UserNavBar';
const {
    View,
    Text,
    ListView,
    Platform,
    Dimensions,
    StyleSheet,
    PanResponder,
    ActionSheetIOS,
    InteractionManager,
    Animated,
} = ReactNative;

export default class User extends React.Component {

    static propTypes = {

        userInfo: ImmutablePropTypes.contains({
            avatar: React.PropTypes.string,
            backgroundImage:React.PropTypes.string,
            nickName:React.PropTypes.string.isRequired,
            sign: React.PropTypes.string,
        }),

        list: ImmutablePropTypes.listOf(
            ImmutablePropTypes.contains({
                posts: ImmutablePropTypes.listOf(
                    ImmutablePropTypes.contains({
                        author: ImmutablePropTypes.contains({
                            avatar: React.PropTypes.string,
                            uid: React.PropTypes.number,
                            name: React.PropTypes.string,
                        }),
                        timeago: React.PropTypes.string.isRequired,
                        isOwner: React.PropTypes.bool,
                        isTop: React.PropTypes.bool,
                        isLike: React.PropTypes.bool,
                        title: React.PropTypes.string,
                        desc: React.PropTypes.string,
                        thumbs: ImmutablePropTypes.listOf(
                            ImmutablePropTypes.contains({
                                src: React.PropTypes.string,
                            })
                        ),
                        section: ImmutablePropTypes.contains({
                            id: React.PropTypes.number,
                            name: React.PropTypes.string,
                        }),
                        commentCount: React.PropTypes.number,
                        likeCount: React.PropTypes.number,
                    })
                ),
                like: ImmutablePropTypes.listOf(
                    ImmutablePropTypes.contains({
                        author: ImmutablePropTypes.contains({
                            avatar: React.PropTypes.string,
                            uid: React.PropTypes.number,
                            name: React.PropTypes.string,
                        }),
                        timeago: React.PropTypes.string.isRequired,
                        isOwner: React.PropTypes.bool,
                        isTop: React.PropTypes.bool,
                        isLike: React.PropTypes.bool,
                        title: React.PropTypes.string,
                        desc: React.PropTypes.string,
                        thumbs: ImmutablePropTypes.listOf(
                            ImmutablePropTypes.contains({
                                src: React.PropTypes.string,
                            })
                        ),
                        section: ImmutablePropTypes.contains({
                            id: React.PropTypes.number,
                            name: React.PropTypes.string,
                        }),
                        commentCount: React.PropTypes.number,
                        likeCount: React.PropTypes.number,
                    })
                ),

                reply: ImmutablePropTypes.listOf(
                    ImmutablePropTypes.contains({
                        reply: ImmutablePropTypes.contains({
                            headIcon: React.PropTypes.string,
                            uid: React.PropTypes.number,
                            name: React.PropTypes.string,
                        }),

                        replyTo: ImmutablePropTypes.contains({
                            headIcon: React.PropTypes.string,
                            uid: React.PropTypes.number,
                            name: React.PropTypes.string,
                        }),

                        id: React.PropTypes.number,
                        postId: React.PropTypes.number,
                        createTime: React.PropTypes.number.isRequired,
                        authorUid: React.PropTypes.number,
                    })

                ),

            })
        ),


        onPressUserAvatar: React.PropTypes.func,
        onPressAvatar: React.PropTypes.func,
        onPressComment: React.PropTypes.func,
        onPressLike: React.PropTypes.func,
        onPressPosts: React.PropTypes.func,
        onEndReached: React.PropTypes.func,
        onRefresh: React.PropTypes.func,
    };

    constructor(props) {
        super (props);

        this.currentPage = 0;
        this.tabs = ['我的帖子', '我赞过的', '我的回复'];
        this.scrollableTabView = null;
        this.state = {
            scrollValueH: new Animated.Value(this.currentPage),
            scrollValueV: new Animated.Value(0),
            listViewMarginTop: new Animated.Value(0),
            listViewTop: 0,
        };

        this.lastValue = 0;

        this._renderSectionHeader = this._renderSectionHeader.bind(this);
        this._renderRow = this._renderRow.bind(this);
        this._renderSeparator = this._renderSeparator.bind(this);
        this._updateHorizontalScrollValue = this._updateHorizontalScrollValue.bind(this);
        this._updateVerticalScrollValue = this._updateVerticalScrollValue.bind(this);
        this.setAnimationValue = this.setAnimationValue.bind(this);
        this.dataSource = new ListView.DataSource({
            rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
            sectionHeaderHasChanged: (s1, s2) => !Immutable.is(s1, s2),
        });
    }

    componentDidMount() {
        InteractionManager.runAfterInteractions(() => {
            this.listView && this.listView.getScrollResponder().startPullToRefresh();
        });

        this._listener = this.state.listViewMarginTop.addListener(this.setAnimationValue);
    }

    setAnimationValue({ value, }) {

        if (value < 0) {
            return;
        }

        if (this.lastValue > value) {
            //down
            if (value < 2) {
                let top = 64 * (value - 1);
                top = top > 64 ? 64 : top;
                top = top < 0 ? 0 : top;
                this.animView && this.animView.setNativeProps({
                    style: {
                        top,
                    },
                });
            }

        } else {
            //up
            if (value > 0.9) {
                let top = 64 * (value - 0.6)
                top = top > 64 ? 64 : top;
                top = top < 0 ? 0 : top;
                this.animView && this.animView.setNativeProps({
                    style: {
                        top,
                    },
                });
            }

        }
        this.lastValue = value;
    }

    _renderRow(rowData, sectionID, rowID, highlightRow) {
        switch (sectionID) {
            case 'userInfo':
                return (
                    <UserCenterTop
                        userInfo={rowData}
                        onPressUserAvatar={this.props.onPressUserAvatar}
                        onPressBackgroundImg={this.props.onPressBackgroundImg}
                    />
                );
                break;

            case 'list':
                return (
                    <ScrollableTabView
                        ref={(c) => {
                            this.scrollableTabView = c;
                        }}
                        renderTabBar={false}
                        initialPage={this.currentPage}
                        onScroll={this._updateHorizontalScrollValue}
                        >

                        <CommunityList
                            data={rowData.get('posts')}
                            onPressPost={this.props.onPressPost}
                            onPressAvatar={this.props.onPressAvatar}
                            onPressSectionTag={this.props.onPressSectionTag}
                            onPressComment={this.props.onPressComment}
                            onPressLike={this.props.onPressLike}
                        />

                        <CommunityList
                            data={rowData.get('like')}
                            onPressPost={this.props.onPressPost}
                            onPressAvatar={this.props.onPressAvatar}
                            onPressSectionTag={this.props.onPressSectionTag}
                            onPressComment={this.props.onPressComment}
                            onPressLike={this.props.onPressLike}

                        />

                        <ReplyList
                            data={rowData.get('reply')}
                            onPressAvatar={(url) => {
                                this.props.onPressAvatar && this.props.onPressAvatar(url);
                            }}
                            onPressReply={(url) => {
                                this.props.onPressReply && this.props.onPressReply(url);
                            }}
                            onPressPosts={(url) => {
                                this.props.onPressPosts && this.props.onPressPosts(url);
                            }}

                        />

                    </ScrollableTabView>
                );
                break;
            default:
                return null;
        }
    }

    _renderSectionHeader(sectionData, sectionID) {
        switch (sectionID) {
			case 'list':
				return (
                    <SectionTabBar
                        style={{borderBottomWidth: 0.5, borderBottomColor: '#e0e0e0',}}
                        tabs={this.tabs}
                        activeTab={this.currentPage}
                        scrollValue={this.state.scrollValueH}
                        goToPage={(page) => this._goToPage(page)}
                    />
				);
            default:
                return null;
		}
    }

    _renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
        return (
            <View key={'separator' + sectionID + rowID} style={styles.separator}/>
        );
    }

    _goToPage(page) {
        this.currentPage = page;
        this.scrollableTabView && this.scrollableTabView.goToPage(page);
    }

    _updateHorizontalScrollValue(value) {
        this.state.scrollValueH.setValue(value);
    }

    _updateVerticalScrollValue(offsetY) {

        this.state.scrollValueV.setValue(offsetY/150);
        this.state.listViewMarginTop.setValue(offsetY/150);

    }

    render() {
        let {userInfo, list, user, endReached, isRefreshing, isLoadingMore, isFetching} = this.props;

        let dataSource = {
            userInfo: userInfo.toArray(),
            list: list.toArray(),
        };
        return (
            <View style={styles.container}>
                <Animated.View
                    ref={(c) => {
                        this.animView = c;
                    }}
                    style={{flex:1, backgroundColor: 'transparent', top: this.state.listViewTop}}
                >
                    <ListView
                        ref={(c) => {
                            this.listView = c;
                        }}
                        dataSource={this.dataSource.cloneWithRowsAndSections(dataSource)}
                        renderRow={this._renderRow}
                        renderSectionHeader={this._renderSectionHeader}
                        renderSeparator={this._renderSeparator}
                        enableEmptySections={true}
                        enablePullToRefresh={true}
                        isOnPullToRefresh={isRefreshing}
                        onRefreshData={() => {
                            this.props.onRefresh && this.props.onRefresh();
                        }}
                        onEndReached={() => {
                            this.props.onEndReached && this.props.onEndReached(this.currentPage);
                        }}
                        renderFooter={() => {
                            if (endReached) {
                                return <LoadMoreIndicator
                                isVisible={true}
                                text={'没有更多啦'}
                                />
                            } else {
                                return <LoadMoreIndicator
                                isVisible={isLoadingMore}
                                animating={isFetching}
                                />
                            }
                        }}
                        onScroll={(e) => {
                            const offsetY = e.nativeEvent.contentOffset.y;
                            this._updateVerticalScrollValue(offsetY);
                        }}
                    />
                </Animated.View>

                <UserNavBar scrollValue={this.state.scrollValueV} channel={this.props.channel}/>
            </View>
        );
    }
}


let {width, height} = Dimensions.get('window');
let navbarHeight = (Platform.OS === 'android') ? 50 : 64;

let styles = StyleSheet.create({
    container: {
        top: 0,
        flex: 1,
        height: height,
        backgroundColor: 'transparent',
        // backgroundColor: 'red',
        // flexDirection: 'column',
        // justifyContent: 'center',
    },

    top: {

    },

    bottom: {
        backgroundColor: 'transparent',
    },

    separator: {
        height: 0.5,
        backgroundColor: '#e0e0e0',
    },
});