diff --git a/client/react-native/common/components/App.js b/client/react-native/common/components/App.js index 51bdec7eda..17919ee6f9 100644 --- a/client/react-native/common/components/App.js +++ b/client/react-native/common/components/App.js @@ -5,6 +5,7 @@ import React, { PureComponent } from 'react' import { parse as parseUrl } from '../helpers/url' import LottieView from 'lottie-react-native' import { Flex } from './Library' +import FlashMessage from 'react-native-flash-message' import Accounts from './Screens/Accounts' import { colors } from './../constants' @@ -106,6 +107,15 @@ export default class App extends PureComponent { deepLink, }} /> : null } + { + this.navigation = nav + }} + screenProps={{ + deepLink, + }} + /> + {Platform.OS === 'ios' && } ) diff --git a/client/react-native/common/components/App.web.js b/client/react-native/common/components/App.web.js index 6d8f3a6fe0..a4a3e6e51d 100644 --- a/client/react-native/common/components/App.web.js +++ b/client/react-native/common/components/App.web.js @@ -1,8 +1,9 @@ -import { Linking, Platform } from 'react-native' +import { Linking } from 'react-native' import { SafeAreaView } from 'react-navigation' import KeyboardSpacer from 'react-native-keyboard-spacer' import React, { PureComponent } from 'react' import { parse as parseUrl } from '../helpers/url' +import FlashMessage from 'react-native-flash-message' import { Loader } from './Library' import Accounts from './Screens/Accounts' @@ -75,7 +76,8 @@ export default class App extends PureComponent { deepLink, }} /> - {Platform.OS === 'ios' && } + + ) } diff --git a/client/react-native/common/components/Library/Avatar.js b/client/react-native/common/components/Library/Avatar.js new file mode 100644 index 0000000000..2d9d10e28f --- /dev/null +++ b/client/react-native/common/components/Library/Avatar.js @@ -0,0 +1,36 @@ +import React from 'react' +import { Image } from 'react-native' +import { fingerprint } from '../../helpers/fingerprint' +import { extractPublicKeyFromId } from '../../helpers/contacts' + +const Avatar = ({ data, size = 40, margin = 4, uri = null, style = [] }) => { + if (uri !== null) { + return + } + + if (!(style instanceof Array)) { + style = [style] + } + + if (!data || !data.id) { + console.error(['No id provided', data]) + } + + const id = extractPublicKeyFromId(data.id) || data.id + const hexCode = fingerprint(id).substring(0, 16) + const retinaMode = 2 + + return +} + +export default Avatar diff --git a/client/react-native/common/components/Library/ContactIdentity.js b/client/react-native/common/components/Library/ContactIdentity.js index 92e43bed56..3055e65a9b 100644 --- a/client/react-native/common/components/Library/ContactIdentity.js +++ b/client/react-native/common/components/Library/ContactIdentity.js @@ -1,14 +1,14 @@ import React from 'react' -import { View, Image, Platform, Text as RNText } from 'react-native' -import Text from './Text' +import { View, Platform, Text as RNText } from 'react-native' +import { Avatar, Text } from '.' import { createMaterialTopTabNavigator } from 'react-navigation' import QRGenerator from './QRGenerator' -import { extractPublicKeyFromId, makeShareableUrl } from '../../helpers/contacts' +import { makeShareableUrl } from '../../helpers/contacts' import colors from '../../constants/colors' -import Icon from './Icon' import { formattedFingerprint } from '../../helpers/fingerprint' import { padding } from '../../styles' -import { withScreenProps } from '../../helpers/views' +import { tabIcon, withScreenProps } from '../../helpers/views' +import { monospaceFont, tabNavigatorOptions } from '../../constants/styling' const PublicKey = ({ data: { id } }) => @@ -20,29 +20,20 @@ const PublicKey = ({ data: { id } }) => - {extractPublicKeyFromId(id)} - + }}>{id} -export const QrCode = ({ data: { id, displayName } }) => -const tabIcon = (iconName) => { - const NamedTabIcon = ({ focused }) => - - return NamedTabIcon -} - const Fingerprint = ({ data: { id } }) => {formattedFingerprint(id)} @@ -86,57 +77,20 @@ const ContactIdentityTabbedContent = createMaterialTopTabNavigator( }, { initialRouteName: 'qrcode', - swipeEnabled: Platform.OS !== 'android', - animationEnabled: true, - backBehavior: 'none', - tabBarOptions: { - activeTintColor: colors.fakeBlack, - inactiveTintColor: colors.fakeBlack, - showIcon: true, - showLabel: true, - upperCaseLabel: false, - style: { - backgroundColor: colors.white, - marginBottom: 0, - marginTop: 0, - }, - tabStyle: { - marginBottom: 0, - marginTop: 0, - }, - indicatorStyle: { - backgroundColor: colors.blue, - marginBottom: 0, - marginTop: 0, - }, - labelStyle: { - fontSize: 12, - marginBottom: 0, - marginTop: 0, - }, - }, + ...tabNavigatorOptions, }, ) const ContactIdentity = ({ data }) => <> - + {data.displayName} - + {} export default ContactIdentity +ContactIdentity.QrCode = QrCode diff --git a/client/react-native/common/components/Library/ContactIdentityActions/ActionButton.js b/client/react-native/common/components/Library/ContactIdentityActions/ActionButton.js new file mode 100644 index 0000000000..a8b0758ef0 --- /dev/null +++ b/client/react-native/common/components/Library/ContactIdentityActions/ActionButton.js @@ -0,0 +1,12 @@ +import React from 'react' +import { Text, TouchableOpacity } from 'react-native' +import { Button, Icon } from '..' +import colors from '../../../constants/colors' + +const ActionButton = ({ icon, title, onPress }) => + + {Platform.OS !== 'web' + ? + : null} + + + } } -) +} -export const ByPublicKeyModal = props => ( - - - -) +export default ByPublicKey diff --git a/client/react-native/common/components/Screens/Contacts/Add/ByQRCode.js b/client/react-native/common/components/Screens/Contacts/Add/ByQRCode.js new file mode 100644 index 0000000000..2939f8f975 --- /dev/null +++ b/client/react-native/common/components/Screens/Contacts/Add/ByQRCode.js @@ -0,0 +1,68 @@ +import React, { PureComponent } from 'react' +import { View, Dimensions } from 'react-native' +import { withOrientation } from 'react-navigation' +import QRReader from '../../../Library/QRReader' +import { parse as parseUrl } from '../../../../helpers/url' +import colors from '../../../../constants/colors' +import { showMessage } from 'react-native-flash-message' +import { showContactModal } from '../../../../helpers/contacts' +import RelayContext from '../../../../relay/RelayContext' + +class ByQRCode extends PureComponent { + reactivate () { + this.scanner.reactivate() + } + + render () { + const { topNavigation } = this.props + const size = Math.min( + Dimensions.get('window').width, + Dimensions.get('window').height, + ) + + return {relayContext => + { this.scanner = scanner }} + cameraStyle={{ height: size, width: size }} + onFound={async data => { + const url = parseUrl(data) + + if (!url || url.pathname !== '/add-contact') { + showMessage({ + message: 'This is not a Berty QR Code', + type: 'danger', + position: 'center', + icon: 'danger', + }) + setTimeout(() => this.reactivate(), 2000) + + return + } + + await showContactModal({ + relayContext, + navigation: topNavigation, + beforeDismiss: () => this.reactivate(), + data: { + id: url.hashParts['public-key'], + displayName: url.hashParts['display-name'] || '', + }, + }) + }} + /> + } + } +} + +export default withOrientation(ByQRCode) diff --git a/client/react-native/common/components/Screens/Contacts/Add/Choice.js b/client/react-native/common/components/Screens/Contacts/Add/Choice.js deleted file mode 100644 index 4acbc04624..0000000000 --- a/client/react-native/common/components/Screens/Contacts/Add/Choice.js +++ /dev/null @@ -1,68 +0,0 @@ -import React, { PureComponent } from 'react' -import { TouchableOpacity } from 'react-native' -import { Text, Flex } from '../../../Library' -import { colors } from '../../../../constants' -import { padding, borderTop } from '../../../../styles' - -export default class Choice extends PureComponent { - render () { - const { navigation } = this.props - return ( - - - - - - - - - ) - } -} - -const Item = ({ icon, name, link, navigation }) => ( - navigation.push(link)} - style={[ - { - borderRadius: 8, - height: 60, - width: 300, - backgroundColor: colors.blue, - paddingLeft: 24, - paddingRight: 8, - margin: 10, - }, - ]} - > - - - {name} - - - - -) diff --git a/client/react-native/common/components/Screens/Contacts/Add/Request.js b/client/react-native/common/components/Screens/Contacts/Add/Request.js index f622c78e90..9a2d6eef99 100644 --- a/client/react-native/common/components/Screens/Contacts/Add/Request.js +++ b/client/react-native/common/components/Screens/Contacts/Add/Request.js @@ -1,9 +1,9 @@ -import { ActivityIndicator, Image } from 'react-native' +import { ActivityIndicator } from 'react-native' import React, { PureComponent } from 'react' import createTabNavigator from 'react-navigation-deprecated-tab-navigator/src/createTabNavigator' -import { Flex, Screen, Text } from '../../../Library' +import { Avatar, Flex, Screen, Text } from '../../../Library' import { Pagination, RelayContext } from '../../../../relay' import { borderBottom, padding } from '../../../../styles' import { colors } from '../../../../constants' @@ -84,12 +84,7 @@ const Item = fragments.Contact( style={[{ height: 72 }, padding, borderBottom]} > - + {overrideDisplayName || displayName} diff --git a/client/react-native/common/components/Screens/Contacts/Add/index.js b/client/react-native/common/components/Screens/Contacts/Add/index.js index 084042f9bf..bcbf3a2fbc 100644 --- a/client/react-native/common/components/Screens/Contacts/Add/index.js +++ b/client/react-native/common/components/Screens/Contacts/Add/index.js @@ -1,31 +1,52 @@ -import { createSubStackNavigator } from '../../../../helpers/react-navigation' -import Choice from './Choice' -import Request from './Request' +import React from 'react' +import { createMaterialTopTabNavigator, withNavigation } from 'react-navigation' +import ByQRCode from './ByQRCode' import ByPublicKey from './ByPublicKey' -import ByBump from './ByBump' import Invite from './Invite' -import React from 'react' -import { Header } from '../../../Library' +import { tabIcon, withScreenProps } from '../../../../helpers/views' +import { tabNavigatorOptions } from '../../../../constants/styling' +import { View } from 'react-native' -export default createSubStackNavigator( +const AddContactTabbedContent = createMaterialTopTabNavigator( { - 'contacts/add/request': Request, - 'contacts/add/by-public-key': ByPublicKey, - 'contacts/add/by-bump': ByBump, - 'contacts/add/invite': Invite, - 'contacts/add/choice': Choice, + 'qrcode': { + screen: withScreenProps(ByQRCode), + navigationOptions: { + title: 'QR Code', + tabBarIcon: tabIcon('material-qrcode'), + }, + }, + 'public-key': { + screen: withScreenProps(ByPublicKey), + navigationOptions: { + title: 'Public key', + tabBarIcon: tabIcon('material-key-variant'), + }, + }, + 'nearby': { + screen: withScreenProps(Invite), + // screen: withScreenProps(ByBump), + navigationOptions: { + title: 'Nearby', + tabBarIcon: tabIcon('radio'), + }, + }, + 'invite': { + screen: withScreenProps(Invite), + navigationOptions: { + title: 'Invite', + tabBarIcon: tabIcon('material-email'), + }, + }, }, { - initialRouteName: 'contacts/add/choice', - navigationOptions: ({ navigation }) => ({ - header: ( -
- ), - }), - } + initialRouteName: 'qrcode', + ...tabNavigatorOptions, + }, ) + +const AddScreen = ({ navigation }) => + {} + + +export default withNavigation(AddScreen) diff --git a/client/react-native/common/components/Screens/Contacts/ContactCardModal.js b/client/react-native/common/components/Screens/Contacts/ContactCardModal.js index 5f3c6e47ca..e62cccf680 100644 --- a/client/react-native/common/components/Screens/Contacts/ContactCardModal.js +++ b/client/react-native/common/components/Screens/Contacts/ContactCardModal.js @@ -1,66 +1,19 @@ import React from 'react' -import ContactIdentity, { QrCode } from '../../Library/ContactIdentity' -import ModalScreen from '../../Library/ModalScreen' import { withNavigation } from 'react-navigation' -import { View, Text, TouchableOpacity, Clipboard, Alert } from 'react-native' -import Button from '../../Library/Button' -import colors from '../../../constants/colors' -import { extractPublicKeyFromId, shareLinkOther, shareLinkSelf, makeShareableUrl } from '../../../helpers/contacts' -import { Icon } from '../../Library' -import saveViewToCamera from '../../Library/SaveViewToCamera' +import { View } from 'react-native' +import { ContactIdentityActions, ContactIdentity, ModalScreen } from '../../Library' const modalWidth = 320 -const QRCodeExport = ({ data }) => <> - {data.displayName} is on Berty - - - -const ActionButton = ({ icon, title, onPress }) => -