Преглед изворни кода

feat refactors the chat flow so it has open and close functions

j8
tmoldovan8x8 пре 4 година
родитељ
комит
65c56669c4
No account linked to committer's email address

+ 2
- 1
modules/API/API.js Прегледај датотеку

16
 import JitsiMeetJS, { JitsiRecordingConstants } from '../../react/features/base/lib-jitsi-meet';
16
 import JitsiMeetJS, { JitsiRecordingConstants } from '../../react/features/base/lib-jitsi-meet';
17
 import { pinParticipant, getParticipantById, kickParticipant } from '../../react/features/base/participants';
17
 import { pinParticipant, getParticipantById, kickParticipant } from '../../react/features/base/participants';
18
 import { setPrivateMessageRecipient } from '../../react/features/chat/actions';
18
 import { setPrivateMessageRecipient } from '../../react/features/chat/actions';
19
+import { openChat } from '../../react/features/chat/actions.web';
19
 import {
20
 import {
20
     processExternalDeviceRequest
21
     processExternalDeviceRequest
21
 } from '../../react/features/device-selection/functions';
22
 } from '../../react/features/device-selection/functions';
342
                 if (!isChatOpen) {
343
                 if (!isChatOpen) {
343
                     APP.UI.toggleChat();
344
                     APP.UI.toggleChat();
344
                 }
345
                 }
345
-                APP.store.dispatch(setPrivateMessageRecipient(participant));
346
+                APP.store.dispatch(openChat(participant));
346
             } else {
347
             } else {
347
                 logger.error('No participant found for the given participantId');
348
                 logger.error('No participant found for the given participantId');
348
             }
349
             }

+ 18
- 9
react/features/chat/actionTypes.js Прегледај датотеку

24
  */
24
  */
25
 export const CLEAR_MESSAGES = 'CLEAR_MESSAGES';
25
 export const CLEAR_MESSAGES = 'CLEAR_MESSAGES';
26
 
26
 
27
+/**
28
+ * The type of the action which signals the cancelation the chat panel.
29
+ *
30
+ * {
31
+ *     type: CLOSE_CHAT
32
+ * }
33
+ */
34
+export const CLOSE_CHAT = 'CLOSE_CHAT';
35
+
36
+/**
37
+ * The type of the action which signals to display the chat panel.
38
+ *
39
+ * {
40
+ *     type: OPEN_CHAT
41
+ * }
42
+ */
43
+export const OPEN_CHAT = 'OPEN_CHAT';
44
+
27
 /**
45
 /**
28
  * The type of the action which signals a send a chat message to everyone in the
46
  * The type of the action which signals a send a chat message to everyone in the
29
  * conference.
47
  * conference.
46
  * }
64
  * }
47
  */
65
  */
48
 export const SET_PRIVATE_MESSAGE_RECIPIENT = 'SET_PRIVATE_MESSAGE_RECIPIENT';
66
 export const SET_PRIVATE_MESSAGE_RECIPIENT = 'SET_PRIVATE_MESSAGE_RECIPIENT';
49
-
50
-/**
51
- * The type of the action which signals to toggle the display of the chat panel.
52
- *
53
- * {
54
- *     type: TOGGLE_CHAT
55
- * }
56
- */
57
-export const TOGGLE_CHAT = 'TOGGLE_CHAT';

+ 14
- 0
react/features/chat/actions.any.js Прегледај датотеку

3
 import {
3
 import {
4
     ADD_MESSAGE,
4
     ADD_MESSAGE,
5
     CLEAR_MESSAGES,
5
     CLEAR_MESSAGES,
6
+    CLOSE_CHAT,
6
     SEND_MESSAGE,
7
     SEND_MESSAGE,
7
     SET_PRIVATE_MESSAGE_RECIPIENT
8
     SET_PRIVATE_MESSAGE_RECIPIENT
8
 } from './actionTypes';
9
 } from './actionTypes';
49
     };
50
     };
50
 }
51
 }
51
 
52
 
