* Add accumulation address cap helper + pair key (Task 1) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add forceNew + cap enforcement + addressesForOption to accumulation hook (Task 2) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Guard createAddress against re-entrant double-mint (Task 2 review fix) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add i18n keys for multi accumulation addresses (Task 3) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add accumulation address + option selector half-modals (Task 4) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Reuse getPairKey in option selector modal (Task 4 review fix) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Group accumulation home by option with per-option count (Task 5) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Manage multiple addresses + option switching in accumulation detail (Task 6) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Guard accumulation detail against externally-emptied option (Task 6 review fix) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add create-new-address button + direct-address display to deposit QR view (Task 7) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add address-selector list icon to deposit QR header (Task 8) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Cap-gate create wizard + always mint additional address (Task 9) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * remove manual create button in favor of automatic * fix select address page * fix opacity * improve details page * fixing translations * adding dislcimer to address details page * adding reindex scan * fixing background color * fixing camel case var name * minor correctness fixes --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
92 lines
2.5 KiB
JavaScript
92 lines
2.5 KiB
JavaScript
import { StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
import { useNavigation } from '@react-navigation/native';
|
|
import { ThemeText } from '../../../../functions/CustomElements';
|
|
import ThemeIcon from '../../../../functions/CustomElements/themeIcon';
|
|
import { ACCUMULATION_CHAINS } from '../../../../constants/accumulationAddresses';
|
|
import { Image } from 'expo-image';
|
|
import { ICONS, SIZES } from '../../../../constants';
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
export default function AccumulationAddressCard({ group }) {
|
|
const navigate = useNavigation();
|
|
const { t } = useTranslation();
|
|
const chainMeta = ACCUMULATION_CHAINS.find(c => c.id === group.sourceChain);
|
|
const chainLabel = chainMeta?.label ?? group.sourceChain ?? '';
|
|
const label = `${group.sourceAsset} → ${
|
|
group.destinationAsset === 'BTC'
|
|
? t('constants.bitcoin_upper')
|
|
: t('constants.dollars_upper')
|
|
}`;
|
|
|
|
if (!chainLabel) return null;
|
|
|
|
return (
|
|
<TouchableOpacity
|
|
activeOpacity={0.7}
|
|
style={styles.card}
|
|
onPress={() =>
|
|
navigate.navigate('AccumulationAddressDetail', {
|
|
sourceChain: group.sourceChain,
|
|
sourceAsset: group.sourceAsset,
|
|
destinationAsset: group.destinationAsset,
|
|
})
|
|
}
|
|
>
|
|
<View style={styles.leftSection}>
|
|
<Image
|
|
style={styles.assetIcon}
|
|
source={ICONS[`chain_${chainLabel.toLocaleLowerCase()}`]}
|
|
contentFit="contain"
|
|
/>
|
|
</View>
|
|
<View style={styles.middleSection}>
|
|
<ThemeText styles={styles.label} content={chainLabel} />
|
|
<ThemeText styles={styles.swapMeta} content={label} />
|
|
{group.count > 1 && (
|
|
<ThemeText
|
|
styles={styles.swapMeta}
|
|
content={t('screens.accumulationAddresses.addressCount', {
|
|
count: group.count,
|
|
})}
|
|
/>
|
|
)}
|
|
</View>
|
|
<ThemeIcon iconName={'ChevronRight'} size={20} />
|
|
</TouchableOpacity>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
card: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
minHeight: 45,
|
|
borderRadius: 16,
|
|
paddingVertical: 10,
|
|
},
|
|
assetIcon: {
|
|
width: 45,
|
|
height: 45,
|
|
borderRadius: 30,
|
|
},
|
|
row: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
},
|
|
label: {
|
|
fontWeight: 500,
|
|
includeFontPadding: false,
|
|
},
|
|
swapMeta: {
|
|
fontSize: SIZES.small,
|
|
opacity: 0.6,
|
|
includeFontPadding: false,
|
|
},
|
|
middleSection: {
|
|
flex: 1,
|
|
gap: 2,
|
|
marginLeft: 8,
|
|
marginRight: 5,
|
|
},
|
|
});
|