homeList.js 12.2 KB
/**
 * Created by Cassie on 2018/03/06
 */
import React, { Component } from 'react';
import {
    StyleSheet,
    View,
    Text,
    TouchableOpacity,
    Image,
    FlatList,
    ActivityIndicator
} from 'react-native';
import Video from 'react-native-video';

import {zoomW,zoomH} from '../utils/getSize';
import {numChange,timeChange,xnToast} from '../utils/utils';
import AppService from "../service/AppService";

const isTop = require('../img/isTop.png');
const cover = require('../img/cover.png');
const video = require('../img/video.png');
const top1 = require('../img/top1.png');
const top2 = require('../img/top2.png');
const top3 = require('../img/top3.png');

export default class HomeList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            homeList:[],
            newList:[],
            hotList:[],
            loadMore:false
        };
    }

    /*获取帖子列表*/
    getList = (param) => {
        this.setState({
            loading:true
        });
        AppService.findPostList({sortColumn:param,pageSize:10}).then(data=>{
            this.setState({
                loading:false
            });
            if(data.message){
                xnToast(data.message);
                return;
            }
            if(data.errors.length > 0) {
                xnToast(data.errors[0].message);
            }else{
                this.setState({
                    title:data.result[0].forumName,
                });
                if(param == 'IS_FORUM_TOP'){
                    this.setState({
                        homeList:data.result,
                    });
                }else if(param == 'NEWEST'){
                    this.setState({
                        newList:data.result,
                    });
                }else if(param == 'HOTEST'){
                    this.setState({
                        hotList:data.result,
                    });
                }
            }
        });
    };
    /*加载更多*/
    addList(type){
        if(this.state.allLoad){
            return;
        }
        let length = 0;
        if(type == 'IS_FORUM_TOP'){
            length = this.state.homeList ? this.state.homeList.length : this.props.homeList.length
        }else if(type == 'NEWEST'){
            length = this.state.newList ? this.state.newList.length : this.props.homeList.length
        }else if(type == 'HOTEST'){
            length = this.state.hotList ? this.state.hotList.length : this.props.homeList.length
        }
        if(length % 10 == 0 && !this.state.loadMore){
            this.setState({
                loadMore:true
            });
            AppService.findPostList({sortColumn:type,pageSize:10,pageNumber:length/10+1}).then(data=>{
                this.setState({
                    loadMore:false
                });
                if(data.message){
                    xnToast(data.message);
                    return;
                }
                if(data.errors.length > 0) {
                    xnToast(data.errors[0].message);
                }else{
                    if(data.result.length == 0) {
                        this.setState({
                            allLoad:true,
                        });
                    }
                    if(type == 'IS_FORUM_TOP'){
                        this.setState({
                            homeList:this.state.homeList.concat(data.result),
                        });
                    }else if(type == 'NEWEST'){
                        this.setState({
                            newList:this.state.newList.concat(data.result),
                        });
                    }else if(type == 'HOTEST'){
                        this.setState({
                            hotList:this.state.hotList.concat(data.result),
                        });
                    }
                }
            });
        }
    }
    /* 渲染列表*/
    keyExtractor = (item,index) => index;
    /*首页列表*/
    renderItem = ({item,index}) => (
        <TouchableOpacity style={styles.listItem} onPress={() => this.toDetail(item.id)}>
            {this.props.hotList && <View style={styles.itemTop}>
                {index == 0 && <Image source={top1} style={styles.topNumIcon} resizeMode="contain" />}
                {index == 1 && <Image source={top2} style={styles.topNumIcon} resizeMode="contain" />}
                {index == 2 && <Image source={top3} style={styles.topNumIcon} resizeMode="contain" />}
                <Text numberOfLines={1} style={[styles.itemTitle,{width:index == 0 || index == 1 || index == 2 ? (295/zoomW):(345/zoomW)}]}>{item.title}</Text>
            </View>}
            {!this.props.hotList && <View style={styles.itemTop}>
                {item.isForumTop && this.props.homeList && <Image source={isTop} style={styles.isTopIcon} resizeMode="contain" />}
                <Text numberOfLines={1} style={[styles.itemTitle,{width:item.isForumTop && this.props.homeList ? (305/zoomW):(345/zoomW)}]}>{item.title}</Text>
            </View>}
            <View style={styles.itemContent}>
                {item.imgeAttachmentCount == 1 && item.vedioAttachmentCount == 0 &&  <Image source={{uri:item.attachmentList[0].filePath}} style={styles.coverImg} resizeMode="contain" />}
                {item.imgeAttachmentCount > 1 && item.vedioAttachmentCount == 0 && item.attachmentList.map((item,index) => this.renderImg(item,index))}
                {item.contentText && !item.attachmentList && <Text numberOfLines={2} style={styles.contentText}>{item.contentText}</Text>}
            </View>
            <View style={styles.itemBottom}>
                <Text style={{fontSize:14,color:'#999'}}>{numChange(item.postCount)}回复</Text>
                <View style={{display:'flex',flexDirection:'row',alignItems:'center'}}>
                    <Image source={{uri:item.threadUserAvatarUrl}} style={styles.avatar} resizeMode="cover" />
                    {this.props.homeList && <Text style={{fontSize:14,color:'#999'}}>{item.threadUserName}·{item.boardName}</Text>}
                    {!this.props.homeList && <Text style={{fontSize:14,color:'#999'}}>{item.threadUserName}·{timeChange(Number(item.threadTime))}</Text>}
                </View>
            </View>
        </TouchableOpacity>
    );
    /*渲染图片*/
    renderImg(item,index){
        return (
            <View key={index}>
                {index == 0 && <Image source={{uri:item.filePath}} style={styles.moreImg} resizeMode="cover" />}
                {index == 1 && <Image source={{uri:item.filePath}} style={[styles.moreImg,{marginLeft:(6/zoomW),marginRight:(6/zoomW)}]} resizeMode="cover" />}
                {index == 2 && <Image source={{uri:item.filePath}} style={styles.moreImg} resizeMode="cover" />}
            </View>
        )
    };
    /*最新列表*/
    renderNewItem = ({item,index}) => (
        <TouchableOpacity style={styles.listItem} onPress={() => this.toDetail(item.id)}>
            <View style={styles.itemTop}>
                <Text numberOfLines={1} style={styles.itemTitle}>{item.title}</Text>
            </View>
            <View style={styles.itemContent}>
                <Image source={video} style={[styles.moreImg,{marginRight:(5/zoomW)}]} resizeMode="cover" />
                <Image source={video} style={[styles.moreImg,{marginRight:(5/zoomW)}]} resizeMode="cover" />
                <Image source={video} style={styles.moreImg} resizeMode="cover" />
            </View>
            <View style={styles.itemBottom}>
                <Text style={{fontSize:14,color:'#999'}}>{numChange(item.postCount)}回复</Text>
                <View style={{display:'flex',flexDirection:'row',alignItems:'center'}}>
                    <Image source={{uri:item.threadUserAvatarUrl}} style={styles.avatar} resizeMode="cover" />
                    <Text style={{fontSize:14,color:'#999'}}>{item.threadUserName}·{timeChange(Number(item.threadTime))}</Text>
                </View>
            </View>
        </TouchableOpacity>
    );
    /*最热列表*/
    renderHotItem = ({item,index}) => (
        <TouchableOpacity style={styles.listItem} onPress={() => this.toDetail(item.id)}>
            <View style={styles.itemTop}>
                {index == 0 && <Image source={top1} style={styles.topNumIcon} resizeMode="contain" />}
                {index == 1 && <Image source={top2} style={styles.topNumIcon} resizeMode="contain" />}
                {index == 2 && <Image source={top3} style={styles.topNumIcon} resizeMode="contain" />}
                <Text numberOfLines={1} style={[styles.itemTitle,{width:index == 0 || index == 1 || index == 2 ? (295/zoomW):(345/zoomW)}]}>{item.title}</Text>
            </View>
            <View style={styles.itemContent}>
                {item.cover && <Image source={cover} style={styles.coverImg} resizeMode="contain" />}
                {item.video && !item.cover && <Image source={video} style={styles.coverImg} resizeMode="contain" />}
                {item.content && !item.cover && !item.video && <Text numberOfLines={2} style={styles.contentText}>{item.content}</Text>}
            </View>
            <View style={styles.itemBottom}>
                <Text style={{fontSize:14,color:'#999'}}>{numChange(item.postCount)}回复</Text>
                <View style={{display:'flex',flexDirection:'row',alignItems:'center'}}>
                    <Image source={{uri:item.threadUserAvatarUrl}} style={styles.avatar} resizeMode="cover" />
                    <Text style={{fontSize:14,color:'#999'}}>{item.threadUserName}·{timeChange(Number(item.threadTime))}</Text>
                </View>
            </View>
        </TouchableOpacity>
    );
    /*跳转到详情*/
    toDetail(id){
        AppService.updateView({id:id}).then((data) => {
            if(!data.message && data.errors.length == 0){
                this.props.navigation.navigate('Detail',{id:id})
            }
        })
    };

    render() {
        return (
            <View style={styles.background}>
                {this.props.homeList && <FlatList onEndReachedThreshold={0.1} onEndReached={() => this.addList('IS_FORUM_TOP')} onRefresh={() => {this.getList('IS_FORUM_TOP')}} refreshing={false} keyExtractor={this.keyExtractor} data={this.state.homeList.length == 0 ? this.props.homeList:this.state.homeList} renderItem={this.renderItem} />}
                {this.props.newList && <FlatList onEndReachedThreshold={0.1} onEndReached={() => this.addList('NEWEST')} onRefresh={() => {this.getList('NEWEST')}} refreshing={false} keyExtractor={this.keyExtractor} data={this.state.newList.length == 0 ? this.props.newList:this.state.newList} renderItem={this.renderItem} />}
                {this.props.hotList && <FlatList onEndReachedThreshold={0.1} onEndReached={() => this.addList('HOTEST')} onRefresh={() => {this.getList('HOTEST')}} refreshing={false} keyExtractor={this.keyExtractor} data={this.state.hotList.length == 0 ? this.props.hotList:this.state.hotList} renderItem={this.renderItem} />}
                {this.state.loadMore && <ActivityIndicator />}
            </View>
        );
    }
}

