1 | import PropTypes from 'prop-types';
|
2 | import React from 'react';
|
3 | import { View, StyleSheet } from 'react-native';
|
4 | import Avatar from './Avatar';
|
5 | import Bubble from './Bubble';
|
6 | import SystemMessage from './SystemMessage';
|
7 | import Day from './Day';
|
8 | import { StylePropType, isSameUser } from './utils';
|
9 | const styles = {
|
10 | left: StyleSheet.create({
|
11 | container: {
|
12 | flexDirection: 'row',
|
13 | alignItems: 'flex-end',
|
14 | justifyContent: 'flex-start',
|
15 | marginLeft: 8,
|
16 | marginRight: 0,
|
17 | },
|
18 | }),
|
19 | right: StyleSheet.create({
|
20 | container: {
|
21 | flexDirection: 'row',
|
22 | alignItems: 'flex-end',
|
23 | justifyContent: 'flex-end',
|
24 | marginLeft: 0,
|
25 | marginRight: 8,
|
26 | },
|
27 | }),
|
28 | };
|
29 | export default class Message extends React.Component {
|
30 | shouldComponentUpdate(nextProps) {
|
31 | const next = nextProps.currentMessage;
|
32 | const current = this.props.currentMessage;
|
33 | const { previousMessage, nextMessage } = this.props;
|
34 | const nextPropsMessage = nextProps.nextMessage;
|
35 | const nextPropsPreviousMessage = nextProps.previousMessage;
|
36 | const shouldUpdate = (this.props.shouldUpdateMessage &&
|
37 | this.props.shouldUpdateMessage(this.props, nextProps)) ||
|
38 | false;
|
39 | return (next.sent !== current.sent ||
|
40 | next.received !== current.received ||
|
41 | next.pending !== current.pending ||
|
42 | next.createdAt !== current.createdAt ||
|
43 | next.text !== current.text ||
|
44 | next.image !== current.image ||
|
45 | next.video !== current.video ||
|
46 | next.audio !== current.audio ||
|
47 | previousMessage !== nextPropsPreviousMessage ||
|
48 | nextMessage !== nextPropsMessage ||
|
49 | shouldUpdate);
|
50 | }
|
51 | renderDay() {
|
52 | if (this.props.currentMessage && this.props.currentMessage.createdAt) {
|
53 | const { containerStyle, ...props } = this.props;
|
54 | if (this.props.renderDay) {
|
55 | return this.props.renderDay(props);
|
56 | }
|
57 | return <Day {...props}/>;
|
58 | }
|
59 | return null;
|
60 | }
|
61 | renderBubble() {
|
62 | const { containerStyle, ...props } = this.props;
|
63 | if (this.props.renderBubble) {
|
64 | return this.props.renderBubble(props);
|
65 | }
|
66 | // @ts-ignore
|
67 | return <Bubble {...props}/>;
|
68 | }
|
69 | renderSystemMessage() {
|
70 | const { containerStyle, ...props } = this.props;
|
71 | if (this.props.renderSystemMessage) {
|
72 | return this.props.renderSystemMessage(props);
|
73 | }
|
74 | return <SystemMessage {...props}/>;
|
75 | }
|
76 | renderAvatar() {
|
77 | const { user, currentMessage, showUserAvatar } = this.props;
|
78 | if (user &&
|
79 | user._id &&
|
80 | currentMessage &&
|
81 | currentMessage.user &&
|
82 | user._id === currentMessage.user._id &&
|
83 | !showUserAvatar) {
|
84 | return null;
|
85 | }
|
86 | if (currentMessage &&
|
87 | currentMessage.user &&
|
88 | currentMessage.user.avatar === null) {
|
89 | return null;
|
90 | }
|
91 | const { containerStyle, ...props } = this.props;
|
92 | return <Avatar {...props}/>;
|
93 | }
|
94 | render() {
|
95 | const { currentMessage, nextMessage, position, containerStyle } = this.props;
|
96 | if (currentMessage) {
|
97 | const sameUser = isSameUser(currentMessage, nextMessage);
|
98 | return (<View>
|
99 | {this.renderDay()}
|
100 | {currentMessage.system ? (this.renderSystemMessage()) : (<View style={[
|
101 | styles[position].container,
|
102 | { marginBottom: sameUser ? 2 : 10 },
|
103 | !this.props.inverted && { marginBottom: 2 },
|
104 | containerStyle && containerStyle[position],
|
105 | ]}>
|
106 | {this.props.position === 'left' ? this.renderAvatar() : null}
|
107 | {this.renderBubble()}
|
108 | {this.props.position === 'right' ? this.renderAvatar() : null}
|
109 | </View>)}
|
110 | </View>);
|
111 | }
|
112 | return null;
|
113 | }
|
114 | }
|
115 | Message.defaultProps = {
|
116 | renderAvatar: undefined,
|
117 | renderBubble: null,
|
118 | renderDay: null,
|
119 | renderSystemMessage: null,
|
120 | position: 'left',
|
121 | currentMessage: {},
|
122 | nextMessage: {},
|
123 | previousMessage: {},
|
124 | user: {},
|
125 | containerStyle: {},
|
126 | showUserAvatar: false,
|
127 | inverted: true,
|
128 | shouldUpdateMessage: undefined,
|
129 | };
|
130 | Message.propTypes = {
|
131 | renderAvatar: PropTypes.func,
|
132 | showUserAvatar: PropTypes.bool,
|
133 | renderBubble: PropTypes.func,
|
134 | renderDay: PropTypes.func,
|
135 | renderSystemMessage: PropTypes.func,
|
136 | position: PropTypes.oneOf(['left', 'right']),
|
137 | currentMessage: PropTypes.object,
|
138 | nextMessage: PropTypes.object,
|
139 | previousMessage: PropTypes.object,
|
140 | user: PropTypes.object,
|
141 | inverted: PropTypes.bool,
|
142 | containerStyle: PropTypes.shape({
|
143 | left: StylePropType,
|
144 | right: StylePropType,
|
145 | }),
|
146 | shouldUpdateMessage: PropTypes.func,
|
147 | };
|
148 | //# sourceMappingURL=Message.js.map |
\ | No newline at end of file |