Переглянути джерело

feat(Chat): Revamp design.

* ensure keyboard stays open when sending messages on mobile web.
master
Mihai-Andrei Uscat 4 роки тому
джерело
коміт
7dabfc21b4
Аккаунт користувача з таким Email не знайдено

+ 11
- 0
css/_atlaskit_overrides.scss Переглянути файл

123
     }
123
     }
124
 }
124
 }
125
 
125
 
126
+// Override Atlaskit inline style for the modal background.
127
+// Important is unfortunately needed for that.
128
+.shift-right .focus-lock [role="dialog"][style] {
129
+    background-color: $chatBackgroundColor !important;
130
+}
131
+
132
+// Remove Atlaskit padding from the chat dialog.
133
+.shift-right .focus-lock [role="dialog"] > div:first-child > div:nth-child(2) {
134
+    padding: 0;
135
+}
136
+
126
 div.Tooltip {
137
 div.Tooltip {
127
     color: #fff;
138
     color: #fff;
128
     font-size: 12px;
139
     font-size: 12px;

+ 46
- 32
css/_chat.scss Переглянути файл

1
 #sideToolbarContainer {
1
 #sideToolbarContainer {
2
-    background-color: $newToolbarBackgroundColor;
2
+    background-color: $chatBackgroundColor;
3
     box-sizing: border-box;
3
     box-sizing: border-box;
4
     color: #FFF;
4
     color: #FFF;
5
     display: flex;
5
     display: flex;
105
 }
105
 }
106
 
106
 
107
 .chat-header {
107
 .chat-header {
108
-    background-color: $chatHeaderBackgroundColor;
109
     height: 70px;
108
     height: 70px;
110
     position: relative;
109
     position: relative;
111
     width: 100%;
110
     width: 100%;
112
     z-index: 1;
111
     z-index: 1;
113
     display: flex;
112
     display: flex;
114
-    justify-content: space-between;
113
+    justify-content: flex-end;
115
     padding: 16px;
114
     padding: 16px;
116
     align-items: center;
115
     align-items: center;
117
     box-sizing: border-box;
116
     box-sizing: border-box;
123
     .jitsi-icon {
122
     .jitsi-icon {
124
         cursor: pointer;
123
         cursor: pointer;
125
     }
124
     }
126
-
127
-    .jitsi-icon > svg {
128
-        fill: #A4B8D1;
129
-    }
130
 }
125
 }
131
 
126
 
132
 .chat-input-container {
127
 .chat-input-container {
133
-    padding: 0 16px 24px;
128
+    padding: 0 16px 16px;
134
 
129
 
135
     &.populated {
130
     &.populated {
136
         #chat-input {
131
         #chat-input {
137
-            border: 1px solid #619CF4;
132
+            &:focus-within {
133
+                border: 1px solid #619CF4;
134
+            }
138
 
135
 
139
             .send-button {
136
             .send-button {
140
                 background: #1B67EC;
137
                 background: #1B67EC;
141
                 cursor: pointer;
138
                 cursor: pointer;
142
 
139
 
140
+                @media (hover: hover) and (pointer: fine) {
141
+                    &:hover {
142
+                        background: #3D82FB;
143
+                    }
144
+                }
145
+
146
+                &:active {
147
+                    background: #0852D4;
148
+                }
149
+
143
                 path {
150
                 path {
144
                     fill: #fff;
151
                     fill: #fff;
145
                 }
152
                 }
151
 #chat-input {
158
 #chat-input {
152
     border: 1px solid $chatInputSeparatorColor;
159
     border: 1px solid $chatInputSeparatorColor;
153
     display: flex;
160
     display: flex;
154
-    padding: 5px 10px;
161
+    padding: 4px;
155
     border-radius: 3px;
162
     border-radius: 3px;
156
 
163
 
157
     * {
164
     * {
177
     }
184
     }
178
 }
185
 }
179
 
186
 
180
-.mobile-browser {
181
-    .send-button {
182
-        height: 48px;
183
-        width: 48px;
187
+.smiley-button {
188
+    display: flex;
189
+    align-items: center;
190
+    justify-content: center;
191
+    height: 40px;
192
+    width: 40px;
193
+    border-radius: 3px;
194
+}
195
+
196
+#chat-input .smiley-button {
197
+    @media (hover: hover) and (pointer: fine) {
198
+        &:hover {
199
+            background-color: #484A4F;
200
+        }
184
     }
201
     }
185
 }
202
 }
186
 
203
 
263
     }
280
     }
264
 
281
 
265
     .display-name {
282
     .display-name {
266
-        font-size: 13px;
267
-        font-weight: bold;
283
+        font-size: 12px;
284
+        font-weight: 600;
268
         margin-bottom: 5px;
285
         margin-bottom: 5px;
269
         white-space: nowrap;
286
         white-space: nowrap;
270
         text-overflow: ellipsis;
287
         text-overflow: ellipsis;
314
     }
331
     }
315
 
332
 
316
     .messagecontent {
333
     .messagecontent {
317
-        margin: 5px 10px;
334
+        margin: 8px;
318
         max-width: 100%;
335
         max-width: 100%;
319
         overflow: hidden;
336
         overflow: hidden;
320
     }
337
     }
321
 }
