Authored by 张丽霞

开通分期页面timer替换,textInput键盘遮挡fix, review by 孙凯

... ... @@ -78,7 +78,7 @@ export default class ConfirmPay extends React.Component {
}
render() {
let{bankCardsInfo}=this.props;
let{payCard}=this.props;
return (
<View style={styles.container}>
<View style={[styles.alertView,{top:this.state.alertViewTop}]}>
... ... @@ -86,7 +86,7 @@ export default class ConfirmPay extends React.Component {
支付¥455.00
</Text>
<Text style={styles.codeTitle}>
请输入银行预留手机**1234收到的验证码
请输入银行预留手机{payCard.outMobile}收到的验证码
</Text>
<View style={styles.codeContainer}>
... ... @@ -218,5 +218,6 @@ let styles = StyleSheet.create({
buttonText: {
marginTop: 14 * DEVICE_WIDTH_RATIO,
fontSize: 16 * DEVICE_WIDTH_RATIO,
color: '#444444',
}
});
... ...
... ... @@ -10,6 +10,8 @@ import ReactNative, {
Dimensions,
TouchableOpacity,
Alert,
Platform,
Keyboard,
} from 'react-native';
import Immutable, {Map} from 'immutable';
... ... @@ -20,19 +22,79 @@ import SlicedImage from '../../../common/components/SlicedImage';
export default class Open extends React.Component {
constructor(props) {
super(props);
this.contentHeight = 0;
this.textInputViewIndex = null;//当前编辑的textInput
this.moveH = 0;//ScrollView滑动的距离
this.lastMoveH = 0;//保留上次滑动的距离
this.needMove = false;//弹出键盘时,textInputView是否需要滑动
this._renderRow = this._renderRow.bind(this);
this._renderHeader=this._renderHeader.bind(this);
this._renderFooter=this._renderFooter.bind(this);
this._onFocus = this._onFocus.bind(this);
this.dataSource = new ListView.DataSource({
rowHasChanged: (r1, r2) => !Immutable.is(r1, r2),
});
}
_onFocus(index) {
let {bankInfo,bankCellIndex} = this.props.openPageInfo;
if (!bankInfo) {
if (index > bankCellIndex) {
index = index - 1;
}
}else {
if (!bankInfo.get('show') && index > bankCellIndex) {
index = index - 1;
}
}
this.textInputViewIndex = index;
}
componentWillMount(){
if (Platform.OS === 'ios') {
this.subscriptions = [
Keyboard.addListener('keyboardDidShow', this._keyboardDidShow),
Keyboard.addListener('keyboardDidHide', this._keyboardDidHide)
];
}
}
componentWillUnmount(){
if (Platform.OS === 'ios') {
this.subscriptions.forEach((sub) => sub.remove());
}
}
_keyboardDidShow = (e) => {
if(! this.textInputViewIndex) return ;
this.needMove = false;
let leftHeight = height - (64 + 56 + this.textInputViewIndex * 44.5) * DEVICE_WIDTH_RATIO;//输入框距离底部的距离 = (屏幕的高度 - 当前TextInput的高度)
//输入框距离底部的距离小于键盘的高度,需要滑动
if( leftHeight < e.startCoordinates.height + 25 ){
this.needMove = true;
// 需要移动的距离
let moveHeight = 50 + (e.startCoordinates.height - leftHeight);
console.log("this.moveH=" + this.moveH,"this.contentHeight=" + this.contentHeight,"height=" + height);
this.lastMoveH = this.moveH;
this.refs.scroll.scrollTo({y:this.moveH + moveHeight ,x:0});
}
}
_keyboardDidHide = () => {
if(this.needMove){
this.refs.scroll.scrollTo({y:this.lastMoveH ,x:0});
}
this.textInputViewIndex = null;
}
_renderRow(rowData, sectionID, rowID, highlightRow) {
let {bankInfo} = this.props.openPageInfo;
if (!rowData) {
return null
}
let rowKey = 'row' + rowID;
if (rowData.get('inputKey') == 'BankIcon') {
if (bankInfo) {
bankInfo = bankInfo.toJS();
... ... @@ -66,12 +128,14 @@ export default class Open extends React.Component {
} else {
return (
<OpenPageInputCell
ref={rowKey}
refId={rowID}
cellParams={rowData}
snsCheckCodeEnable={this.props.openPageInfo.snsCheckCodeEnable}
snsCheckCodeText={this.props.openPageInfo.snsCheckCodeText}
onPressCardNoQuestion={this.props.onPressCardNoQuestion}
updateOpenPageCellInfo={this.props.updateOpenPageCellInfo}
onPressCheckCode={this.props.onPressCheckCode}
onFocus={this._onFocus}
/>
);
}
... ... @@ -117,8 +181,8 @@ export default class Open extends React.Component {
<View style={styles.nextContainer}>
<Text style={{color:'#b0b0b0',fontSize:10*DEVICE_WIDTH_RATIO}}>数据智能加密,保障您的用卡安全</Text>
<TouchableOpacity onPress={() => {this.props.onPressOpenNext && this.props.onPressOpenNext()}} >
<Text style={[styles.next,{backgroundColor:nextBtnColor}]}>{nextBtnText}</Text>
<TouchableOpacity style={[styles.nextTouchableOpacity,{backgroundColor:nextBtnColor}]} onPress={() => {this.props.onPressOpenNext && this.props.onPressOpenNext()}} >
<Text style={[styles.next]}>{nextBtnText}</Text>
</TouchableOpacity>
<Text style={{color:'#444444',fontSize:10*DEVICE_WIDTH_RATIO}}>Yoho!Buy有货及信而富联合提供</Text>
</View>
... ... @@ -144,12 +208,16 @@ export default class Open extends React.Component {
return(
<View style={styles.container}>
<ListView
ref='scroll'
contentContainerStyle={styles.contentContainer}
enableEmptySections={true}
dataSource={this.dataSource.cloneWithRows(cellList)}
renderRow={this._renderRow}
renderHeader={this._renderHeader}
renderFooter={this._renderFooter}
onContentSizeChange ={(contentWidth, contentHeight)=>{
this.contentHeight = parseInt(contentHeight);
}}
/>
{tipMessage !== '' ? <Prompt
text={tipMessage}
... ... @@ -212,16 +280,22 @@ let styles = StyleSheet.create({
alignItems: 'center',
marginTop: 60 * DEVICE_WIDTH_RATIO,
},
next: {
nextTouchableOpacity: {
width: 236 * DEVICE_WIDTH_RATIO,
height: 44 * DEVICE_WIDTH_RATIO,
marginTop: 8 * DEVICE_WIDTH_RATIO,
marginBottom: 30 * DEVICE_WIDTH_RATIO,
backgroundColor: '#b0b0b0',
borderRadius: 5 * DEVICE_WIDTH_RATIO,
backgroundColor: '#444444',
},
next: {
width: 236 * DEVICE_WIDTH_RATIO,
height: 44 * DEVICE_WIDTH_RATIO,
textAlign: 'center',
color: 'white',
fontSize: 14 * DEVICE_WIDTH_RATIO,
lineHeight: 26 * DEVICE_WIDTH_RATIO,
backgroundColor: 'transparent',
},
bankCellContainer: {
width: width,
... ...
... ... @@ -19,6 +19,14 @@ export default class OpenPageInputCell extends React.Component {
constructor(props) {
super(props);
this._updateCellParams = this._updateCellParams.bind(this);
this._onFocus = this._onFocus.bind(this);
this._onPressCheckCode = this._onPressCheckCode.bind(this);
this.state = {
snsCode: '',
countDown: 59,
tickTimeOut: false,
resendBtnText: '获取验证码',
};
}
_updateCellParams(event) {
... ... @@ -27,8 +35,57 @@ export default class OpenPageInputCell extends React.Component {
cellParams.text = event.nativeEvent.text;
this.props.updateOpenPageCellInfo && this.props.updateOpenPageCellInfo(cellParams);
}
_onFocus(event) {
let index = this.props.refId;
this.props.onFocus && this.props.onFocus(index);
}
_onPressCheckCode(){
if (this.state.resendBtnText !== '获取验证码') {
return;
}else {
this.setState({
countDown: 60,
tickTimeOut: false,
resendBtnText: '59s',
});
this.props.onPressCheckCode && this.props.onPressCheckCode();
}
}
componentDidMount() {
this.timer = setInterval(function () {
if (this.state.resendBtnText == '获取验证码') {
return;
}
let count = this.state.countDown - 1;
if (count < 0) {
count = 60;
this.setState({
countDown: count,
tickTimeOut: true,
resendBtnText: '获取验证码',
});
}
if (!this.state.tickTimeOut) {
this.setState({
countDown: count,
resendBtnText: count+'s',
});
}
}.bind(this), 1000);
}
componentWillUnmount() {
this.timer && clearInterval(this.timer);
}
render() {
let {cellParams,snsCheckCodeEnable,snsCheckCodeText} = this.props;
let {cellParams,snsCheckCodeEnable,refId} = this.props;
cellParams = cellParams.toJS();
let checkCodeColor = '#e0e0e0';
if (snsCheckCodeEnable) {
... ... @@ -52,6 +109,10 @@ export default class OpenPageInputCell extends React.Component {
onChange={this._updateCellParams}
style={[styles.textInput,{width:inputBoxWidth}]}
maxLength={cellParams.maxLength}
onFocus={() => {
this.props.onFocus && this.props.onFocus(refId);
}}
/>
{cellParams.inputKey == "cardNo" ?
<TouchableOpacity style={styles.touchContainer} onPress={() => {
... ... @@ -64,11 +125,9 @@ export default class OpenPageInputCell extends React.Component {
: null
}
{cellParams.inputKey == "snsCheckCode" ?
<TouchableOpacity onPress={() => {
this.props.onPressCheckCode && this.props.onPressCheckCode();
}}>
<TouchableOpacity onPress={this._onPressCheckCode}>
<Text style={[styles.checkCode,{color:checkCodeColor,borderColor:checkCodeColor}]}>
{snsCheckCodeText}
{this.state.resendBtnText}
</Text>
</TouchableOpacity>
... ... @@ -131,5 +190,6 @@ let styles = StyleSheet.create({
textAlign: 'center',
lineHeight: 20 * DEVICE_WIDTH_RATIO,
marginTop: 8 * DEVICE_WIDTH_RATIO,
fontSize: 12 * DEVICE_WIDTH_RATIO,
},
});
... ...
... ... @@ -106,7 +106,7 @@ export default class RepayList extends React.Component {
<TouchableOpacity onPress={() => {this.props.onPressPayNow &&this.props.onPressPayNow()}} >
<View style={styles.repaymentBtn}>
<Text style={{color:'white',fontSize:17,lineHeight:29*DEVICE_WIDTH_RATIO}}>立即还款</Text>
<Text style={{color:'white',fontSize:13*DEVICE_WIDTH_RATIO,lineHeight:29*DEVICE_WIDTH_RATIO}}>立即还款</Text>
</View>
</TouchableOpacity>
... ... @@ -133,6 +133,7 @@ export default class RepayList extends React.Component {
reSendConfirmPaySnsCode={this.props.reSendConfirmPaySnsCode}
cancelPayInConfirm={this.props.cancelPayInConfirm}
confirmPayAction={this.props.confirmPayAction}
payCard={payCard}
/>
:null
}
... ...
... ... @@ -8,7 +8,7 @@ import ReactNative, {
Dimensions,
PixelRatio,
TouchableOpacity,
ListView,
Alert,
} from 'react-native';
import Immutable, {Map} from 'immutable';
... ... @@ -45,7 +45,11 @@ export default class RepayList extends React.Component {
{dataSource.isOverdue?
<View style={styles.cellRightContainer}>
<Text style={{color:'#d0021b',fontSize:12*DEVICE_WIDTH_RATIO,marginRight:5*DEVICE_WIDTH_RATIO}}>逾期{dataSource.day}</Text>
<Image style={{width:12*DEVICE_WIDTH_RATIO,height:12*DEVICE_WIDTH_RATIO,marginRight:5*DEVICE_WIDTH_RATIO}} source={require("../../image/fenqi_3_ic.png")}/>
<TouchableOpacity style={styles.bankTip} onPress={() => Alert.alert('逾期服务费信息','如果您到期未还款:需要加收逾期利息费和延迟还款费\n逾期利息费:待还本金 *利息率*延迟还款天数,利息率=0.025%/天\n延迟还款费:逾期3天内还款免收延迟还款服务费,逾期4天,从第一天逾期开始算,500元之内,加收1元/天延迟还款服务费。每500元增加1元/天。',[
{text: '我知道了'},
])} >
<Image style={{width:12*DEVICE_WIDTH_RATIO,height:12*DEVICE_WIDTH_RATIO,marginRight:5*DEVICE_WIDTH_RATIO}} source={require("../../image/red_question_icon.png")}/>
</TouchableOpacity>
<Image style={{marginRight:5*DEVICE_WIDTH_RATIO}} source={require("../../image/category_b_arrow.png")}/>
</View>
:<View style={styles.cellRightContainer}>
... ...
... ... @@ -20,7 +20,6 @@ export default keyMirror({
UPDATE_SNS_CHECK_CODE_ENABLE_STATUS: null,
UPDATE_CELL_LIST: null,
UPDATE_NEXT_BTN_ENABLE_STATUS: null,
UPDATE_SNS_CHECK_CODE_TEXT: null,
UPDATE_TIP_MESSAGE: null,
UPDATE_BANK_INFO: null,
NEXT_BTN_PROCESSING_REQUEST: null,
... ...
... ... @@ -84,7 +84,6 @@ class RepayListContainer extends Component {
}
_onPressRepaylistCellDetail(cellInfo) {
this.props.actions.onPressRepaylistCellDetail(cellInfo);
}
_onPressPayNow() {
... ...
... ... @@ -12,7 +12,6 @@ UPDATE_AGREE_PROTOCOL_STATUS,
UPDATE_SNS_CHECK_CODE_ENABLE_STATUS,
UPDATE_CELL_LIST,
UPDATE_NEXT_BTN_ENABLE_STATUS,
UPDATE_SNS_CHECK_CODE_TEXT,
UPDATE_TIP_MESSAGE,
UPDATE_BANK_INFO,
NEXT_BTN_PROCESSING_REQUEST,
... ... @@ -21,11 +20,6 @@ NEXT_BTN_PROCESSING_FAILURE,
} = require('../../constants/actionTypes').default;
var Timer = function() {
this.counter = 0;
this.countdownTimer = null;
};
export function updateShowBankAlertStatus(status) {
return {
type: UPDATE_SHOW_BANK_ALERT_STATUS,
... ... @@ -61,13 +55,6 @@ export function updateNextBtnEnableStatus(status) {
}
}
export function updateSnsCheckCodeText(text) {
return {
type: UPDATE_SNS_CHECK_CODE_TEXT,
payload: text
}
}
export function updateTipMessage(message) {
return {
type: UPDATE_TIP_MESSAGE,
... ... @@ -199,6 +186,7 @@ export function getBankInfo(cellInfo,cardNo) {
bankName: '',
bankText: '',
bankLogo: '',
cellIndex: 3,
show: false,
};
let nextBtnEnable = true;
... ... @@ -293,80 +281,20 @@ export function updateOpenPageCellInfo(cellInfo) {
};
}
/**
* 倒计时
*
* @param start 启动回调
* @param tick 进度回调
* @param complete 完成回调
*/
Timer.prototype.startCountdown = function(start, tick, complete) {
var self = this;
if (this.counter > 0 || this.countdownTimer) {
return;
} else {
this.counter = 59;
}
// 启动回调
if (start) {
start.call(this);
}
if (tick) {
tick.call(this, this.counter);
}
this.complete = complete;
// 开始计时器
this.countdownTimer = setInterval(function() {
self.counter--;
if (self.counter <= 0) {
if (complete) {
clearInterval(self.countdownTimer);
// 重置计时器
self.counter = 0;
self.countdownTimer = null;
complete.call(self);
}
}
// 完成回调
if (tick && self.counter > 0) {
tick.call(self, self.counter);
}
}, 1000);
return this;
};
export function onPressCheckCode() {
return (dispatch, getState) => {
let {app, newRegister} = getState();
let {cellList,snsCheckCodeEnable,snsCheckCodeText} = newRegister;
if (snsCheckCodeEnable && snsCheckCodeText == '获取验证码') {
return new InstallmentService(app.host).sendVerifyCode('17705176933')
let mobile = '';
cellList.map((item, i) => {
if (item.get('inputKey') == 'mobile') {
mobile= item.get('text');
}
});
return new InstallmentService(app.host).sendVerifyCode(mobile)
.then(json => {
let status = 0;
let snsText = '';
new Timer().startCountdown(function() {
}, function(counter) {
// 进度回调
snsText = counter + 's';
dispatch(updateSnsCheckCodeText(snsText));
}, function() {
// 倒计时结束后再次显示 "获取验证码"
snsText = '获取验证码';
dispatch(updateSnsCheckCodeText(snsText));
});
dispatch(updateSnsCheckCodeText(snsText));
})
.catch(error => {
});
... ...
... ... @@ -51,12 +51,12 @@ let InitialState = Record({
nextBtnText: '下一步',
nextProcessing: false,
snsCheckCodeEnable: false,
snsCheckCodeText: '获取验证码',
banks: banks.join('、'),
showBankAlert: false,
bankList: Immutable.fromJS(banks),
tipMessage: '',
bankInfo: Immutable.fromJS(),
bankCellIndex: 3,
});
export default InitialState;
... ...
... ... @@ -333,15 +333,12 @@ export function onPressPayNow() {
}
}
export function onPressRepaylistCellDetail(cellInfo) {
}
function processBankCardsInfo(list) {
if (list && list.length > 0) {
_.forEach(list, (data) => {
let cardNo = data.cardNo;
data.outBankNameNumb = data.bankName +'(' + cardNo.substring(cardNo.length - 4) +')';
data.outMobile = data.mobile.substring(data.mobile.length - 6);
});
return list;
}
... ...