Authored by aozhe.zhu

有赚商品详情UI review by 宏勇

... ... @@ -107,7 +107,7 @@ export default function native(platform) {
} else if (type === 'shareDetail') {
return (
<Provider store={store}>
<ShareDetailContainer />
<ShareDetailContainer product_skn={this.props.product_skn}/>
</Provider>
);
} else if (type === 'recommendProduct') {
... ...
... ... @@ -61,7 +61,7 @@ export default class Home extends Component {
key={'row' + rowID}
rowID={rowID}
data={rowData}
onPressProduct={this.props.onPressProduct}
onPressProduct={() => this.props.onPressProduct(rowData)}
/>
);
}
... ...
... ... @@ -8,10 +8,6 @@ import { getSlicedUrl } from '../../classify/utils/Utils';
const DEVICE_WIDTH_RATIO = Dimensions.get('window').width / 375;
export default class RankBody extends Component {
// state = { dataSource: this.props.dataSource }
// componentDidMount() {
// this.setState({dataSource: this.props.dataSource})
// }
render() {
return (
<View style={this.props.style}>
... ... @@ -58,7 +54,7 @@ class RankItem extends PureComponent {
_renderImage(url) {
if (url) {
url = getSlicedUrl(url, 40 * DEVICE_WIDTH_RATIO, 40 * DEVICE_WIDTH_RATIO, 2);
return <YH_Image style={styles.avatar} url={url} circle={true}></YH_Image>
return <YH_Image style={styles.avatar} url={url} circle={true} />
} else {
return <Image source={require('../../groupPurchase/images/PT_head.png')} style={styles.avatar} />
}
... ...
import React, { Component, PureComponent } from 'react';
import React, { Component } from 'react';
import { Dimensions, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
const { width } = Dimensions.get('window');
const DEVICE_WIDTH_RATIO = width / 375;
export default class ShareDetail extends Component {
state = { opacity: 0 }
render() {
return (
<View style={styles.container}>
<View style={{backgroundColor: 'black', height: 42, width, opacity: this.state.opacity, position: 'absolute', top: 0, zIndex: 10}}>
<View style={[styles.navigatorBackground, {opacity: this.state.opacity}]}>
</View>
<View style={styles.navigatorContainer}>
<View style={[styles.navigatorBtn, {opacity: 0.4 - this.state.opacity}]} />
<View style={styles.navigatorBtnRightContainer}>
<View style={[styles.navigatorBtn,styles.navigatorBtnRight, {opacity: 0.4 - this.state.opacity}]} />
</View>
</View>
<View style={{backgroundColor: 'black', height: 24, width: 24, opacity: 0.5 - this.state.opacity, borderWidth: 1, borderColor: 'transparent', borderRadius: 12, position: 'absolute', top: 9, left: 20}} />
<ScrollView
style={styles.container}
contentContainerStyle={styles.contentContainerStyle}
showsVerticalScrollIndicator={false}
onScroll={(e) => this.changeOpacity(e)}>
<View style={[styles.imgContainer]}>
</View>
<View style={styles.nameContainer}>
<Text style={styles.name}>HUMAN MADE 字母印花圆领T</Text>
</View>
<View style={[styles.priceContainer, styles.border]}>
<Text style={styles.price}> 99.9</Text>
<Text style={styles.origPrice}> 239</Text>
<View style={styles.infoContainer}>
<Text style={styles.name}>CHRISTINA DADA</Text>
<View style={styles.priceContainer}>
<View style={styles.alignBottom}>
<Text style={styles.priceUnit}></Text>
<Text style={styles.price}>99.9</Text>
<Text style={styles.origpriceUnit}></Text>
<Text style={styles.origPrice}>2999</Text>
</View>
</View>
</View>
<View style={[styles.promContainer, styles.border]}>
<View style={styles.divider} />
<View style={styles.promContainer}>
<Text style={styles.proDesc}>新客订单返现10%,老客订单返现3%(预计最高返现¥9.9</Text>
</View>
<View style={[styles.recommendContainer, styles.border]}>
<TouchableOpacity onPress={() => null}>
<View style={styles.recommendContainer}>
<View style={styles.solid} />
<Text style={styles.recommendText}>查看其它推荐商品</Text>
</TouchableOpacity>
<View style={styles.solid} />
</View>
</ScrollView>
<View style={[styles.bottomBar, styles.border]}>
<View style={styles.bottomBar}>
<View style={[styles.favContainer, styles.center]}>
<TouchableOpacity onPress={() => null} style={styles.favorite} />
</View>
... ... @@ -57,7 +67,7 @@ export default class ShareDetail extends Component {
changeOpacity(e) {
let opacity = 1 - (600 - e.nativeEvent.contentOffset.y) / 600;
this.setState({opacity: opacity < 0.5 ? opacity : 0.5});
this.setState({opacity: opacity < 0.4 ? opacity : 0.4});
console.log(e.nativeEvent.contentOffset.y);
}
}
... ... @@ -66,70 +76,134 @@ const styles = StyleSheet.create({
container: {
flex: 1,
},
contentContainerStyle: {
height: 1000,
navigatorBackground: {
backgroundColor: '#000000',
height: 44 * DEVICE_WIDTH_RATIO,
width,
position: 'absolute',
top: 0,
zIndex: 10
},
center: {
justifyContent: 'center',
navigatorContainer: {
height: 44 * DEVICE_WIDTH_RATIO,
flexDirection: 'row',
alignItems: 'center',
},
imgContainer: {
navigatorBtn: {
backgroundColor: '#000000',
height: 32 * DEVICE_WIDTH_RATIO,
width: 32 * DEVICE_WIDTH_RATIO,
overflow: 'hidden',
borderRadius: 16 * DEVICE_WIDTH_RATIO,
marginLeft: 9 * DEVICE_WIDTH_RATIO,
},
navigatorBtnRightContainer: {
flex: 1,
alignItems: 'flex-end',
},
nameContainer: {
height: 46,
paddingLeft: 20,
backgroundColor: '#393939',
navigatorBtnRight: {
marginLeft: 0,
marginRight: 9 * DEVICE_WIDTH_RATIO,
},
center: {
justifyContent: 'center',
alignItems: 'center',
},
imgContainer: {
height: 480 * DEVICE_WIDTH_RATIO,
},
name: {
color: '#fff',
fontFamily: 'SanFranciscoText-Regular',
fontSize: 16,
color: '#444444',
lineHeight: 22,
},
border: {
borderTopWidth: 1,
borderColor: '#5d5d5d'
},
infoContainer: {
height: 97 * DEVICE_WIDTH_RATIO,
paddingTop: 15 * DEVICE_WIDTH_RATIO,
paddingHorizontal: 15 * DEVICE_WIDTH_RATIO,
},
priceContainer: {
height: 46,
paddingLeft: 20,
height: 60 * DEVICE_WIDTH_RATIO,
flexDirection: 'row',
alignItems: 'center',
},
alignBottom: {
flexDirection: 'row',
alignItems: 'flex-end',
},
priceUnit: {
fontSize: 14,
color: '#D0021B',
lineHeight: 14,
},
price: {
fontSize: 16,
fontWeight: '500',
color: '#D0021B'
fontSize: 22,
color: '#D0021B',
lineHeight: 22,
},
origpriceUnit: {
marginLeft: 7 * DEVICE_WIDTH_RATIO,
fontSize: 14,
lineHeight: 16,
textDecorationLine: 'line-through',
textDecorationStyle: 'solid',
textDecorationColor: '#B0B0B0',
color: '#B0B0B0',
},
origPrice: {
color: '#909090',
marginLeft: 12
fontSize: 14,
lineHeight: 16,
textDecorationLine: 'line-through',
textDecorationStyle: 'solid',
textDecorationColor: '#B0B0B0',
color: '#B0B0B0',
},
divider: {
height: 10 * DEVICE_WIDTH_RATIO,
backgroundColor: '#F0F0F0'
},
promContainer: {
height: 46,
paddingLeft: 20,
height: 50 * DEVICE_WIDTH_RATIO,
paddingHorizontal: 15 * DEVICE_WIDTH_RATIO,
flexDirection: 'row',
alignItems: 'center',
},
proDesc: {
color: '#909090',
fontSize: 10,
color: '#444444',
fontSize: 12,
lineHeight: 17,
},
recommendContainer: {
height: 80,
height: 51 * DEVICE_WIDTH_RATIO,
backgroundColor: '#F0F0F0',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
solid: {
borderColor: '#E0E0E0',
width: 54.5 * DEVICE_WIDTH_RATIO,
borderWidth: 0.5 * DEVICE_WIDTH_RATIO,
},
recommendText: {
marginHorizontal: 6 * DEVICE_WIDTH_RATIO,
fontWeight: '500',
fontSize: 12,
color: '#B0B0B0'
},
bottomBar: {
flexDirection: 'row',
height: 64,
height: 60 * DEVICE_WIDTH_RATIO,
alignItems: 'center',
},
favContainer: {
width: width / 5,
width: 72 * DEVICE_WIDTH_RATIO,
marginHorizontal: 8 * DEVICE_WIDTH_RATIO,
},
favorite: {
height: 24,
... ... @@ -140,21 +214,22 @@ const styles = StyleSheet.create({
},
buttonContainer: {
flex: 1,
marginRight: 20,
marginRight: 15 * DEVICE_WIDTH_RATIO,
flexDirection: 'row',
justifyContent: 'space-between',
},
button: {
backgroundColor: 'black',
borderRadius: 3,
height: 50,
width: width / 3,
backgroundColor: '#444444',
borderRadius: 4 * DEVICE_WIDTH_RATIO,
height: 44 * DEVICE_WIDTH_RATIO,
width: 130 * DEVICE_WIDTH_RATIO,
},
red: {
backgroundColor: '#D0021B'
},
btnText: {
color: '#fff',
fontSize: 13,
color: '#FFFFFF',
fontSize: 15,
lineHeight: 21,
}
})
\ No newline at end of file
... ...
... ... @@ -107,8 +107,6 @@ class HomeContainer extends Component {
_onPressProduct(product) {
let productSkn = product && product.get('product_skn', 0);
let is_global = product && product.get('is_global', 'N');
if (!productSkn) {
return;
}
... ... @@ -118,11 +116,7 @@ class HomeContainer extends Component {
pageName = 'aFP_Alliance';
}
let url = `http://m.yohobuy.com?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":"${productSkn}", "from_page_name":"${pageName}"}}`;
if (is_global === 'Y') {
url = `http://m.yohobuy.com?openby:yohobuy={"action":"go.globalpurchase","params":{"skn":"${productSkn}"}}`;
}
let url = `http://m.yohobuy.com?openby:yohobuy={"action":"go.minealliance","params":{"type":"shareDetail", "product_skn":"${productSkn}", "from_page_name":"${pageName}"}}`;
ReactNative.NativeModules.YH_CommonHelper.jumpWithUrl(url);
}
... ...
... ... @@ -4,11 +4,11 @@ import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { Map } from 'immutable';
import * as allianceActions from '../reducers/alliance/allianceActions';
import * as shareDetailActions from '../reducers/shareDetail/shareDetailActions';
import ShareDetail from '../components/ShareDetail';
const actions = [
allianceActions,
shareDetailActions,
];
function mapStateToProps(state) {
... ... @@ -42,6 +42,10 @@ class ShareDetailContainer extends Component {
</ShareDetail>
)
}
componentDidMount() {
this.props.actions.fetchShareDetail({product_skn: 51026744});
}
}
const styles = StyleSheet.create({
... ... @@ -50,4 +54,4 @@ const styles = StyleSheet.create({
}
})
export default connect(mapDispatchToProps, mapStateToProps)(ShareDetailContainer)
\ No newline at end of file
export default connect(mapStateToProps, mapDispatchToProps)(ShareDetailContainer)
\ No newline at end of file
... ...
'use strict';
import ReactNative from 'react-native';
import Service from '../../services/ShareDetailService';
const {
SHARE_DETAIL_REQUEST,
SHARE_DETAIL_SUCCESS,
SHARE_DETAIL_FAILURE
} = require('../../constants/actionTypes').default;
export function shareDetailRequest() {
return {
type: SHARE_DETAIL_REQUEST
}
}
export function shareDetailSuccess(json) {
return {
type: SHARE_DETAIL_SUCCESS,
payload: json
}
}
export function shareDetailFailue(error) {
return {
type: SHARE_DETAIL_FAILURE,
payload: error
}
}
export function fetchShareDetail(params) {
return async (dispatch, getState) => {
let { app: { host } } = getState();
try {
console.log(1);
data = await new Service(host).fetchShareDetail(params);
} catch(error) {
console.log(error);
}
console.log(data);
}
}
\ No newline at end of file
... ...
'use strict';
import {List, Map, Record} from 'immutable';
let InitialState = Record({
isFetching: false,
monthRank: new (Record({
amountStr: '',
image: '',
nickname: '',
rankList: Map({
list: [],
page: 1,
size: 0,
total: 0,
totalPage: 1
}),
rankNum: 0,
uid: 0,
})),
totalRank: new (Record({
amountStr: '',
image: '',
nickname: '',
rankList: Map({
list: [],
page: 1,
size: 0,
total: 0,
totalPage: 1
}),
rankNum: 0,
uid: 0,
}))
});
export default InitialState;
... ...
'use strict';
import InitialState from './shareDetailInitialState';
import Immutable, {List} from "immutable";
const {
TALENT_RANK_REQUEST,
MONTH_RANK_SUCCESS,
TOTAL_RANK_SUCCESS,
TALENT_RANK_FAILURE
} = require('../../constants/actionTypes').default;
const initialState = new InitialState;
export default function appReducer(state = initialState, action) {
if (!(state instanceof InitialState)) return initialState.merge(state);
switch (action.type) {
case TALENT_RANK_REQUEST:
return state.set('isFetching', true);
case MONTH_RANK_SUCCESS:
return state.set('isFetching', false)
.set('monthRank', Immutable.fromJS(action.payload));
case TOTAL_RANK_SUCCESS:
return state.set('isFetching', false)
.set('totalRank', Immutable.fromJS(action.payload));
case TALENT_RANK_FAILURE:
return state.set('isFetching', false);
}
return state;
}
... ...
import Request from '../../common/services/NativeRequest';
export default class Service {
constructor (host) {
let baseURL = 'http://api.yoho.cn';
if(host){
baseURL = host;
}
this.api = new Request(baseURL);
}
async fetchShareDetail(params) {
return await this.api.get({
url: '',
body: {
method: 'app.union.shareOrder.getProductInfo',
...params
}
})
.then((json) => {
return json;
})
.catch((error) => {
throw(error);
});
}
}
\ No newline at end of file
... ...