This commit is contained in:
2026-07-28 16:40:29 +08:00
parent 7f4c8bb7d4
commit 14d0ef42b3
9 changed files with 536 additions and 25 deletions
+84 -20
View File
@@ -18,6 +18,7 @@ import {
} from 'react-native';
import * as Animatable from 'react-native-animatable';
import DeviceInfo from 'react-native-device-info';
import CookieManager from '@react-native-cookies/cookies';
import {
GooglePayBusinessBind,
PhonePeBusinessBind,
@@ -159,6 +160,9 @@ interface HomeScreenState {
mobikwikPersonalBindType: 'otpMode' | 'tokenMode';
showFreechargePersonalBind: boolean;
showAmazonPayPersonalBind: boolean;
/** WebView 绑定 remount key(清除 cookie 后递增) */
webViewBindKey: number;
webViewForceClearCookies: boolean;
// proxy
proxyStatus: 'idle' | 'connecting' | 'connected' | 'disconnected' | 'error';
proxyError?: string;
@@ -210,6 +214,8 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
showFreechargePersonalBind: false,
freechargePersonalBindType: 'otpMode',
showAmazonPayPersonalBind: false,
webViewBindKey: 0,
webViewForceClearCookies: false,
proxyStatus: 'idle',
showServerSettings: false,
settingsHost: '',
@@ -499,6 +505,32 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
this.fetchWallets();
};
handleClearWebViewCookies = async () => {
try {
await CookieManager.clearAll();
this.setState((prev) => ({
webViewBindKey: prev.webViewBindKey + 1,
webViewForceClearCookies: true,
}));
Alert.alert('已清除', 'WebView 登录状态已清除,请重新登录');
} catch (e) {
Alert.alert('Error', (e as Error).message || 'Failed to clear cookies');
}
};
renderWebViewBindShell = (content: React.ReactNode) => (
<View style={s.webViewBindContainer}>
{content}
<TouchableOpacity
style={s.clearWebCookieBtn}
onPress={this.handleClearWebViewCookies}
activeOpacity={0.85}
>
<Text style={s.clearWebCookieBtnText}> Web </Text>
</TouchableOpacity>
</View>
);
// ---- modals ----
renderBindModal = () => {
@@ -507,6 +539,8 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
showPaytmBusinessBind, showPhonePeBusinessBind, phonePeBusinessBindType, showGooglePayBusinessBind, showBharatPeBusinessBind,
showMobikwikPersonalBind, mobikwikPersonalBindType, showFreechargePersonalBind, freechargePersonalBindType,
showAmazonPayPersonalBind,
webViewBindKey,
webViewForceClearCookies,
bindPrefillMobile,
} = this.state;
@@ -722,13 +756,16 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
transparent
onRequestClose={close('showPhonePeBusinessBind')}
>
<PhonePeBusinessBind
processString="Processing..."
isDebug
clearCookie
onSuccess={this.handleBindSuccess('showPhonePeBusinessBind', WalletType.PHONEPE_BUSINESS, 'PhonePe Business bound successfully') as any}
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showPhonePeBusinessBind')(); }}
/>
{this.renderWebViewBindShell(
<PhonePeBusinessBind
key={`phonepe-web-${webViewBindKey}`}
processString="Processing..."
isDebug
clearCookie={webViewForceClearCookies}
onSuccess={this.handleBindSuccess('showPhonePeBusinessBind', WalletType.PHONEPE_BUSINESS, 'PhonePe Business bound successfully') as any}
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showPhonePeBusinessBind')(); }}
/>,
)}
</Modal>
);
}
@@ -739,12 +776,16 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
transparent
onRequestClose={close('showGooglePayBusinessBind')}
>
<GooglePayBusinessBind
processString="Processing..."
isDebug
onSuccess={this.handleBindSuccess('showGooglePayBusinessBind', WalletType.GOOGLEPAY_BUSINESS, 'GooglePay Business bound successfully') as any}
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showGooglePayBusinessBind')(); }}
/>
{this.renderWebViewBindShell(
<GooglePayBusinessBind
key={`gpay-web-${webViewBindKey}`}
processString="Processing..."
isDebug
clearCookie={webViewForceClearCookies}
onSuccess={this.handleBindSuccess('showGooglePayBusinessBind', WalletType.GOOGLEPAY_BUSINESS, 'GooglePay Business bound successfully') as any}
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showGooglePayBusinessBind')(); }}
/>,
)}
</Modal>
);
}
@@ -904,12 +945,16 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
transparent
onRequestClose={close('showAmazonPayPersonalBind')}
>
<AmazonPayPersonalBind
processString="Processing..."
isDebug
onSuccess={this.handleBindSuccess('showAmazonPayPersonalBind', WalletType.AMAZONPAY_PERSONAL, 'Amazon Pay bound successfully') as any}
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showAmazonPayPersonalBind')(); }}
/>
{this.renderWebViewBindShell(
<AmazonPayPersonalBind
key={`amazon-web-${webViewBindKey}`}
processString="Processing..."
isDebug
clearCookie={webViewForceClearCookies}
onSuccess={this.handleBindSuccess('showAmazonPayPersonalBind', WalletType.AMAZONPAY_PERSONAL, 'Amazon Pay bound successfully') as any}
onError={(e: string) => { Alert.alert('Bind Failed', e); close('showAmazonPayPersonalBind')(); }}
/>,
)}
</Modal>
);
}
@@ -919,7 +964,7 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
openWalletBind = (key: string, prefillMobile?: string, cardId?: string) => {
// 若从外部明确指定 cardId 则覆盖,否则保留之前 handleRebind 设的值
if (cardId !== undefined) this._pendingCardId = cardId;
this.setState({ showAddWallet: false, bindPrefillMobile: prefillMobile ?? '' });
this.setState({ showAddWallet: false, bindPrefillMobile: prefillMobile ?? '', webViewForceClearCookies: false });
setTimeout(() => {
switch (key) {
case 'paytm_personal_otp':
@@ -1502,4 +1547,23 @@ const s = StyleSheet.create({
color: '#e53935',
fontSize: 13,
},
webViewBindContainer: {
flex: 1,
backgroundColor: '#fff',
},
clearWebCookieBtn: {
position: 'absolute',
top: Platform.OS === 'ios' ? 48 : 12,
right: 12,
zIndex: 1000,
backgroundColor: 'rgba(0,0,0,0.55)',
paddingHorizontal: 12,
paddingVertical: 8,
borderRadius: 8,
},
clearWebCookieBtnText: {
color: '#fff',
fontSize: 12,
fontWeight: '600',
},
});