const styles = StyleSheet.create({
    background:{
        width:'100%',
        height:'100%',
        backgroundColor:'#f2f2f2'
    },
    listItem:{
        minHeight:(110/zoomH),
        maxHeight:(318/zoomH),
        backgroundColor:'#fff',
        marginBottom:(8/zoomH),
        padding:(15/zoomH),
    },
    itemTop:{
        width:(345/zoomW),
        display:'flex',
        flexDirection:'row',
        alignItems:'center'
    },
    itemTitle:{
        color:'#000',
        fontSize:16,
        fontWeight:'600'
    },
    isTopIcon:{
        width:(40/zoomW),
    },
    topNumIcon:{
        width:(40/zoomW),
        marginRight:10,
        marginTop:(2/zoomH)
    },
    coverImg:{
        width:(345/zoomW),
        height:(193/zoomH)
    },
    moreImg:{
        width:(112/zoomW),
        height:(112/zoomW)
    },
    itemContent:{
        display:'flex',
        flexDirection:'row',
        marginTop:(15/zoomH),
        marginBottom:(15/zoomH)
    },
    contentText:{
        fontSize:14,
        color:'#666'
    },
    itemBottom:{
        display:'flex',
        flexDirection:'row',
        justifyContent:'space-between'
    },
    avatar:{
        width:(20/zoomW),
        height:(20/zoomW),
        borderRadius:(10/zoomW),
        marginRight:(6/zoomW)
    }
});