53
+/**
54
+ * Action to signal the closing of the chat dialog.
55
+ *
56
+ * @returns {{
57
+ *     type: CLOSE_CHAT
58
+ * }}
59
+ */
60
+export function closeChat() {
61
+    return {
62
+        type: CLOSE_CHAT
63
+    };
64
+}
65
+
52
 /**
66
 /**
53
  * Sends a chat message to everyone in the conference.
67
  * Sends a chat message to everyone in the conference.
54
  *
68
  *

+ 12
- 6
react/features/chat/actions.native.js Прегледај датотеку

1
 // @flow
1
 // @flow
2
 
2
 
3
-import { TOGGLE_CHAT } from './actionTypes';
3
+import { OPEN_CHAT } from './actionTypes';
4
 
4
 
5
 export * from './actions.any';
5
 export * from './actions.any';
6
 
6
 
7
 /**
7
 /**
8
- * Toggles display of the chat panel.
8
+ * Displays the chat panel.
9
  *
9
  *
10
- * @returns {Function}
10
+ * @param {Object} participant - The recipient for the private chat.
11
+ *
12
+ * @returns {{
13
+ *     participant: Participant,
14
+ *     type: OPEN_CHAT
15
+ * }}
11
  */
16
  */
12
-export function toggleChat() {
13
-    return function(dispatch: (Object) => Object) {
14
-        dispatch({ type: TOGGLE_CHAT });
17
+export function openChat(participant: Object) {
18
+    return {
19
+        participant,
20
+        type: OPEN_CHAT
15
     };
21
     };
16
 }
22
 }

+ 30
- 6
react/features/chat/actions.web.js Прегледај датотеку

1
 // @flow
1
 // @flow
2
 
2
 
3
+import type { Dispatch } from 'redux';
4
+
3
 import VideoLayout from '../../../modules/UI/videolayout/VideoLayout';
5
 import VideoLayout from '../../../modules/UI/videolayout/VideoLayout';
4
 
6
 
5
-import { TOGGLE_CHAT } from './actionTypes';
7
+import { OPEN_CHAT } from './actionTypes';
8
+import { closeChat } from './actions.any';
6
 
9
 
7
 export * from './actions.any';
10
 export * from './actions.any';
8
 
11
 
9
 /**
12
 /**
10
- * Toggles display of the chat side panel while also taking window
11
- * resize into account.
13
+ * Displays the chat panel.
12
  *
14
  *
13
- * @returns {Function}
15
+ * @param {Object} participant - The recipient for the private chat.
16
+ * @returns {{
17
+ *     participant: Participant,
18
+ *     type: OPEN_CHAT
19
+ * }}
14
  */
20
  */
15
-export function toggleChat() {
21
+export function openChat(participant: Object) {
16
     return function(dispatch: (Object) => Object) {
22
     return function(dispatch: (Object) => Object) {
17
-        dispatch({ type: TOGGLE_CHAT });
23
+        dispatch({ participant,
24
+            type: OPEN_CHAT });
18
         VideoLayout.onResize();
25
         VideoLayout.onResize();
19
     };
26
     };
20
 }
27
 }
28
+
29
+/**
30
+ * Toggles display of the chat panel.
31
+ *
32
+ * @returns {Function}
33
+ */
34
+export function toggleChat() {
35
+    return (dispatch: Dispatch<any>, getState: Function) => {
36
+        const isOpen = getState()['features/chat'].isOpen;
37
+
38
+        if (isOpen) {
39
+            dispatch(closeChat());
40
+        } else {
41
+            dispatch(openChat());
42
+        }
43
+    };
44
+}

+ 28
- 35
react/features/chat/components/AbstractChat.js Прегледај датотеку

5
 
5
 
6
 import { isMobileBrowser } from '../../base/environment/utils';
6
 import { isMobileBrowser } from '../../base/environment/utils';
7
 import { getLocalParticipant } from '../../base/participants';
7
 import { getLocalParticipant } from '../../base/participants';
8
-import { sendMessage, toggleChat } from '../actions';
8
+import { sendMessage } from '../actions';
9
 import { DESKTOP_SMALL_WIDTH_THRESHOLD, MOBILE_SMALL_WIDTH_THRESHOLD } from '../constants';
9
 import { DESKTOP_SMALL_WIDTH_THRESHOLD, MOBILE_SMALL_WIDTH_THRESHOLD } from '../constants';
