1 | import PropTypes from 'prop-types';
|
2 | import React from 'react';
|
3 | import { Linking, StyleSheet, View, } from 'react-native';
|
4 |
|
5 | import ParsedText from 'react-native-parsed-text';
|
6 | import Communications from 'react-native-communications';
|
7 | import { StylePropType } from './utils';
|
8 | const WWW_URL_PATTERN = /^www\./i;
|
9 | const textStyle = {
|
10 | fontSize: 16,
|
11 | lineHeight: 20,
|
12 | marginTop: 5,
|
13 | marginBottom: 5,
|
14 | marginLeft: 10,
|
15 | marginRight: 10,
|
16 | };
|
17 | const styles = {
|
18 | left: StyleSheet.create({
|
19 | container: {},
|
20 | text: {
|
21 | color: 'black',
|
22 | ...textStyle,
|
23 | },
|
24 | link: {
|
25 | color: 'black',
|
26 | textDecorationLine: 'underline',
|
27 | },
|
28 | }),
|
29 | right: StyleSheet.create({
|
30 | container: {},
|
31 | text: {
|
32 | color: 'white',
|
33 | ...textStyle,
|
34 | },
|
35 | link: {
|
36 | color: 'white',
|
37 | textDecorationLine: 'underline',
|
38 | },
|
39 | }),
|
40 | };
|
41 | const DEFAULT_OPTION_TITLES = ['Call', 'Text', 'Cancel'];
|
42 | export default class MessageText extends React.Component {
|
43 | constructor() {
|
44 | super(...arguments);
|
45 | this.onUrlPress = (url) => {
|
46 |
|
47 |
|
48 | if (WWW_URL_PATTERN.test(url)) {
|
49 | this.onUrlPress(`http://${url}`);
|
50 | }
|
51 | else {
|
52 | Linking.canOpenURL(url).then(supported => {
|
53 | if (!supported) {
|
54 | console.error('No handler for URL:', url);
|
55 | }
|
56 | else {
|
57 | Linking.openURL(url);
|
58 | }
|
59 | });
|
60 | }
|
61 | };
|
62 | this.onPhonePress = (phone) => {
|
63 | const { optionTitles } = this.props;
|
64 | const options = optionTitles && optionTitles.length > 0
|
65 | ? optionTitles.slice(0, 3)
|
66 | : DEFAULT_OPTION_TITLES;
|
67 | const cancelButtonIndex = options.length - 1;
|
68 | this.context.actionSheet().showActionSheetWithOptions({
|
69 | options,
|
70 | cancelButtonIndex,
|
71 | }, (buttonIndex) => {
|
72 | switch (buttonIndex) {
|
73 | case 0:
|
74 | Communications.phonecall(phone, true);
|
75 | break;
|
76 | case 1:
|
77 | Communications.text(phone);
|
78 | break;
|
79 | default:
|
80 | break;
|
81 | }
|
82 | });
|
83 | };
|
84 | this.onEmailPress = (email) => Communications.email([email], null, null, null, null);
|
85 | }
|
86 | shouldComponentUpdate(nextProps) {
|
87 | return (!!this.props.currentMessage &&
|
88 | !!nextProps.currentMessage &&
|
89 | this.props.currentMessage.text !== nextProps.currentMessage.text);
|
90 | }
|
91 | render() {
|
92 | const linkStyle = [
|
93 | styles[this.props.position].link,
|
94 | this.props.linkStyle && this.props.linkStyle[this.props.position],
|
95 | ];
|
96 | return (<View style={[
|
97 | styles[this.props.position].container,
|
98 | this.props.containerStyle &&
|
99 | this.props.containerStyle[this.props.position],
|
100 | ]}>
|
101 | <ParsedText style={[
|
102 | styles[this.props.position].text,
|
103 | this.props.textStyle && this.props.textStyle[this.props.position],
|
104 | this.props.customTextStyle,
|
105 | ]} parse={[
|
106 | ...this.props.parsePatterns(linkStyle),
|
107 | { type: 'url', style: linkStyle, onPress: this.onUrlPress },
|
108 | { type: 'phone', style: linkStyle, onPress: this.onPhonePress },
|
109 | { type: 'email', style: linkStyle, onPress: this.onEmailPress },
|
110 | ]} childrenProps={{ ...this.props.textProps }}>
|
111 | {this.props.currentMessage.text}
|
112 | </ParsedText>
|
113 | </View>);
|
114 | }
|
115 | }
|
116 | MessageText.contextTypes = {
|
117 | actionSheet: PropTypes.func,
|
118 | };
|
119 | MessageText.defaultProps = {
|
120 | position: 'left',
|
121 | optionTitles: DEFAULT_OPTION_TITLES,
|
122 | currentMessage: {
|
123 | text: '',
|
124 | },
|
125 | containerStyle: {},
|
126 | textStyle: {},
|
127 | linkStyle: {},
|
128 | customTextStyle: {},
|
129 | textProps: {},
|
130 | parsePatterns: () => [],
|
131 | };
|
132 | MessageText.propTypes = {
|
133 | position: PropTypes.oneOf(['left', 'right']),
|
134 | optionTitles: PropTypes.arrayOf(PropTypes.string),
|
135 | currentMessage: PropTypes.object,
|
136 | containerStyle: PropTypes.shape({
|
137 | left: StylePropType,
|
138 | right: StylePropType,
|
139 | }),
|
140 | textStyle: PropTypes.shape({
|
141 | left: StylePropType,
|
142 | right: StylePropType,
|
143 | }),
|
144 | linkStyle: PropTypes.shape({
|
145 | left: StylePropType,
|
146 | right: StylePropType,
|
147 | }),
|
148 | parsePatterns: PropTypes.func,
|
149 | textProps: PropTypes.object,
|
150 | customTextStyle: StylePropType,
|
151 | };
|
152 |
|
\ | No newline at end of file |