ProductListCell.js 9.82 KB
'use strict';

import React, {Component} from 'react';
import ReactNative, {
    View,
    Text,
    Image,
    Platform,
    ListView,
    StyleSheet,
    Dimensions,
    TouchableOpacity,
} from 'react-native';

import Tags from './Tags';
import GPTags from './GPTags';
import DeleteLineText from '../DeleteLineText';
import YH_Image from '../YH_Image';
import SimilarProductAnim from './SimilarProductAnim';
import SimilarProductGuider from './SimilarProductGuider';
import Immutable, {Map} from 'immutable';

export default class ProductListCell extends Component {

    constructor(props) {
        super(props);

        this._renderTags = this._renderTags.bind(this);
        this._renderImages = this._renderImages.bind(this);
        this._renderPrice = this._renderPrice.bind(this);
    }

    shouldComponentUpdate(nextProps){
        if (Immutable.is(nextProps.data, this.props.data)
            && nextProps.similarIndex == this.props.similarIndex
            && nextProps.rowID == this.props.rowID) {
            return false;
        } else {
            return true;
        }
    }

    _renderTags() {
        let {data, sourceType} = this.props;
        let isGlobalProduct = data.get('is_global') && data.get('is_global') == 'Y'; // 是否全球购商品
        let showGPLimitTag = isGlobalProduct && data.get('is_limited') && data.get('is_limited') == 'Y';    // 全球购限量商品

        let tags = data.get('tags');    // 商品标签
        // 数据源是全球购
        if (sourceType == 1) {
            if (isGlobalProduct) {

            } else {
                tags = ['is_in_stock', ...tags];
            }
        }

        let countryName = isGlobalProduct && data.get('country_name');  // 全球购国家名称

        if (isGlobalProduct) {
            return <GPTags title={countryName} limit={showGPLimitTag}/>;
        } else {
            return <Tags items={tags}/>;
        }
    }

    _renderImages() {
        let {data, sourceType, similarIndex, rowID, showSimilarGuider} = this.props;

        let url = data.get('default_images', '').replace('{mode}', 2)
            .replace(/{width}/g, 290)
            .replace(/{height}/g, 386)

        let isGlobalProduct = data.get('is_global') && data.get('is_global') == 'Y'; // 是否全球购商品

        let showGPLimitTag = isGlobalProduct && data.get('is_limited') && data.get('is_limited') == 'Y';    // 全球购限量商品
        let showGPSoldOut = isGlobalProduct && data.get('is_stock') && data.get('is_stock') == 'Y';    // 全球购售罄

        let showAlmostSoldOut = !isGlobalProduct && data.get('tags', []).indexOf('is_soon_sold_out') !== -1;    // 非全球购的即将售罄
        let showSoldOut = !isGlobalProduct && data.get('tags', []).indexOf('is_solded') !== -1;    // 非全球购的即将售罄
        let showOutletSoldOut = sourceType == 2 && data.get('storage_num') && data.get('storage_num') == 0;   // 数据源是奥莱才显示

        return (
            <View style={styles.imageContainer}>
                <YH_Image style={styles.image} url={url}>
                    {rowID == similarIndex?
                        <SimilarProductAnim
                            onPressFindSimilar={this.props.onPressFindSimilar}
                            product={data}
                            similarIndex={similarIndex}
                            onPressDislike={this.props.onPressDislike}
                        />
                    :null}
                    {showAlmostSoldOut ? <Image style={styles.almostSoldOutImage} source={require('../../images/tag/tip_jjsq.png')}/> : null}
                    {showOutletSoldOut ? <Image style={styles.soldOutImage} source={require('../../images/tag/outlet_sellout_bg.png')}/> : null}
                    {showGPSoldOut ? <Image style={styles.gpSoldOutImage} source={require('../../images/tag/gp_tip_SQ.png')}/> : null}
                    {showSoldOut ? <Image style={styles.almostSoldOutImage} source={require('../../images/tag/tip_ysq.png')}/> : null}
                    {showSimilarGuider ? <SimilarProductGuider /> : null}
                </YH_Image>
            </View>
        );
    }

    _renderPrice() {
        let {data, sourceType, fromPage} = this.props;
        let isGlobalProduct = data.get('is_global') && data.get('is_global') == 'Y'; // 是否全球购商品

        let salePrice = 0; // 售卖价
        let originPrice = 0; // 原价
        let salePriceStr = ''; // 拼接的售卖价
        let originPriceStr = ''; // 拼接的原价
        let showOriginPrice = true;  // 是否显示原价
        let salePriceColor = '#d0021b';  // 不显示原价时,售卖价颜色

        if (isGlobalProduct) {
            salePrice = parseFloat(data.get('final_price'));
            originPrice = parseFloat(data.get('orign_price'));
            salePriceStr = data.get('formart_final_price');
            originPriceStr = data.get('formart_orign_price');
        } else {
            salePrice = parseFloat(data.get('sales_price'));
            originPrice = parseFloat(data.get('market_price'));
            salePriceStr = '¥' + salePrice.toFixed(2);
            originPriceStr = '¥' + originPrice.toFixed(2);
        }

        if (!originPrice || (salePrice == originPrice)) {
            showOriginPrice = false;
            salePriceColor = '#444444';
        }

        //新品到着升级为sectionList后价格会被遮挡
        let priceMarginTop = (Platform.OS === 'android' && fromPage === 'newArrival') ? Math.ceil(-18 * DEVICE_WIDTH_RATIO) : Math.ceil(-4 * DEVICE_WIDTH_RATIO);

        return (
            <View style={[styles.priceContainer, {marginTop: priceMarginTop,} ]}>
                <Text style={[styles.nowPrice, {color: salePriceColor}]} numberOfLines={1}>{salePriceStr}</Text>
                {showOriginPrice ? <DeleteLineText
                    style={styles.oldPriceContainer}
                    textStyle={styles.oldPrice}
                    lineStyle={styles.deleteLine}
                    text={originPriceStr}
                /> : null}
            </View>

        );
    }


