fix fix fix
This commit is contained in:
@@ -8,6 +8,9 @@ import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.CountDownTimer;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowInsetsController;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
@@ -36,6 +39,25 @@ public class IncomingCallActivity extends Activity {
|
||||
}
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
// 真全屏:隐藏状态栏和导航栏
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
getWindow().setDecorFitsSystemWindows(false);
|
||||
WindowInsetsController wic = getWindow().getInsetsController();
|
||||
if (wic != null) {
|
||||
wic.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
|
||||
wic.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
||||
}
|
||||
} else {
|
||||
//noinspection deprecation
|
||||
getWindow().getDecorView().setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
}
|
||||
|
||||
String caller = getIntent().getStringExtra("caller");
|
||||
int ringDuration = getIntent().getIntExtra("ringDuration", 30);
|
||||
boolean autoAccept = getIntent().getBooleanExtra("auto_accept", false);
|
||||
@@ -121,7 +143,7 @@ public class IncomingCallActivity extends Activity {
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||
rowLp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
|
||||
rowLp.bottomMargin = dp(78);
|
||||
rowLp.bottomMargin = dp(48);
|
||||
rowLp.leftMargin = dp(13);
|
||||
rowLp.rightMargin = dp(13);
|
||||
btnRow.setLayoutParams(rowLp);
|
||||
|
||||
@@ -39,6 +39,7 @@ public class RnpayProxyService extends BaseProxyService {
|
||||
if (userId <= 0) userId = prefs.getInt("userId", 0);
|
||||
|
||||
JSONObject body = new JSONObject();
|
||||
body.put("cardId", walletId);
|
||||
body.put("walletType", walletType);
|
||||
body.put("params", params);
|
||||
|
||||
|
||||
+51
-31
@@ -98,10 +98,9 @@ function groupBoundWallets(wallets: WalletItem[]) {
|
||||
}));
|
||||
}
|
||||
|
||||
function parseWalletId(walletId: string): { walletType: string; phone: string } | null {
|
||||
const i = walletId.lastIndexOf('_');
|
||||
if (i <= 0) return null;
|
||||
return { walletType: walletId.slice(0, i), phone: walletId.slice(i + 1) };
|
||||
/** 生成新 cardId,格式 {userId}_{ns近似} */
|
||||
function newCardId(userId: number | string): string {
|
||||
return `${userId}_${Date.now()}${String(Math.floor(Math.random() * 1e6)).padStart(6, '0')}`;
|
||||
}
|
||||
|
||||
function getBindKeyForWallet(item: WalletItem): string | null {
|
||||
@@ -175,6 +174,10 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
private clientId: string = '';
|
||||
|
||||
private appStateSubscription?: any;
|
||||
/** 重绑时保留原 cardId,透传给 register/verifyOTP;新绑时为 undefined */
|
||||
private _pendingCardId?: string;
|
||||
/** OTP 绑定流程中暂存 cardId,requestOTP 时生成,verifyOTP 时复用 */
|
||||
private _otpCardId = '';
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
@@ -270,19 +273,18 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
|
||||
handleNotificationTap = (payload: FcmNotificationTapPayload) => {
|
||||
if (payload.cmd !== 'rebind_wallet') return;
|
||||
const { walletId, walletType, phone } = payload.params;
|
||||
const item = walletId
|
||||
? this.state.wallets.find(w => w.id === walletId)
|
||||
const { cardId, walletType, phone } = payload.params;
|
||||
const item = cardId
|
||||
? this.state.wallets.find(w => w.id === cardId)
|
||||
: undefined;
|
||||
if (item) {
|
||||
this.handleRebind(item);
|
||||
return;
|
||||
}
|
||||
const parsed = walletId ? parseWalletId(walletId) : null;
|
||||
const wt = walletType || parsed?.walletType;
|
||||
const mobile = phone || parsed?.phone;
|
||||
const wt = walletType;
|
||||
const mobile = phone;
|
||||
if (wt) {
|
||||
const key = getBindKeyForWallet({ id: walletId ?? '', walletType: wt, otpMode: false });
|
||||
const key = getBindKeyForWallet({ id: cardId ?? '', walletType: wt, otpMode: false });
|
||||
if (key) this.openWalletBind(key, mobile);
|
||||
}
|
||||
};
|
||||
@@ -404,6 +406,7 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
Alert.alert('Rebind', 'Unsupported wallet type');
|
||||
return;
|
||||
}
|
||||
this._pendingCardId = item.id; // 重绑保留原 cardId
|
||||
this.openWalletBind(key, item.phone);
|
||||
};
|
||||
|
||||
@@ -421,8 +424,12 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
this.setState({ [key]: false } as any);
|
||||
};
|
||||
|
||||
// 重绑用原 cardId,新绑生成新 cardId
|
||||
const cardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
|
||||
this._pendingCardId = undefined;
|
||||
|
||||
try {
|
||||
await Api.instance.register(walletType, result);
|
||||
await Api.instance.register(walletType, result, cardId);
|
||||
finishSuccess();
|
||||
} catch (error: any) {
|
||||
const errMsg = (error as Error).message || '';
|
||||
@@ -453,7 +460,7 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
chVersion: data.chVersion,
|
||||
appVersion: data.appVersion ?? data.version ?? result.appVersion,
|
||||
tokenExpiresAt: data.tokenExpiresAt ?? data.expiresAt,
|
||||
});
|
||||
}, cardId);
|
||||
finishSuccess();
|
||||
return;
|
||||
} catch (retryErr) {
|
||||
@@ -559,10 +566,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
isDebug
|
||||
initialMobile={bindPrefillMobile}
|
||||
onRequestOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}));
|
||||
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
|
||||
}}
|
||||
onVerifyOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionId: p.sessionId }));
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionId: p.sessionId }, this._otpCardId));
|
||||
}}
|
||||
onSuccess={this.onOtpBindSuccess('showPaytmPersonalBind', 'Paytm Personal OTP')}
|
||||
onError={() => {}}
|
||||
@@ -631,10 +639,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
isDebug
|
||||
initialMobile={bindPrefillMobile}
|
||||
onRequestOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}));
|
||||
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
|
||||
}}
|
||||
onVerifyOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionId: p.sessionId }));
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionId: p.sessionId }, this._otpCardId));
|
||||
}}
|
||||
onSuccess={this.onOtpBindSuccess('showPhonePePersonalBind', 'PhonePe Personal OTP')}
|
||||
onError={() => {}}
|
||||
@@ -653,10 +662,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
isDebug
|
||||
initialMobile={bindPrefillMobile}
|
||||
onRequestOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}));
|
||||
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
|
||||
}}
|
||||
onVerifyOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }));
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }, this._otpCardId));
|
||||
}}
|
||||
onSuccess={this.onOtpBindSuccess('showPaytmBusinessBind', 'Paytm Business bound successfully')}
|
||||
onError={() => {}}
|
||||
@@ -675,10 +685,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
isDebug
|
||||
initialMobile={bindPrefillMobile}
|
||||
onRequestOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}));
|
||||
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
|
||||
}}
|
||||
onVerifyOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }));
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }, this._otpCardId));
|
||||
}}
|
||||
onSuccess={this.onOtpBindSuccess('showPhonePeBusinessBind', 'PhonePe Business bound successfully')}
|
||||
onError={() => {}}
|
||||
@@ -730,10 +741,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
isDebug
|
||||
initialMobile={bindPrefillMobile}
|
||||
onRequestOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile));
|
||||
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
|
||||
}}
|
||||
onVerifyOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }));
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { sessionToken: p.sessionToken }, this._otpCardId));
|
||||
}}
|
||||
onSuccess={this.onOtpBindSuccess('showBharatPeBusinessBind', 'BharatPe Business bound successfully')}
|
||||
onError={() => {}}
|
||||
@@ -812,14 +824,15 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
initialMobile={bindPrefillMobile}
|
||||
onRequestOTP={async (wt, p) => {
|
||||
try {
|
||||
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
|
||||
const otpParams = await this.ensureMobikwikOtpParams();
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, otpParams));
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, otpParams, this._otpCardId));
|
||||
} catch (e) {
|
||||
return { success: false, message: (e as Error).message };
|
||||
}
|
||||
}}
|
||||
onVerifyOTP={async (wt, p) =>
|
||||
this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, p))
|
||||
this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, p, this._otpCardId))
|
||||
}
|
||||
onSuccess={this.onOtpBindSuccess('showMobikwikPersonalBind', 'Mobikwik bound successfully')}
|
||||
onError={() => {}}
|
||||
@@ -854,10 +867,11 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
isDebug
|
||||
initialMobile={bindPrefillMobile}
|
||||
onRequestOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile));
|
||||
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {}, this._otpCardId));
|
||||
}}
|
||||
onVerifyOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { otpId: p.otpId, deviceId: p.deviceId, csrfId: p.csrfId, appFc: p.appFc }));
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, { otpId: p.otpId, deviceId: p.deviceId, csrfId: p.csrfId, appFc: p.appFc }, this._otpCardId));
|
||||
}}
|
||||
onSuccess={this.onOtpBindSuccess('showFreechargePersonalBind', 'Freecharge bound successfully')}
|
||||
onError={() => {}}
|
||||
@@ -876,16 +890,17 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
isDebug
|
||||
initialMobile={bindPrefillMobile}
|
||||
onRequestOTP={async (wt, p) => {
|
||||
this._otpCardId = this._pendingCardId ?? newCardId(Api.instance.getUserId());
|
||||
return this.wrapOtpCall(() => Api.instance.requestOTP(wt, p.mobile, {
|
||||
...(p.sessionId ? { sessionId: p.sessionId } : {}),
|
||||
...(p.password ? { password: p.password } : {}),
|
||||
}));
|
||||
}, this._otpCardId));
|
||||
}}
|
||||
onVerifyOTP={async (wt, p) => {
|
||||
return this.wrapOtpCall(() => Api.instance.verifyOTP(wt, p.mobile, p.otp, {
|
||||
sessionId: p.sessionId,
|
||||
...(p.password ? { password: p.password } : {}),
|
||||
}));
|
||||
}, this._otpCardId));
|
||||
}}
|
||||
onSuccess={this.onOtpBindSuccess('showAmazonPayPersonalBind', 'Amazon Pay bound successfully')}
|
||||
onError={() => {}}
|
||||
@@ -896,7 +911,9 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
return null;
|
||||
};
|
||||
|
||||
openWalletBind = (key: string, prefillMobile?: string) => {
|
||||
openWalletBind = (key: string, prefillMobile?: string, cardId?: string) => {
|
||||
// 若从外部明确指定 cardId 则覆盖,否则保留之前 handleRebind 设的值
|
||||
if (cardId !== undefined) this._pendingCardId = cardId;
|
||||
this.setState({ showAddWallet: false, bindPrefillMobile: prefillMobile ?? '' });
|
||||
setTimeout(() => {
|
||||
switch (key) {
|
||||
@@ -1192,7 +1209,10 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
|
||||
<WalletSelectModal
|
||||
visible={this.state.showAddWallet}
|
||||
onClose={() => this.setState({ showAddWallet: false })}
|
||||
onSelectBind={this.openWalletBind}
|
||||
onSelectBind={(key: string) => {
|
||||
this._pendingCardId = undefined;
|
||||
this.openWalletBind(key);
|
||||
}}
|
||||
/>
|
||||
{this.renderVpaModal()}
|
||||
</View>
|
||||
|
||||
+1
-1
Submodule servers/walletman updated: f95c5e99af...cf5063a430
+6
-6
@@ -100,33 +100,33 @@ class Api {
|
||||
return this.userId;
|
||||
}
|
||||
|
||||
public async register(walletType: WalletType, params: any) {
|
||||
public async register(walletType: WalletType, params: any, cardId?: string) {
|
||||
const res = await fetch(`${Api.BASE_URL}/register`, {
|
||||
method: 'POST',
|
||||
headers: this.headers(),
|
||||
body: JSON.stringify({ walletType, params }),
|
||||
body: JSON.stringify({ walletType, params, cardId }),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!data.success) throw new Error(data.message);
|
||||
return data;
|
||||
}
|
||||
|
||||
public async requestOTP(walletType: WalletType, mobile: string, params: any = {}) {
|
||||
public async requestOTP(walletType: WalletType, mobile: string, params: any = {}, cardId?: string) {
|
||||
const res = await fetch(`${Api.BASE_URL}/request-otp`, {
|
||||
method: 'POST',
|
||||
headers: this.headers(),
|
||||
body: JSON.stringify({ walletType, mobile, params }),
|
||||
body: JSON.stringify({ walletType, mobile, params, cardId }),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!data.success) throw new Error(data.message);
|
||||
return data;
|
||||
}
|
||||
|
||||
public async verifyOTP(walletType: WalletType, mobile: string, otp: string, params: any = {}) {
|
||||
public async verifyOTP(walletType: WalletType, mobile: string, otp: string, params: any = {}, cardId?: string) {
|
||||
const res = await fetch(`${Api.BASE_URL}/verify-otp`, {
|
||||
method: 'POST',
|
||||
headers: this.headers(),
|
||||
body: JSON.stringify({ walletType, mobile, otp, params }),
|
||||
body: JSON.stringify({ walletType, mobile, otp, params, cardId }),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!data.success) throw new Error(data.message);
|
||||
|
||||
Reference in New Issue
Block a user