Skip to content

Commit 17d131a

Browse files
committed
saving progress
1 parent 0e1725c commit 17d131a

File tree

3 files changed

+262
-4
lines changed

3 files changed

+262
-4
lines changed

packages/mobile-app/app/(tabs)/index.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { StatusBar } from "expo-status-bar";
2-
import { useState } from "react";
2+
import React, { useState } from "react";
33
import {
44
Layout,
55
Text,
@@ -301,7 +301,13 @@ export default function Balances() {
301301
{selectedIndex === 1 && (
302302
<>
303303
{getTransactionsResult.data?.map((transaction) => (
304-
<Card key={transaction.hash} style={styles.transactionCard}>
304+
<Card
305+
key={transaction.hash}
306+
style={styles.transactionCard}
307+
onPress={() =>
308+
router.push(`/transaction/${transaction.hash}`)
309+
}
310+
>
305311
<Text category="s1">{transaction.type.toString()}</Text>
306312
<Text category="p2" appearance="hint">
307313
Block: {transaction.block?.sequence ?? "Pending"}
@@ -444,6 +450,7 @@ const styles = StyleSheet.create({
444450
},
445451
transactionCard: {
446452
marginVertical: 4,
453+
cursor: "pointer",
447454
},
448455
backdrop: {
449456
backgroundColor: "rgba(0, 0, 0, 0.5)",

packages/mobile-app/app/send/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { StatusBar } from "expo-status-bar";
22
import { StyleSheet, View } from "react-native";
3+
import React, { useState, useMemo } from "react";
34
import { useFacade } from "../../data/facades";
4-
import { useState, useMemo } from "react";
55
import { IRON_ASSET_ID_HEX } from "../../data/constants";
66
import { CurrencyUtils } from "@ironfish/sdk";
77
import { useQueries } from "@tanstack/react-query";
@@ -325,7 +325,7 @@ export default function Send() {
325325
appearance="filled"
326326
style={styles.confirmButton}
327327
onPress={() => {
328-
console.log("will navigate to", sentTxHash);
328+
router.push(`/transaction/${sentTxHash}`);
329329
}}
330330
>
331331
View Transaction
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
import { StatusBar } from "expo-status-bar";
2+
import { StyleSheet, View, Linking } from "react-native";
3+
import { useLocalSearchParams, Stack } from "expo-router";
4+
import React, { useState } from "react";
5+
import {
6+
Layout,
7+
Text,
8+
Button,
9+
Divider,
10+
Icon,
11+
IconProps,
12+
Spinner,
13+
} from "@ui-kitten/components";
14+
import { useFacade } from "../../data/facades";
15+
import { CurrencyUtils } from "@ironfish/sdk";
16+
import { useQueries } from "@tanstack/react-query";
17+
import { IRON_ASSET_ID_HEX } from "../../data/constants";
18+
19+
const ExternalLinkIcon = (props: IconProps) => (
20+
<Icon {...props} name="external-link-outline" />
21+
);
22+
23+
export default function TransactionDetails() {
24+
const { hash } = useLocalSearchParams<{ hash: string }>();
25+
const facade = useFacade();
26+
27+
const transactionQuery = facade.getTransaction.useQuery(
28+
{
29+
accountName: facade.getAccount.useQuery({}).data?.name ?? "",
30+
hash,
31+
},
32+
{
33+
enabled: !!hash,
34+
},
35+
);
36+
37+
// Get assets for all balance deltas
38+
const assetQueries = useQueries({
39+
queries:
40+
transactionQuery.data?.assetBalanceDeltas.map((delta) => ({
41+
queryKey: facade.getAsset.buildQueryKey({ assetId: delta.assetId }),
42+
queryFn: () => facade.getAsset.resolver({ assetId: delta.assetId }),
43+
enabled: !!delta.assetId,
44+
})) ?? [],
45+
});
46+
47+
const openInExplorer = () => {
48+
Linking.openURL(`https://explorer.ironfish.network/transaction/${hash}`);
49+
};
50+
51+
if (transactionQuery.isLoading || assetQueries.some((q) => q.isLoading)) {
52+
return (
53+
<Layout style={styles.container}>
54+
<Spinner size="large" />
55+
</Layout>
56+
);
57+
}
58+
59+
if (!transactionQuery.data) {
60+
return (
61+
<Layout style={styles.container}>
62+
<Text>Transaction not found</Text>
63+
</Layout>
64+
);
65+
}
66+
67+
const transaction = transactionQuery.data;
68+
console.log(`########################`);
69+
console.log("transaction", transaction);
70+
console.log(`########################`);
71+
72+
// Create a map of assetId to asset data
73+
const assetMap = new Map();
74+
assetQueries.forEach((query) => {
75+
if (query.data) {
76+
assetMap.set(query.data.id, query.data);
77+
}
78+
});
79+
80+
// Calculate total amount for each asset
81+
const assetAmounts = transaction.assetBalanceDeltas.reduce(
82+
(acc, delta) => {
83+
const asset = assetMap.get(delta.assetId);
84+
console.log("asset", asset);
85+
const assetName =
86+
asset?.verification.status === "verified"
87+
? asset.verification.symbol
88+
: (asset?.name ?? delta.assetId);
89+
90+
return {
91+
...acc,
92+
[assetName]: (acc[assetName] || 0n) + BigInt(delta.delta),
93+
};
94+
},
95+
{} as Record<string, bigint>,
96+
);
97+
98+
console.log(`$$$$$$`);
99+
console.log("assetAmounts", assetAmounts);
100+
console.log(`$$$$$$`);
101+
102+
// Get the main asset and transaction type
103+
const mainAssetAmount = Object.entries(assetAmounts)[0] || [];
104+
const [mainAssetName, mainAmount] = mainAssetAmount;
105+
const isReceived = mainAmount > 0n;
106+
107+
return (
108+
<Layout style={styles.container}>
109+
<Stack.Screen
110+
options={{
111+
headerTitle: "",
112+
headerTransparent: true,
113+
}}
114+
/>
115+
116+
{/* Header Section */}
117+
<View style={styles.headerSection}>
118+
<Text category="h3" style={styles.transactionType}>
119+
{isReceived ? "Received" : "Sent"}
120+
</Text>
121+
<Text category="h2" style={styles.mainAmount}>
122+
{CurrencyUtils.render(
123+
(mainAmount < 0n ? -mainAmount : mainAmount).toString(),
124+
false,
125+
)}{" "}
126+
{mainAssetName}
127+
</Text>
128+
<Text category="s1" appearance="hint" style={styles.timestamp}>
129+
{new Date(transaction.timestamp).toLocaleString()}
130+
</Text>
131+
</View>
132+
133+
{/* Transaction Details */}
134+
<View style={styles.detailsSection}>
135+
<View style={styles.section}>
136+
<Text category="s1" style={styles.label}>
137+
{isReceived ? "From" : "To"}
138+
</Text>
139+
<Text style={styles.value} selectable>
140+
{isReceived
141+
? transaction.notes[0]?.sender
142+
: transaction.notes[0]?.owner}
143+
</Text>
144+
</View>
145+
146+
<Divider style={styles.divider} />
147+
148+
<View style={styles.section}>
149+
<Text category="s1" style={styles.label}>
150+
Transaction Hash
151+
</Text>
152+
<Text style={styles.value} selectable>
153+
{hash}
154+
</Text>
155+
</View>
156+
157+
<Divider style={styles.divider} />
158+
159+
<View style={styles.section}>
160+
<Text category="s1" style={styles.label}>
161+
Status
162+
</Text>
163+
<Text style={styles.value}>
164+
{transaction.status.charAt(0).toUpperCase() +
165+
transaction.status.slice(1).toLowerCase()}
166+
</Text>
167+
</View>
168+
169+
<Divider style={styles.divider} />
170+
171+
{transaction.fee && (
172+
<>
173+
<View style={styles.section}>
174+
<Text category="s1" style={styles.label}>
175+
Fee
176+
</Text>
177+
<Text style={styles.value}>
178+
{CurrencyUtils.render(transaction.fee)} $IRON
179+
</Text>
180+
</View>
181+
<Divider style={styles.divider} />
182+
</>
183+
)}
184+
185+
{transaction.notes.some((note) => note.memo) && (
186+
<>
187+
<View style={styles.section}>
188+
<Text category="s1" style={styles.label}>
189+
Memo
190+
</Text>
191+
<Text style={styles.value}>
192+
{transaction.notes.find((note) => note.memo)?.memo}
193+
</Text>
194+
</View>
195+
<Divider style={styles.divider} />
196+
</>
197+
)}
198+
199+
<Button
200+
style={styles.explorerButton}
201+
accessoryRight={ExternalLinkIcon}
202+
onPress={openInExplorer}
203+
>
204+
View on Explorer
205+
</Button>
206+
</View>
207+
208+
<StatusBar style="auto" />
209+
</Layout>
210+
);
211+
}
212+
213+
const styles = StyleSheet.create({
214+
container: {
215+
flex: 1,
216+
},
217+
headerSection: {
218+
padding: 32,
219+
paddingTop: 80,
220+
alignItems: "center",
221+
backgroundColor: "#f5f5f5",
222+
},
223+
transactionType: {
224+
marginBottom: 8,
225+
},
226+
mainAmount: {
227+
marginBottom: 8,
228+
},
229+
timestamp: {
230+
marginBottom: 16,
231+
},
232+
detailsSection: {
233+
padding: 32,
234+
flex: 1,
235+
},
236+
section: {
237+
marginVertical: 8,
238+
},
239+
label: {
240+
marginBottom: 4,
241+
},
242+
value: {
243+
fontSize: 16,
244+
},
245+
divider: {
246+
marginVertical: 8,
247+
},
248+
explorerButton: {
249+
marginTop: 24,
250+
},
251+
});

0 commit comments

Comments
 (0)