Header.js 7.98 KB
'use strict';

import React from 'react';
import ReactNative from 'react-native';
import Immutable, {Map} from 'immutable';
import DeviceInfo from 'react-native-device-info';
import {getSlicedUrl} from '../../../classify/utils/Utils';
import {removeHTMLTag} from '../../utils/Helper';
import YH_Image from '../../../common/components/YH_Image';

const {
    View,
	Image,
    Text,
    TouchableOpacity,
    Dimensions,
    StyleSheet,
    WebView,
    Platform,
} = ReactNative;

const BODY_TAG_PATTERN = /\<\/ *body\>/;

var script = `
;(function() {
var wrapper = document.createElement("div");
wrapper.id = "height-wrapper";
while (document.body.firstChild) {
    wrapper.appendChild(document.body.firstChild);
}
document.body.appendChild(wrapper);
var i = 0;
function updateHeight() {
    document.title = wrapper.clientHeight;
    window.location.hash = ++i;
}
updateHeight();
window.addEventListener("load", function() {
    updateHeight();
    setTimeout(updateHeight, 1000);
});
window.addEventListener("resize", updateHeight);
}());
`;


const style = `
<style>
body, html, #height-wrapper {
    margin: 0;
    padding: 0;
}
#height-wrapper {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}
</style>
<script>
${script}
</script>
`;

const codeInject = (html) => html.replace(BODY_TAG_PATTERN, style + "</body>");

export default class Header extends React.Component {

    constructor(props) {
        super (props);
        this.handleNavigationChange = this.handleNavigationChange.bind(this);
        this.shouldStartLoadWithRequest = this.shouldStartLoadWithRequest.bind(this);
        this.state = {
           realContentHeight : 40,
        };
    }

    shouldComponentUpdate(nextProps,nextState){
        if (Immutable.is(nextProps.resource, this.props.resource) && nextProps.launchProfile==this.props.launchProfile && nextState.realContentHeight == this.state.realContentHeight) {
            return false;
        } else {
            return true;
        }
    }

    handleNavigationChange(navState) {
        let heightT = parseInt(navState.title, 10) || 0; // turn NaN to 0
        heightT>0?this.setState({
            realContentHeight: heightT,
        }):null;
    }

    shouldStartLoadWithRequest(event) {
        if (event.navigationType == 'click') {
            this.props.onPressLink && this.props.onPressLink(event.url);
           return false;
        }
        return true;
    }

