Bläddra i källkod

feat: add chat color scheming

master
Bettenbuk Zoltan 6 år sedan
förälder
incheckning
a35099f949

+ 2
- 0
react/features/base/color-scheme/ColorSchemeRegistry.js Visa fil

@@ -153,6 +153,8 @@ class ColorSchemeRegistry {
153 153
         const colorScheme = toState(stateful)['features/base/color-scheme'];
154 154
 
155 155
         return {
156
+            ...defaultScheme._defaultTheme,
157
+            ...colorScheme._defaultTheme,
156 158
             ...defaultScheme[componentName],
157 159
             ...colorScheme[componentName]
158 160
         }[colorDefinition];

+ 16
- 9
react/features/base/color-scheme/defaultScheme.js Visa fil

@@ -6,18 +6,26 @@ import { ColorPalette, getRGBAFormat } from '../styles';
6 6
  * The default color scheme of the application.
7 7
  */
8 8
 export default {
9
-    'BottomSheet': {
9
+    '_defaultTheme': {
10
+        // Generic app theme colors that are used accross the entire app.
11
+        // All scheme definitions below inherit these values.
10 12
         background: 'rgb(255, 255, 255)',
11
-        icon: '#1c2025',
12
-        label: '#1c2025'
13
+        icon: 'rgb(28, 32, 37)',
14
+        text: 'rgb(28, 32, 37)'
15
+    },
16
+    'Chat': {
17
+        displayName: 'rgb(94, 109, 121)',
18
+        localMsgBackground: 'rgb(215, 230, 249)',
19
+        privateMsgBackground: 'rgb(250, 219, 219)',
20
+        privateMsgNotice: 'rgb(186, 39, 58)',
21
+        remoteMsgBackground: 'rgb(241, 242, 246)',
22
+        replyBorder: 'rgb(219, 197, 200)',
23
+        replyIcon: 'rgb(94, 109, 121)'
13 24
     },
14 25
     'Dialog': {
15
-        background: 'rgb(255, 255, 255)',
16 26
         border: 'rgba(0, 3, 6, 0.6)',
17 27
         buttonBackground: ColorPalette.blue,
18
-        buttonLabel: ColorPalette.white,
19
-        icon: '#1c2025',
20
-        text: '#1c2025'
28
+        buttonLabel: ColorPalette.white
21 29
     },
22 30
     'Header': {
23 31
         background: ColorPalette.blue,
@@ -30,8 +38,7 @@ export default {
30 38
         background: 'rgb(42, 58, 75)'
31 39
     },
32 40
     'LoadConfigOverlay': {
33
-        background: 'rgb(249, 249, 249)',
34
-        text: 'rgb(28, 32, 37)'
41
+        background: 'rgb(249, 249, 249)'
35 42
     },
36 43
     'Thumbnail': {
37 44
         activeParticipantHighlight: 'rgb(81, 214, 170)',

+ 1
- 1
react/features/base/dialog/components/native/styles.js Visa fil

@@ -147,7 +147,7 @@ ColorSchemeRegistry.register('BottomSheet', {
147 147
      * Style for the label in a generic item rendered in the menu.
148 148
      */
149 149
     labelStyle: {
150
-        color: schemeColor('label'),
150
+        color: schemeColor('text'),
151 151
         flexShrink: 1,
152 152
         fontSize: MD_FONT_SIZE,
153 153
         marginLeft: 32,

+ 4
- 2
react/features/chat/components/AbstractChatMessage.js Visa fil

@@ -4,6 +4,8 @@ import { PureComponent } from 'react';
4 4
 
5 5
 import { getLocalizedDateFormatter } from '../../base/i18n';
6 6
 
7
+import { MESSAGE_TYPE_ERROR, MESSAGE_TYPE_LOCAL } from '../constants';
8
+
7 9
 /**
8 10
  * Formatter string to display the message timestamp.
9 11
  */
@@ -65,7 +67,7 @@ export default class AbstractChatMessage<P: Props> extends PureComponent<P> {
65 67
     _getMessageText() {
66 68
         const { message } = this.props;
67 69
 
68
-        return message.messageType === 'error'
70
+        return message.messageType === MESSAGE_TYPE_ERROR
69 71
             ? this.props.t('chat.error', {
70 72
                 error: message.message
71 73
             })
@@ -81,7 +83,7 @@ export default class AbstractChatMessage<P: Props> extends PureComponent<P> {
81 83
         const { message, t } = this.props;
82 84
 
83 85
         return t('chat.privateNotice', {
84
-            recipient: message.messageType === 'local' ? message.recipient : t('chat.you')
86
+            recipient: message.messageType === MESSAGE_TYPE_LOCAL ? message.recipient : t('chat.you')
85 87
         });
86 88
     }
87 89
 }

+ 2
- 2
react/features/chat/components/AbstractMessageRecipient.js Visa fil

@@ -6,7 +6,7 @@ import { getParticipantDisplayName } from '../../base/participants';
6 6
 
7 7
 import { setPrivateMessageRecipient } from '../actions';
8 8
 
9
-type Props = {
9
+export type Props = {
10 10
 
11 11
     /**
12 12
      * Function used to translate i18n labels.
@@ -27,7 +27,7 @@ type Props = {
27 27
 /**
28 28
  * Abstract class for the {@code MessageRecipient} component.
29 29
  */
30
-export default class AbstractMessageRecipient extends PureComponent<Props> {
30
+export default class AbstractMessageRecipient<P: Props> extends PureComponent<P> {
31 31
 
32 32
 }
33 33
 

+ 28
- 4
react/features/chat/components/native/Chat.js Visa fil

@@ -3,15 +3,16 @@
3 3
 import React from 'react';
4 4
 import { KeyboardAvoidingView, SafeAreaView } from 'react-native';
5 5
 
6
+import { ColorSchemeRegistry } from '../../../base/color-scheme';
6 7
 import { translate } from '../../../base/i18n';
7
-
8 8
 import { HeaderWithNavigation, SlidingView } from '../../../base/react';
9 9
 import { connect } from '../../../base/redux';
10
+import { StyleType } from '../../../base/styles';
10 11
 
11 12
 import AbstractChat, {
12 13
     _mapDispatchToProps,
13
-    _mapStateToProps,
14
-    type Props
14
+    _mapStateToProps as _abstractMapStateToProps,
15
+    type Props as AbstractProps
15 16
 } from '../AbstractChat';
16 17
 
17 18
 import ChatInputBar from './ChatInputBar';
@@ -19,6 +20,14 @@ import MessageContainer from './MessageContainer';
19 20
 import MessageRecipient from './MessageRecipient';
20 21
 import styles from './styles';
21 22
 
23
+type Props = AbstractProps & {
24
+
25
+    /**
26
+     * The color-schemed stylesheet of the feature.
27
+     */
28
+    _styles: StyleType
29
+};
30
+
22 31
 /**
23 32
  * Implements a React native component that renders the chat window (modal) of
24 33
  * the mobile client.
@@ -41,6 +50,8 @@ class Chat extends AbstractChat<Props> {
41 50
      * @inheritdoc
42 51
      */
43 52
     render() {
53
+        const { _styles } = this.props;
54
+
44 55
         return (
45 56
             <SlidingView
46 57
                 onHide = { this._onClose }
@@ -52,7 +63,7 @@ class Chat extends AbstractChat<Props> {
52 63
                     <HeaderWithNavigation
53 64
                         headerLabelKey = 'chat.title'
54 65
                         onPressBack = { this._onClose } />
55
-                    <SafeAreaView style = { styles.backdrop }>
66
+                    <SafeAreaView style = { _styles.backdrop }>
56 67
                         <MessageContainer messages = { this.props._messages } />
57 68
                         <MessageRecipient />
58 69
                         <ChatInputBar onSend = { this.props._onSendMessage } />
@@ -80,4 +91,17 @@ class Chat extends AbstractChat<Props> {
80 91
     }
81 92
 }
82 93
 
94
+/**
95
+ * Maps part of the redux state to the props of this component.
96
+ *
97
+ * @param {Object} state - The Redux state.
98
+ * @returns {Props}
99
+ */
100
+function _mapStateToProps(state) {
101
+    return {
102
+        ..._abstractMapStateToProps(state),
103
+        _styles: ColorSchemeRegistry.get(state, 'Chat')
104
+    };
105
+}
106
+
83 107
 export default translate(connect(_mapStateToProps, _mapDispatchToProps)(Chat));

+ 104
- 37
react/features/chat/components/native/ChatMessage.js Visa fil

@@ -4,16 +4,28 @@ import React from 'react';
4 4
 import { Text, View } from 'react-native';
5 5
 
6 6
 import { Avatar } from '../../../base/avatar';
7
+import { ColorSchemeRegistry } from '../../../base/color-scheme';
7 8
 import { translate } from '../../../base/i18n';
8 9
 import { Linkify } from '../../../base/react';
10
+import { connect } from '../../../base/redux';
11
+import { type StyleType } from '../../../base/styles';
9 12
 
13
+import { MESSAGE_TYPE_ERROR, MESSAGE_TYPE_LOCAL } from '../../constants';
10 14
 import { replaceNonUnicodeEmojis } from '../../functions';
11 15
 
12
-import AbstractChatMessage, { type Props } from '../AbstractChatMessage';
16
+import AbstractChatMessage, { type Props as AbstractProps } from '../AbstractChatMessage';
13 17
 import PrivateMessageButton from '../PrivateMessageButton';
14 18
 
15 19
 import styles from './styles';
16 20
 
21
+type Props = AbstractProps & {
22
+
23
+    /**
24
+     * The color-schemed stylesheet of the feature.
25
+     */
26
+    _styles: StyleType
27
+};
28
+
17 29
 /**
18 30
  * Renders a single chat message.
19 31
  */
@@ -24,55 +36,58 @@ class ChatMessage extends AbstractChatMessage<Props> {
24 36
      * @inheritdoc
25 37
      */
26 38
     render() {
27
-        const { message } = this.props;
28
-        const localMessage = message.messageType === 'local';
39
+        const { _styles, message } = this.props;
40
+        const localMessage = message.messageType === MESSAGE_TYPE_LOCAL;
41
+        const { privateMessage } = message;
29 42
 
30 43
         // Style arrays that need to be updated in various scenarios, such as
31 44
         // error messages or others.
32 45
         const detailsWrapperStyle = [
33 46
             styles.detailsWrapper
34 47
         ];
35
-        const textWrapperStyle = [
36
-            styles.textWrapper
48
+        const messageBubbleStyle = [
49
+            styles.messageBubble
37 50
         ];
38 51
 
39 52
         if (localMessage) {
53
+            // This is a message sent by the local participant.
54
+
40 55
             // The wrapper needs to be aligned to the right.
41 56
             detailsWrapperStyle.push(styles.ownMessageDetailsWrapper);
42 57
 
43
-            // The bubble needs to be differently styled.
44
-            textWrapperStyle.push(styles.ownTextWrapper);
45
-        } else if (message.messageType === 'error') {
46
-            // The bubble needs to be differently styled.
47
-            textWrapperStyle.push(styles.systemTextWrapper);
58
+            // The bubble needs some additional styling
59
+            messageBubbleStyle.push(_styles.localMessageBubble);
60
+        } else if (message.messageType === MESSAGE_TYPE_ERROR) {
61
+            // This is a system message.
62
+
63
+            // The bubble needs some additional styling
64
+            messageBubbleStyle.push(styles.systemMessageBubble);
65
+        } else {
66
+            // This is a remote message sent by a remote participant.
67
+
68
+            // The bubble needs some additional styling
69
+            messageBubbleStyle.push(_styles.remoteMessageBubble);
70
+        }
71
+
72
+        if (privateMessage) {
73
+            messageBubbleStyle.push(_styles.privateMessageBubble);
48 74
         }
49 75
 
50 76
         return (
51 77
             <View style = { styles.messageWrapper } >
52 78
                 { this._renderAvatar() }
53 79
                 <View style = { detailsWrapperStyle }>
54
-                    <View style = { styles.replyWrapper }>
55
-                        <View style = { textWrapperStyle } >
56
-                            {
57
-                                this.props.showDisplayName
58
-                                    && this._renderDisplayName()
59
-                            }
80
+                    <View style = { messageBubbleStyle }>
81
+                        <View style = { styles.textWrapper } >
82
+                            { this._renderDisplayName() }
60 83
                             <Linkify linkStyle = { styles.chatLink }>
61 84
                                 { replaceNonUnicodeEmojis(this._getMessageText()) }
62 85
                             </Linkify>
63
-                            {
64
-                                message.privateMessage
65
-                                    && this._renderPrivateNotice()
66
-                            }
86
+                            { this._renderPrivateNotice() }
67 87
                         </View>
68
-                        { message.privateMessage && !localMessage
69
-                            && <PrivateMessageButton
70
-                                participantID = { message.id }
71
-                                reply = { true }
72
-                                showLabel = { false }
73
-                                toggledStyles = { styles.replyStyles } /> }
88
+                        { this._renderPrivateReplyButton() }
74 89
                     </View>
75
-                    { this.props.showTimestamp && this._renderTimestamp() }
90
+                    { this._renderTimestamp() }
76 91
                 </View>
77 92
             </View>
78 93
         );
@@ -104,37 +119,77 @@ class ChatMessage extends AbstractChatMessage<Props> {
104 119
     }
105 120
 
106 121
     /**
107
-     * Renders the display name of the sender.
122
+     * Renders the display name of the sender if necessary.
108 123
      *
109
-     * @returns {React$Element<*>}
124
+     * @returns {React$Element<*> | null}
110 125
      */
111 126
     _renderDisplayName() {
127
+        const { _styles, message, showDisplayName } = this.props;
128
+
129
+        if (!showDisplayName) {
130
+            return null;
131
+        }
132
+
112 133
         return (
113
-            <Text style = { styles.displayName }>
114
-                { this.props.message.displayName }
134
+            <Text style = { _styles.displayName }>
135
+                { message.displayName }
115 136
             </Text>
116 137
         );
117 138
     }
118 139
 
119 140
     /**
120
-     * Renders the message privacy notice.
141
+     * Renders the message privacy notice, if necessary.
121 142
      *
122
-     * @returns {React$Element<*>}
143
+     * @returns {React$Element<*> | null}
123 144
      */
124 145
     _renderPrivateNotice() {
146
+        const { _styles, message } = this.props;
147
+
148
+        if (!message.privateMessage) {
149
+            return null;
150
+        }
151
+
125 152
         return (
126
-            <Text style = { styles.privateNotice }>
153
+            <Text style = { _styles.privateNotice }>
127 154
                 { this._getPrivateNoticeMessage() }
128 155
             </Text>
129 156
         );
130 157
     }
131 158
 
132 159
     /**
133
-     * Renders the time at which the message was sent.
160
+     * Renders the private reply button, if necessary.
134 161
      *
135
-     * @returns {React$Element<*>}
162
+     * @returns {React$Element<*> | null}
163
+     */
164
+    _renderPrivateReplyButton() {
165
+        const { _styles, message } = this.props;
166
+        const { messageType, privateMessage } = message;
167
+
168
+        if (!privateMessage || messageType === MESSAGE_TYPE_LOCAL) {
169
+            return null;
170
+        }
171
+
172
+        return (
173
+            <View style = { _styles.replyContainer }>
174
+                <PrivateMessageButton
175
+                    participantID = { message.id }
176
+                    reply = { true }
177
+                    showLabel = { false }
178
+                    toggledStyles = { _styles.replyStyles } />
179
+            </View>
180
+        );
181
+    }
182
+
183
+    /**
184
+     * Renders the time at which the message was sent, if necessary.
185
+     *
186
+     * @returns {React$Element<*> | null}
136 187
      */
137 188
     _renderTimestamp() {
189
+        if (!this.props.showTimestamp) {
190
+            return null;
191
+        }
192
+
138 193
         return (
139 194
             <Text style = { styles.timeText }>
140 195
                 { this._getFormattedTimestamp() }
@@ -143,4 +198,16 @@ class ChatMessage extends AbstractChatMessage<Props> {
143 198
     }
144 199
 }
145 200
 
146
-export default translate(ChatMessage);
201
+/**
202
+ * Maps part of the redux state to the props of this component.
203
+ *
204
+ * @param {Object} state - The Redux state.
205
+ * @returns {Props}
206
+ */
207
+function _mapStateToProps(state) {
208
+    return {
209
+        _styles: ColorSchemeRegistry.get(state, 'Chat')
210
+    };
211
+}
212
+
213
+export default translate(connect(_mapStateToProps)(ChatMessage));

+ 4
- 2
react/features/chat/components/native/ChatMessageGroup.js Visa fil

@@ -3,6 +3,8 @@
3 3
 import React, { Component } from 'react';
4 4
 import { FlatList } from 'react-native';
5 5
 
6
+import { MESSAGE_TYPE_LOCAL, MESSAGE_TYPE_REMOTE } from '../../constants';
7
+
6 8
 import ChatMessage from './ChatMessage';
7 9
 import styles from './styles';
8 10
 
@@ -73,11 +75,11 @@ export default class ChatMessageGroup extends Component<Props> {
73 75
             <ChatMessage
74 76
                 message = { message }
75 77
                 showAvatar = {
76
-                    this.props.messages[0].messageType !== 'local'
78
+                    this.props.messages[0].messageType !== MESSAGE_TYPE_LOCAL
77 79
                         && index === this.props.messages.length - 1
78 80
                 }
79 81
                 showDisplayName = {
80
-                    this.props.messages[0].messageType === 'remote'
82
+                    this.props.messages[0].messageType === MESSAGE_TYPE_REMOTE
81 83
                         && index === this.props.messages.length - 1
82 84
                 }
83 85
                 showTimestamp = { index === 0 } />

+ 29
- 7
react/features/chat/components/native/MessageRecipient.js Visa fil

@@ -3,28 +3,37 @@
3 3
 import React from 'react';
4 4
 import { Text, TouchableHighlight, View } from 'react-native';
5 5
 
6
+import { ColorSchemeRegistry } from '../../../base/color-scheme';
6 7
 import { translate } from '../../../base/i18n';
7 8
 import { Icon, IconCancelSelection } from '../../../base/icons';
8 9
 import { connect } from '../../../base/redux';
10
+import { type StyleType } from '../../../base/styles';
9 11
 
10 12
 import AbstractMessageRecipient, {
11 13
     _mapDispatchToProps,
12
-    _mapStateToProps
14
+    _mapStateToProps as _abstractMapStateToProps,
15
+    type Props as AbstractProps
13 16
 } from '../AbstractMessageRecipient';
14 17
 
15
-import styles from './styles';
18
+type Props = AbstractProps & {
19
+
20
+    /**
21
+     * The color-schemed stylesheet of the feature.
22
+     */
23
+    _styles: StyleType
24
+};
16 25
 
17 26
 /**
18 27
  * Class to implement the displaying of the recipient of the next message.
19 28
  */
20
-class MessageRecipient extends AbstractMessageRecipient {
29
+class MessageRecipient extends AbstractMessageRecipient<Props> {
21 30
     /**
22 31
      * Implements {@code PureComponent#render}.
23 32
      *
24 33
      * @inheritdoc
25 34
      */
26 35
     render() {
27
-        const { _privateMessageRecipient } = this.props;
36
+        const { _privateMessageRecipient, _styles } = this.props;
28 37
 
29 38
         if (!_privateMessageRecipient) {
30 39
             return null;
@@ -33,8 +42,8 @@ class MessageRecipient extends AbstractMessageRecipient {
33 42
         const { t } = this.props;
34 43
 
35 44
         return (
36
-            <View style = { styles.messageRecipientContainer }>
37
-                <Text style = { styles.messageRecipientText }>
45
+            <View style = { _styles.messageRecipientContainer }>
46
+                <Text style = { _styles.messageRecipientText }>
38 47
                     { t('chat.messageTo', {
39 48
                         recipient: _privateMessageRecipient
40 49
                     }) }
@@ -42,11 +51,24 @@ class MessageRecipient extends AbstractMessageRecipient {
42 51
                 <TouchableHighlight onPress = { this.props._onRemovePrivateMessageRecipient }>
43 52
                     <Icon
44 53
                         src = { IconCancelSelection }
45
-                        style = { styles.messageRecipientCancelIcon } />
54
+                        style = { _styles.messageRecipientCancelIcon } />
46 55
                 </TouchableHighlight>
47 56
             </View>
48 57
         );
49 58
     }
50 59
 }
51 60
 
61
+/**
62
+ * Maps part of the redux state to the props of this component.
63
+ *
64
+ * @param {Object} state - The Redux state.
65
+ * @returns {Props}
66
+ */
67
+function _mapStateToProps(state) {
68
+    return {
69
+        ..._abstractMapStateToProps(state),
70
+        _styles: ColorSchemeRegistry.get(state, 'Chat')
71
+    };
72
+}
73
+
52 74
 export default translate(connect(_mapStateToProps, _mapDispatchToProps)(MessageRecipient));

+ 78
- 66
react/features/chat/components/native/styles.js Visa fil

@@ -1,7 +1,10 @@
1 1
 // @flow
2 2
 
3
+import { ColorSchemeRegistry, schemeColor } from '../../../base/color-scheme';
3 4
 import { BoxModel, ColorPalette } from '../../../base/styles';
4 5
 
6
+const BUBBLE_RADIUS = 8;
7
+
5 8
 /**
6 9
  * The styles of the feature chat.
7 10
  *
@@ -20,14 +23,6 @@ export default {
20 23
         width: 32
21 24
     },
22 25
 
23
-    /**
24
-     * Background of the chat screen.
25
-     */
26
-    backdrop: {
27
-        backgroundColor: ColorPalette.white,
28
-        flex: 1
29
-    },
30
-
31 26
     chatContainer: {
32 27
         alignItems: 'stretch',
33 28
         flex: 1,
@@ -47,14 +42,6 @@ export default {
47 42
         flexDirection: 'column'
48 43
     },
49 44
 
50
-    /**
51
-     * The text node for the display name.
52
-     */
53
-    displayName: {
54
-        color: 'rgb(118, 136, 152)',
55
-        fontSize: 13
56
-    },
57
-
58 45
     /**
59 46
      * A special padding to avoid issues on some devices (such as Android devices with custom suggestions bar).
60 47
      */
@@ -76,35 +63,16 @@ export default {
76 63
         height: 48
77 64
     },
78 65
 
79
-    messageContainer: {
80
-        flex: 1
81
-    },
82
-
83
-    messageRecipientCancelIcon: {
84
-        color: ColorPalette.white,
85
-        fontSize: 18
86
-    },
87
-
88
-    messageRecipientContainer: {
66
+    messageBubble: {
89 67
         alignItems: 'center',
90
-        backgroundColor: ColorPalette.warning,
91
-        flexDirection: 'row',
92
-        padding: BoxModel.padding
68
+        borderRadius: BUBBLE_RADIUS,
69
+        flexDirection: 'row'
93 70
     },
94 71
 
95
-    messageRecipientText: {
96
-        color: ColorPalette.white,
72
+    messageContainer: {
97 73
         flex: 1
98 74
     },
99 75
 
100
-    /**
101
-     * The message text itself.
102
-     */
103
-    messageText: {
104
-        color: 'rgb(28, 32, 37)',
105
-        fontSize: 15
106
-    },
107
-
108 76
     /**
109 77
      * Wrapper View for the entire block.
110 78
      */
@@ -123,34 +91,11 @@ export default {
123 91
         alignItems: 'flex-end'
124 92
     },
125 93
 
126
-    /**
127
-     * Style modifier for the {@code textWrapper} for own messages.
128
-     */
129
-    ownTextWrapper: {
130
-        backgroundColor: 'rgb(210, 231, 249)',
131
-        borderTopLeftRadius: 8,
132
-        borderTopRightRadius: 0
133
-    },
134
-
135 94
     replyWrapper: {
136 95
         alignItems: 'center',
137 96
         flexDirection: 'row'
138 97
     },
139 98
 
140
-    replyStyles: {
141
-        iconStyle: {
142
-            color: 'rgb(118, 136, 152)',
143
-            fontSize: 22,
144
-            margin: BoxModel.margin / 2
145
-        }
146
-    },
147
-
148
-    privateNotice: {
149
-        color: ColorPalette.warning,
150
-        fontSize: 13,
151
-        fontStyle: 'italic'
152
-    },
153
-
154 99
     sendButtonIcon: {
155 100
         color: ColorPalette.darkGrey,
156 101
         fontSize: 22
@@ -159,7 +104,7 @@ export default {
159 104
     /**
160 105
      * Style modifier for system (error) messages.
161 106
      */
162
-    systemTextWrapper: {
107
+    systemMessageBubble: {
163 108
         backgroundColor: 'rgb(247, 215, 215)'
164 109
     },
165 110
 
@@ -168,9 +113,6 @@ export default {
168 113
      */
169 114
     textWrapper: {
170 115
         alignItems: 'flex-start',
171
-        backgroundColor: 'rgb(240, 243, 247)',
172
-        borderRadius: 8,
173
-        borderTopLeftRadius: 0,
174 116
         flexDirection: 'column',
175 117
         padding: 9
176 118
     },
@@ -183,3 +125,73 @@ export default {
183 125
         fontSize: 13
184 126
     }
185 127
 };
128
+
129
+ColorSchemeRegistry.register('Chat', {
130
+    /**
131
+     * Background of the chat screen.
132
+     */
133
+    backdrop: {
134
+        backgroundColor: schemeColor('background'),
135
+        flex: 1
136
+    },
137
+
138
+    /**
139
+     * The text node for the display name.
140
+     */
141
+    displayName: {
142
+        color: schemeColor('displayName'),
143
+        fontSize: 13
144
+    },
145
+
146
+    localMessageBubble: {
147
+        backgroundColor: schemeColor('localMsgBackground'),
148
+        borderTopRightRadius: 0
149
+    },
150
+
151
+    messageRecipientCancelIcon: {
152
+        color: schemeColor('icon'),
153
+        fontSize: 18
154
+    },
155
+
156
+    messageRecipientContainer: {
157
+        alignItems: 'center',
158
+        backgroundColor: schemeColor('privateMsgBackground'),
159
+        flexDirection: 'row',
160
+        padding: BoxModel.padding
161
+    },
162
+
163
+    messageRecipientText: {
164
+        color: schemeColor('text'),
165
+        flex: 1
166
+    },
167
+
168
+    privateNotice: {
169
+        color: schemeColor('privateMsgNotice'),
170
+        fontSize: 11,
171
+        marginTop: 6
172
+    },
173
+
174
+    privateMessageBubble: {
175
+        backgroundColor: schemeColor('privateMsgBackground')
176
+    },
177
+
178
+    remoteMessageBubble: {
179
+        backgroundColor: schemeColor('remoteMsgBackground'),
180
+        borderTopLeftRadius: 0
181
+    },
182
+
183
+    replyContainer: {
184
+        alignSelf: 'stretch',
185
+        borderLeftColor: schemeColor('replyBorder'),
186
+        borderLeftWidth: 1,
187
+        justifyContent: 'center'
188
+    },
189
+
190
+    replyStyles: {
191
+        iconStyle: {
192
+            color: schemeColor('replyIcon'),
193
+            fontSize: 22,
194
+            padding: 8
195
+        }
196
+    }
197
+});

+ 3
- 1
react/features/chat/components/web/ChatMessage.js Visa fil

@@ -7,6 +7,8 @@ import { toArray } from 'react-emoji-render';
7 7
 import { translate } from '../../../base/i18n';
8 8
 import { Linkify } from '../../../base/react';
9 9
 
10
+import { MESSAGE_TYPE_LOCAL } from '../../constants';
11
+
10 12
 import AbstractChatMessage, {
11 13
     type Props
12 14
 } from '../AbstractChatMessage';
@@ -47,7 +49,7 @@ class ChatMessage extends AbstractChatMessage<Props> {
47 49
                         </div>
48 50
                         { message.privateMessage && this._renderPrivateNotice() }
49 51
                     </div>
50
-                    { message.privateMessage && message.messageType !== 'local'
52
+                    { message.privateMessage && message.messageType !== MESSAGE_TYPE_LOCAL
51 53
                     && <PrivateMessageButton
52 54
                         participantID = { message.id }
53 55
                         reply = { true }

+ 3
- 1
react/features/chat/components/web/MessageContainer.js Visa fil

@@ -2,6 +2,8 @@
2 2
 
3 3
 import React from 'react';
4 4
 
5
+import { MESSAGE_TYPE_REMOTE } from '../../constants';
6
+
5 7
 import AbstractMessageContainer, { type Props }
6 8
     from '../AbstractMessageContainer';
7 9
 
@@ -61,7 +63,7 @@ export default class MessageContainer extends AbstractMessageContainer {
61 63
 
62 64
             return (
63 65
                 <ChatMessageGroup
64
-                    className = { messageType || 'remote' }
66
+                    className = { messageType || MESSAGE_TYPE_REMOTE }
65 67
                     key = { index }
66 68
                     messages = { group } />
67 69
             );

+ 3
- 2
react/features/chat/components/web/MessageRecipient.js Visa fil

@@ -8,13 +8,14 @@ import { connect } from '../../../base/redux';
8 8
 
9 9
 import AbstractMessageRecipient, {
10 10
     _mapDispatchToProps,
11
-    _mapStateToProps
11
+    _mapStateToProps,
12
+    type Props
12 13
 } from '../AbstractMessageRecipient';
13 14
 
14 15
 /**
15 16
  * Class to implement the displaying of the recipient of the next message.
16 17
  */
17
-class MessageRecipient extends AbstractMessageRecipient {
18
+class MessageRecipient extends AbstractMessageRecipient<Props> {
18 19
     /**
19 20
      * Implements {@code PureComponent#render}.
20 21
      *

+ 17
- 0
react/features/chat/constants.js Visa fil

@@ -1,3 +1,5 @@
1
+// @flow
2
+
1 3
 /**
2 4
  * The audio ID of the audio element for which the {@link playAudio} action is
3 5
  * triggered when new chat message is received.
@@ -5,3 +7,18 @@
5 7
  * @type {string}
6 8
  */
7 9
 export const INCOMING_MSG_SOUND_ID = 'INCOMING_MSG_SOUND';
10
+
11
+/**
12
+ * The {@code messageType} of error (system) messages.
13
+ */
14
+export const MESSAGE_TYPE_ERROR = 'error';
15
+
16
+/**
17
+ * The {@code messageType} of local messages.
18
+ */
19
+export const MESSAGE_TYPE_LOCAL = 'local';
20
+
21
+/**
22
+ * The {@code messageType} of remote messages.
23
+ */
24
+export const MESSAGE_TYPE_REMOTE = 'remote';

+ 6
- 6
react/features/chat/middleware.js Visa fil

@@ -22,7 +22,7 @@ import { isButtonEnabled, showToolbox } from '../toolbox';
22 22
 import { SEND_MESSAGE, SET_PRIVATE_MESSAGE_RECIPIENT } from './actionTypes';
23 23
 import { addMessage, clearMessages, toggleChat } from './actions';
24 24
 import { ChatPrivacyDialog } from './components';
25
-import { INCOMING_MSG_SOUND_ID } from './constants';
25
+import { INCOMING_MSG_SOUND_ID, MESSAGE_TYPE_ERROR, MESSAGE_TYPE_LOCAL, MESSAGE_TYPE_REMOTE } from './constants';
26 26
 import { INCOMING_MSG_SOUND_FILE } from './sounds';
27 27
 
28 28
 declare var APP: Object;
@@ -194,7 +194,7 @@ function _addChatMsgListener(conference, store) {
194 194
 function _handleChatError({ dispatch }, error) {
195 195
     dispatch(addMessage({
196 196
         hasRead: true,
197
-        messageType: 'error',
197
+        messageType: MESSAGE_TYPE_ERROR,
198 198
         message: error,
199 199
         privateMessage: false,
200 200
         timestamp: Date.now()
@@ -231,7 +231,7 @@ function _handleReceivedMessage({ dispatch, getState }, { id, message, nick, pri
231 231
         displayName,
232 232
         hasRead,
233 233
         id,
234
-        messageType: participant.local ? 'local' : 'remote',
234
+        messageType: participant.local ? MESSAGE_TYPE_LOCAL : MESSAGE_TYPE_REMOTE,
235 235
         message,
236 236
         privateMessage,
237 237
         recipient: getParticipantDisplayName(state, localParticipant.id),
@@ -285,7 +285,7 @@ function _persistSentPrivateMessage({ dispatch, getState }, recipientID, message
285 285
         displayName,
286 286
         hasRead: true,
287 287
         id: localParticipant.id,
288
-        messageType: 'local',
288
+        messageType: MESSAGE_TYPE_LOCAL,
289 289
         message,
290 290
         privateMessage: true,
291 291
         recipient: getParticipantDisplayName(getState, recipientID),
@@ -323,7 +323,7 @@ function _shouldSendPrivateMessageTo(state, action): ?string {
323 323
     const lastMessage = navigator.product === 'ReactNative'
324 324
         ? messages[0] : messages[messages.length - 1];
325 325
 
326
-    if (lastMessage.messageType === 'local') {
326
+    if (lastMessage.messageType === MESSAGE_TYPE_LOCAL) {
327 327
         // The sender is probably aware of any private messages as already sent
328 328
         // a message since then. Doesn't make sense to display the notice now.
329 329
         return undefined;
@@ -339,7 +339,7 @@ function _shouldSendPrivateMessageTo(state, action): ?string {
339 339
     const now = Date.now();
340 340
     const recentPrivateMessages = messages.filter(
341 341
         message =>
342
-            message.messageType !== 'local'
342
+            message.messageType !== MESSAGE_TYPE_LOCAL
343 343
             && message.privateMessage
344 344
             && message.timestamp + PRIVACY_NOTICE_TIMEOUT > now);
345 345
     const recentPrivateMessage = navigator.product === 'ReactNative'

Laddar…
Avbryt
Spara