feat refactors the chat flow so it has open and close functions
This commit is contained in:
parent
2cd43ba2e4
commit
65c56669c4
|
@ -16,6 +16,7 @@ import { parseJWTFromURLParams } from '../../react/features/base/jwt';
|
|||
import JitsiMeetJS, { JitsiRecordingConstants } from '../../react/features/base/lib-jitsi-meet';
|
||||
import { pinParticipant, getParticipantById, kickParticipant } from '../../react/features/base/participants';
|
||||
import { setPrivateMessageRecipient } from '../../react/features/chat/actions';
|
||||
import { openChat } from '../../react/features/chat/actions.web';
|
||||
import {
|
||||
processExternalDeviceRequest
|
||||
} from '../../react/features/device-selection/functions';
|
||||
|
@ -342,7 +343,7 @@ function initCommands() {
|
|||
if (!isChatOpen) {
|
||||
APP.UI.toggleChat();
|
||||
}
|
||||
APP.store.dispatch(setPrivateMessageRecipient(participant));
|
||||
APP.store.dispatch(openChat(participant));
|
||||
} else {
|
||||
logger.error('No participant found for the given participantId');
|
||||
}
|
||||
|
|
|
@ -24,6 +24,24 @@ export const ADD_MESSAGE = 'ADD_MESSAGE';
|
|||
*/
|
||||
export const CLEAR_MESSAGES = 'CLEAR_MESSAGES';
|
||||
|
||||
/**
|
||||
* The type of the action which signals the cancelation the chat panel.
|
||||
*
|
||||
* {
|
||||
* type: CLOSE_CHAT
|
||||
* }
|
||||
*/
|
||||
export const CLOSE_CHAT = 'CLOSE_CHAT';
|
||||
|
||||
/**
|
||||
* The type of the action which signals to display the chat panel.
|
||||
*
|
||||
* {
|
||||
* type: OPEN_CHAT
|
||||
* }
|
||||
*/
|
||||
export const OPEN_CHAT = 'OPEN_CHAT';
|
||||
|
||||
/**
|
||||
* The type of the action which signals a send a chat message to everyone in the
|
||||
* conference.
|
||||
|
@ -46,12 +64,3 @@ export const SEND_MESSAGE = 'SEND_MESSAGE';
|
|||
* }
|
||||
*/
|
||||
export const SET_PRIVATE_MESSAGE_RECIPIENT = 'SET_PRIVATE_MESSAGE_RECIPIENT';
|
||||
|
||||
/**
|
||||
* The type of the action which signals to toggle the display of the chat panel.
|
||||
*
|
||||
* {
|
||||
* type: TOGGLE_CHAT
|
||||
* }
|
||||
*/
|
||||
export const TOGGLE_CHAT = 'TOGGLE_CHAT';
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import {
|
||||
ADD_MESSAGE,
|
||||
CLEAR_MESSAGES,
|
||||
CLOSE_CHAT,
|
||||
SEND_MESSAGE,
|
||||
SET_PRIVATE_MESSAGE_RECIPIENT
|
||||
} from './actionTypes';
|
||||
|
@ -49,6 +50,19 @@ export function clearMessages() {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to signal the closing of the chat dialog.
|
||||
*
|
||||
* @returns {{
|
||||
* type: CLOSE_CHAT
|
||||
* }}
|
||||
*/
|
||||
export function closeChat() {
|
||||
return {
|
||||
type: CLOSE_CHAT
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a chat message to everyone in the conference.
|
||||
*
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
// @flow
|
||||
|
||||
import { TOGGLE_CHAT } from './actionTypes';
|
||||
import { OPEN_CHAT } from './actionTypes';
|
||||
|
||||
export * from './actions.any';
|
||||
|
||||
/**
|
||||
* Toggles display of the chat panel.
|
||||
* Displays the chat panel.
|
||||
*
|
||||
* @returns {Function}
|
||||
* @param {Object} participant - The recipient for the private chat.
|
||||
*
|
||||
* @returns {{
|
||||
* participant: Participant,
|
||||
* type: OPEN_CHAT
|
||||
* }}
|
||||
*/
|
||||
export function toggleChat() {
|
||||
return function(dispatch: (Object) => Object) {
|
||||
dispatch({ type: TOGGLE_CHAT });
|
||||
export function openChat(participant: Object) {
|
||||
return {
|
||||
participant,
|
||||
type: OPEN_CHAT
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,20 +1,44 @@
|
|||
// @flow
|
||||
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import VideoLayout from '../../../modules/UI/videolayout/VideoLayout';
|
||||
|
||||
import { TOGGLE_CHAT } from './actionTypes';
|
||||
import { OPEN_CHAT } from './actionTypes';
|
||||
import { closeChat } from './actions.any';
|
||||
|
||||
export * from './actions.any';
|
||||
|
||||
/**
|
||||
* Toggles display of the chat side panel while also taking window
|
||||
* resize into account.
|
||||
* Displays the chat panel.
|
||||
*
|
||||
* @param {Object} participant - The recipient for the private chat.
|
||||
* @returns {{
|
||||
* participant: Participant,
|
||||
* type: OPEN_CHAT
|
||||
* }}
|
||||
*/
|
||||
export function openChat(participant: Object) {
|
||||
return function(dispatch: (Object) => Object) {
|
||||
dispatch({ participant,
|
||||
type: OPEN_CHAT });
|
||||
VideoLayout.onResize();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles display of the chat panel.
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function toggleChat() {
|
||||
return function(dispatch: (Object) => Object) {
|
||||
dispatch({ type: TOGGLE_CHAT });
|
||||
VideoLayout.onResize();
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
const isOpen = getState()['features/chat'].isOpen;
|
||||
|
||||
if (isOpen) {
|
||||
dispatch(closeChat());
|
||||
} else {
|
||||
dispatch(openChat());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import type { Dispatch } from 'redux';
|
|||
|
||||
import { isMobileBrowser } from '../../base/environment/utils';
|
||||
import { getLocalParticipant } from '../../base/participants';
|
||||
import { sendMessage, toggleChat } from '../actions';
|
||||
import { sendMessage } from '../actions';
|
||||
import { DESKTOP_SMALL_WIDTH_THRESHOLD, MOBILE_SMALL_WIDTH_THRESHOLD } from '../constants';
|
||||
|
||||
/**
|
||||
|
@ -59,41 +59,34 @@ export type Props = {
|
|||
/**
|
||||
* Implements an abstract chat panel.
|
||||
*/
|
||||
export default class AbstractChat<P: Props> extends Component<P> {}
|
||||
export default class AbstractChat<P: Props> extends Component<P> {
|
||||
|
||||
/**
|
||||
* Maps redux actions to the props of the component.
|
||||
*
|
||||
* @param {Function} dispatch - The redux action {@code dispatch} function.
|
||||
* @returns {{
|
||||
* _onSendMessage: Function,
|
||||
* _onToggleChat: Function
|
||||
* }}
|
||||
* @private
|
||||
*/
|
||||
export function _mapDispatchToProps(dispatch: Dispatch<any>) {
|
||||
return {
|
||||
/**
|
||||
* Toggles the chat window.
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
_onToggleChat() {
|
||||
dispatch(toggleChat());
|
||||
},
|
||||
/**
|
||||
* Initializes a new {@code AbstractChat} instance.
|
||||
*
|
||||
* @param {Props} props - The React {@code Component} props to initialize
|
||||
* the new {@code AbstractChat} instance with.
|
||||
*/
|
||||
constructor(props: P) {
|
||||
super(props);
|
||||
|
||||
/**
|
||||
* Sends a text message.
|
||||
*
|
||||
* @private
|
||||
* @param {string} text - The text message to be sent.
|
||||
* @returns {void}
|
||||
* @type {Function}
|
||||
*/
|
||||
_onSendMessage(text: string) {
|
||||
dispatch(sendMessage(text));
|
||||
}
|
||||
};
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onSendMessage = this._onSendMessage.bind(this);
|
||||
}
|
||||
|
||||
_onSendMessage: (string) => void;
|
||||
|
||||
/**
|
||||
* Sends a text message.
|
||||
*
|
||||
* @private
|
||||
* @param {string} text - The text message to be sent.
|
||||
* @returns {void}
|
||||
* @type {Function}
|
||||
*/
|
||||
_onSendMessage(text: string) {
|
||||
this.props.dispatch(sendMessage(text));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,7 @@ import { IconMessage, IconReply } from '../../base/icons';
|
|||
import { getParticipantById } from '../../base/participants';
|
||||
import { connect } from '../../base/redux';
|
||||
import { AbstractButton, type AbstractButtonProps } from '../../base/toolbox/components';
|
||||
import { setPrivateMessageRecipient } from '../actions';
|
||||
import { openChat } from '../actions';
|
||||
|
||||
export type Props = AbstractButtonProps & {
|
||||
|
||||
|
@ -24,15 +24,15 @@ export type Props = AbstractButtonProps & {
|
|||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* The Redux dispatch function.
|
||||
*/
|
||||
dispatch: Function,
|
||||
|
||||
/**
|
||||
* The participant object retreived from Redux.
|
||||
*/
|
||||
_participant: Object,
|
||||
|
||||
/**
|
||||
* Function to dispatch the result of the participant selection to send a private message.
|
||||
*/
|
||||
_setPrivateMessageRecipient: Function
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -51,9 +51,9 @@ class PrivateMessageButton extends AbstractButton<Props, any> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_handleClick() {
|
||||
const { _participant, _setPrivateMessageRecipient } = this.props;
|
||||
const { dispatch, _participant } = this.props;
|
||||
|
||||
_setPrivateMessageRecipient(_participant);
|
||||
dispatch(openChat(_participant));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,20 +69,6 @@ class PrivateMessageButton extends AbstractButton<Props, any> {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the props of this component to Redux actions.
|
||||
*
|
||||
* @param {Function} dispatch - The Redux dispatch function.
|
||||
* @returns {Props}
|
||||
*/
|
||||
export function _mapDispatchToProps(dispatch: Function): $Shape<Props> {
|
||||
return {
|
||||
_setPrivateMessageRecipient: participant => {
|
||||
dispatch(setPrivateMessageRecipient(participant));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the Redux store to the props of this component.
|
||||
*
|
||||
|
@ -96,4 +82,4 @@ export function _mapStateToProps(state: Object, ownProps: Props): $Shape<Props>
|
|||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps, _mapDispatchToProps)(PrivateMessageButton));
|
||||
export default translate(connect(_mapStateToProps)(PrivateMessageButton));
|
||||
|
|
|
@ -5,9 +5,9 @@ import React from 'react';
|
|||
import { translate } from '../../../base/i18n';
|
||||
import { JitsiModal } from '../../../base/modal';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { closeChat } from '../../actions.any';
|
||||
import { CHAT_VIEW_MODAL_ID } from '../../constants';
|
||||
import AbstractChat, {
|
||||
_mapDispatchToProps,
|
||||
_mapStateToProps,
|
||||
type Props
|
||||
} from '../AbstractChat';
|
||||
|
@ -48,11 +48,13 @@ class Chat extends AbstractChat<Props> {
|
|||
|
||||
<MessageContainer messages = { this.props._messages } />
|
||||
<MessageRecipient />
|
||||
<ChatInputBar onSend = { this.props._onSendMessage } />
|
||||
<ChatInputBar onSend = { this._onSendMessage } />
|
||||
</JitsiModal>
|
||||
);
|
||||
}
|
||||
|
||||
_onSendMessage: (string) => void;
|
||||
|
||||
_onClose: () => boolean
|
||||
|
||||
/**
|
||||
|
@ -61,10 +63,10 @@ class Chat extends AbstractChat<Props> {
|
|||
* @returns {boolean}
|
||||
*/
|
||||
_onClose() {
|
||||
this.props._onToggleChat();
|
||||
this.props.dispatch(closeChat());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps, _mapDispatchToProps)(Chat));
|
||||
export default translate(connect(_mapStateToProps)(Chat));
|
||||
|
|
|
@ -2,41 +2,22 @@
|
|||
|
||||
import { CHAT_ENABLED, getFeatureFlag } from '../../../base/flags';
|
||||
import { IconChat, IconChatUnread } from '../../../base/icons';
|
||||
import { setActiveModalId } from '../../../base/modal';
|
||||
import { getLocalParticipant } from '../../../base/participants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import {
|
||||
AbstractButton,
|
||||
type AbstractButtonProps
|
||||
} from '../../../base/toolbox/components';
|
||||
import { openDisplayNamePrompt } from '../../../display-name';
|
||||
import { CHAT_VIEW_MODAL_ID } from '../../constants';
|
||||
import { openChat } from '../../actions.native';
|
||||
import { getUnreadCount } from '../../functions';
|
||||
|
||||
type Props = AbstractButtonProps & {
|
||||
|
||||
/**
|
||||
* Function to display chat.
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
_displayChat: Function,
|
||||
|
||||
/**
|
||||
* Function to diaply the name prompt before displaying the chat
|
||||
* window, if the user has no display name set.
|
||||
*/
|
||||
_displayNameInputDialog: Function,
|
||||
|
||||
/**
|
||||
* Whether or not to block chat access with a nickname input form.
|
||||
*/
|
||||
_showNamePrompt: boolean,
|
||||
|
||||
/**
|
||||
* The unread message count.
|
||||
*/
|
||||
_unreadMessageCount: number
|
||||
_unreadMessageCount: number,
|
||||
|
||||
dispatch: Function
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -55,13 +36,7 @@ class ChatButton extends AbstractButton<Props, *> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_handleClick() {
|
||||
if (this.props._showNamePrompt) {
|
||||
this.props._displayNameInputDialog(() => {
|
||||
this.props._displayChat();
|
||||
});
|
||||
} else {
|
||||
this.props._displayChat();
|
||||
}
|
||||
this.props.dispatch(openChat());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,41 +50,6 @@ class ChatButton extends AbstractButton<Props, *> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps redux actions to the props of the component.
|
||||
*
|
||||
* @param {Function} dispatch - The redux action {@code dispatch} function.
|
||||
* @returns {{
|
||||
* _displayChat,
|
||||
* _displayNameInputDialog
|
||||
* }}
|
||||
* @private
|
||||
*/
|
||||
function _mapDispatchToProps(dispatch: Function) {
|
||||
return {
|
||||
/**
|
||||
* Launches native invite dialog.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_displayChat() {
|
||||
dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays a display name prompt.
|
||||
*
|
||||
* @param {Function} onPostSubmit - The function to invoke after a
|
||||
* succesfulsetting of the display name.
|
||||
* @returns {void}
|
||||
*/
|
||||
_displayNameInputDialog(onPostSubmit) {
|
||||
dispatch(openDisplayNamePrompt(onPostSubmit));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps part of the redux state to the component's props.
|
||||
*
|
||||
|
@ -118,15 +58,13 @@ function _mapDispatchToProps(dispatch: Function) {
|
|||
* @returns {Props}
|
||||
*/
|
||||
function _mapStateToProps(state, ownProps) {
|
||||
const localParticipant = getLocalParticipant(state);
|
||||
const enabled = getFeatureFlag(state, CHAT_ENABLED, true);
|
||||
const { visible = enabled } = ownProps;
|
||||
|
||||
return {
|
||||
_showNamePrompt: !localParticipant.name,
|
||||
_unreadMessageCount: getUnreadCount(state),
|
||||
visible
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(_mapStateToProps, _mapDispatchToProps)(ChatButton);
|
||||
export default connect(_mapStateToProps)(ChatButton);
|
||||
|
|
|
@ -4,8 +4,8 @@ import React from 'react';
|
|||
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { toggleChat } from '../../actions.web';
|
||||
import AbstractChat, {
|
||||
_mapDispatchToProps,
|
||||
_mapStateToProps,
|
||||
type Props
|
||||
} from '../AbstractChat';
|
||||
|
@ -49,9 +49,8 @@ class Chat extends AbstractChat<Props> {
|
|||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
this._renderPanelContent = this._renderPanelContent.bind(this);
|
||||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
this._onChatInputResize = this._onChatInputResize.bind(this);
|
||||
this._onToggleChat = this._onToggleChat.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,7 +118,7 @@ class Chat extends AbstractChat<Props> {
|
|||
<MessageRecipient />
|
||||
<ChatInput
|
||||
onResize = { this._onChatInputResize }
|
||||
onSend = { this.props._onSendMessage } />
|
||||
onSend = { this._onSendMessage } />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -135,7 +134,7 @@ class Chat extends AbstractChat<Props> {
|
|||
return (
|
||||
<Header
|
||||
className = 'chat-header'
|
||||
onCancel = { this.props._onToggleChat } />
|
||||
onCancel = { this._onToggleChat } />
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -197,6 +196,20 @@ class Chat extends AbstractChat<Props> {
|
|||
this._messageContainerRef.current.scrollToBottom(withAnimation);
|
||||
}
|
||||
}
|
||||
|
||||
_onSendMessage: (string) => void;
|
||||
|
||||
_onToggleChat: () => void;
|
||||
|
||||
/**
|
||||
* Toggles the chat window.
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
_onToggleChat() {
|
||||
this.props.dispatch(toggleChat());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps, _mapDispatchToProps)(Chat));
|
||||
export default translate(connect(_mapStateToProps)(Chat));
|
||||
|
|
|
@ -5,7 +5,7 @@ import React from 'react';
|
|||
import { translate } from '../../../base/i18n';
|
||||
import { Icon, IconClose } from '../../../base/icons';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { toggleChat } from '../../../chat';
|
||||
import { closeChat } from '../../actions.any';
|
||||
|
||||
type Props = {
|
||||
|
||||
|
@ -42,6 +42,6 @@ function Header({ onCancel, className, t }: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = { onCancel: toggleChat };
|
||||
const mapDispatchToProps = { onCancel: closeChat };
|
||||
|
||||
export default translate(connect(null, mapDispatchToProps)(Header));
|
||||
|
|
|
@ -18,10 +18,12 @@ import {
|
|||
} from '../base/participants';
|
||||
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
|
||||
import { playSound, registerSound, unregisterSound } from '../base/sounds';
|
||||
import { openDisplayNamePrompt } from '../display-name';
|
||||
import { showToolbox } from '../toolbox/actions';
|
||||
|
||||
import { ADD_MESSAGE, TOGGLE_CHAT, SEND_MESSAGE, SET_PRIVATE_MESSAGE_RECIPIENT } from './actionTypes';
|
||||
import { addMessage, clearMessages, toggleChat } from './actions';
|
||||
import { ADD_MESSAGE, SEND_MESSAGE, OPEN_CHAT, CLOSE_CHAT } from './actionTypes';
|
||||
import { addMessage, clearMessages } from './actions';
|
||||
import { closeChat } from './actions.any';
|
||||
import { ChatPrivacyDialog } from './components';
|
||||
import {
|
||||
CHAT_VIEW_MODAL_ID,
|
||||
|
@ -52,6 +54,7 @@ const PRIVACY_NOTICE_TIMEOUT = 20 * 1000;
|
|||
*/
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
const { dispatch, getState } = store;
|
||||
const localParticipant = getLocalParticipant(getState());
|
||||
let isOpen, unreadCount;
|
||||
|
||||
switch (action.type) {
|
||||
|
@ -63,14 +66,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
APP.API.notifyChatUpdated(unreadCount, isOpen);
|
||||
}
|
||||
break;
|
||||
case TOGGLE_CHAT:
|
||||
unreadCount = 0;
|
||||
isOpen = !getState()['features/chat'].isOpen;
|
||||
|
||||
if (typeof APP !== 'undefined') {
|
||||
APP.API.notifyChatUpdated(unreadCount, isOpen);
|
||||
}
|
||||
break;
|
||||
case APP_WILL_MOUNT:
|
||||
dispatch(
|
||||
registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_FILE));
|
||||
|
@ -84,6 +80,32 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
_addChatMsgListener(action.conference, store);
|
||||
break;
|
||||
|
||||
case OPEN_CHAT:
|
||||
if (localParticipant.name) {
|
||||
dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
|
||||
_maybeFocusField();
|
||||
} else {
|
||||
dispatch(openDisplayNamePrompt(() => {
|
||||
dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
|
||||
_maybeFocusField();
|
||||
}));
|
||||
}
|
||||
|
||||
unreadCount = 0;
|
||||
|
||||
if (typeof APP !== 'undefined') {
|
||||
APP.API.notifyChatUpdated(unreadCount, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case CLOSE_CHAT:
|
||||
unreadCount = 0;
|
||||
|
||||
if (typeof APP !== 'undefined') {
|
||||
APP.API.notifyChatUpdated(unreadCount, true);
|
||||
}
|
||||
break;
|
||||
|
||||
case SEND_MESSAGE: {
|
||||
const state = store.getState();
|
||||
const { conference } = state['features/base/conference'];
|
||||
|
@ -117,12 +139,6 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SET_PRIVATE_MESSAGE_RECIPIENT: {
|
||||
Boolean(action.participant) && dispatch(setActiveModalId(CHAT_VIEW_MODAL_ID));
|
||||
_maybeFocusField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return next(action);
|
||||
|
@ -141,7 +157,7 @@ StateListenerRegistry.register(
|
|||
|
||||
if (getState()['features/chat'].isOpen) {
|
||||
// Closes the chat if it's left open.
|
||||
dispatch(toggleChat());
|
||||
dispatch(closeChat());
|
||||
}
|
||||
|
||||
// Clear chat messages.
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
// @flow
|
||||
|
||||
import { SET_ACTIVE_MODAL_ID } from '../base/modal';
|
||||
import { ReducerRegistry } from '../base/redux';
|
||||
|
||||
import {
|
||||
ADD_MESSAGE,
|
||||
CLEAR_MESSAGES,
|
||||
SET_PRIVATE_MESSAGE_RECIPIENT,
|
||||
TOGGLE_CHAT
|
||||
CLOSE_CHAT,
|
||||
OPEN_CHAT,
|
||||
SET_PRIVATE_MESSAGE_RECIPIENT
|
||||
} from './actionTypes';
|
||||
import { CHAT_VIEW_MODAL_ID } from './constants';
|
||||
|
||||
const DEFAULT_STATE = {
|
||||
isOpen: false,
|
||||
|
@ -58,38 +57,28 @@ ReducerRegistry.register('features/chat', (state = DEFAULT_STATE, action) => {
|
|||
messages: []
|
||||
};
|
||||
|
||||
case SET_ACTIVE_MODAL_ID:
|
||||
if (action.activeModalId === CHAT_VIEW_MODAL_ID) {
|
||||
return updateChatState(state);
|
||||
}
|
||||
|
||||
break;
|
||||
case SET_PRIVATE_MESSAGE_RECIPIENT:
|
||||
return {
|
||||
...state,
|
||||
isOpen: Boolean(action.participant) || state.isOpen,
|
||||
privateMessageRecipient: action.participant
|
||||
};
|
||||
|
||||
case TOGGLE_CHAT:
|
||||
return updateChatState(state);
|
||||
case OPEN_CHAT:
|
||||
return {
|
||||
...state,
|
||||
isOpen: true,
|
||||
privateMessageRecipient: action.participant
|
||||
};
|
||||
|
||||
case CLOSE_CHAT:
|
||||
return {
|
||||
...state,
|
||||
isOpen: false,
|
||||
lastReadMessage: state.messages[
|
||||
navigator.product === 'ReactNative' ? 0 : state.messages.length - 1],
|
||||
privateMessageRecipient: action.participant
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
/**
|
||||
* Updates the chat status on opening the chat view.
|
||||
*
|
||||
* @param {Object} state - The Redux state of the feature.
|
||||
* @returns {Object}
|
||||
*/
|
||||
function updateChatState(state) {
|
||||
return {
|
||||
...state,
|
||||
isOpen: !state.isOpen,
|
||||
lastReadMessage: state.messages[
|
||||
navigator.product === 'ReactNative' ? 0 : state.messages.length - 1],
|
||||
privateMessageRecipient: state.isOpen ? undefined : state.privateMessageRecipient
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ import React, { Component } from 'react';
|
|||
import { translate } from '../../../base/i18n';
|
||||
import { IconMessage } from '../../../base/icons';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { openChat } from '../../../chat/';
|
||||
import {
|
||||
_mapDispatchToProps,
|
||||
_mapStateToProps as _abstractMapStateToProps,
|
||||
type Props as AbstractProps
|
||||
} from '../../../chat/components/PrivateMessageButton';
|
||||
|
@ -72,9 +72,9 @@ class PrivateMessageMenuButton extends Component<Props> {
|
|||
* @returns {void}
|
||||
*/
|
||||
_onClick() {
|
||||
const { _participant, _setPrivateMessageRecipient } = this.props;
|
||||
const { dispatch, _participant } = this.props;
|
||||
|
||||
_setPrivateMessageRecipient(_participant);
|
||||
dispatch(openChat(_participant));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,4 +93,4 @@ function _mapStateToProps(state: Object, ownProps: Props): $Shape<Props> {
|
|||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps, _mapDispatchToProps)(PrivateMessageMenuButton));
|
||||
export default translate(connect(_mapStateToProps)(PrivateMessageMenuButton));
|
||||
|
|
Loading…
Reference in New Issue