    render() {
        let {data, sourceType, similarIndex, rowID, style} = this.props;
        let name = data.get('product_name') ? data.get('product_name') : '';
        let yh_exposureData = data.get('yh_exposureData', null);

        return (
            <TouchableOpacity
                style={[styles.container, style]}
                activeOpacity={1}
                yh_exposureData={yh_exposureData}
                onPress={() => {
                    if (rowID == similarIndex) {
                        this.props.onLongPressProduct&&this.props.onLongPressProduct(-1);
                        return;
                    }
                    this.props.onPressProduct && this.props.onPressProduct(data, rowID);
                }}
                onLongPress={() => {
                    this.props.onLongPressProduct&&this.props.onLongPressProduct(rowID);
                }}
            >
                <View>

                    {this._renderTags()}

                    {this._renderImages()}

                    <View style={styles.nameContainer}>
                        <Text style={styles.name} numberOfLines={2}>{name}</Text>
                    </View>

                    {this._renderPrice()}

                </View>
            </TouchableOpacity>
        );
    }
}

let {width, height} = Dimensions.get('window');

const DEVICE_WIDTH_RATIO = width / 320;
let rowWidth = Math.ceil(137.5 * DEVICE_WIDTH_RATIO);
let rowHeight = Math.ceil(254 * DEVICE_WIDTH_RATIO);
let rowMarginTop = Math.ceil(10 * DEVICE_WIDTH_RATIO);
let rowMarginBottom = Math.ceil(4 * DEVICE_WIDTH_RATIO);

const IMAGE_WIDTH = 145;
const IMAGE_HEIGHT = 193;
const IMAGE_RATIO = IMAGE_HEIGHT / IMAGE_WIDTH;
let imageTop = 14 * DEVICE_WIDTH_RATIO;
let imageHeight = rowWidth * IMAGE_RATIO;

let almostSoldOutImageHeight = Math.ceil(14 * DEVICE_WIDTH_RATIO);
let almostSoldOutImageTop = imageHeight - almostSoldOutImageHeight;

let nameMarginTop = Math.ceil(12 * DEVICE_WIDTH_RATIO);
let nameHeight = Math.ceil(36 * DEVICE_WIDTH_RATIO);

let gpSoldOutImageHeight = Math.ceil(25 * DEVICE_WIDTH_RATIO);

let styles = StyleSheet.create({
    container: {
        width: rowWidth,
        height: Platform.OS === 'ios'?rowHeight:rowHeight+4,
        marginTop: rowMarginTop,
        marginBottom: rowMarginBottom,
        overflow: 'hidden',
    },
    rowContainer: {
        width: rowWidth,
        height: Platform.OS === 'ios'?rowHeight:rowHeight+4,

    },
    imageContainer: {
        width: rowWidth,
        height: imageHeight,
        backgroundColor: '#f0f0f0',
    },
    image: {
        width: rowWidth,
        height: imageHeight,
        backgroundColor: '#f0f0f0',
    },
    soldOutImage: {
        position: 'absolute',
        top: 0,
        left: 0,
        width: rowWidth,
        height: imageHeight,
    },
    almostSoldOutImage: {
        top: almostSoldOutImageTop,
        width: rowWidth,
        height: almostSoldOutImageHeight,
        backgroundColor: '#ff9e0d',
    },
    nameContainer: {
        // justifyContent: 'center',
        marginTop: nameMarginTop,
        width: rowWidth,
        height: nameHeight,
    },
    name: {
        fontFamily: 'STHeitiSC-Light',
        fontSize: 12,
        color: '#444444',
    },
    priceContainer: {
        flexDirection: 'row',
    },
    nowPrice: {
        fontSize: 12,
        color: '#d0021b',
    },
    oldPriceContainer: {
        flexDirection: 'row',
        marginLeft: 5,
    },
    oldPrice: {
        fontSize: 12,
        color: '#b0b0b0',
        height: 16,
    },
    deleteLine: {
        position: 'absolute',
        top: (16 / 2) - 0.8,
        left: 0,
        right: 0,
        height: 1,
        backgroundColor: '#b0b0b0',
    },
    gpSoldOutImage: {
        position: 'absolute',
        top: 5,
        right: 5,
        width: gpSoldOutImageHeight,
        height: gpSoldOutImageHeight,
    },
});