Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:rainbow-me/rainbow into brody/de…
Browse files Browse the repository at this point in the history
…eplink-add

* 'develop' of github.com:rainbow-me/rainbow:
  Cover a few more edge cases with showing the swap warnings (#5648)
  refetch quote if a user selects a new assset to sell with a buy asset already selected (#5643)
  Fix random quote edge cases (#5644)
  use dapp metadata where possible (#5629)
  Output chain selection context menu (#5630)
  chore: use native currency balances (#5631)
  browser: android fixes (#5642)
  Review Sheet (#5632)
  • Loading branch information
BrodyHughes committed Apr 22, 2024
2 parents 304fc80 + f009a9d commit a1becb3
Show file tree
Hide file tree
Showing 49 changed files with 1,497 additions and 537 deletions.
12 changes: 8 additions & 4 deletions src/__swaps__/screens/Swap/Swap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import { navbarHeight } from '@/components/navbar/Navbar';
import { Box } from '@/design-system';
import { safeAreaInsetValues } from '@/utils';

import { SheetGestureBlocker } from '@/__swaps__/screens/Swap/components/SheetGestureBlocker';
import { SwapSheetGestureBlocker } from '@/__swaps__/screens/Swap/components/SwapSheetGestureBlocker';
import { SwapBackground } from '@/__swaps__/screens/Swap/components/SwapBackground';
import { FlipButton } from '@/__swaps__/screens/Swap/components/FlipButton';
import { ExchangeRateBubble } from '@/__swaps__/screens/Swap/components/ExchangeRateBubble';
import { SwapInputAsset } from '@/__swaps__/screens/Swap/components/controls/SwapInputAsset';
import { SwapOutputAsset } from '@/__swaps__/screens/Swap/components/controls/SwapOutputAsset';
import { SwapNavbar } from '@/__swaps__/screens/Swap/components/SwapNavbar';
import { SwapAmountInputs } from '@/__swaps__/screens/Swap/components/controls/SwapAmountInputs';
import { SwapActions } from '@/__swaps__/screens/Swap/components/controls/SwapActions';
import { SwapWarning } from './components/SwapWarning';

/** README
Expand Down Expand Up @@ -57,23 +58,26 @@ import { SwapWarning } from './components/SwapWarning';

export function SwapScreen() {
return (
<SheetGestureBlocker>
<SwapSheetGestureBlocker>
<Box as={Page} style={styles.rootViewBackground} testID="swap-screen" width="full">
<SwapBackground />
<Box alignItems="center" height="full" paddingTop={{ custom: safeAreaInsetValues.top + (navbarHeight - 12) + 29 }} width="full">
<SwapInputAsset />
<FlipButton />
<SwapOutputAsset />
<Box width="full" position="absolute" bottom="0px">
<SwapAmountInputs />
<SwapActions />
</Box>
<Box alignItems="center" justifyContent="center" style={{ position: 'relative' }}>
<ExchangeRateBubble />
<SwapWarning />
</Box>

<SwapAmountInputs />
</Box>
<SwapNavbar />
</Box>
</SheetGestureBlocker>
</SwapSheetGestureBlocker>
);
}

Expand Down
90 changes: 90 additions & 0 deletions src/__swaps__/screens/Swap/components/AnimatedSwitch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';

import { AnimatedText, Box, Inline, globalColors, useColorMode, useForegroundColor } from '@/design-system';
import Animated, { DerivedValue, useAnimatedStyle, useDerivedValue, withSpring, withTiming } from 'react-native-reanimated';
import { fadeConfig, springConfig } from '../constants';
import { opacityWorklet } from '@/__swaps__/utils/swaps';
import { GestureHandlerButtonProps, GestureHandlerV1Button } from './GestureHandlerV1Button';
import { StyleSheet } from 'react-native';

type AnimatedSwitchProps = {
onToggle: () => void;
value: DerivedValue<boolean>;
activeLabel?: string;
inactiveLabel?: string;
} & Omit<GestureHandlerButtonProps, 'children'>;

export function AnimatedSwitch({ value, onToggle, activeLabel, inactiveLabel, ...props }: AnimatedSwitchProps) {
const { isDarkMode } = useColorMode();

const inactiveBg = useForegroundColor('fillSecondary');
const activeBg = useForegroundColor('green');
const border = useForegroundColor('separatorSecondary');

const containerStyles = useAnimatedStyle(() => {
return {
backgroundColor: !value.value
? withTiming(opacityWorklet(inactiveBg, 0.12), fadeConfig)
: withTiming(opacityWorklet(activeBg, 0.64), fadeConfig),
borderColor: opacityWorklet(border, 0.06),
};
});

const circleStyles = useAnimatedStyle(() => {
return {
transform: [
{
translateX: withSpring(value.value ? 11 : 1, springConfig),
},
],
};
});

const labelItem = useDerivedValue(() => {
if (!activeLabel && !inactiveLabel) {
return;
}

if (value.value) {
return activeLabel;
}

return inactiveLabel;
});

if (labelItem.value) {
return (
<Inline alignVertical="center" horizontalSpace="6px">
<AnimatedText align="right" color={isDarkMode ? 'labelSecondary' : 'label'} size="15pt" weight="heavy" text={labelItem} />
{/* TODO: Small switch, so let's move this out to be the whole row */}
<GestureHandlerV1Button onPressWorklet={onToggle} style={[styles.containerStyles, containerStyles]} {...props}>
<Box style={[styles.circleStyles, circleStyles]} as={Animated.View} />
</GestureHandlerV1Button>
</Inline>
);
}

return (
<GestureHandlerV1Button onPressWorklet={onToggle} style={[styles.containerStyles, containerStyles]} {...props}>
<Box style={[styles.circleStyles, circleStyles]} as={Animated.View} />
</GestureHandlerV1Button>
);
}

const styles = StyleSheet.create({
containerStyles: {
position: 'relative',
borderWidth: 1,
borderRadius: 100,
width: 26,
height: 16,
},
circleStyles: {
top: 1,
backgroundColor: globalColors.white100,
borderRadius: 100,
width: 12,
height: 12,
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export const ExchangeRateBubble = () => {
});

return (
<ButtonPressAnimation onPress={() => setExchangeRateIndex((exchangeRateIndex + 1) % 4)} scaleTo={0.925} style={{ marginTop: 4 }}>
<ButtonPressAnimation onPress={() => setExchangeRateIndex((exchangeRateIndex + 1) % 4)} scaleTo={0.925}>
<Box
as={Animated.View}
alignItems="center"
Expand Down
80 changes: 76 additions & 4 deletions src/__swaps__/screens/Swap/components/GasButton.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useMemo, useState, useCallback, useRef, useEffect, ReactNode } from 'react';
import { InteractionManager } from 'react-native';
import { ButtonPressAnimation } from '@/components/animations';
import { AnimatedText, Inline, Stack, Text, TextIcon } from '@/design-system';
import { AnimatedText, Box, Inline, Stack, Text, TextIcon, useColorMode, useForegroundColor } from '@/design-system';
import { useGasStore } from '@/state/gas/gasStore';
import { Centered } from '@/components/layout';
import { useTheme } from '@/theme';
Expand All @@ -18,21 +18,27 @@ import { ethereumUtils, gasUtils } from '@/utils';
import styled from '@/styled-thing';
import { useMeteorology } from '@/__swaps__/utils/meteorology';
import { parseGasFeeParamsBySpeed } from '@/__swaps__/utils/gasUtils';
import { useDerivedValue } from 'react-native-reanimated';
import Animated, { useAnimatedStyle, useDerivedValue } from 'react-native-reanimated';
import { ParsedAddressAsset } from '@/entities';
import { GasFeeLegacyParamsBySpeed, GasFeeParamsBySpeed, GasSpeed } from '@/__swaps__/types/gas';
import { ParsedAsset } from '@/__swaps__/types/assets';
import { ETH_COLOR, ETH_COLOR_DARK, THICK_BORDER_WIDTH } from '../constants';

const { GasSpeedOrder, CUSTOM, GAS_ICONS, GAS_EMOJIS, getGasLabel, getGasFallback } = gasUtils;
const mockedGasLimit = '21000';

export const GasButton = ({ accentColor }: { accentColor?: string }) => {
export const GasButton = ({ accentColor, isReviewing = false }: { accentColor?: string; isReviewing?: boolean }) => {
const { isDarkMode } = useColorMode();
const { params } = useRoute();
const { currentNetwork } = (params as any) || {};
const chainId = getNetworkObj(currentNetwork).id;
const { selectedGas } = useGasStore();
const { data, isLoading } = useMeteorology({ chainId });
const [nativeAsset, setNativeAsset] = useState<ParsedAddressAsset | undefined>();
const { nativeCurrency } = useAccountSettings();

const separatatorSecondary = useForegroundColor('separatorSecondary');

useEffect(() => {
const getNativeAsset = async () => {
const theNativeAsset = await ethereumUtils.getNativeAssetForNetwork(currentNetwork);
Expand All @@ -41,7 +47,7 @@ export const GasButton = ({ accentColor }: { accentColor?: string }) => {
getNativeAsset();
}, [currentNetwork, setNativeAsset]);

let gasFeeBySpeed: GasFeeParamsBySpeed | GasFeeLegacyParamsBySpeed | any = useMemo(() => {
const gasFeeBySpeed: GasFeeParamsBySpeed | GasFeeLegacyParamsBySpeed | any = useMemo(() => {
if (!isLoading) {
return parseGasFeeParamsBySpeed({
chainId,
Expand All @@ -55,10 +61,76 @@ export const GasButton = ({ accentColor }: { accentColor?: string }) => {
}, [isLoading, nativeAsset]);
const gasFallback = getGasFallback(nativeCurrency);
const [showGasOptions, setShowGasOptions] = useState(false);
// TODO: Move this navigation state inside of SwapNavigation
const [showCustomGasSheet, setShowCustomGasSheet] = useState(false);
const animatedGas = useDerivedValue(() => {
return gasFeeBySpeed[selectedGas?.option]?.gasFee?.display ?? gasFallback;
}, [gasFeeBySpeed, selectedGas]);

const buttonWrapperStyles = useAnimatedStyle(() => {
return {
display: 'flex',
flexDirection: 'row',
backgroundColor: 'transparent',
borderWidth: 2,
borderColor: isDarkMode ? ETH_COLOR_DARK : ETH_COLOR,
borderRadius: 15,
paddingHorizontal: 10,
paddingVertical: 6,
gap: 5,
alignItems: 'center',
justifyContent: 'center',
};
});

if (isReviewing) {
return (
<Inline alignVertical="center" wrap={false}>
<GasMenu gasFeeBySpeed={gasFeeBySpeed} flashbotTransaction={false}>
<ButtonPressAnimation onPress={() => setShowGasOptions(!showGasOptions)}>
<Box as={Animated.View} style={buttonWrapperStyles}>
<Inline alignVertical="center" space="4px">
<TextIcon
color={accentColor ? { custom: accentColor } : 'red'}
height={10}
size="icon 12px"
textStyle={{ marginTop: -1.5 }}
width={16}
weight="bold"
>
􀙭
</TextIcon>
<Text color="label" size="15pt" weight="heavy">
{getGasLabel(selectedGas?.option || GasSpeed.FAST)}
</Text>
</Inline>
<TextIcon color="labelSecondary" height={10} size="icon 13px" weight="bold" width={12}>
􀆏
</TextIcon>
</Box>
</ButtonPressAnimation>
</GasMenu>

<ButtonPressAnimation onPress={() => setShowCustomGasSheet(prev => !prev)}>
<Box
style={{
paddingHorizontal: 7,
paddingVertical: 6,
gap: 10,
borderRadius: 15,
borderWidth: THICK_BORDER_WIDTH,
borderColor: separatatorSecondary,
}}
>
<Text weight="heavy" size="15pt" color="label">
􀌆
</Text>
</Box>
</ButtonPressAnimation>
</Inline>
);
}

return (
<ButtonPressAnimation onPress={() => setShowGasOptions(!showGasOptions)}>
<GasMenu gasFeeBySpeed={gasFeeBySpeed} flashbotTransaction={false}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Animated, { runOnJS, useAnimatedGestureHandler } from 'react-native-reani
import { ButtonPressAnimation } from '@/components/animations';
import { IS_IOS } from '@/env';

type GestureHandlerButtonProps = {
export type GestureHandlerButtonProps = {
children: React.ReactNode;
disableButtonPressWrapper?: boolean;
disabled?: boolean;
Expand Down
Loading

0 comments on commit a1becb3

Please sign in to comment.