338
 }
322
 
339
 
340
+.timestamp {
341
+    color: #757575;
342
+}
343
+
323
 .smiley {
344
 .smiley {
324
     font-size: 14pt;
345
     font-size: 14pt;
325
 }
346
 }
355
     max-height: 0;
376
     max-height: 0;
356
     overflow: hidden;
377
     overflow: hidden;
357
     position: absolute;
378
     position: absolute;
358
-    width: $sidebarWidth;
379
+    width: calc(#{$sidebarWidth} - 32px);
380
+    margin-bottom: 5px;
381
+    margin-left: -5px;
359
 
382
 
360
     /**
383
     /**
361
      * CSS transitions do not apply for auto dimensions. So to produce the css
384
      * CSS transitions do not apply for auto dimensions. So to produce the css
370
     }
393
     }
371
 
394
 
372
     #smileysContainer {
395
     #smileysContainer {
373
-        background-color: $newToolbarBackgroundColor;
374
-        border-bottom: 1px solid;
375
-        border-top: 1px solid;
396
+        background-color: $chatBackgroundColor;
397
+        border-top: 1px solid $chatInputSeparatorColor;
376
     }
398
     }
377
 }
399
 }
378
 
400
 
478
 
500
 
479
     &-header {
501
     &-header {
480
         display: flex;
502
         display: flex;
481
-        justify-content: space-between;
503
+        justify-content: flex-end;
482
         align-items: center;
504
         align-items: center;
483
-        margin: 16px 16px 24px;
505
+        margin: 16px;
484
         width: calc(100% - 32px);
506
         width: calc(100% - 32px);
485
         box-sizing: border-box;
507
         box-sizing: border-box;
486
         color: #fff;
508
         color: #fff;
491
         .jitsi-icon {
513
         .jitsi-icon {
492
             cursor: pointer;
514
             cursor: pointer;
493
         }
515
         }
494
-
495
-        .jitsi-icon > svg {
496
-            fill: #A4B8D1;
497
-        }
498
     }
516
     }
499
 
517
 
500
     #chatconversation {
518
     #chatconversation {
501
         width: 100%;
519
         width: 100%;
502
     }
520
     }
503
-
504
-    .chat-input-container {
505
-        padding: 0 0 24px;
506
-    }
507
 }
521
 }
508
 
522
 
509
 .touchmove-hack {
523
 .touchmove-hack {
520
     place-items: center;
534
     place-items: center;
521
     height: 48px;
535
     height: 48px;
522
     width: 48px;
536
     width: 48px;
523
-    background: #2a3a4b;
537
+    background: #36383C;
524
     border-radius: 3px;
538
     border-radius: 3px;
525
 }
539
 }

+ 4
- 4
css/_variables.scss Переглянути файл

91
  * Chat
91
  * Chat
92
  */
92
  */
93
 $chatActionsSeparatorColor: rgb(173, 105, 112);
93
 $chatActionsSeparatorColor: rgb(173, 105, 112);
94
-$chatHeaderBackgroundColor: rgba(42, 58, 75, 0.9);
94
+$chatBackgroundColor: #131519;
95
 $chatInputSeparatorColor: #A4B8D1;
95
 $chatInputSeparatorColor: #A4B8D1;
96
-$chatLocalMessageBackgroundColor: rgb(4, 98, 178);
96
+$chatLocalMessageBackgroundColor: #484A4F;
97
 $chatPrivateMessageBackgroundColor: rgb(153, 69, 77);
97
 $chatPrivateMessageBackgroundColor: rgb(153, 69, 77);
98
-$chatRemoteMessageBackgroundColor:  rgb(86, 101, 114);
99
-$sidebarWidth: 375px;
98
+$chatRemoteMessageBackgroundColor:  #242528;
99
+$sidebarWidth: 315px;
100
 
100
 
101
  /**
101
  /**
102
  * Misc.
102
  * Misc.

+ 1
- 0
react/features/base/icons/svg/index.js Переглянути файл

102
 export { default as IconShareDesktop } from './share-desktop.svg';
102
 export { default as IconShareDesktop } from './share-desktop.svg';
103
 export { default as IconShareDoc } from './share-doc.svg';
103
 export { default as IconShareDoc } from './share-doc.svg';
104
 export { default as IconShareVideo } from './shared-video.svg';
104
 export { default as IconShareVideo } from './shared-video.svg';
105
+export { default as IconSmile } from './smile.svg';
105
 export { default as IconSwitchCamera } from './switch-camera.svg';
106
 export { default as IconSwitchCamera } from './switch-camera.svg';
106
 export { default as IconTileView } from './tiles-many.svg';
107
 export { default as IconTileView } from './tiles-many.svg';
107
 export { default as IconToggleRecording } from './camera-take-picture.svg';
108
 export { default as IconToggleRecording } from './camera-take-picture.svg';

+ 3
- 0
react/features/base/icons/svg/smile.svg Переглянути файл

1
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+<path fill-rule="evenodd" clip-rule="evenodd" d="M9.99996 18.3333C5.39759 18.3333 1.66663 14.6023 1.66663 9.99996C1.66663 5.39759 5.39759 1.66663 9.99996 1.66663C14.6023 1.66663 18.3333 5.39759 18.3333 9.99996C18.3333 14.6023 14.6023 18.3333 9.99996 18.3333ZM9.99996 16.6666C13.6819 16.6666 16.6666 13.6819 16.6666 9.99996C16.6666 6.31806 13.6819 3.33329 9.99996 3.33329C6.31806 3.33329 3.33329 6.31806 3.33329 9.99996C3.33329 13.6819 6.31806 16.6666 9.99996 16.6666ZM8.33329 8.74996C8.33329 9.44031 7.77365 9.99996 7.08329 9.99996C6.39294 9.99996 5.83329 9.44031 5.83329 8.74996C5.83329 8.0596 6.39294 7.49996 7.08329 7.49996C7.77365 7.49996 8.33329 8.0596 8.33329 8.74996ZM12.9166 9.99996C13.607 9.99996 14.1666 9.44031 14.1666 8.74996C14.1666 8.0596 13.607 7.49996 12.9166 7.49996C12.2263 7.49996 11.6666 8.0596 11.6666 8.74996C11.6666 9.44031 12.2263 9.99996 12.9166 9.99996ZM9.99996 15C11.7491 15 13.2885 14.1018 14.1821 12.7414L12.8867 11.6691C12.3021 12.6792 11.2131 13.3333 9.99996 13.3333C8.801 13.3333 7.71376 12.6771 7.12376 11.6672L5.8304 12.741C6.72576 14.0962 8.25894 15 9.99996 15Z"/>
3
+</svg>

+ 2
- 9
react/features/chat/components/web/ChatDialogHeader.js Переглянути файл

2
 
2
 
3
 import React from 'react';
3
 import React from 'react';
4
 
4
 
5
-import { translate } from '../../../base/i18n';
6
 import { Icon, IconClose } from '../../../base/icons';
5
 import { Icon, IconClose } from '../../../base/icons';
7
 import { connect } from '../../../base/redux';
6
 import { connect } from '../../../base/redux';
8
 import { toggleChat } from '../../actions.web';
7
 import { toggleChat } from '../../actions.web';
18
      * An optional class name.
17
      * An optional class name.
19
      */
18
      */
20
     className: string,
19
     className: string,
21
-
22
-    /**
23
-     * Invoked to obtain translated strings.
24
-     */
25
-    t: Function
26
 };
