Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Browser Dapp Showcase #423

Merged
merged 22 commits into from
Feb 21, 2019
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`BrowserFavorites should render correctly 1`] = `
<ContextConsumer>
<Component />
</ContextConsumer>
`;
153 changes: 153 additions & 0 deletions app/components/UI/BrowserFavorites/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withNavigation } from 'react-navigation';
import PropTypes from 'prop-types';
import { strings } from '../../../../locales/i18n';
import { TouchableOpacity, Text, StyleSheet, View, FlatList } from 'react-native';
import WebsiteIcon from '../WebsiteIcon';
import { colors, fontStyles } from '../../../styles/common';
import ActionSheet from 'react-native-actionsheet';
import { removeBookmark } from '../../../actions/bookmarks';

const styles = StyleSheet.create({
bookmarksWrapper: {
flex: 1
},
bookmarkItem: {
paddingTop: 20,
paddingHorizontal: 18
},
bookmarksItemsWrapper: {
flex: 1
},

bookmarkTouchable: {
flexDirection: 'row',
alignItems: 'center'
},
bookmarkUrl: {
flex: 1,
...fontStyles.normal
},
bookmarkIco: {
width: 26,
height: 26,
marginRight: 7,
borderRadius: 13
},
noBookmarks: {
color: colors.fontSecondary,
...fontStyles.normal
},
fallbackTextStyle: {
fontSize: 12
},
wrapper: {
flex: 1
}
});

/**
* Browser favorite sites
*/
class BrowserFavorites extends Component {
static propTypes = {
/**
* Array containing all the bookmark items
*/
bookmarks: PropTypes.array,
/**
* Function to be called when tapping on a bookmark item
*/
goTo: PropTypes.any,
/**
* function that removes a bookmark
*/
removeBookmark: PropTypes.func
};

actionSheet = null;

keyExtractor = item => item.url;

bookmarkUrlToRemove = null;

showRemoveMenu = url => {
this.bookmarkUrlToRemove = url;
this.actionSheet.show();
};

removeBookmark = () => {
const bookmark = this.props.bookmarks.find(bookmark => bookmark.url === this.bookmarkUrlToRemove);
this.props.removeBookmark(bookmark);
};

createActionSheetRef = ref => {
this.actionSheet = ref;
};

renderItem = ({ item }) => {
const { url, name } = item;
return (
<View key={item.url} style={styles.bookmarkItem}>
<TouchableOpacity
style={styles.bookmarkTouchable}
onPress={() => this.props.goTo(url)} // eslint-disable-line react/jsx-no-bind
// eslint-disable-next-line react/jsx-no-bind
onLongPress={() => this.showRemoveMenu(url)}
>
<WebsiteIcon
style={styles.bookmarkIco}
url={url}
title={name}
textStyle={styles.fallbackTextStyle}
/>
<Text numberOfLines={1} style={styles.bookmarkUrl}>
{name}
</Text>
</TouchableOpacity>
</View>
);
};

renderBookmarks() {
const { bookmarks } = this.props;
let content = null;
if (bookmarks.length) {
content = <FlatList data={bookmarks} keyExtractor={this.keyExtractor} renderItem={this.renderItem} />;
} else {
content = <Text style={styles.noBookmarks}>{strings('home_page.no_bookmarks')}</Text>;
}
return (
<View style={styles.bookmarksWrapper}>
<View style={styles.bookmarksItemsWrapper}>{content}</View>
<ActionSheet
ref={this.createActionSheetRef}
title={strings('home_page.remove_bookmark_title')}
options={['Remove', 'Cancel']}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to locales

cancelButtonIndex={1}
destructiveButtonIndex={0}
// eslint-disable-next-line react/jsx-no-bind
onPress={index => (index === 0 ? this.removeBookmark() : null)}
/>
</View>
);
}

render() {
return <View style={styles.wrapper}>{this.renderBookmarks()}</View>;
}
}

const mapStateToProps = state => ({
bookmarks: state.bookmarks
});

const mapDispatchToProps = dispatch => ({
removeBookmark: bookmark => dispatch(removeBookmark(bookmark))
});

export default connect(
mapStateToProps,
mapDispatchToProps
)(withNavigation(BrowserFavorites));
19 changes: 19 additions & 0 deletions app/components/UI/BrowserFavorites/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { shallow } from 'enzyme';
import BrowserFavorites from './';
import configureMockStore from 'redux-mock-store';

const mockStore = configureMockStore();