10
 
10
 
11
 /**
11
 /**
59
 /**
59
 /**
60
  * Implements an abstract chat panel.
60
  * Implements an abstract chat panel.
61
  */
61
  */
62
-export default class AbstractChat<P: Props> extends Component<P> {}
62
+export default class AbstractChat<P: Props> extends Component<P> {
63
 
63
 
64
-/**
65
- * Maps redux actions to the props of the component.
66
- *
67
- * @param {Function} dispatch - The redux action {@code dispatch} function.
68
- * @returns {{
69
- *     _onSendMessage: Function,
70
- *     _onToggleChat: Function
71
- * }}
72
- * @private
73
- */
74
-export function _mapDispatchToProps(dispatch: Dispatch<any>) {
75
-    return {
76
-        /**
77
-         * Toggles the chat window.
78
-         *
79
-         * @returns {Function}
80
-         */
81
-        _onToggleChat() {
82
-            dispatch(toggleChat());
83
-        },
84
-
85
-        /**
86
-         * Sends a text message.
87
-         *
88
-         * @private
89
-         * @param {string} text - The text message to be sent.
90
-         * @returns {void}
91
-         * @type {Function}
92
-         */
93
-        _onSendMessage(text: string) {
94
-            dispatch(sendMessage(text));
95
-        }
96
-    };
64
+    /**
65
+     * Initializes a new {@code AbstractChat} instance.
66
+     *
67
+     * @param {Props} props - The React {@code Component} props to initialize
68
+     * the new {@code AbstractChat} instance with.
69
+     */
70
+    constructor(props: P) {
71
+        super(props);
72
+
73
+        // Bind event handlers so they are only bound once per instance.
74
+        this._onSendMessage = this._onSendMessage.bind(this);
75
+    }
76
+
77
+    _onSendMessage: (string) => void;
78
+
79
+    /**
80
+    * Sends a text message.
81
+    *
82
+    * @private
83
+    * @param {string} text - The text message to be sent.
84
+    * @returns {void}
85
+    * @type {Function}
86
+    */
87
+    _onSendMessage(text: string) {
88
+        this.props.dispatch(sendMessage(text));
89
+    }
97
 }
90
 }
98
 
91
 
99
 /**
92
 /**

+ 8
- 22
react/features/chat/components/PrivateMessageButton.js Прегледај датотеку

5
 import { getParticipantById } from '../../base/participants';
5
 import { getParticipantById } from '../../base/participants';
6
 import { connect } from '../../base/redux';
6
 import { connect } from '../../base/redux';
7
 import { AbstractButton, type AbstractButtonProps } from '../../base/toolbox/components';
7
 import { AbstractButton, type AbstractButtonProps } from '../../base/toolbox/components';
8
-import { setPrivateMessageRecipient } from '../actions';
8
+import { openChat } from '../actions';
9
 
9
 
10
 export type Props = AbstractButtonProps & {
10
 export type Props = AbstractButtonProps & {
11
 
11
 
25
     t: Function,
25
     t: Function,
26
 
26
 
27
     /**
27
     /**
28
-     * The participant object retreived from Redux.
28
+     * The Redux dispatch function.
29
      */
29
      */
30
-    _participant: Object,
30
+    dispatch: Function,
31
 
31
 
32
     /**
32
     /**
33
-     * Function to dispatch the result of the participant selection to send a private message.
33
+     * The participant object retreived from Redux.
34
      */
34
      */
35
-    _setPrivateMessageRecipient: Function
35
+    _participant: Object,
36
 };
36
 };
37
 
37
 
38
 /**
38
 /**
51
      * @returns {void}
51
      * @returns {void}
52
      */
52
      */
53
     _handleClick() {
53
     _handleClick() {
54
-        const { _participant, _setPrivateMessageRecipient } = this.props;
54
+        const { dispatch, _participant } = this.props;
55
 
55
 
56
-        _setPrivateMessageRecipient(_participant);
56
+        dispatch(openChat(_participant));
57
     }
57
     }
58
 
58
 