    render() {
        let {resource,launchProfile} = this.props;
        if (!resource) {
            return null;
        }
        let data = resource.toJS();
        let htmlText = data.shop_intro;
        let text = htmlText?removeHTMLTag(htmlText):'';
        htmlText = '<html><style type="text/css">img {max-width: 100%;}</style><body>' + htmlText + '</body></html>';


        let hasLink = false;
        if (htmlText.indexOf('href=') >= 0) {
            hasLink = true;
        }

        let brandName = data.is_show_shop_name?data.shop_name:'';
        let num = data.favoriteCount?data.favoriteCount:0;
        let numberOfFav = '粉丝: '+ num;
        let backgroundImage = data.shopBanner?data.shopBanner.module_data.data[0].pic:'null';
        let brandIcon = getSlicedUrl(data.shop_logo, 60, 60, 2);
        let isFav = data.is_addFav;
        let favImage = isFav?require('../../image/btn_gz_h.png'):require('../../image/btn_gz_n.png');
        //下拉图标
        let sourceIcon = launchProfile?require('../../image/arrow_ic_up.png'):require('../../image/arrow_ic.png');
        //计算控件高度,图片+标题+简介+下拉图标+20空白
        let cellHeight = launchProfile ? (imageHeigth + titleHeigth + this.state.realContentHeight + 20 + 20) : (imageHeigth + titleHeigth + 60 + 20);
        //获取字体
        let fontFamilyStyle = {};
        if (Platform.OS === 'ios') {
            let systemVersion = DeviceInfo.getSystemVersion();
            systemVersion = parseFloat(systemVersion);
            if (systemVersion >= 9.0) {
                fontFamilyStyle = {fontFamily: 'PingFang SC'};
            }
        }

        return (
                <View style={{width: width, height: cellHeight,backgroundColor: 'white'}}>
    				<YH_Image
                        url={backgroundImage}
    					style={{width, height: imageHeigth }}
    				/>
                    <View style={styles.maskView}/>
                    <View style={styles.header}>
                        <Text style={styles.number} numberOfLines={1}>{numberOfFav}</Text>
                        <TouchableOpacity activeOpacity={0.5} onPress={() => {
                            this.props.onPressCollection && this.props.onPressCollection(isFav);
                        }}>
                            <Image source={favImage} style={styles.favImage}/>
                        </TouchableOpacity>
                    </View>

    				<View style={styles.titleView}>
    					<Text style={styles.name} numberOfLines={1}>{brandName}</Text>
    				</View>

    				<YH_Image
                        url={brandIcon}
    					style={styles.brandIcon}
    				/>
                    <TouchableOpacity activeOpacity={0.5} onPress={() => {
                        this.props.onPressLaunchProfile && this.props.onPressLaunchProfile(!launchProfile);
                    }}>
                            {launchProfile ?<View style={{width: width,height: this.state.realContentHeight,backgroundColor: 'white'}}>
            				<WebView style={{width: width-40,height: this.state.realContentHeight,backgroundColor: 'white',marginRight: 20,marginLeft: 20}}
            					source= {{html: codeInject(htmlText)}}
            					scrollEnabled={false}
                                javaScriptEnabled={true}
                                decelerationRate="normal"
                                domStorageEnabled={true}
                                onNavigationStateChange={this.handleNavigationChange}
                                onShouldStartLoadWithRequest={hasLink?this.shouldStartLoadWithRequest:null}
            				>
            				</WebView>
            			</View>:<Text style={[styles.text, fontFamilyStyle]} numberOfLines={2}>{text}</Text>}

            			<View style={styles.fliter}>
            				<Image source={sourceIcon} style={styles.pullDown}/>
            			</View>
                    </TouchableOpacity>
                </View>
        );
    }
}

let {width, height} = Dimensions.get('window');
let titleHeigth = 60;
let imageHeigth = Math.ceil((234/750)*width);

let styles = StyleSheet.create({
    container: {
		backgroundColor:'white',
    },
    brandIcon: {
        width: 60,
        height: 60,
        position: 'absolute',
        marginLeft: 15,
        marginTop: -(titleHeigth+20),
        borderWidth: 1,
        borderColor: '#e0e0e0',
    },

	titleView: {
		flexDirection: 'row',
		backgroundColor:'white',
		width: width,
		height: titleHeigth,
    },
    maskView: {
        width: width,
		height: imageHeigth,
        position: 'absolute',
        marginTop: -imageHeigth,
        backgroundColor: 'rgba(0,0,0,.15)'
    },
    header: {
        justifyContent: 'flex-end',
        flexDirection: 'row',
        width: width,
		height: 25,
        position: 'absolute',
        marginTop: -35,
        backgroundColor: 'transparent',
    },
	name: {
		marginLeft: 15 + 60 + 15,
        backgroundColor: 'white',
        width: width-120,
        marginTop: 22,
        color: '#444444',
        fontWeight: 'bold',
        fontSize: 16,
	},
	number: {
        color: '#ffffff',
        fontSize: 13,
        marginRight: 10,
        marginTop: 8,
        backgroundColor: 'transparent',
	},
    favImage: {
        width: 64,
        height: 25,
        backgroundColor: 'transparent',
        marginRight: 15,
    },
	text: {
		marginLeft: 20,
		width: width-40,
		height: 40,
		backgroundColor: 'white',
		lineHeight: 18,
        fontSize: 14,
        color: '#444444',
	},
	fliter: {
		width: width,
		height: 30,
		backgroundColor: 'white',
		alignItems: 'center',
		justifyContent: 'center',
	},
    pullDown: {
        width: 15,
        height: 8,
    },
});