jitsi-meet/react/features/chat/actions.any.ts
theluyuan 38ba663466
Some checks failed
Close stale issues and PRs / stale (push) Has been cancelled
init
2025-09-02 14:49:16 +08:00

360 lines
9.4 KiB
TypeScript

import { IStore } from '../app/types';
import { getCurrentConference } from '../base/conference/functions';
import { getLocalParticipant, getParticipantById } from '../base/participants/functions';
import { IParticipant } from '../base/participants/types';
import { LOBBY_CHAT_INITIALIZED } from '../lobby/constants';
import {
ADD_MESSAGE,
ADD_MESSAGE_REACTION,
CLEAR_MESSAGES,
CLOSE_CHAT,
EDIT_MESSAGE,
NOTIFY_PRIVATE_RECIPIENTS_CHANGED,
OPEN_CHAT,
REMOVE_LOBBY_CHAT_PARTICIPANT,
SEND_MESSAGE,
SEND_REACTION,
SET_FOCUSED_TAB,
SET_LOBBY_CHAT_ACTIVE_STATE,
SET_LOBBY_CHAT_RECIPIENT,
SET_PRIVATE_MESSAGE_RECIPIENT
} from './actionTypes';
import { ChatTabs } from './constants';
/**
* Adds a chat message to the collection of messages.
*
* @param {Object} messageDetails - The chat message to save.
* @param {string} messageDetails.displayName - The displayName of the
* participant that authored the message.
* @param {boolean} messageDetails.hasRead - Whether or not to immediately mark
* the message as read.
* @param {string} messageDetails.message - The received message to display.
* @param {string} messageDetails.messageType - The kind of message, such as
* "error" or "local" or "remote".
* @param {string} messageDetails.timestamp - A timestamp to display for when
* the message was received.
* @param {string} messageDetails.isReaction - Whether or not the
* message is a reaction message.
* @returns {{
* type: ADD_MESSAGE,
* displayName: string,
* hasRead: boolean,
* message: string,
* messageType: string,
* timestamp: string,
* isReaction: boolean
* }}
*/
export function addMessage(messageDetails: Object) {
return {
type: ADD_MESSAGE,
...messageDetails
};
}
/**
* Adds a reaction to a chat message.
*
* @param {Object} reactionDetails - The reaction to add.
* @param {string} reactionDetails.participantId - The ID of the message to react to.
* @param {string} reactionDetails.reactionList - The reaction to add.
* @param {string} reactionDetails.messageId - The receiver ID of the reaction.
* @returns {{
* type: ADD_MESSAGE_REACTION,
* participantId: string,
* reactionList: string[],
* messageId: string
* }}
*/
export function addMessageReaction(reactionDetails: Object) {
return {
type: ADD_MESSAGE_REACTION,
...reactionDetails
};
}
/**
* Edits an existing chat message.
*
* @param {Object} message - The chat message to edit/override. The messages will be matched from the state
* comparing the messageId.
* @returns {{
* type: EDIT_MESSAGE,
* message: Object
* }}
*/
export function editMessage(message: Object) {
return {
type: EDIT_MESSAGE,
message
};
}
/**
* Clears the chat messages in Redux.
*
* @returns {{
* type: CLEAR_MESSAGES
* }}
*/
export function clearMessages() {
return {
type: CLEAR_MESSAGES
};
}
/**
* 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.
*
* @param {string} message - The chat message to send out.
* @param {boolean} ignorePrivacy - True if the privacy notification should be ignored.
* @returns {{
* type: SEND_MESSAGE,
* ignorePrivacy: boolean,
* message: string
* }}
*/
export function sendMessage(message: string, ignorePrivacy = false) {
return {
type: SEND_MESSAGE,
ignorePrivacy,
message
};
}
/**
* Sends a reaction to a message.
*
* @param {string} reaction - The reaction to send.
* @param {string} messageId - The message ID to react to.
* @param {string} receiverId - The receiver ID of the reaction.
* @returns {Function}
*/
export function sendReaction(reaction: string, messageId: string, receiverId?: string) {
return {
type: SEND_REACTION,
reaction,
messageId,
receiverId
};
}
/**
* Initiates the sending of a private message to the supplied participant.
*
* @param {IParticipant} participant - The participant to set the recipient to.
* @returns {{
* participant: IParticipant,
* type: SET_PRIVATE_MESSAGE_RECIPIENT
* }}
*/
export function setPrivateMessageRecipient(participant?: Object) {
return {
participant,
type: SET_PRIVATE_MESSAGE_RECIPIENT
};
}
/**
* Initiates the sending of a private message to the supplied participantId.
*
* @param {string} participantId - The participant id to set the recipient to.
* @returns {{
* participant: IParticipant,
* type: SET_PRIVATE_MESSAGE_RECIPIENT
* }}
*/
export function setPrivateMessageRecipientById(participantId: string) {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const participant = getParticipantById(getState(), participantId);
if (participant) {
dispatch(setPrivateMessageRecipient(participant));
}
};
}
/**
* Set the value of the currently focused tab.
*
* @param {string} tabId - The id of the currently focused tab.
* @returns {{
* type: SET_FOCUSED_TAB,
* tabId: string
* }}
*/
export function setFocusedTab(tabId: ChatTabs) {
return {
type: SET_FOCUSED_TAB,
tabId
};
}
/**
* Opens the chat panel with CC tab active.
*
* @returns {Object} The redux action.
*/
export function openCCPanel() {
return async (dispatch: IStore['dispatch']) => {
dispatch(setFocusedTab(ChatTabs.CLOSED_CAPTIONS));
dispatch({
type: OPEN_CHAT
});
};
}
/**
* Initiates the sending of messages between a moderator and a lobby attendee.
*
* @param {Object} lobbyChatInitializedInfo - The information about the attendee and the moderator
* that is going to chat.
*
* @returns {Function}
*/
export function onLobbyChatInitialized(lobbyChatInitializedInfo: { attendee: IParticipant; moderator: IParticipant; }) {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const conference = getCurrentConference(state);
const lobbyLocalId = conference?.myLobbyUserId();
if (!lobbyLocalId) {
return;
}
if (lobbyChatInitializedInfo.moderator.id === lobbyLocalId) {
dispatch({
type: SET_LOBBY_CHAT_RECIPIENT,
participant: lobbyChatInitializedInfo.attendee,
open: true
});
}
if (lobbyChatInitializedInfo.attendee.id === lobbyLocalId) {
return dispatch({
type: SET_LOBBY_CHAT_RECIPIENT,
participant: lobbyChatInitializedInfo.moderator,
open: false
});
}
};
}
/**
* Sets the lobby room's chat active state.
*
* @param {boolean} value - The active state.
*
* @returns {Object}
*/
export function setLobbyChatActiveState(value: boolean) {
return {
type: SET_LOBBY_CHAT_ACTIVE_STATE,
payload: value
};
}
/**
* Notifies the private chat recipients list changed.
*
* @returns {Object}
*/
export function notifyPrivateRecipientsChanged() {
return (dispatch: IStore['dispatch']) => {
const timestamp = Date.now();
return dispatch({
type: NOTIFY_PRIVATE_RECIPIENTS_CHANGED,
payload: timestamp
});
};
}
/**
* Removes lobby type messages.
*
* @param {boolean} removeLobbyChatMessages - Should remove messages from chat (works only for accepted users).
* If not specified, it will delete all lobby messages.
*
* @returns {Object}
*/
export function removeLobbyChatParticipant(removeLobbyChatMessages?: boolean) {
return {
type: REMOVE_LOBBY_CHAT_PARTICIPANT,
removeLobbyChatMessages
};
}
/**
* Handles initial setup of lobby message between
* Moderator and participant.
*
* @param {string} participantId - The participant id.
*
* @returns {Object}
*/
export function handleLobbyChatInitialized(participantId: string) {
return async (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
if (!participantId) {
return;
}
const state = getState();
const conference = state['features/base/conference'].conference;
const { knockingParticipants } = state['features/lobby'];
const { lobbyMessageRecipient } = state['features/chat'];
const me = getLocalParticipant(state);
const lobbyLocalId = conference?.myLobbyUserId();
if (lobbyMessageRecipient && lobbyMessageRecipient.id === participantId) {
return dispatch(setLobbyChatActiveState(true));
}
const attendee = knockingParticipants.find(p => p.id === participantId);
if (attendee && attendee.chattingWithModerator === lobbyLocalId) {
return dispatch({
type: SET_LOBBY_CHAT_RECIPIENT,
participant: attendee,
open: true
});
}
if (!attendee) {
return;
}
const payload = { type: LOBBY_CHAT_INITIALIZED,
moderator: {
...me,
name: 'Moderator',
id: lobbyLocalId
},
attendee };
// notify attendee privately.
conference?.sendLobbyMessage(payload, attendee.id);
// notify other moderators.
return conference?.sendLobbyMessage(payload);
};
}