59
     /**
59
     /**
69
 
69
 
70
 }
70
 }
71
 
71
 
72
-/**
73
- * Maps part of the props of this component to Redux actions.
74
- *
75
- * @param {Function} dispatch - The Redux dispatch function.
76
- * @returns {Props}
77
- */
78
-export function _mapDispatchToProps(dispatch: Function): $Shape<Props> {
79
-    return {
80
-        _setPrivateMessageRecipient: participant => {
81
-            dispatch(setPrivateMessageRecipient(participant));
82
-        }
83
-    };
84
-}
85
-
86
 /**
72
 /**
87
  * Maps part of the Redux store to the props of this component.
73
  * Maps part of the Redux store to the props of this component.
88
  *
74
  *
96
     };
82
     };
97
 }
83
 }
98
 
84
 
99
-export default translate(connect(_mapStateToProps, _mapDispatchToProps)(PrivateMessageButton));
85
+export default translate(connect(_mapStateToProps)(PrivateMessageButton));

+ 6
- 4
react/features/chat/components/native/Chat.js Прегледај датотеку

5
 import { translate } from '../../../base/i18n';
5
 import { translate } from '../../../base/i18n';
6
 import { JitsiModal } from '../../../base/modal';
6
 import { JitsiModal } from '../../../base/modal';
7
 import { connect } from '../../../base/redux';
7
 import { connect } from '../../../base/redux';
8
+import { closeChat } from '../../actions.any';
8
 import { CHAT_VIEW_MODAL_ID } from '../../constants';
9
 import { CHAT_VIEW_MODAL_ID } from '../../constants';
9
 import AbstractChat, {
10
 import AbstractChat, {
10
-    _mapDispatchToProps,
11
     _mapStateToProps,
11
     _mapStateToProps,
12
     type Props
12
     type Props
13
 } from '../AbstractChat';
13
 } from '../AbstractChat';
48
 
48
 
49
                 <MessageContainer messages = { this.props._messages } />
49
                 <MessageContainer messages = { this.props._messages } />
50
                 <MessageRecipient />
50
                 <MessageRecipient />
51
-                <ChatInputBar onSend = { this.props._onSendMessage } />
51
+                <ChatInputBar onSend = { this._onSendMessage } />
52
             </JitsiModal>
52
             </JitsiModal>
53
         );
53
         );
54
     }
54
     }
55
 
55
 
56
+    _onSendMessage: (string) => void;
57
+
56
     _onClose: () => boolean
58
     _onClose: () => boolean
57
 
59
 
58
     /**
60
     /**
61
      * @returns {boolean}
63
      * @returns {boolean}
62
      */
64
      */
63
     _onClose() {
65
     _onClose() {
64
-        this.props._onToggleChat();
66
+        this.props.dispatch(closeChat());
65
 
67
 
66
         return true;
68
         return true;
67
     }
69
     }
68
 }
70
 }
69
 
71
 
70
-export default translate(connect(_mapStateToProps, _mapDispatchToProps)(Chat));
72
+export default translate(connect(_mapStateToProps)(Chat));

+ 6
- 68
react/features/chat/components/native/ChatButton.js Прегледај датотеку

2
 
2
 
3
 import { CHAT_ENABLED, getFeatureFlag } from '../../../base/flags';
3
 import { CHAT_ENABLED, getFeatureFlag } from '../../../base/flags';
4
 import { IconChat, IconChatUnread } from '../../../base/icons';
4
 import { IconChat, IconChatUnread } from '../../../base/icons';
5
-import { setActiveModalId } from '../../../base/modal';
6
-import { getLocalParticipant } from '../../../base/participants';
7
 import { connect } from '../../../base/redux';
5
 import { connect } from '../../../base/redux';
8
 import {
6
 import {
9
     AbstractButton,
7
     AbstractButton,
10
     type AbstractButtonProps
8
     type AbstractButtonProps
11
 } from '../../../base/toolbox/components';
9
 } from '../../../base/toolbox/components';
12
-import { openDisplayNamePrompt } from '../../../display-name';
13
-import { CHAT_VIEW_MODAL_ID } from '../../constants';
10
+import { openChat } from '../../actions.native';
14
 import { getUnreadCount } from '../../functions';
11
 import { getUnreadCount } from '../../functions';