describe('BrowserFavorites', () => {
it('should render correctly', () => {
const initialState = {
bookmarks: [{ url: 'url', name: 'name' }]
};

const wrapper = shallow(<BrowserFavorites />, {
context: { store: mockStore(initialState) }
});
expect(wrapper.dive()).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FeaturedItem should render correctly 1`] = `
<ContextConsumer>
<Component />
</ContextConsumer>
`;
80 changes: 80 additions & 0 deletions app/components/UI/BrowserFeatured/FeaturedItem/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Text, StyleSheet, View } from 'react-native';
import WebsiteIcon from '../../WebsiteIcon';
import { colors, fontStyles } from '../../../../styles/common';

const styles = StyleSheet.create({
wrapper: {
padding: 15,
flex: 1,
flexDirection: 'row'
},
icon: {
height: 35,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this icons are bigger, I'd refactor the websiteIcon component to receive a prop size, and use it to build the url of faviconkit so they don't get scaled on high res screens

Should look something like this:
<WebsiteIcon url={'https://metamask.io'} size={PixelRatio.getPixelSizeForLayoutSize(35)} />

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice! didn't know this

width: 35
},
iconWrapper: {
borderRadius: 8,
height: 88,
width: 88,
backgroundColor: colors.white,
alignItems: 'center',
justifyContent: 'center',
shadowOpacity: 0.25,
shadowOffset: {
width: 0,
height: 0
}
},
contentWrapper: {
flex: 1,
paddingHorizontal: 18
},
name: {
fontSize: 16,
marginBottom: 7,
...fontStyles.bold
},
description: {
fontSize: 14,
...fontStyles.normal
}
});

/**
* Featured item to be rendered
*/
export default class FeaturedItem extends Component {
static propTypes = {
/**
* Dapp description
*/
description: PropTypes.string,
/**
* Dapp name
*/
name: PropTypes.string,
/**
* Dapp url
*/
url: PropTypes.string
};

render() {
const { name, url, description } = this.props;
return (
<View style={styles.wrapper}>
<View style={styles.iconWrapper}>
<WebsiteIcon style={styles.icon} title={name} url={url} />
</View>
<View style={styles.contentWrapper}>
<Text style={styles.name}>{name}</Text>
<Text style={styles.description} numberOfLines={3}>
{description}
</Text>
</View>
</View>
);
}
}
16 changes: 16 additions & 0 deletions app/components/UI/BrowserFeatured/FeaturedItem/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { shallow } from 'enzyme';
import FeaturedItem from './';
import configureMockStore from 'redux-mock-store';

const mockStore = configureMockStore();

describe('FeaturedItem', () => {
it('should render correctly', () => {
const initialState = {};
const wrapper = shallow(<FeaturedItem name={'name'} url={'url'} description={'description'} />, {
context: { store: mockStore(initialState) }
});
expect(wrapper.dive()).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`BrowserFeatured should render correctly 1`] = `
<ContextConsumer>
<Component />
</ContextConsumer>
`;
44 changes: 44 additions & 0 deletions app/components/UI/BrowserFeatured/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { Component } from 'react';
import dappList from '../../../util/featured-dapp-list';
import FeaturedItem from './FeaturedItem';
import PropTypes from 'prop-types';
import { TouchableOpacity, FlatList, StyleSheet, View } from 'react-native';

const styles = StyleSheet.create({
wrapper: {
flex: 1
}
});

/**
* Browser features dapps
*/
export default class BrowserFeatured extends Component {
static propTypes = {
/*
* Function to be called when tapping on a favorite item
*/
goTo: PropTypes.any
};

keyExtractor = item => item.name;

renderItem = ({ item }) => {
const { name, description, url } = item;
return (
<TouchableOpacity
key={url}
onPress={() => this.props.goTo(url)} // eslint-disable-line react/jsx-no-bind
>
<FeaturedItem name={name} url={url} description={description} />
</TouchableOpacity>
);
};
render() {
return (
<View style={styles.wrapper}>
<FlatList data={dappList} keyExtractor={this.keyExtractor} renderItem={this.renderItem} />
</View>
);
}
}
16 changes: 16 additions & 0 deletions app/components/UI/BrowserFeatured/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { shallow } from 'enzyme';
import BrowserFeatured from './';
import configureMockStore from 'redux-mock-store';

const mockStore = configureMockStore();

describe('BrowserFeatured', () => {
it('should render correctly', () => {
const initialState = {};
const wrapper = shallow(<BrowserFeatured />, {
context: { store: mockStore(initialState) }
});
expect(wrapper.dive()).toMatchSnapshot();
});
});
Loading