Skip to content

Commit 2521bf2

Browse files
committed
Ref: show Archax banner for UK location
1 parent 39df97b commit 2521bf2

32 files changed

+409
-158
lines changed

src/Root.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {DeviceEmitterEvents} from './constants/device-emitter-events';
2828
import {baseNavigatorOptions} from './constants/NavigationOptions';
2929
import {LOCK_AUTHORIZED_TIME} from './constants/Lock';
3030
import BiometricModal from './components/modal/biometric/BiometricModal';
31+
import ArchaxBanner from './components/archax/archax-banner';
3132
import {AppEffects, AppActions} from './store/app';
3233
import {BitPayDarkTheme, BitPayLightTheme} from './themes/bitpay';
3334
import {LogActions} from './store/log';
@@ -286,6 +287,7 @@ export default () => {
286287
({WALLET}) => WALLET.accountEvmCreationMigrationComplete,
287288
);
288289
const notificationsState = useAppSelector(selectSettingsNotificationState);
290+
const showArchaxBanner = useAppSelector(({APP}) => APP.showArchaxBanner);
289291

290292
const blurScreenList: string[] = [
291293
OnboardingScreens.IMPORT,
@@ -565,7 +567,8 @@ export default () => {
565567
<ThemeProvider theme={theme}>
566568
<GestureHandlerRootView style={{flex: 1}}>
567569
<BottomSheetModalProvider>
568-
<SafeAreaView style={{ flex: 1}} >
570+
<SafeAreaView style={{flex: 1}}>
571+
{showArchaxBanner && <ArchaxBanner />}
569572
{/* https://github.com/react-navigation/react-navigation/issues/11353#issuecomment-1548114655 */}
570573
<HeaderShownContext.Provider value>
571574
<NavigationContainer

src/components/amount/Amount.tsx

+28-15
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import SwapButton, {
99
ButtonText,
1010
SwapButtonContainer,
1111
} from '../../components/swap-button/SwapButton';
12-
import VirtualKeyboard from '../../components/virtual-keyboard/VirtualKeyboard';
12+
import VirtualKeyboard, {
13+
PIXEL_DENSITY_LIMIT,
14+
} from '../../components/virtual-keyboard/VirtualKeyboard';
1315
import {getAvailableFiatCurrencies} from '../../navigation/services/buy-crypto/utils/buy-crypto-utils';
1416
import {getAvailableSellCryptoFiatCurrencies} from '../../navigation/services/sell-crypto/utils/sell-crypto-utils';
1517
import {ParseAmount} from '../../store/wallet/effects/amount/amount';
@@ -25,22 +27,24 @@ import CurrencySymbol from '../icons/currency-symbol/CurrencySymbol';
2527
import {useLogger} from '../../utils/hooks/useLogger';
2628
import {getBuyCryptoFiatLimits} from '../../store/buy-crypto/buy-crypto.effects';
2729
import KeyEvent from 'react-native-keyevent';
30+
import ArchaxFooter from '../archax/archax-footer';
31+
import {PixelRatio, View} from 'react-native';
2832

2933
const AmountContainer = styled.SafeAreaView`
3034
flex: 1;
3135
`;
3236

33-
const CtaContainer = styled.View`
37+
const CtaContainer = styled.View<{isSmallScreen?: boolean}>`
3438
width: 100%;
35-
margin-top: 20px;
39+
margin-top: ${({isSmallScreen}) => (isSmallScreen ? 0 : '20px')};
3640
flex-direction: row;
3741
justify-content: space-between;
3842
`;
3943

40-
export const AmountHeroContainer = styled.View`
44+
export const AmountHeroContainer = styled.View<{isSmallScreen: boolean}>`
4145
flex-direction: column;
4246
align-items: center;
43-
margin-top: 20px;
47+
margin-top: ${({isSmallScreen}) => (isSmallScreen ? 0 : '20px')};
4448
padding: 0 ${ScreenGutter};
4549
`;
4650

@@ -95,9 +99,8 @@ const CurrencySuperScript = styled.View`
9599
top: 10px;
96100
right: -20px;
97101
`;
98-
99-
const CurrencyText = styled(BaseText)`
100-
font-size: 20px;
102+
const CurrencyText = styled(BaseText)<{bigAmount?: boolean}>`
103+
font-size: ${({bigAmount}) => (bigAmount ? '12px' : '20px')};
101104
color: ${({theme}) => theme.colors.text};
102105
position: absolute;
103106
`;
@@ -150,6 +153,10 @@ const Amount: React.FC<AmountProps> = ({
150153
const defaultAltCurrency = useAppSelector(({APP}) => APP.defaultAltCurrency);
151154
const allRates = useAppSelector(({RATE}) => RATE.rates);
152155
const curValRef = useRef('');
156+
const showArchaxBanner = useAppSelector(({APP}) => APP.showArchaxBanner);
157+
const _isSmallScreen = showArchaxBanner
158+
? true
159+
: PixelRatio.get() < PIXEL_DENSITY_LIMIT;
153160

154161
const fiatCurrency = useMemo(() => {
155162
if (fiatCurrencyAbbreviation) {
@@ -440,16 +447,17 @@ const Amount: React.FC<AmountProps> = ({
440447
return (
441448
<AmountContainer>
442449
<ViewContainer>
443-
<AmountHeroContainer>
450+
<AmountHeroContainer isSmallScreen={_isSmallScreen}>
444451
<Row>
445452
<AmountText
446453
numberOfLines={1}
447454
ellipsizeMode={'tail'}
448-
bigAmount={displayAmount?.length > 8}>
455+
bigAmount={_isSmallScreen ? true : displayAmount?.length > 8}>
449456
{displayAmount || 0}
450457
</AmountText>
451458
<CurrencySuperScript>
452-
<CurrencyText>
459+
<CurrencyText
460+
bigAmount={_isSmallScreen ? true : displayAmount?.length > 8}>
453461
{formatCurrencyAbbreviation(currency) || 'USD'}
454462
</CurrencyText>
455463
</CurrencySuperScript>
@@ -465,14 +473,18 @@ const Amount: React.FC<AmountProps> = ({
465473
</AmountEquivText>
466474
</Row>
467475
) : null}
468-
<Row>{getWarnMsg}</Row>
469-
<CtaContainer>
476+
<View style={{position: 'absolute', top: _isSmallScreen ? 70 : 100}}>
477+
{getWarnMsg}
478+
</View>
479+
<CtaContainer isSmallScreen={_isSmallScreen}>
470480
{context &&
471481
['sellCrypto', 'swapCrypto'].includes(context) &&
472482
limitsOpts?.maxWalletAmount ? (
473-
<SwapButtonContainer onPress={() => swapCryptoSendMax()}>
483+
<SwapButtonContainer
484+
isSmallScreen={_isSmallScreen}
485+
onPress={() => swapCryptoSendMax()}>
474486
<CurrencySymbol />
475-
<ButtonText>MAX</ButtonText>
487+
<ButtonText isSmallScreen={_isSmallScreen}>MAX</ButtonText>
476488
</SwapButtonContainer>
477489
) : (
478490
<Row />
@@ -519,6 +531,7 @@ const Amount: React.FC<AmountProps> = ({
519531
{t('Continue')}
520532
</Button>
521533
</ButtonContainer>
534+
{showArchaxBanner && <ArchaxFooter />}
522535
</ActionContainer>
523536
</ViewContainer>
524537
</AmountContainer>

src/components/amount/AmountModal.tsx

+11-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import SheetModal from '../modal/base/sheet/SheetModal';
1010
import Amount, {AmountProps, LimitsOpts} from './Amount';
1111
import {Platform} from 'react-native';
1212
import {TouchableOpacity} from 'react-native-gesture-handler';
13+
import {useAppSelector} from '../../utils/hooks';
14+
import ArchaxBanner from '../archax/archax-banner';
1315

1416
const ModalHeaderText = styled(BaseText)`
1517
font-size: 18px;
@@ -39,7 +41,7 @@ const ModalHeaderRight = styled(BaseText)`
3941
const StyledAmountModalContainer = styled.SafeAreaView<{platform: string}>`
4042
background-color: ${({theme}) => (theme.dark ? Black : White)};
4143
flex: 1;
42-
margin-bottom: ${({platform}) => platform === 'ios' ? 25 : 10}px;
44+
margin-bottom: ${({platform}) => (platform === 'ios' ? 25 : 10)}px;
4345
`;
4446

4547
type AmountModalProps = AmountProps & {
@@ -52,7 +54,9 @@ type AmountModalProps = AmountProps & {
5254

5355
const AmountModalContainerHOC = gestureHandlerRootHOC(props => {
5456
return (
55-
<StyledAmountModalContainer platform={Platform.OS}>{props.children}</StyledAmountModalContainer>
57+
<StyledAmountModalContainer platform={Platform.OS}>
58+
{props.children}
59+
</StyledAmountModalContainer>
5660
);
5761
});
5862

@@ -66,6 +70,7 @@ const AmountModal: React.VFC<AmountModalProps> = props => {
6670
...amountProps
6771
} = props;
6872
const theme = useTheme();
73+
const showArchaxBanner = useAppSelector(({APP}) => APP.showArchaxBanner);
6974

7075
return (
7176
<SheetModal
@@ -74,6 +79,7 @@ const AmountModal: React.VFC<AmountModalProps> = props => {
7479
onBackdropPress={onClose}
7580
fullscreen>
7681
<AmountModalContainerHOC>
82+
{showArchaxBanner && <ArchaxBanner />}
7783
<ModalHeader>
7884
<CloseModalButton
7985
onPress={() => {
@@ -87,7 +93,9 @@ const AmountModal: React.VFC<AmountModalProps> = props => {
8793
}}
8894
/>
8995
</CloseModalButton>
90-
{modalTitle ? <ModalHeaderText>{modalTitle}</ModalHeaderText> : null}
96+
{modalTitle && !showArchaxBanner ? (
97+
<ModalHeaderText>{modalTitle}</ModalHeaderText>
98+
) : null}
9199
{onSendMaxPressed &&
92100
(!props.context ||
93101
!['sellCrypto', 'swapCrypto'].includes(props.context)) ? (
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
import {useSafeAreaInsets} from 'react-native-safe-area-context';
3+
import {ArchaxBannerText, ArchaxBannerLink} from '../styled/Text';
4+
import {openUrlWithInAppBrowser} from '../../store/app/app.effects';
5+
import {useAppDispatch} from '../../utils/hooks';
6+
import {ArchaxBannerContainer} from '../../components/styled/Containers';
7+
8+
const ArchaxBanner: React.FC = () => {
9+
const dispatch = useAppDispatch();
10+
const insets = useSafeAreaInsets();
11+
return (
12+
<ArchaxBannerContainer inset={insets}>
13+
<ArchaxBannerText>
14+
Don't invest unless you're prepared to lose all the money you invest.
15+
This is a high-risk investment and you should not expect to be protected
16+
if something goes worng.
17+
<ArchaxBannerLink
18+
onPress={() => {
19+
dispatch(openUrlWithInAppBrowser('http://localhost:8080')); // TODO: Update URL
20+
}}>
21+
Take 2 mins to learn more.
22+
</ArchaxBannerLink>
23+
</ArchaxBannerText>
24+
</ArchaxBannerContainer>
25+
);
26+
};
27+
28+
export default ArchaxBanner;
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
import styled from 'styled-components/native';
3+
import {LinkBlue} from '../../styles/colors';
4+
import {SubText} from '../styled/Text';
5+
6+
const Container = styled.View`
7+
border: 1px solid ${LinkBlue};
8+
border-radius: 30px;
9+
padding: 15px;
10+
margin: 15px 15px 20px 15px;
11+
`;
12+
13+
const ArchaxFooter = () => {
14+
return (
15+
<Container>
16+
<SubText style={{textAlign: 'center'}}>
17+
This Financial Promotion has been approved by Archax LTD on November 28,
18+
2024.
19+
</SubText>
20+
</Container>
21+
);
22+
};
23+
24+
export default ArchaxFooter;

src/components/icons/currency-symbol/CurrencySymbol.tsx

+18-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,23 @@ import React from 'react';
22
import {useTheme} from 'styled-components/native';
33
import {Path, Svg, G} from 'react-native-svg';
44
import {NotificationPrimary, White} from '../../../styles/colors';
5+
import useAppSelector from '../../../utils/hooks/useAppSelector';
6+
import {PixelRatio} from 'react-native';
7+
import {PIXEL_DENSITY_LIMIT} from '../../virtual-keyboard/VirtualKeyboard';
58

69
interface CurrencySymbolProps {
710
isDark: boolean;
11+
isSmallScreen?: boolean;
812
}
913

10-
const CurrencySymbolSvg: React.FC<CurrencySymbolProps> = ({isDark}) => {
14+
const CurrencySymbolSvg: React.FC<CurrencySymbolProps> = ({
15+
isDark,
16+
isSmallScreen,
17+
}) => {
18+
const width = isSmallScreen ? 12 : 20;
19+
const height = isSmallScreen ? 12 : 20;
1120
return (
12-
<Svg width="20" height="20" viewBox="0 0 20 20" fill="none">
21+
<Svg width={width} height={height} viewBox="0 0 20 20" fill="none">
1322
<G opacity="0.5">
1423
<Path
1524
fill-rule="evenodd"
@@ -23,8 +32,14 @@ const CurrencySymbolSvg: React.FC<CurrencySymbolProps> = ({isDark}) => {
2332
};
2433
const CurrencySymbol = () => {
2534
const theme = useTheme();
35+
const showArchaxBanner = useAppSelector(({APP}) => APP.showArchaxBanner);
36+
const _isSmallScreen = showArchaxBanner
37+
? true
38+
: PixelRatio.get() < PIXEL_DENSITY_LIMIT;
2639

27-
return <CurrencySymbolSvg isDark={theme.dark} />;
40+
return (
41+
<CurrencySymbolSvg isDark={theme.dark} isSmallScreen={_isSmallScreen} />
42+
);
2843
};
2944

3045
export default CurrencySymbol;

src/components/styled/Containers.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
import {BaseText} from './Text';
1717
import {TouchableOpacity} from '@components/base/TouchableOpacity';
1818
export {ActiveOpacity} from '@components/base/TouchableOpacity';
19+
import {useSafeAreaInsets} from 'react-native-safe-area-context';
1920

2021
export const {height: HEIGHT, width: WIDTH} = Dimensions.get('window');
2122
export const isNotMobile = HEIGHT / WIDTH < 1.6;
@@ -115,7 +116,9 @@ export const RowContainer = styled(TouchableOpacity)<RowContainerProps>`
115116
isLast || noBorder ? 0 : 1}px;
116117
`;
117118

118-
export const RowContainerWithoutBorders = styled(TouchableOpacity)<RowContainerProps>`
119+
export const RowContainerWithoutBorders = styled(
120+
TouchableOpacity,
121+
)<RowContainerProps>`
119122
flex-direction: row;
120123
align-items: center;
121124
padding: 10px 0px;
@@ -533,3 +536,9 @@ export const CloseButtonContainer = styled(TouchableOpacity)`
533536
justify-content: center;
534537
align-items: center;
535538
`;
539+
540+
export const ArchaxBannerContainer = styled.View<{inset: any}>`
541+
background: ${({theme}) => (theme.dark ? '#a25718' : '#ffedc9')};
542+
overflow: hidden;
543+
padding: 20px;
544+
`;

src/components/styled/Text.tsx

+10
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,13 @@ export const CopyToClipboardText = styled(BaseText)`
258258
color: ${({theme: {dark}}) => (dark ? NeutralSlate : '#6F7782')};
259259
padding: 0 20px 0 10px;
260260
`;
261+
262+
export const ArchaxBannerText = styled(H7)`
263+
color: ${({theme}) => theme.colors.text};
264+
`;
265+
266+
export const ArchaxBannerLink = styled(BaseText)`
267+
color: ${({theme}) => theme.colors.link};
268+
text-decoration: underline;
269+
text-decoration-color: ${({theme}) => theme.colors.link};
270+
`;

src/components/swap-button/SwapButton.tsx

+17-6
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,24 @@ import {LightBlack, NotificationPrimary, White} from '../../styles/colors';
55
import haptic from '../haptic-feedback/haptic';
66
import SwapHorizontal from '../icons/swap-horizontal/SwapHorizontal';
77
import {TouchableOpacity} from '@components/base/TouchableOpacity';
8+
import useAppSelector from '../../utils/hooks/useAppSelector';
9+
import {PixelRatio} from 'react-native';
10+
import {PIXEL_DENSITY_LIMIT} from '../virtual-keyboard/VirtualKeyboard';
811

9-
export const SwapButtonContainer = styled(TouchableOpacity)`
12+
export const SwapButtonContainer = styled(TouchableOpacity)<{
13+
isSmallScreen?: boolean;
14+
}>`
1015
flex-direction: row;
1116
align-items: center;
1217
background-color: ${({theme: {dark}}) => (dark ? LightBlack : '#edf1fe')};
13-
height: 39px;
18+
height: ${({isSmallScreen}) => (isSmallScreen ? 30 : 39)}px;
1419
padding: 0 15px;
1520
border-radius: 19.09px;
1621
`;
1722

18-
export const ButtonText = styled(BaseText)`
23+
export const ButtonText = styled(BaseText)<{isSmallScreen?: boolean}>`
1924
margin-left: 10px;
20-
font-size: 18px;
25+
font-size: ${({isSmallScreen}) => (isSmallScreen ? 12 : 18)}px;
2126
font-weight: 500;
2227
color: ${({theme: {dark}}) => (dark ? White : NotificationPrimary)};
2328
`;
@@ -30,6 +35,10 @@ export interface SwapButtonProps {
3035
const SwapButton = ({swapList, onChange}: SwapButtonProps) => {
3136
const initText = swapList[0];
3237
const [text, setText] = useState(initText);
38+
const showArchaxBanner = useAppSelector(({APP}) => APP.showArchaxBanner);
39+
const _isSmallScreen = showArchaxBanner
40+
? true
41+
: PixelRatio.get() < PIXEL_DENSITY_LIMIT;
3342

3443
const swapText = (val: string) => {
3544
if (swapList.length === 1) {
@@ -42,9 +51,11 @@ const SwapButton = ({swapList, onChange}: SwapButtonProps) => {
4251
};
4352

4453
return (
45-
<SwapButtonContainer onPress={() => swapText(text)}>
54+
<SwapButtonContainer
55+
isSmallScreen={_isSmallScreen}
56+
onPress={() => swapText(text)}>
4657
<SwapHorizontal />
47-
<ButtonText>{text}</ButtonText>
58+
<ButtonText isSmallScreen={_isSmallScreen}>{text}</ButtonText>
4859
</SwapButtonContainer>
4960
);
5061
};

0 commit comments

Comments
 (0)