11/**
22 * Receive screen.
3- * Displays current receive address with QR code and copy action.
3+ * Displays current receive address with QR code, copy action,
4+ * and a scrollable list of all generated addresses.
45 */
56
6- import { useCallback } from "react" ;
7- import { View , Text , Pressable , Alert , ActivityIndicator } from "react-native" ;
7+ import { useCallback , useState } from "react" ;
8+ import {
9+ View ,
10+ Text ,
11+ Pressable ,
12+ Alert ,
13+ ActivityIndicator ,
14+ ScrollView ,
15+ FlatList ,
16+ } from "react-native" ;
817import { SafeAreaView } from "react-native-safe-area-context" ;
918import * as Clipboard from "expo-clipboard" ;
1019import QRCode from "react-native-qrcode-svg" ;
1120import { useWalletStore } from "../../src/wallet/wallet-store" ;
1221import { Button } from "../../src/ui/components/Button" ;
1322
23+ function truncateAddress ( address : string ) : string {
24+ if ( address . length <= 16 ) return address ;
25+ return `${ address . slice ( 0 , 10 ) } ...${ address . slice ( - 8 ) } ` ;
26+ }
27+
1428export default function ReceiveScreen ( ) {
1529 const receiveAddress = useWalletStore ( ( s ) => s . currentReceiveAddress ) ;
30+ const addresses = useWalletStore ( ( s ) => s . addresses ) ;
1631 const getNewAddress = useWalletStore ( ( s ) => s . getNewAddress ) ;
1732
33+ const [ selectedAddress , setSelectedAddress ] = useState < string | null > ( null ) ;
34+ const displayAddress = selectedAddress ?? receiveAddress ;
35+
1836 const handleCopy = useCallback ( async ( ) => {
19- await Clipboard . setStringAsync ( receiveAddress ) ;
37+ await Clipboard . setStringAsync ( displayAddress ) ;
2038 Alert . alert ( "Copied" , "Address copied to clipboard" ) ;
21- } , [ receiveAddress ] ) ;
39+ } , [ displayAddress ] ) ;
2240
2341 const handleNewAddress = useCallback ( ( ) => {
24- getNewAddress ( ) ;
42+ const addr = getNewAddress ( ) ;
43+ setSelectedAddress ( addr ) ;
2544 } , [ getNewAddress ] ) ;
2645
46+ const handleSelectAddress = useCallback (
47+ ( address : string ) => {
48+ setSelectedAddress ( address ) ;
49+ } ,
50+ [ ] ,
51+ ) ;
52+
53+ const handleCopyAddress = useCallback ( async ( address : string ) => {
54+ await Clipboard . setStringAsync ( address ) ;
55+ Alert . alert ( "Copied" , "Address copied to clipboard" ) ;
56+ } , [ ] ) ;
57+
2758 if ( ! receiveAddress ) {
2859 return (
2960 < SafeAreaView className = "flex-1 bg-fair-dark" edges = { [ "top" , "left" , "right" ] } >
@@ -39,40 +70,45 @@ export default function ReceiveScreen() {
3970
4071 return (
4172 < SafeAreaView className = "flex-1 bg-fair-dark" edges = { [ "top" , "left" , "right" ] } >
42- < View className = "flex-1 items-center px-6 pt-8" >
73+ < ScrollView
74+ className = "flex-1"
75+ contentContainerClassName = "px-6 pt-6 pb-8"
76+ >
4377 { /* Title */ }
44- < Text className = "text-white text-xl font-bold mb-2 " >
78+ < Text className = "text-white text-xl font-bold mb-1 text-center " >
4579 Receive FAIR
4680 </ Text >
47- < Text className = "text-fair-muted text-sm mb-8 text-center" >
81+ < Text className = "text-fair-muted text-sm mb-6 text-center" >
4882 Share this address to receive FairCoin
4983 </ Text >
5084
5185 { /* QR Code */ }
52- < View className = "w-56 h-56 items-center justify-center mb-6" >
53- < QRCode
54- value = { `faircoin:${ receiveAddress } ` }
55- size = { 200 }
56- color = "#9ffb50"
57- backgroundColor = "transparent"
58- />
86+ < View className = "items-center mb-6" >
87+ < View className = "w-56 h-56 items-center justify-center" >
88+ < QRCode
89+ value = { `faircoin:${ displayAddress } ` }
90+ size = { 200 }
91+ color = "#9ffb50"
92+ backgroundColor = "transparent"
93+ />
94+ </ View >
5995 </ View >
6096
61- { /* Address display */ }
97+ { /* Selected address display */ }
6298 < Pressable
63- className = "bg-fair-dark-light border border-fair-border rounded-xl p-4 w-full mb-2 "
99+ className = "bg-fair-dark-light border border-fair-border rounded-xl p-4 w-full mb-4 "
64100 onPress = { handleCopy }
65101 >
66102 < Text
67103 className = "text-white text-sm text-center font-mono"
68104 selectable
69105 >
70- { receiveAddress }
106+ { displayAddress }
71107 </ Text >
72108 </ Pressable >
73109
74110 { /* Actions */ }
75- < View className = "w-full gap-3" >
111+ < View className = "w-full gap-3 mb-8 " >
76112 < Button
77113 title = "Copy Address"
78114 onPress = { handleCopy }
@@ -84,7 +120,58 @@ export default function ReceiveScreen() {
84120 variant = "outline"
85121 />
86122 </ View >
87- </ View >
123+
124+ { /* All addresses */ }
125+ { addresses . length > 0 ? (
126+ < >
127+ < Text className = "text-fair-muted text-xs font-semibold uppercase tracking-wider mb-3 px-1" >
128+ Your Addresses ({ addresses . length } )
129+ </ Text >
130+ < View className = "bg-fair-dark-light rounded-xl overflow-hidden" >
131+ { addresses . map ( ( address , idx ) => {
132+ const isActive = address === displayAddress ;
133+ return (
134+ < Pressable
135+ key = { `${ idx } -${ address } ` }
136+ className = { `flex-row items-center justify-between px-4 py-3 ${
137+ idx < addresses . length - 1 ? "border-b border-fair-border" : ""
138+ } ${ isActive ? "bg-fair-green/5" : "" } `}
139+ onPress = { ( ) => handleSelectAddress ( address ) }
140+ onLongPress = { ( ) => handleCopyAddress ( address ) }
141+ >
142+ < View className = "flex-1 mr-3" >
143+ < View className = "flex-row items-center" >
144+ { isActive ? (
145+ < View className = "w-2 h-2 rounded-full bg-fair-green mr-2" />
146+ ) : null }
147+ < Text
148+ className = { `text-xs font-mono ${
149+ isActive ? "text-fair-green" : "text-white"
150+ } `}
151+ >
152+ { truncateAddress ( address ) }
153+ </ Text >
154+ </ View >
155+ < Text className = "text-fair-muted text-xs mt-0.5" >
156+ #{ idx + 1 }
157+ </ Text >
158+ </ View >
159+ < Pressable
160+ className = "bg-fair-dark border border-fair-border rounded-lg px-3 py-1.5"
161+ onPress = { ( ) => handleCopyAddress ( address ) }
162+ >
163+ < Text className = "text-fair-green text-xs" > Copy</ Text >
164+ </ Pressable >
165+ </ Pressable >
166+ ) ;
167+ } ) }
168+ </ View >
169+ < Text className = "text-fair-muted text-xs mt-2 text-center" >
170+ Tap to select, long press to copy
171+ </ Text >
172+ </ >
173+ ) : null }
174+ </ ScrollView >
88175 </ SafeAreaView >
89176 ) ;
90177}
0 commit comments