15
 
12
 
16
 type Props = AbstractButtonProps & {
13
 type Props = AbstractButtonProps & {
17
 
14
 
18
-    /**
19
-     * Function to display chat.
20
-     *
21
-     * @protected
22
-     */
23
-    _displayChat: Function,
24
-
25
-    /**
26
-     * Function to diaply the name prompt before displaying the chat
27
-     * window, if the user has no display name set.
28
-     */
29
-    _displayNameInputDialog: Function,
30
-
31
-    /**
32
-     * Whether or not to block chat access with a nickname input form.
33
-     */
34
-    _showNamePrompt: boolean,
35
-
36
     /**
15
     /**
37
      * The unread message count.
16
      * The unread message count.
38
      */
17
      */
39
-    _unreadMessageCount: number
18
+    _unreadMessageCount: number,
19
+
20
+    dispatch: Function
40
 };
21
 };
41
 
22
 
42
 /**
23
 /**
55
      * @returns {void}
36
      * @returns {void}
56
      */
37
      */
57
     _handleClick() {
38
     _handleClick() {
58
-        if (this.props._showNamePrompt) {
59
-            this.props._displayNameInputDialog(() => {
60
-                this.props._displayChat();
61
-            });
62
-        } else {
63
-            this.props._displayChat();
64
-        }
39
+        this.props.dispatch(openChat());
65
     }
40
     }
66
 
41
 
67
     /**
42
     /**
75
     }
50
     }
76
 }
51
 }
77
 
52
 
78
-/**
79
- * Maps redux actions to the props of the component.
80
- *
81
- * @param {Function} dispatch - The redux action {@code dispatch} function.
82
- * @returns {{
83
- *     _displayChat,
84
- *     _displayNameInputDialog
85
- * }}
86
- * @private
87
- */
88
-function _mapDispatchToProps(dispatch: Function) {
89
-    return {
90
-        /**
91
-         * Launches native invite dialog.
92
-         *
93
-         * @private
94
-         * @returns {void}
95
-         */
96
-        _displayChat() {
97
-            dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
98
-        },
99
-
100
-        /**
101
-         * Displays a display name prompt.
102
-         *
103
-         * @param {Function} onPostSubmit - The function to invoke after a
104
-         * succesfulsetting of the display name.
105
-         * @returns {void}
106
-         */
107
-        _displayNameInputDialog(onPostSubmit) {
108
-            dispatch(openDisplayNamePrompt(onPostSubmit));
109
-        }
110
-    };
111
-}
112
-
113
 /**
53
 /**
114
  * Maps part of the redux state to the component's props.
54
  * Maps part of the redux state to the component's props.
115
  *
55
  *
118
  * @returns {Props}
58
  * @returns {Props}
119
  */
59
  */
120
 function _mapStateToProps(state, ownProps) {
60
 function _mapStateToProps(state, ownProps) {
121
-    const localParticipant = getLocalParticipant(state);
122
     const enabled = getFeatureFlag(state, CHAT_ENABLED, true);
61
     const enabled = getFeatureFlag(state, CHAT_ENABLED, true);
123
     const { visible = enabled } = ownProps;
62
     const { visible = enabled } = ownProps;
124
 
63
 
125
     return {
64
     return {
126
-        _showNamePrompt: !localParticipant.name,
127
         _unreadMessageCount: getUnreadCount(state),
65
         _unreadMessageCount: getUnreadCount(state),
128
         visible
66
         visible
129
     };
67
     };
130
 }
68
 }
131
 
69
 
132
-export default connect(_mapStateToProps, _mapDispatchToProps)(ChatButton);
70
+export default connect(_mapStateToProps)(ChatButton);

+ 19
- 6
react/features/chat/components/web/Chat.js Прегледај датотеку

4
 
4
 
5
 import { translate } from '../../../base/i18n';
5
 import { translate } from '../../../base/i18n';
6
 import { connect } from '../../../base/redux';
6
 import { connect } from '../../../base/redux';
