From f84fc63268d9a0092449fbfc3ac3b205027df336 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Mon, 17 Nov 2025 12:19:01 -0600 Subject: [PATCH] Fix XNT balance display and add toast notifications - Enable cleartext HTTP traffic in AndroidManifest for API access - Add react-native-toast-message for modern notifications - Replace Alert.alert with Toast.show for better UX: - Send transaction validation errors - Clipboard copy confirmations - Wallet deletion success - Swap/Stake/Bridge placeholder messages - Update handleSendSubmit to accept parameters from SendScreen - Custom dark theme toast configuration with: - Color-coded borders (green/red/blue) - Bottom positioning with 80px offset - Dark background matching app theme --- android/App.js | 191 ++++++++++++++++-- .../android/app/src/main/AndroidManifest.xml | 2 +- 2 files changed, 178 insertions(+), 15 deletions(-) diff --git a/android/App.js b/android/App.js index d455f66..3443cb5 100644 --- a/android/App.js +++ b/android/App.js @@ -90,6 +90,7 @@ import WalletManagerScreen from "./screens/WalletManagerScreen"; import WalletSettingsScreen from "./screens/WalletSettingsScreen"; import AddressSelectorScreen from "./screens/AddressSelectorScreen"; import LedgerConnectionScreen from "./screens/LedgerConnectionScreen"; +import Toast from "react-native-toast-message"; // Network configurations const API_SERVER = "http://162.250.126.66:4000"; @@ -309,7 +310,8 @@ function AppContent() { const [wallets, setWallets] = useState([]); const [selectedWallet, setSelectedWallet] = useState(null); - const [selectedAddressFromSelector, setSelectedAddressFromSelector] = useState(""); + const [selectedAddressFromSelector, setSelectedAddressFromSelector] = + useState(""); const [accounts, setAccounts] = useState(MOCK_ACCOUNTS); const [selectedAccount, setSelectedAccount] = useState(MOCK_ACCOUNTS[0]); const [balance, setBalance] = useState("0"); @@ -1111,7 +1113,12 @@ function AppContent() { }); } - Alert.alert("Success", "Wallet deleted successfully"); + Toast.show({ + type: "success", + text1: "Success", + text2: "Wallet deleted successfully", + position: "bottom", + }); }, }, ] @@ -1215,37 +1222,66 @@ function AppContent() { console.log("📋 selectedWallet.address:", selectedWallet?.address); console.log("📋 selectedWallet.publicKey:", selectedWallet?.publicKey); Clipboard.setString(text); - Alert.alert("Copied", "Address copied to clipboard"); + Toast.show({ + type: "success", + text1: "Copied", + text2: "Address copied to clipboard", + position: "bottom", + }); }; - const handleSendSubmit = async () => { + const handleSendSubmit = async (amount, address) => { // Dismiss keyboard when Send button is pressed Keyboard.dismiss(); if (!selectedWallet) { - Alert.alert("Error", "No wallet selected"); + Toast.show({ + type: "error", + text1: "Error", + text2: "No wallet selected", + position: "bottom", + }); return; } - if (!sendAddress || !sendAmount) { - Alert.alert("Error", "Please enter both address and amount"); + if (!address || !amount) { + Toast.show({ + type: "error", + text1: "Error", + text2: "Please enter both address and amount", + position: "bottom", + }); return; } + // Store values in state for confirmation screen + setSendAmount(amount); + setSendAddress(address); + // Trim the address to remove any whitespace - const trimmedAddress = sendAddress.trim(); + const trimmedAddress = address.trim(); // Validate address format try { new PublicKey(trimmedAddress); } catch (e) { - Alert.alert("Error", "Invalid recipient address"); + Toast.show({ + type: "error", + text1: "Error", + text2: "Invalid recipient address", + position: "bottom", + }); return; } // Validate amount - const amountNum = parseFloat(sendAmount); + const amountNum = parseFloat(amount); if (isNaN(amountNum) || amountNum <= 0) { - Alert.alert("Error", "Invalid amount"); + Toast.show({ + type: "error", + text1: "Error", + text2: "Invalid amount", + position: "bottom", + }); return; } @@ -1428,15 +1464,30 @@ function AppContent() { }; const handleSwap = () => { - Alert.alert("Swap", "Swap functionality would open here"); + Toast.show({ + type: "info", + text1: "Swap", + text2: "Swap functionality would open here", + position: "bottom", + }); }; const handleStake = () => { - Alert.alert("Stake", "Stake functionality would open here"); + Toast.show({ + type: "info", + text1: "Stake", + text2: "Stake functionality would open here", + position: "bottom", + }); }; const handleBridge = () => { - Alert.alert("Bridge", "Bridge functionality would open here"); + Toast.show({ + type: "info", + text1: "Bridge", + text2: "Bridge functionality would open here", + position: "bottom", + }); }; const copyAddress = () => { @@ -4687,6 +4738,118 @@ function AppContent() { + + {/* Toast notifications */} + ( + + + {props.text1} + + + {props.text2} + + + ), + error: (props) => ( + + + {props.text1} + + + {props.text2} + + + ), + info: (props) => ( + + + {props.text1} + + + {props.text2} + + + ), + }} + /> {/* Settings - Full Page - Outside GestureHandler */} diff --git a/android/android/app/src/main/AndroidManifest.xml b/android/android/app/src/main/AndroidManifest.xml index c5ab1bd..8c091d8 100644 --- a/android/android/app/src/main/AndroidManifest.xml +++ b/android/android/app/src/main/AndroidManifest.xml @@ -13,7 +13,7 @@ - +