Skip to content

Commit

Permalink
Add Initial Token Selector with dummy tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
wachunei committed Nov 16, 2020
1 parent 8644be0 commit 707b491
Show file tree
Hide file tree
Showing 12 changed files with 674 additions and 129 deletions.
10 changes: 6 additions & 4 deletions app/components/Base/ListItem.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, View } from 'react-native';
import Device from '../../util/Device';
// import Device from '../../util/Device';
import { colors, fontStyles } from '../../styles/common';
import Text from './Text';

const styles = StyleSheet.create({
wrapper: {
padding: 15,
minHeight: Device.isIos() ? 95 : 100
padding: 15
// TODO(wachunei): check if this can be removed without breaking anything
// minHeight: Device.isIos() ? 55 : 100
},
date: {
color: colors.fontSecondary,
Expand All @@ -17,7 +18,8 @@ const styles = StyleSheet.create({
...fontStyles.normal
},
content: {
flexDirection: 'row'
flexDirection: 'row',
alignItems: 'center'
},
actions: {
flexDirection: 'row',
Expand Down
32 changes: 32 additions & 0 deletions app/components/Base/ModalDragger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { colors } from '../../styles/common';
import Device from '../../util/Device';

const styles = StyleSheet.create({
draggerWrapper: {
width: '100%',
height: 33,
alignItems: 'center',
justifyContent: 'center',
borderBottomWidth: StyleSheet.hairlineWidth,
borderColor: colors.grey100
},
dragger: {
width: 48,
height: 5,
borderRadius: 4,
backgroundColor: colors.grey400,
opacity: Device.isAndroid() ? 0.6 : 0.5
}
});

function ModalDragger() {
return (
<View style={styles.draggerWrapper}>
<View style={styles.dragger} />
</View>
);
}

export default ModalDragger;
8 changes: 2 additions & 6 deletions app/components/Base/ModalHandler.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { useState } from 'react';
import useModalHandler from './hooks/useModalHandler';

function ModalHandler({ children }) {
const [isVisible, setVisible] = useState(false);

const showModal = () => setVisible(true);
const hideModal = () => setVisible(true);
const toggleModal = () => setVisible(!isVisible);
const [isVisible, toggleModal, showModal, hideModal] = useModalHandler(false);

if (typeof children === 'function') {
return children({ isVisible, toggleModal, showModal, hideModal });
Expand Down
11 changes: 11 additions & 0 deletions app/components/Base/hooks/useModalHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useState } from 'react';
function useModalHandler(initialState = false) {
const [isVisible, setVisible] = useState(initialState);

const showModal = () => setVisible(true);
const hideModal = () => setVisible(true);
const toggleModal = () => setVisible(!isVisible);

return [isVisible, toggleModal, showModal, hideModal];
}
export default useModalHandler;
20 changes: 2 additions & 18 deletions app/components/UI/ReceiveRequest/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { protectWalletModalVisible } from '../../../actions/user';
import { colors, fontStyles } from '../../../styles/common';
import Text from '../../Base/Text';
import ModalHandler from '../../Base/ModalHandler';
import ModalDragger from '../../Base/ModalDragger';
import AddressQRCode from '../../Views/AddressQRCode';
import EthereumAddress from '../EthereumAddress';
import GlobalAlert from '../GlobalAlert';
Expand All @@ -33,21 +34,6 @@ const styles = StyleSheet.create({
borderTopLeftRadius: 10,
borderTopRightRadius: 10
},
draggerWrapper: {
width: '100%',
height: 33,
alignItems: 'center',
justifyContent: 'center',
borderBottomWidth: StyleSheet.hairlineWidth,
borderColor: colors.grey100
},
dragger: {
width: 48,
height: 5,
borderRadius: 4,
backgroundColor: colors.grey400,
opacity: Device.isAndroid() ? 0.6 : 0.5
},
body: {
alignItems: 'center',
paddingHorizontal: 15
Expand Down Expand Up @@ -222,9 +208,7 @@ class ReceiveRequest extends PureComponent {
render() {
return (
<SafeAreaView style={styles.wrapper}>
<View style={styles.draggerWrapper}>
<View style={styles.dragger} />
</View>
<ModalDragger />
<View style={styles.titleWrapper}>
<Text style={styles.title} testID={'receive-request-screen'}>
{strings('receive_request.title')}
Expand Down
78 changes: 78 additions & 0 deletions app/components/UI/Swaps/components/TokenIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, View } from 'react-native';

import RemoteImage from '../../../Base/RemoteImage';
import Text from '../../../Base/Text';
import { colors } from '../../../../styles/common';

// eslint-disable-next-line import/no-commonjs
const ethLogo = require('../../../../images/eth-logo.png');

const styles = StyleSheet.create({
icon: {
width: 24,
height: 24
},
iconMedium: {
width: 36,
height: 36
},
emptyIcon: {
borderRadius: 12,
backgroundColor: colors.grey200,
alignItems: 'center',
justifyContent: 'center'
},
emptyIconMedium: {
borderRadius: 18
},
tokenSymbol: {
fontSize: 16,
textAlign: 'center',
textAlignVertical: 'center'
},
tokenSymbolMedium: {
fontSize: 22
}
});

const EmptyIcon = ({ medium, ...props }) => (
<View
style={[
styles.icon,
props.medium && styles.iconMedium,
styles.emptyIcon,
props.medium && styles.emptyIconMedium
]}
{...props}
/>
);

EmptyIcon.propTypes = {
medium: PropTypes.bool
};

function TokenIcon({ symbol, icon, medium }) {
if (symbol === 'ETH') {
return <RemoteImage fadeIn source={ethLogo} style={[styles.icon, medium && styles.iconMedium]} />;
} else if (icon) {
return <RemoteImage fadeIn source={{ uri: icon }} style={[styles.icon, medium && styles.iconMedium]} />;
} else if (symbol) {
return (
<EmptyIcon medium={medium}>
<Text style={[styles.tokenSymbol, medium && styles.tokenSymbolMedium]}>{symbol[0].toUpperCase()}</Text>
</EmptyIcon>
);
}

return <EmptyIcon medium={medium} />;
}

TokenIcon.propTypes = {
symbol: PropTypes.string,
icon: PropTypes.string,
medium: PropTypes.bool
};

export default TokenIcon;
35 changes: 35 additions & 0 deletions app/components/UI/Swaps/components/TokenIcon.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { shallow } from 'enzyme';
import TokenIcon from './TokenIcon';

describe('TokenIcon component', () => {
it('should Render correctly', () => {
const empty = shallow(<TokenIcon />);
expect(empty).toMatchSnapshot();
const eth = shallow(<TokenIcon symbol="ETH" />);
expect(eth).toMatchSnapshot();
const symbol = shallow(<TokenIcon symbol="cDAI" />);
expect(symbol).toMatchSnapshot();
const icon = shallow(
<TokenIcon
symbol="DAI"
icon="https://cloudflare-ipfs.com/ipfs/QmNYVMm3iC7HEoxfvxsZbRoapdjDHj9EREFac4BPeVphSJ"
/>
);
expect(icon).toMatchSnapshot();
const emptyMedium = shallow(<TokenIcon medium />);
expect(emptyMedium).toMatchSnapshot();
const ethMedium = shallow(<TokenIcon medium symbol="ETH" />);
expect(ethMedium).toMatchSnapshot();
const symbolMedium = shallow(<TokenIcon medium symbol="cDAI" />);
expect(symbolMedium).toMatchSnapshot();
const iconMedium = shallow(
<TokenIcon
medium
symbol="DAI"
icon="https://cloudflare-ipfs.com/ipfs/QmNYVMm3iC7HEoxfvxsZbRoapdjDHj9EREFac4BPeVphSJ"
/>
);
expect(iconMedium).toMatchSnapshot();
});
});
44 changes: 7 additions & 37 deletions app/components/UI/Swaps/components/TokenSelectButton.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useMemo } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { View, StyleSheet, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { colors } from '../../../../styles/common';
import RemoteImage from '../../../Base/RemoteImage';

import Text from '../../../Base/Text';
import TokenIcon from './TokenIcon';

const styles = StyleSheet.create({
container: {
Expand All @@ -17,20 +18,7 @@ const styles = StyleSheet.create({
justifyContent: 'center'
},
icon: {
marginRight: 8,
width: 24,
height: 24
},
emptyIcon: {
borderRadius: 12,
backgroundColor: colors.grey200,
alignItems: 'center',
justifyContent: 'center'
},
tokenSymbol: {
fontSize: 16,
textAlign: 'center',
textAlignVertical: 'center'
marginRight: 8
},
caretDown: {
textAlign: 'right',
Expand All @@ -40,31 +28,13 @@ const styles = StyleSheet.create({
}
});

// eslint-disable-next-line import/no-commonjs
const ethLogo = require('../../../../images/eth-logo.png');

const EmptyIcon = props => <View style={[styles.icon, styles.emptyIcon]} {...props} />;

function TokenSelectButton({ icon, symbol, onPress, disabled }) {
const renderIcon = useMemo(() => {
if (symbol === 'ETH') {
return <RemoteImage fadeIn source={ethLogo} style={styles.icon} />;
} else if (symbol && icon) {
return <RemoteImage fadeIn source={{ uri: icon }} style={styles.icon} />;
} else if (symbol) {
return (
<EmptyIcon>
<Text style={styles.tokenSymbol}>{symbol[0].toUpperCase()}</Text>
</EmptyIcon>
);
}

return <EmptyIcon />;
}, [symbol, icon]);
return (
<TouchableOpacity onPress={onPress} disabled={disabled}>
<View style={styles.container}>
{renderIcon}
<View style={styles.icon}>
<TokenIcon icon={icon} symbol={symbol} />
</View>
<Text primary>{symbol || 'Select a token'}</Text>
<Icon name="caret-down" size={18} style={styles.caretDown} />
</View>
Expand Down
Loading

0 comments on commit 707b491

Please sign in to comment.