7
+import { toggleChat } from '../../actions.web';
7
 import AbstractChat, {
8
 import AbstractChat, {
8
-    _mapDispatchToProps,
9
     _mapStateToProps,
9
     _mapStateToProps,
10
     type Props
10
     type Props
11
 } from '../AbstractChat';
11
 } from '../AbstractChat';
49
 
49
 
50
         // Bind event handlers so they are only bound once for every instance.
50
         // Bind event handlers so they are only bound once for every instance.
51
         this._renderPanelContent = this._renderPanelContent.bind(this);
51
         this._renderPanelContent = this._renderPanelContent.bind(this);
52
-
53
-        // Bind event handlers so they are only bound once for every instance.
54
         this._onChatInputResize = this._onChatInputResize.bind(this);
52
         this._onChatInputResize = this._onChatInputResize.bind(this);
53
+        this._onToggleChat = this._onToggleChat.bind(this);
55
     }
54
     }
56
 
55
 
57
     /**
56
     /**
119
                 <MessageRecipient />
118
                 <MessageRecipient />
120
                 <ChatInput
119
                 <ChatInput
121
                     onResize = { this._onChatInputResize }
120
                     onResize = { this._onChatInputResize }
122
-                    onSend = { this.props._onSendMessage } />
121
+                    onSend = { this._onSendMessage } />
123
             </>
122
             </>
124
         );
123
         );
125
     }
124
     }
135
         return (
134
         return (
136
             <Header
135
             <Header
137
                 className = 'chat-header'
136
                 className = 'chat-header'
138
-                onCancel = { this.props._onToggleChat } />
137
+                onCancel = { this._onToggleChat } />
139
         );
138
         );
140
     }
139
     }
141
 
140
 
197
             this._messageContainerRef.current.scrollToBottom(withAnimation);
196
             this._messageContainerRef.current.scrollToBottom(withAnimation);
198
         }
197
         }
199
     }
198
     }
199
+
200
+    _onSendMessage: (string) => void;
201
+
202
+    _onToggleChat: () => void;
203
+
204
+    /**
205
+    * Toggles the chat window.
206
+    *
207
+    * @returns {Function}
208
+    */
209
+    _onToggleChat() {
210
+        this.props.dispatch(toggleChat());
211
+    }
212
+
200
 }
213
 }
201
 
214
 
202
-export default translate(connect(_mapStateToProps, _mapDispatchToProps)(Chat));
215
+export default translate(connect(_mapStateToProps)(Chat));

+ 2
- 2
react/features/chat/components/web/ChatDialogHeader.js Прегледај датотеку

5
 import { translate } from '../../../base/i18n';
5
 import { translate } from '../../../base/i18n';
6
 import { Icon, IconClose } from '../../../base/icons';
6
 import { Icon, IconClose } from '../../../base/icons';
7
 import { connect } from '../../../base/redux';
7
 import { connect } from '../../../base/redux';
8
-import { toggleChat } from '../../../chat';
8
+import { closeChat } from '../../actions.any';
9
 
9
 
10
 type Props = {
10
 type Props = {
11
 
11
 
42
     );
42
     );
43
 }
43
 }
44
 
44
 
45
-const mapDispatchToProps = { onCancel: toggleChat };
45
+const mapDispatchToProps = { onCancel: closeChat };
46
 
46
 
47
 export default translate(connect(null, mapDispatchToProps)(Header));
47
 export default translate(connect(null, mapDispatchToProps)(Header));

+ 32
- 16
react/features/chat/middleware.js Прегледај датотеку

18
 } from '../base/participants';
18
 } from '../base/participants';
19
 import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
19
 import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
20
 import { playSound, registerSound, unregisterSound } from '../base/sounds';
20
 import { playSound, registerSound, unregisterSound } from '../base/sounds';
21
+import { openDisplayNamePrompt } from '../display-name';
21
 import { showToolbox } from '../toolbox/actions';
22
 import { showToolbox } from '../toolbox/actions';
22
 
23
 
23
-import { ADD_MESSAGE, TOGGLE_CHAT, SEND_MESSAGE, SET_PRIVATE_MESSAGE_RECIPIENT } from './actionTypes';
24
-import { addMessage, clearMessages, toggleChat } from './actions';
24
+import { ADD_MESSAGE, SEND_MESSAGE, OPEN_CHAT, CLOSE_CHAT } from './actionTypes';
25
+import { addMessage, clearMessages } from './actions';
26
+import { closeChat } from './actions.any';
25
 import { ChatPrivacyDialog } from './components';
