Authored by 张文文

拼团详情页分享&添加banner位

'use strict';
import React from 'react';
import ReactNative from 'react-native';
const {
AppRegistry,
StyleSheet,
Image,
View,
Dimensions,
TouchableOpacity,
Modal,
Text,
TouchableWithoutFeedback,
} = ReactNative;
export default class DetailShareViewModal extends React.Component {
constructor(props) {
super(props);
}
render() {
let { unionType } = this.props;
return (
<Modal
visible={this.props.show}
animationType={'none'}
transparent={true}
onRequestClose={() => {
}}>
<View style={styles.modalContainer}>
<TouchableWithoutFeedback onPress={() => {
this.props.showShareView && this.props.showShareView(false);
}}>
<View style={styles.topView}/>
</TouchableWithoutFeedback>
<View style={styles.shareView}>
<View style={styles.buttons}>
<TouchableOpacity activeOpacity={0.5} style={styles.button1} onPress={() => {
this.props.shareMiniApp && this.props.shareMiniApp();
}}>
<Image source={unionType ? require('../images/unionShare_wx_icon.png') : require('../images/weixin.png')} style={styles.icon} />
<Text style={styles.text}>微信好友</Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.5} style={styles.button2} onPress={() => {
this.props.shareWXTimeLine && this.props.shareWXTimeLine();
}}>
<Image source={unionType ? require('../images/unionShare_timeline_icon.png') : require('../images/pengyou.png')} style={styles.icon} />
<Text style={styles.text}>微信朋友圈</Text>
</TouchableOpacity>
</View>
<View style={styles.line}/>
<TouchableOpacity activeOpacity={0.5} style={styles.cancel} onPress={() => {
this.props.showShareView && this.props.showShareView(false);
}}>
<Text style={styles.canceltext}>取消</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
);
}
};
let {width, height} = Dimensions.get('window');
const DEVICE_WIDTH_RATIO = width / 375;
let styles = StyleSheet.create({
modalContainer: {
flex: 1,
width: width,
height: height,
backgroundColor: 'rgba(0, 0, 0, 0.6)',
},
topView: {
flex: 1,
},
shareView: {
width,
height: 171*DEVICE_WIDTH_RATIO,
backgroundColor: 'white',
alignItems: 'center',
},
image :{
width: 305*DEVICE_WIDTH_RATIO,
height: 88*DEVICE_WIDTH_RATIO,
marginTop: 25*DEVICE_WIDTH_RATIO,
},
buttons: {
width,
height: 115*DEVICE_WIDTH_RATIO,
alignItems: 'center',
flexDirection: 'row',
},
button1: {
marginLeft: (width - 180*DEVICE_WIDTH_RATIO)/3,
alignItems: 'center',
},
button2: {
marginLeft: (width - 180*DEVICE_WIDTH_RATIO)/3,
alignItems: 'center',
},
icon: {
width: 45*DEVICE_WIDTH_RATIO,
height: 45*DEVICE_WIDTH_RATIO,
},
text: {
marginTop: 8*DEVICE_WIDTH_RATIO,
fontSize: 12,
color: '#444444',
width: 90*DEVICE_WIDTH_RATIO,
textAlign: 'center',
},
line: {
width: width - 52,
height: 1,
backgroundColor: '#CCCCCC',
},
cancel: {
width,
height: 54*DEVICE_WIDTH_RATIO,
justifyContent: 'center',
alignItems: 'center',
},
canceltext: {
fontSize: 17,
color: '#444444',
},
});
... ...
... ... @@ -140,7 +140,7 @@ export default class GroupDetailHeader extends React.Component {
tipTitlecolor = '#000000';
}else if (pageGo == 5) {
tipTitle = '你来晚了';
buttonText = '查看更多拼团活动';
buttonText = '我也要开团';
tipTitlecolor = '#000000';
}else if (pageGo == 6) {
tipTitle = '拼团失败';
... ...
... ... @@ -43,6 +43,34 @@ export default class GroupPurchaseDetail extends Component {
switch(sectionID) {
case 'productResourceInfo': {
if(!rowData || !rowData.get('data')){
return null;
}
let infoData = rowData.get('data');
let imageWidth = infoData.get('imageWidth');
let imageHeight = infoData.get('imageHeight');
let listInfo = infoData.get('list').toJS();
let item = listInfo[0];
let src = YH_Image.getSlicedUrl(item.src, imageWidth, imageHeight, 2);
return(
<View style={{width:width, height:121*DEVICE_WIDTH_RATIO+8, backgroundColor:'#f0f0f0'}}>
<View style={{width:width, height:121*DEVICE_WIDTH_RATIO}}>
<TouchableOpacity activeOpacity={1} onPress={() => {
this.props.didTouchBanner && this.props.didTouchBanner(item.url);
}}>
<YH_Image style={{width: '100%', height: '100%'}} url={src}></YH_Image>
</TouchableOpacity>
</View>
</View>
);
}
case 'productListTitle': {
return(
<View style={styles.productListheader}>
... ... @@ -52,6 +80,7 @@ export default class GroupPurchaseDetail extends Component {
</View>
);
}
case 'productList': {
return(
<GroupProductCell resource={rowData} didTouchProduct={this.props.didTouchProduct}/>
... ... @@ -65,9 +94,11 @@ export default class GroupPurchaseDetail extends Component {
render() {
let {
productList,
resource,
} = this.props;
let dataSource = {
productListTitle: [1],
productResourceInfo: resource.resourceList ? resource.resourceList.toArray() : [],
productListTitle: [2],
productList: productList.list ? productList.list.toArray() : [],
};
... ...
'use strict';
import React, {Component} from 'react';
import ReactNative, {Platform, StyleSheet, View,Dimensions,} from 'react-native'
import ReactNative, {Platform, StyleSheet, View, Dimensions, NativeAppEventEmitter} from 'react-native'
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
... ... @@ -9,7 +9,7 @@ import {Map} from 'immutable';
import { setUnionType } from '../reducers/app/appActions';
import * as groupPurchaseDetailActions from '../reducers/groupPurchaseDetail/groupPurchaseDetailActions';
import GroupPurchaseDetail from '../components/GroupPurchaseDetail'
import ShareViewModal from '../components/ShareViewModal'
import DetailShareViewModal from '../components/DetailShareViewModal'
import SnapshootShare from '../components/SnapshootShare'
import {getSlicedUrl} from '../../classify/utils/Utils';
... ... @@ -42,24 +42,33 @@ class GroupPurchaseDetailContainer extends Component {
constructor(props) {
super(props);
this._onEndReached = this._onEndReached.bind(this);
this._didTouchBanner = this._didTouchBanner.bind(this);
this.updateTime = this.updateTime.bind(this);
this.didTouchProduct = this.didTouchProduct.bind(this);
this.goComment = this.goComment.bind(this);
this.didTouchButton = this.didTouchButton.bind(this);
this.showShareView = this.showShareView.bind(this);
this.shareMiniApp = this.shareMiniApp.bind(this);
this.shareWXTimeLine = this.shareWXTimeLine.bind(this);
this.showSnapshootShare = this.showSnapshootShare.bind(this);
this.shareSnapshootAction = this.shareSnapshootAction.bind(this);
this.subscription = NativeAppEventEmitter.addListener(
'ShareCollageDetailEvent',
() => {
this.props.actions.showShareView(true);
}
);
}
async componentDidMount() {
this.props.actions.getProductList();
this.props.actions.fetchActivityGroupDetail();
this.props.actions.fetchResourceInfo();
}
componentWillUnmount() {
this.subscription && this.subscription.remove();
}
updateTime(leftTime) {
... ... @@ -74,7 +83,7 @@ class GroupPurchaseDetailContainer extends Component {
let { activityId, groupNo, groupDetail } = this.props.groupPurchaseDetail;
if(pageGo == 1) {
this.props.actions.showShareView(true);
}else if (pageGo == 2) {
}else if (pageGo == 2 || pageGo == 5) {
let membershipItems = groupDetail.get('membershipItems');
let productDetail = membershipItems.size > 0 ? membershipItems.get(0) : new Map();
let productSkn = productDetail.get('productSkn');
... ... @@ -91,7 +100,7 @@ class GroupPurchaseDetailContainer extends Component {
ReactNative.NativeModules.YH_CommonHelper.showBuyPicker(params);
}else if (pageGo == 3) {
this.props.actions.showShareView(true);
}else if (pageGo == 4 || pageGo == 5 || pageGo == 7 || pageGo == 6) {
}else if (pageGo == 4 || pageGo == 7 || pageGo == 6) {
let url = `http://m.yohobuy.com?openby:yohobuy={"action":"go.activitytemplate","params":{"type":"2", "activityId":"${activityId}"}}`;
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
}
... ... @@ -109,6 +118,10 @@ class GroupPurchaseDetailContainer extends Component {
this.props.actions.showSnapshootShare(false);
}
showShareView(show){
this.props.actions.showShareView(show);
}
didTouchProduct(productSkn,activityId,newSrc) {
if(newSrc){
let arr=newSrc.split("?");
... ... @@ -123,8 +136,15 @@ class GroupPurchaseDetailContainer extends Component {
ReactNative.NativeModules.YH_CommonHelper.goLinkUrl(url);
}
showShareView(show){
this.props.actions.showShareView(show);
_didTouchBanner(url) {
if (!url) {
return;
}
let params = {
URL: url,
};
ReactNative.NativeModules.YH_CommonHelper.logEvent('YB_GROUP_DEATIL_BANNER_C', params);
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
}
async shareMiniApp(){
... ... @@ -165,6 +185,44 @@ class GroupPurchaseDetailContainer extends Component {
ReactNative.NativeModules.YH_CommonHelper.shareWXMiniProgram(param);
}
async shareWXTimeLine(){
let {
activityId,
groupNo,
groupDetail,
} = this.props.groupPurchaseDetail;
let { unionType } = this.props.app;
let productDetail = groupDetail ? groupDetail.toJS():null;
if(!productDetail){
return;
}
let membershipItems = productDetail.membershipItems;
let resource = membershipItems ? membershipItems[0]: null;
let lackNum = productDetail ? productDetail.lackNum : 0;
if (!resource) {
return;
}
let productIcon = resource.productIcon ? getSlicedUrl(resource.productIcon,150*DEVICE_WIDTH_RATIO, 120*DEVICE_WIDTH_RATIO, 2) : '';
let miniProgramPath = '/pages/groupPurchase/groupPurchaseResult?activity_id=' + activityId + '&group_no=' + groupNo;
unionType && (miniProgramPath += '&unionType=' + unionType);
let productGroupPrice = resource.productGroupPrice;
let productName = resource.productName;
let title = '【还差' + lackNum + '人】' + productGroupPrice + '拼' + productName;
let fromPage = 'GroupPurchaseDetail';
this.props.actions.showShareView(false);
let businessId = 'collage';
let param = {
title: title,
image: productIcon,
shareUrl: '', //缺少分享到H5的url
miniProgramPath,
fromPage,
businessId
}
ReactNative.NativeModules.YH_CommonHelper.shareWXTimeLine(param);
}
showSnapshootShare(show){
this.props.actions.showShareView(false);
this.props.actions.showSnapshootShare(show);
... ... @@ -182,6 +240,7 @@ class GroupPurchaseDetailContainer extends Component {
showSnapshootShare,
groupDetail,
productList,
resourceInfo
} = this.props.groupPurchaseDetail;
let {
... ... @@ -198,7 +257,7 @@ class GroupPurchaseDetailContainer extends Component {
return (
<View style={styles.container}>
<ShareViewModal show={showShareView} unionType={unionType} showShareView={this.showShareView} shareMiniApp={this.shareMiniApp} showSnapshootShare={this.showSnapshootShare}/>
<DetailShareViewModal show={showShareView} unionType={unionType} showShareView={this.showShareView} shareMiniApp={this.shareMiniApp} shareWXTimeLine={this.shareWXTimeLine}/>
<SnapshootShare
show={showSnapshootShare}
unionType={unionType}
... ... @@ -211,11 +270,13 @@ class GroupPurchaseDetailContainer extends Component {
activityId={activityId}
productList={productList}
groupDetail={groupDetail}
resource={resourceInfo}
onEndReached={this._onEndReached}
updateTime={this.updateTime}
didTouchButton={this.didTouchButton}
didTouchProduct={this.didTouchProduct}
goComment={this.goComment}
didTouchBanner={this._didTouchBanner}
/>
</View>
);
... ...
... ... @@ -11,6 +11,9 @@ const {
PRODUCT_LIST_REQUEST,
PRODUCT_LIST_SUCCESS,
PRODUCT_LIST_FAILURE,
RESOURCEINFO_REQUEST,
RESOURCEINFO_SUCCESS,
RESOURCEINFO_FAILURE,
ACTIVITY_GROUP_DETAIL_REQUEST,
ACTIVITY_GROUP_DETAIL_SUCCESS,
ACTIVITY_GROUP_DETAIL_FAILURE,
... ... @@ -65,6 +68,26 @@ export function productListFailure(error) {
}
}
export function resourceInfoRequest() {
return {
type: RESOURCEINFO_REQUEST,
};
}
export function resourceInfoSuccess(json) {
return {
type: RESOURCEINFO_SUCCESS,
payload: json
}
}
export function resourceInfoFailure(error) {
return {
type: RESOURCEINFO_FAILURE,
payload: error
}
}
export function activityGroupDetailRequest() {
return {
type: ACTIVITY_GROUP_DETAIL_REQUEST,
... ... @@ -157,3 +180,18 @@ export function updateTime(leftTime) {
payload: leftTime
}
}
export function fetchResourceInfo() {
return (dispatch, getState) => {
let {app} = getState();
dispatch(resourceInfoRequest());
let content_code = 'cea0efae77f4e04c935beb1e87181247';
return new GroupPurchaseService(app.host).fetchDetailResourceInfo(content_code)
.then(json => {
dispatch(resourceInfoSuccess(json));
})
.catch(error => {
dispatch(resourceInfoFailure(error));
});
};
}
... ...
... ... @@ -17,6 +17,11 @@ let InitialState = Record({
pageSize: 20,//60,
endReached: false,
})),
resourceInfo: new (Record({
isFetching: false,
error: null,
resourceList: List(),
})),
groupDetail: new (Record({
isFetching: false,
error: null,
... ...
... ... @@ -9,6 +9,9 @@ const {
PRODUCT_LIST_REQUEST,
PRODUCT_LIST_SUCCESS,
PRODUCT_LIST_FAILURE,
RESOURCEINFO_REQUEST,
RESOURCEINFO_SUCCESS,
RESOURCEINFO_FAILURE,
ACTIVITY_GROUP_DETAIL_REQUEST,
ACTIVITY_GROUP_DETAIL_SUCCESS,
ACTIVITY_GROUP_DETAIL_FAILURE,
... ... @@ -62,6 +65,21 @@ export default function couponReducer(state = initialState, action) {
return state.setIn(['productList', 'isFetching'], false)
.setIn(['productList', 'error'], action.payload);
}
case RESOURCEINFO_REQUEST: {
return state.setIn(['resourceInfo', 'isFetching'], true)
.setIn(['resourceInfo', 'error'], null);
}
case RESOURCEINFO_SUCCESS: {
return state.setIn(['resourceInfo', 'isFetching'], false)
.setIn(['resourceInfo', 'resourceList'], Immutable.fromJS(action.payload))
.setIn(['resourceInfo', 'error'], null);
}
case RESOURCEINFO_FAILURE: {
return state.setIn(['resourceInfo', 'isFetching'], false)
.setIn(['resourceInfo', 'error'], action.payload);
}
case ACTIVITY_GROUP_DETAIL_REQUEST: {
return state.setIn(['groupDetail', 'isFetching'], true)
.setIn(['groupDetail', 'error'], null);
... ...
... ... @@ -68,6 +68,23 @@ export default class groupPurchaseService {
});
}
async fetchDetailResourceInfo(content_code) {
let fromPage = Platform.OS === 'android' ? 'aFP_GroupPurchaseDetail' : 'iFP_GroupPurchaseDetail';
return await this.api.get({
url: '/operations/api/v5/resource/get',
body: {
content_code,
fromPage,
}
})
.then((json) => {
return json;
})
.catch((error) => {
throw(error);
});
}
async fetchShareCodeInfo(params) {
return await this.api.get({
url: '/operations/api/v5/webshare/getShare',
... ...