Authored by 于良

Merge branch 'classify' into guang

... ... @@ -36,6 +36,7 @@ export default class BrandStore extends Component {
this.renderSectionHeader = this.renderSectionHeader.bind(this);
this.renderRow = this.renderRow.bind(this);
this._onPressProductFilter = this._onPressProductFilter.bind(this);
this._onPressStoreFilter = this._onPressStoreFilter.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
... ... @@ -50,17 +51,26 @@ export default class BrandStore extends Component {
this._showToast && this._showToast(showToastMessage);
}
}
_onPressProductFilter(value){
_onPressStoreFilter(value){
this.props.onPressStoreFilter && this.props.onPressStoreFilter(value);
if (value != 3) {
if (value == 0) {
this.refs.brandStoreList && this.refs.brandStoreList.scrollTo({x: 0, y: Math.ceil((200 / 640) * width), animated: false});
}else {
this.refs.brandStoreList && this.refs.brandStoreList.scrollTo({x: 0, y: storeFilter_y_Position, animated: false});
}
}
}
_onPressProductFilter(value){
if(value === 'filter'){
this.refs.brandStoreList && this.refs.brandStoreList.scrollTo({x: 0, y: yPosition, animated: false});
}
if(value==='default'){
this.refs.brandStoreList && this.refs.brandStoreList.scrollTo({x: 0, y: yPosition, animated: false});
}
this.props.onPressProductFilter && this.props.onPressProductFilter(value);
}
_showToast(message){
... ... @@ -70,9 +80,10 @@ export default class BrandStore extends Component {
duration: 255,
children: message,
animationEnd : () => {
if(this._toast){
this._toast._toastAnimationToggle = setTimeout(
() => {
this._toast.hide({
this._toast && this._toast.hide({
duration: 0,
animationEnd: () => {
}
... ... @@ -81,25 +92,27 @@ export default class BrandStore extends Component {
1000
);
}
}
})
}
renderSectionHeader(sectionData, sectionID) {
switch(sectionID) {
case 'brandReource': {
return (
<BrandStoreFilter
selectID={this.props.storeFilter}
onPressFilter={this.props.onPressStoreFilter}
/>
);
}
case 'brandReource':
case 'storeFilter': {
return (
<View
style={styles.brandFilterContainer}
onLayout={(evt) => {
storeFilter_y_Position = evt.nativeEvent.layout.y;
}}
>
<BrandStoreFilter
selectID={this.props.storeFilter}
onPressFilter={this.props.onPressStoreFilter}
onPressFilter={this._onPressStoreFilter}
/>
</View>
);
}
case 'productList': {
... ... @@ -357,6 +370,7 @@ let rowHeight = Math.ceil(254 * width / 320);
let rowMarginTop = Math.ceil(10 * width / 320);
let rowMarginHorizontal = (width - rowWidth * 2) / 3;
let yPosition = 0;
let storeFilter_y_Position = 0;
let styles = StyleSheet.create({
container: {
... ...
... ... @@ -74,7 +74,7 @@ export default class CouponCell extends React.Component {
moneySize = {fontSize:25};
name = {marginLeft: 10,marginTop: 1,width: 80,height: 30};
nameSize = {fontSize:9};
statesTitleStyle = {alignItems:'center',marginTop: 5,width: cellUpOneBack,height: 30};
statesTitleStyle = {alignItems:'center',marginTop: 5,width: cellUpOneBack,height: 60};
states = {marginTop: rowData.status?6:10,fontSize:9,width: 10,height: 60};
}
... ...
... ... @@ -25,9 +25,14 @@ export default class BrandSearch extends Component {
}
componentDidMount() {
this.timer = setTimeout(() => {
this.searchBar && this.searchBar.focus();
}, 0);
}
componentWillUnmount() {
this.timer && clearTimeout(this.timer);
}
render() {
... ...
... ... @@ -99,12 +99,17 @@ export default class Prompt extends Component {
marginBottom: 15,
},
});
if (!this.props.icon) {
if (!this.props.text) {
return null;
}
}
return (
<Animated.View style={[styles.container, {opacity: this.state.fadeAnim,}]}>
<View style={customStyles.overlay}>
{this.props.icon ? <Image source={this.props.icon} style={customStyles.title}/> : null}
<Text style={customStyles.text}>{this.props.text}</Text>
{this.props.text ? <Text style={customStyles.text}>{this.props.text}</Text> : null}
</View>
</Animated.View>
);
... ...
... ... @@ -12,43 +12,24 @@ import ReactNative, {
Image,
Animated,
NetInfo,
Alert,
} from 'react-native';
import Camera from 'yh_rncamera';
import ScanBar from './ScanBar'
const yh_QRCodeHelperEvt = new NativeEventEmitter(ReactNative.NativeModules.YH_QRCodeHelper)
let camera;
let scanTypeValue, animationFromTopToBottom;
let animationStartHeight = Dimensions.get('window').height * 0.10;
let animationEndHeight = Dimensions.get('window').height * 0.44;
let kScreenPointScale = Dimensions.get('window').width/320.0;
let kScreenPoint6Scale = Dimensions.get('window').width/375.0;
let KScanRectOfInterestWidth = (175+220)*kScreenPointScale/Dimensions.get('window').height;
let KScanRectOfInterestHeight = (190+220)*kScreenPointScale/ Dimensions.get('window').width;
let animationStartHeight = height * 0.10;
let animationEndHeight = height * 0.44;
let kScreenPointScale = width/320.0;
let kScreenPoint6Scale = width/375.0;
let KScanRectOfInterestWidth = (175+220)*kScreenPointScale/height;
let KScanRectOfInterestHeight = (190+220)*kScreenPointScale/ width;
export default class QRCode extends React.Component {
startAnimation() {
Animated.timing(this.state.destX, {
toValue: animationFromTopToBottom ? animationEndHeight : animationStartHeight,
duration: 1480,
}).start(() => {
animationFromTopToBottom = !animationFromTopToBottom;
});
};
componentDidMount() {
this.timer = setInterval(() => {
this.startAnimation();
}, 1500);
}
componentWillUnmount() {
this.timer && clearInterval(this.timer);
}
constructor(props) {
super(props);
camera = null;
... ... @@ -61,8 +42,16 @@ export default class QRCode extends React.Component {
render() {
let {scanType} = this.props;
let {scanType,dataInfo} = this.props;
scanTypeValue = scanType;
let {alertInfo} = dataInfo;
let alertTitle = alertInfo.get('title');
let alertMessage = '';
if (alertInfo.get('message1') && alertInfo.get('message1') != '') {
alertMessage += alertInfo.get('message1');
} if (alertInfo.get('message2') && alertInfo.get('message2') != '') {
alertMessage += alertInfo.get('message2');
}
return (
<View style={styles.container}>
<Camera
... ... @@ -81,20 +70,14 @@ export default class QRCode extends React.Component {
style={styles.camera}
captureAudio={false}
>
<Image style={styles.sacnRange} source={require('../../images/cameraQR5.png')}>
<ScanBar
style={styles.sacnRange}
/>
<Image style={styles.tipInfoImage} source={require('../../images/qr_bt.png')}>
<Text style={styles.tipInfo}>
尽量让二维码充满框内
</Text>
</Image>
<Animated.Image style={[styles.sacnLine,{
top: this.state.destX
}]} source={require('../../images/cameraQRLine.png')} />
</Image>
</Camera>
... ... @@ -111,6 +94,15 @@ export default class QRCode extends React.Component {
</TouchableOpacity>
</View>
{alertInfo.get('show')?
Alert.alert(alertTitle, alertMessage, [
{text: alertInfo.get('confirmInfo'), onPress: () => {
this.props.hideAlertView && this.props.hideAlertView();
camera._addOnBarCodeReadListener();
}}
])
:null}
</View>
);
... ... @@ -119,32 +111,29 @@ export default class QRCode extends React.Component {
}
let {width, height} = Dimensions.get('window');
let styles = StyleSheet.create({
container: {
flex: 1
},
sacnRange: {
position: 'absolute',
backgroundColor: 'rgba(255, 255, 255, 0.00)',
height: Dimensions.get('window').height - 44,
width: Dimensions.get('window').width,
},
sacnLine: {
backgroundColor: 'rgba(255, 255, 255, 0.00)',
height: 2,
width: 210,
left: (Dimensions.get('window').width - 210) / 2,
top: animationStartHeight,
height: height - 44,
width: width,
top: 0,
},
camera: {
height: Dimensions.get('window').height - 44,
height: height - 44,
alignItems: 'center',
},
tipInfoImage: {
top: Dimensions.get('window').height * 0.6,
left: (Dimensions.get('window').width - 170) / 2,
top: height * 0.6,
width: 170,
height: 20,
borderRadius: 10,
justifyContent: 'center',
},
tipInfo: {
flex: 1,
... ...
var { requireNativeComponent } = require('react-native');
module.exports = requireNativeComponent('YH_ScanBarView', null);
... ...
... ... @@ -7,4 +7,5 @@ export default keyMirror({
SET_SCANTYPE: null,
JUMP_WITH_OBJECT_NEWFLAG: null,
PROCESS_SCAN_STRING: null,
UPDATE_ALERT_INFO: null,
});
... ...
... ... @@ -44,6 +44,7 @@ class QRCodeContainer extends Component {
super(props);
this._onBarCodeRead = this._onBarCodeRead.bind(this);
this._hideAlertView = this._hideAlertView.bind(this);
}
componentDidMount() {
... ... @@ -56,20 +57,33 @@ class QRCodeContainer extends Component {
_onBarCodeRead(scanString) {
if (!scanString) {
__DEV__ && console.log('Illegal scanString');
console.log('Illegal scanString');
return;
}
this.props.actions.processURL(scanString);
}
_hideAlertView(){
let alertInfo = {
show: false,
title:'',
message1: '',
message2: '',
confirmInfo: '',
};
this.props.actions.updateAlertInfo(alertInfo);
}
render() {
let {qrcode} = this.props;
let {scanType} = qrcode;
return (
<View style={styles.container}>
<QRCode
dataInfo={qrcode}
scanType={scanType}
onBarCodeRead={this._onBarCodeRead}
hideAlertView={this._hideAlertView}
/>
</View>
);
... ...
... ... @@ -11,7 +11,7 @@ const {
JUMP_WITH_URL,
SET_SCANTYPE,
JUMP_WITH_OBJECT_NEWFLAG,
PROCESS_SCAN_STRING,
UPDATE_ALERT_INFO,
} = require('../../constants/actionTypes').default;
let showTip = false;
... ... @@ -43,64 +43,116 @@ function showAlert(title = '二维码扫描', message1, message2, confirmInfo =
function scanSkn(scanString) {
let strs= new Array();
strs = scanString.split(":");
let sknAlertInfo = {
show: true,
title:'二维码扫描',
message1: '商品skn无法识别:',
message2: scanString,
confirmInfo: '确定',
};
if (strs.length < 2) {
showAlert('二维码扫描','商品skn无法识别:', scanString,);
return false;
return sknAlertInfo;
}
let sknID = strs[1];
if (sknID === '') {
showAlert('二维码扫描','商品skn无法识别:', scanString,);
return;
return sknAlertInfo;
}
ReactNative.NativeModules.YH_QRCodeHelper.jumpWithUrl(sknID, ScanTypeInfo.YHScanType_Skn);
return true;
return {
show: false,
title:'',
message1: '',
message2: '',
confirmInfo: '',
};
}
function scanBear(scanString) {
let strs= new Array();
let bearAlertInfo = {
show: true,
title:'二维码扫描',
message1: '小熊二维码无法识别:',
message2: {scanString},
confirmInfo: '确定',
};
strs = scanString.split(":");
if (strs.length < 2) {
showAlert('二维码扫描','小熊二维码无法识别:', scanString,);
return false;
return bearAlertInfo;
}
let bearID = strs[1];
if (bearID === '') {
showAlert('二维码扫描','小熊二维码无法识别:', scanString,);
return false;
return bearAlertInfo;
}
ReactNative.NativeModules.YH_QRCodeHelper.jumpWithUrl(bearID, ScanTypeInfo.YHScanType_Bear);
return true;
return {
show: false,
title:'',
message1: '',
message2: '',
confirmInfo: '',
};
}
function scanBooth(scanString) {
let strs= new Array();
strs = scanString.split(":");
let boothAlertInfo = {
show: true,
title:'二维码扫描',
message1: '品牌店铺号无法识别:',
message2: scanString,
confirmInfo: '确定',
};
if (strs.length < 2) {
showAlert('二维码扫描','品牌店铺号无法识别:', scanString,);
return false;
return boothAlertInfo;
}
let boothID = strs[1];
if (boothID === '') {
showAlert('二维码扫描','品牌店铺号无法识别:', scanString,);
return false;
return boothAlertInfo;
}
ReactNative.NativeModules.YH_QRCodeHelper.jumpWithUrl(boothID, ScanTypeInfo.YHScanType_Booth);
return true;
return {
show: false,
title:'',
message1: '',
message2: '',
confirmInfo: '',
};
}
function scanExpress(expressString) {
let expressAlertInfo = {
show: true,
title:'二维码扫描',
message1: '快递单号无法识别:',
message2: expressString,
confirmInfo: '确定',
};
if (scanString === '') {
showAlert('二维码扫描','快递单号无法识别:', expressString,);
return false;
return expressAlertInfo;
}
ReactNative.NativeModules.YH_QRCodeHelper.jumpWithUrl(expressString, ScanTypeInfo.YHScanType_Express);
return true;
return {
show: false,
title:'',
message1: '',
message2: '',
confirmInfo: '',
};
}
function scanYohoBuy(scanString) {
let dataString = '';
let isNew = false;
let strs= new Array();
let yohoBuyAlertInfo = {
show: true,
title:'二维码扫描',
message1: '',
message2: scanString,
confirmInfo: '确定',
};
if (scanString.indexOf('yohobuy:') !== -1) {
strs = scanString.split("yohobuy:");
if (strs.length == 1) {
... ... @@ -127,15 +179,26 @@ function scanYohoBuy(scanString) {
}
}
}
var obj = JSON.parse(dataString); //由JSON字符串转换为JSON对象
var obj;
try {
obj = JSON.parse(dataString); //由JSON字符串转换为JSON对象
} catch(err) {
return yohoBuyAlertInfo;
}
console.log(obj);
if (!obj) {
showAlert('二维码扫描','', dataString,);
return false;
return yohoBuyAlertInfo;
} else {
//回传
ReactNative.NativeModules.YH_QRCodeHelper.jumpWithObjectNewFlag(obj, isNew);
}
return true;
return {
show: false,
title:'',
message1: '',
message2: '',
confirmInfo: '',
};
}
function handleUrlForSknId(scanString) {
... ... @@ -195,14 +258,26 @@ function scanAddressLink (scanString) {
let sknId = handleUrlForSknId(scanString);
if (sknId !== '') {
ReactNative.NativeModules.YH_QRCodeHelper.jumpWithUrl(sknId, ScanTypeInfo.YHScanType_Skn);
return true;
return {
show: false,
title:'',
message1: '',
message2: scanString,
confirmInfo: '',
};
}
//判断yoho 品牌链接二维码
let brandId = handleUrlForBrandId(scanString);
if (brandId !== '') {
ReactNative.NativeModules.YH_QRCodeHelper.jumpWithUrl(brandId, ScanTypeInfo.YHScanType_Brand);
return true;
return {
show: false,
title:'',
message1: '',
message2: scanString,
confirmInfo: '',
};
}
//判断PC登录二维码
... ... @@ -212,18 +287,22 @@ function scanAddressLink (scanString) {
if (!isConnected) {
if (!showTip) {
showTip = true;
Alert.alert('提示', '无网络连接,刷新试试', [
{text: '取消', onPress: () => {
showTip = false;
}},
{text: '刷新', onPress: () => {
showTip = false;
}}
]);
return false;
return {
show: true,
title:'提示',
message1: '无网络连接,刷新试试',
message2: '',
confirmInfo: '取消',
};;
};
ReactNative.NativeModules.YH_QRCodeHelper.jumpWithUrl(pcLoginCode, ScanTypeInfo.YHScanType_PCLogin);
return true;
return {
show: false,
title:'',
message1: '',
message2: '',
confirmInfo: '',
};
}
});
}
... ... @@ -231,51 +310,80 @@ function scanAddressLink (scanString) {
//扫描信息全局变量
let scanQRString = scanComonURL(scanString);
ReactNative.NativeModules.YH_QRCodeHelper.jumpWithUrl(scanQRString, ScanTypeInfo.YHScanType_CommonUrl);
return true;
return {
show: false,
title:'',
message1: '',
message2: '',
confirmInfo: '',
};
}
function processScanString(url,scanType) {
let prefixRegex = '^skn:|^booth:|^bear:|^yohobuy:|^yohobuy=|^http://|^https://';
let isHasPrefix = url.match(prefixRegex);//prefixRegex.search(url);
let alertInfo = {
show: false,
title:'',
message1: '',
message2: '',
confirmInfo: '',
};
if(isHasPrefix === -1 && scanType !== 4 && !showTip){
showAlert('二维码扫描','无法识别的二维码:', url,);
return false;
alertInfo = {
show: true,
title:'二维码扫描',
message1: '无法识别的二维码:',
message2: url,
confirmInfo: '确定',
};
};
switch (scanType) {
case ScanTypeInfo.YHScanType_Skn://YHScanType_Skn
scanSkn(url);
alertInfo = scanSkn(url);
break;
case ScanTypeInfo.YHScanType_Bear:
scanBear(url);
alertInfo =scanBear(url);
break;
case ScanTypeInfo.YHScanType_Booth:
scanBooth(url);
alertInfo = scanBooth(url);
break;
case ScanTypeInfo.YHScanType_Express:
scanExpress(url);
alertInfo = scanExpress(url);
break;
case ScanTypeInfo.YHScanType_Default: {
if (url.indexOf('skn:') !== -1) {
scanSkn(url);
console.log('skn');
alertInfo = scanSkn(url);
} else if (url.indexOf('booth:') !== -1) {
scanBooth(url);
console.log('booth');
alertInfo = scanBooth(url);
} else if (url.indexOf('bear:') !== -1) {
scanBear(url);
} else if (url.indexOf('yohobuy:') !== -1 || url.indexOf('yohobuy=') !== -1) {
scanYohoBuy(url);
console.log('bear');
alertInfo = scanBear(url);
} else if (url.indexOf('yohobuy:') !== -1 || url.indexOf('yohobuy=') !== -1 || url.indexOf('yohobuy=') !== -1) {
console.log('yohobuy');
alertInfo = scanYohoBuy(url);
} else if (url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1) {
scanAddressLink(url);
console.log('http&s');
alertInfo = scanAddressLink(url);
} else {
showAlert('二维码扫描','无法识别的二维码:', url,);
return false;
alertInfo = {
show: true,
title:'二维码扫描',
message1: '无法识别的二维码:',
message2: url,
confirmInfo: '确定',
};
}
break;
}
break;
default:
}
return alertInfo;
};
export function setScanType(scanType) {
... ... @@ -285,6 +393,13 @@ export function setScanType(scanType) {
};
}
export function updateAlertInfo(info) {
return {
type: UPDATE_ALERT_INFO,
payload: info,
};
}
export function processURL(scanString) {
return (dispatch, getState) => {
... ... @@ -292,21 +407,15 @@ export function processURL(scanString) {
if(!scanString) {
return;
}
let useableScanString = processScanString(scanString,qrcode.scanType);
if (useableScanString) {
return;
}
dispatch({
type: PROCESS_SCAN_STRING,
payload: useableScanString
});
let alertInfo = processScanString(scanString,qrcode.scanType);
dispatch(updateAlertInfo(alertInfo));
};
}
export function jumpWithUrl(url, JumpType) {
if (!url) {
__DEV__ && console.log('Illegal url');
console.log('Illegal url');
return;
}
... ... @@ -316,16 +425,3 @@ export function jumpWithUrl(url, JumpType) {
payload: url
};
}
export function jumpWithObjectNewFlag(jsonObj, isNew) {
if (!url) {
__DEV__ && console.log('Illegal object');
return;
}
ReactNative.NativeModules.YH_QRCodeHelper.jumpWithObjectNewFlag({jsonObj, isNew});
return {
type: JUMP_WITH_OBJECT_NEWFLAG,
payload: url
};
}
... ...
... ... @@ -7,6 +7,13 @@ let InitialState = Record({
scanType: 0,
jumpScanStringFaild: 0,
segment: null,
alertInfo: new (Record({
show: false,
title:'',
message1: '',
message2: '',
confirmInfo: '',
})),
});
export default InitialState;
... ...
... ... @@ -8,6 +8,7 @@ const {
SET_SCANTYPE,
JUMP_WITH_OBJECT_NEWFLAG,
PROCESS_SCAN_STRING,
UPDATE_ALERT_INFO,
} = require('../../constants/actionTypes').default;
const initialState = new InitialState;
... ... @@ -20,6 +21,9 @@ export default function qrcodeReducer(state=initialState, action) {
case PROCESS_SCAN_STRING: {
return state.set('jumpScanStringFaild',action.payload);
}
case UPDATE_ALERT_INFO: {
return state.set('alertInfo',Immutable.fromJS(action.payload));
}
}
return state;
... ...
... ... @@ -76,10 +76,16 @@ export default class ProductListView extends Component {
</View>
:<View style={[styles.secKillMarketPriceContainer, {marginTop: 2}]}>
<Text style={[styles.secKillPrice,{color:'#d0021b'}]}>¥{rowData.secKillPrice}</Text>
<DeleteLineText style={{top:3, left:8}} text={'¥' + rowData.marketPrice+' '} />
<DeleteLineText style={{top:3, left:8}} lineStyle={{marginRight:8}} text={'¥' + rowData.marketPrice+' '} />
</View>
}
</View>
{tipState == '已抢光' ?
<View style={[styles.priceClickTipViewRight,{backgroundColor: btnBgColor}]}>
<Text style={{color:btnTextcolor}}>{tipState}</Text>
</View>
:
<TouchableOpacity onPress={() => {
if (this.tipMessage == '') {
if (rowData.wait) {
... ... @@ -101,7 +107,7 @@ export default class ProductListView extends Component {
}
</TouchableOpacity>
}
</View>
</View>
</View>
... ...
... ... @@ -19,7 +19,7 @@ import TimerMixin from 'react-timer-mixin';
import Immutable, {Map} from 'immutable';
import ProductListView from './ProductListView';
import TimeListView from './TimeListView';
import Toast from 'react-native-root-toast'
import Prompt from '../../../coupon/components/coupon/Prompt';
export default class Seckill extends Component {
constructor(props) {
... ... @@ -57,9 +57,6 @@ export default class Seckill extends Component {
componentWillReceiveProps(nextProps) {
this.firstLaunch = false;
if (nextProps.tipMessage && nextProps.tipMessage !== '') {
this._showToast && this._showToast(nextProps.tipMessage);
}
}
_onPressTimeItem(activity) {
... ... @@ -69,26 +66,6 @@ export default class Seckill extends Component {
}
}
_showToast = (message) => {
if (this.toast) {
return;
}
this.toast = Toast.show(message, {
duration: 3000,
position: height / 2 - 60,
shadow: false,
animation: true,
hideOnPress: true,
onHidden: () => {
if (this.toast) {
this.toast.destroy();
this.toast = null;
}
this.props.onClearTipMessage && this.props.onClearTipMessage();
}
});
};
renderSectionHeader(sectionData, sectionID) {
if (this.queryActivityInfo && this.queryActivityInfo.secKillProductVoList && this.queryActivityInfo.secKillProductVoList.size > 0) {
return (
... ... @@ -221,6 +198,15 @@ export default class Seckill extends Component {
}}
/>
}
{tipMessage != '' ?
<Prompt
text={tipMessage}
duration={800}
onPromptHidden={this.props.onClearTipMessage}
/>
:null
}
</View>
);
}
... ...
... ... @@ -313,6 +313,7 @@ export function clickRemindBtn(product) {
ReactNative.NativeModules.YH_CommonHelper.login()
.then(uid => {
dispatch(clickActivityTimeItem(product));
queryRemindList(uid);
})
.catch(error => {
... ... @@ -363,7 +364,9 @@ export function clickRemindBtn(product) {
dispatch(addCancelUserReminder(method, product.activityId, skn,uid, product.id, okTip, failTip));
})
.catch(error => {
dispatch(showTipMessage(error));
console.log('error');
console.log(error);
dispatch(showTipMessage('请到设置中开启日历授权'));
});
};
... ...