27
 import { ChatPrivacyDialog } from './components';
26
 import {
28
 import {
27
     CHAT_VIEW_MODAL_ID,
29
     CHAT_VIEW_MODAL_ID,
52
  */
54
  */
53
 MiddlewareRegistry.register(store => next => action => {
55
 MiddlewareRegistry.register(store => next => action => {
54
     const { dispatch, getState } = store;
56
     const { dispatch, getState } = store;
57
+    const localParticipant = getLocalParticipant(getState());
55
     let isOpen, unreadCount;
58
     let isOpen, unreadCount;
56
 
59
 
57
     switch (action.type) {
60
     switch (action.type) {
63
             APP.API.notifyChatUpdated(unreadCount, isOpen);
66
             APP.API.notifyChatUpdated(unreadCount, isOpen);
64
         }
67
         }
65
         break;
68
         break;
66
-    case TOGGLE_CHAT:
67
-        unreadCount = 0;
68
-        isOpen = !getState()['features/chat'].isOpen;
69
 
69
 
70
-        if (typeof APP !== 'undefined') {
71
-            APP.API.notifyChatUpdated(unreadCount, isOpen);
72
-        }
73
-        break;
74
     case APP_WILL_MOUNT:
70
     case APP_WILL_MOUNT:
75
         dispatch(
71
         dispatch(
76
                 registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_FILE));
72
                 registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_FILE));
84
         _addChatMsgListener(action.conference, store);
80
         _addChatMsgListener(action.conference, store);
85
         break;
81
         break;
86
 
82
 
83
+    case OPEN_CHAT:
84
+        if (localParticipant.name) {
85
+            dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
86
+            _maybeFocusField();
87
+        } else {
88
+            dispatch(openDisplayNamePrompt(() => {
89
+                dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
90
+                _maybeFocusField();
91
+            }));
92
+        }
93
+
94
+        unreadCount = 0;
95
+
96
+        if (typeof APP !== 'undefined') {
97
+            APP.API.notifyChatUpdated(unreadCount, true);
98
+        }
99
+        break;
100
+
101
+    case CLOSE_CHAT:
102
+        unreadCount = 0;
103
+
104
+        if (typeof APP !== 'undefined') {
105
+            APP.API.notifyChatUpdated(unreadCount, true);
106
+        }
107
+        break;
108
+
87
     case SEND_MESSAGE: {
109
     case SEND_MESSAGE: {
88
         const state = store.getState();
110
         const state = store.getState();
89
         const { conference } = state['features/base/conference'];
111
         const { conference } = state['features/base/conference'];
117
         }
139
         }
118
         break;
140
         break;
119
     }
141
     }
120
-
121
-    case SET_PRIVATE_MESSAGE_RECIPIENT: {
122
-        Boolean(action.participant) && dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
123
-        _maybeFocusField();
124
-        break;
125
-    }
126
     }
142
     }
127
 
143
 
128
     return next(action);
144
     return next(action);
141
 
157
 
142
             if (getState()['features/chat'].isOpen) {
158
             if (getState()['features/chat'].isOpen) {
143
                 // Closes the chat if it's left open.
159
                 // Closes the chat if it's left open.
144
-                dispatch(toggleChat());
160
+                dispatch(closeChat());
145
             }
161
             }
146
 
162
 
147
             // Clear chat messages.
163
             // Clear chat messages.

+ 18
- 29
react/features/chat/reducer.js Прегледај датотеку

1
 // @flow
1
 // @flow
2
 
2
 
3
-import { SET_ACTIVE_MODAL_ID } from '../base/modal';
4
 import { ReducerRegistry } from '../base/redux';
3
 import { ReducerRegistry } from '../base/redux';
5
 
4
 