20
 };
27
 
21
 
28
 /**
22
 /**
30
  *
24
  *
31
  * @returns {React$Element<any>}
25
  * @returns {React$Element<any>}
32
  */
26
  */
33
-function Header({ onCancel, className, t }: Props) {
27
+function Header({ onCancel, className }: Props) {
34
     return (
28
     return (
35
         <div
29
         <div
36
             className = { className || 'chat-dialog-header' }>
30
             className = { className || 'chat-dialog-header' }>
37
-            { t('chat.title') }
38
             <Icon
31
             <Icon
39
                 onClick = { onCancel }
32
                 onClick = { onCancel }
40
                 src = { IconClose } />
33
                 src = { IconClose } />
44
 
37
 
45
 const mapDispatchToProps = { onCancel: toggleChat };
38
 const mapDispatchToProps = { onCancel: toggleChat };
46
 
39
 
47
-export default translate(connect(null, mapDispatchToProps)(Header));
40
+export default connect(null, mapDispatchToProps)(Header);

+ 14
- 10
react/features/chat/components/web/ChatInput.js Переглянути файл

1
 // @flow
1
 // @flow
2
 
2
 
3
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
4
-import Emoji from 'react-emoji-render';
5
 import TextareaAutosize from 'react-textarea-autosize';
4
 import TextareaAutosize from 'react-textarea-autosize';
6
 import type { Dispatch } from 'redux';
5
 import type { Dispatch } from 'redux';
7
 
6
 
7
+import { isMobileBrowser } from '../../../base/environment/utils';
8
 import { translate } from '../../../base/i18n';
8
 import { translate } from '../../../base/i18n';
9
-import { Icon, IconPlane } from '../../../base/icons';
9
+import { Icon, IconPlane, IconSmile } from '../../../base/icons';
10
 import { connect } from '../../../base/redux';
10
 import { connect } from '../../../base/redux';
11
 
11
 
12
 import SmileysPanel from './SmileysPanel';
12
 import SmileysPanel from './SmileysPanel';
93
      * @inheritdoc
93
      * @inheritdoc
94
      */
94
      */
95
     componentDidMount() {
95
     componentDidMount() {
96
-        /**
97
-         * HTML Textareas do not support autofocus. Simulate autofocus by
98
-         * manually focusing.
99
-         */
100
-        this._focus();
96
+        if (isMobileBrowser()) {
97
+            // Ensure textarea is not focused when opening chat on mobile browser.
98
+            this._textArea && this._textArea.blur();
99
+        }
101
     }
100
     }
102
 
101
 
103
     /**
102
     /**
116
                     <div className = 'smiley-input'>
115
                     <div className = 'smiley-input'>
117
                         <div id = 'smileysarea'>
116
                         <div id = 'smileysarea'>
118
                             <div id = 'smileys'>
117
                             <div id = 'smileys'>
119
-                                <Emoji
120
-                                    onClick = { this._onToggleSmileysPanel }
121
-                                    text = ':)' />
118
+                                <div
119
+                                    className = 'smiley-button'
120
+                                    onClick = { this._onToggleSmileysPanel }>
121
+                                    <Icon src = { IconSmile } />
122
+                                </div>
122
                             </div>
123
                             </div>
123
                         </div>
124
                         </div>
124
                         <div className = { smileysPanelClassName }>
125
                         <div className = { smileysPanelClassName }>
174
             this.props.onSend(trimmed);
175
             this.props.onSend(trimmed);
175
 
176
 
176
             this.setState({ message: '' });
177
             this.setState({ message: '' });
178
+
179
+            // Keep the textarea in focus when sending messages via submit button.
180
+            this._focus();
177
         }
181
         }
178
 
182
 
179
     }
183
     }

+ 1
- 1
react/features/chat/constants.js Переглянути файл

5
 /**
5
 /**
6
  * The size of the chat.
6
  * The size of the chat.
7
  */
7
  */
8
-export const CHAT_SIZE = 375;
8
+export const CHAT_SIZE = 315;
9
 
9
 
10
 /**
10
 /**
11
  * The audio ID of the audio element for which the {@link playAudio} action is
11
  * The audio ID of the audio element for which the {@link playAudio} action is

+ 9
- 20
react/features/chat/middleware.js Переглянути файл

81
         break;
81
         break;
82
 
82
 
83
     case OPEN_CHAT:
83
     case OPEN_CHAT:
84
-        if (localParticipant.name) {
85
-            dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
86
-            _maybeFocusField();
87
-        } else {
88
-            dispatch(openDisplayNamePrompt(() => {
84
+        if (navigator.product === 'ReactNative') {
85
+            if (localParticipant.name) {
89
                 dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
86
                 dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
90
-                _maybeFocusField();
91
-            }));
87
+            } else {
88
+                dispatch(openDisplayNamePrompt(() => {
89
+                    dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
90
+                }));
91
+            }
92
+        } else {
93
+            dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
92
         }
94
         }
93
 
95
 
94
         unreadCount = 0;
96
         unreadCount = 0;
291
     }
293
     }
292
 }
294
 }
293
 
295
 
294
-/**
295
- * Focuses the chat text field on web after the message recipient was updated, if needed.
296
- *
297
- * @returns {void}
298
- */
299
-function _maybeFocusField() {
300
-    if (navigator.product !== 'ReactNative') {
301
-        const textField = document.getElementById('usermsg');
302
-
303
-        textField && textField.focus();
304
-    }
305
-}
306
-
307
 /**
296
 /**
308
  * Persists the sent private messages as if they were received over the muc.
297
  * Persists the sent private messages as if they were received over the muc.
309
  *
298
  *

Завантаження…
Відмінити
Зберегти