6
 import {
5
 import {
7
     ADD_MESSAGE,
6
     ADD_MESSAGE,
8
     CLEAR_MESSAGES,
7
     CLEAR_MESSAGES,
9
-    SET_PRIVATE_MESSAGE_RECIPIENT,
10
-    TOGGLE_CHAT
8
+    CLOSE_CHAT,
9
+    OPEN_CHAT,
10
+    SET_PRIVATE_MESSAGE_RECIPIENT
11
 } from './actionTypes';
11
 } from './actionTypes';
12
-import { CHAT_VIEW_MODAL_ID } from './constants';
13
 
12
 
14
 const DEFAULT_STATE = {
13
 const DEFAULT_STATE = {
15
     isOpen: false,
14
     isOpen: false,
58
             messages: []
57
             messages: []
59
         };
58
         };
60
 
59
 
61
-    case SET_ACTIVE_MODAL_ID:
62
-        if (action.activeModalId === CHAT_VIEW_MODAL_ID) {
63
-            return updateChatState(state);
64
-        }
65
-
66
-        break;
67
     case SET_PRIVATE_MESSAGE_RECIPIENT:
60
     case SET_PRIVATE_MESSAGE_RECIPIENT:
68
         return {
61
         return {
69
             ...state,
62
             ...state,
70
-            isOpen: Boolean(action.participant) || state.isOpen,
71
             privateMessageRecipient: action.participant
63
             privateMessageRecipient: action.participant
72
         };
64
         };
73
 
65
 
74
-    case TOGGLE_CHAT:
75
-        return updateChatState(state);
66
+    case OPEN_CHAT:
67
+        return {
68
+            ...state,
69
+            isOpen: true,
70
+            privateMessageRecipient: action.participant
71
+        };
72
+
73
+    case CLOSE_CHAT:
74
+        return {
75
+            ...state,
76
+            isOpen: false,
77
+            lastReadMessage: state.messages[
78
+                navigator.product === 'ReactNative' ? 0 : state.messages.length - 1],
79
+            privateMessageRecipient: action.participant
80
+        };
76
     }
81
     }
77
 
82
 
78
     return state;
83
     return state;
79
 });
84
 });
80
-
81
-/**
82
- * Updates the chat status on opening the chat view.
83
- *
84
- * @param {Object} state - The Redux state of the feature.
85
- * @returns {Object}
86
- */
87
-function updateChatState(state) {
88
-    return {
89
-        ...state,
90
-        isOpen: !state.isOpen,
91
-        lastReadMessage: state.messages[
92
-            navigator.product === 'ReactNative' ? 0 : state.messages.length - 1],
93
-        privateMessageRecipient: state.isOpen ? undefined : state.privateMessageRecipient
94
-    };
95
-}

+ 4
- 4
react/features/remote-video-menu/components/web/PrivateMessageMenuButton.js Прегледај датотеку

5
 import { translate } from '../../../base/i18n';
5
 import { translate } from '../../../base/i18n';
6
 import { IconMessage } from '../../../base/icons';
6
 import { IconMessage } from '../../../base/icons';
7
 import { connect } from '../../../base/redux';
7
 import { connect } from '../../../base/redux';
8
+import { openChat } from '../../../chat/';
8
 import {
9
 import {
9
-    _mapDispatchToProps,
10
     _mapStateToProps as _abstractMapStateToProps,
10
     _mapStateToProps as _abstractMapStateToProps,
11
     type Props as AbstractProps
11
     type Props as AbstractProps
12
 } from '../../../chat/components/PrivateMessageButton';
12
 } from '../../../chat/components/PrivateMessageButton';
72
      * @returns {void}
72
      * @returns {void}
73
      */
73
      */
74
     _onClick() {
74
     _onClick() {
75
-        const { _participant, _setPrivateMessageRecipient } = this.props;
75
+        const { dispatch, _participant } = this.props;
76
 
76
 
77
-        _setPrivateMessageRecipient(_participant);
77
+        dispatch(openChat(_participant));
78
     }
78
     }
79
 }
79
 }
80
 
80
 
93
     };
93
     };
94
 }
94
 }
95
 
95
 
96
-export default translate(connect(_mapStateToProps, _mapDispatchToProps)(PrivateMessageMenuButton));
96
+export default translate(connect(_mapStateToProps)(PrivateMessageMenuButton));

Loading…
Откажи
Сачувај