fix(reactions) Batch events before sending
This commit is contained in:
parent
4276f82c03
commit
251eec19cd
|
@ -823,8 +823,8 @@
|
|||
"hangup": "Leave the meeting",
|
||||
"help": "Help",
|
||||
"invite": "Invite people",
|
||||
"joy": "Laugh",
|
||||
"kick": "Kick participant",
|
||||
"laugh": "Laugh",
|
||||
"like": "Thumbs Up",
|
||||
"lobbyButton": "Enable/disable lobby mode",
|
||||
"localRecording": "Toggle local recording controls",
|
||||
|
@ -892,7 +892,7 @@
|
|||
"hangup": "Leave the meeting",
|
||||
"help": "Help",
|
||||
"invite": "Invite people",
|
||||
"joy": "Laugh",
|
||||
"laugh": "Laugh",
|
||||
"like": "Thumbs Up",
|
||||
"lobbyButtonDisable": "Disable lobby mode",
|
||||
"lobbyButtonEnable": "Enable lobby mode",
|
||||
|
@ -922,7 +922,7 @@
|
|||
"raiseYourHand": "Raise your hand",
|
||||
"reactionBoo": "Send boo reaction",
|
||||
"reactionClap": "Send clap reaction",
|
||||
"reactionJoy": "Send laugh reaction",
|
||||
"reactionLaugh": "Send laugh reaction",
|
||||
"reactionLike": "Send thumbs up reaction",
|
||||
"reactionParty": "Send party popper reaction",
|
||||
"reactionSurprised": "Send surprised reaction",
|
||||
|
|
|
@ -795,6 +795,23 @@ export function createToolbarEvent(buttonName, attributes = {}) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an event associated with a reaction button being clicked/pressed.
|
||||
*
|
||||
* @param {string} buttonName - The identifier of the reaction button which was
|
||||
* clicked/pressed.
|
||||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createReactionMenuEvent(buttonName) {
|
||||
return {
|
||||
action: 'clicked',
|
||||
actionSubject: buttonName,
|
||||
source: 'reaction.button',
|
||||
type: TYPE_UI
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an event which indicates that a local track was muted.
|
||||
*
|
||||
|
|
|
@ -22,11 +22,9 @@ import {
|
|||
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
|
||||
import { playSound, registerSound, unregisterSound } from '../base/sounds';
|
||||
import { openDisplayNamePrompt } from '../display-name';
|
||||
import { ADD_REACTIONS_MESSAGE } from '../reactions/actionTypes';
|
||||
import {
|
||||
pushReaction
|
||||
} from '../reactions/actions.any';
|
||||
import { REACTIONS } from '../reactions/constants';
|
||||
import { ADD_REACTION_MESSAGE } from '../reactions/actionTypes';
|
||||
import { pushReactions } from '../reactions/actions.any';
|
||||
import { getReactionMessageFromBuffer } from '../reactions/functions.any';
|
||||
import { endpointMessageReceived } from '../subtitles';
|
||||
import { showToolbox } from '../toolbox/actions';
|
||||
import {
|
||||
|
@ -158,7 +156,7 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
break;
|
||||
}
|
||||
|
||||
case ADD_REACTIONS_MESSAGE: {
|
||||
case ADD_REACTION_MESSAGE: {
|
||||
_handleReceivedMessage(store, {
|
||||
id: localParticipant.id,
|
||||
message: action.message,
|
||||
|
@ -212,8 +210,6 @@ StateListenerRegistry.register(
|
|||
* @returns {void}
|
||||
*/
|
||||
function _addChatMsgListener(conference, store) {
|
||||
const reactions = {};
|
||||
|
||||
if (store.getState()['features/base/config'].iAmRecorder) {
|
||||
// We don't register anything on web if we are in iAmRecorder mode
|
||||
return;
|
||||
|
@ -252,30 +248,21 @@ function _addChatMsgListener(conference, store) {
|
|||
const [ { _id }, eventData ] = args;
|
||||
|
||||
if (eventData.name === ENDPOINT_REACTION_NAME) {
|
||||
reactions[_id] = reactions[_id] ?? {
|
||||
timeout: null,
|
||||
message: ''
|
||||
};
|
||||
batch(() => {
|
||||
store.dispatch(pushReaction(eventData.reaction));
|
||||
store.dispatch(setToolboxVisible(true));
|
||||
store.dispatch(setToolboxTimeout(
|
||||
() => store.dispatch(hideToolbox()),
|
||||
5000)
|
||||
);
|
||||
store.dispatch(pushReactions(eventData.reactions));
|
||||
});
|
||||
|
||||
clearTimeout(reactions[_id].timeout);
|
||||
reactions[_id].message = `${reactions[_id].message}${REACTIONS[eventData.reaction].message}`;
|
||||
reactions[_id].timeout = setTimeout(() => {
|
||||
_handleReceivedMessage(store, {
|
||||
id: _id,
|
||||
message: reactions[_id].message,
|
||||
privateMessage: false,
|
||||
timestamp: eventData.timestamp
|
||||
}, false);
|
||||
delete reactions[_id];
|
||||
}, 500);
|
||||
_handleReceivedMessage(store, {
|
||||
id: _id,
|
||||
message: getReactionMessageFromBuffer(eventData.reactions),
|
||||
privateMessage: false,
|
||||
timestamp: eventData.timestamp
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -13,21 +13,31 @@ export const TOGGLE_REACTIONS_VISIBLE = 'TOGGLE_REACTIONS_VISIBLE';
|
|||
* a new timeout.
|
||||
*
|
||||
* {
|
||||
* type: SET_REACTION_MESSAGE,
|
||||
* type: ADD_REACTION_BUFFER,
|
||||
* message: string,
|
||||
* timeoutID: number
|
||||
* }
|
||||
*/
|
||||
export const SET_REACTIONS_MESSAGE = 'SET_REACTIONS_MESSAGE';
|
||||
export const ADD_REACTION_BUFFER = 'ADD_REACTION_BUFFER';
|
||||
|
||||
/**
|
||||
* The type of the action which resets the reactions message and timeout.
|
||||
* The type of the action which sends the reaction buffer and resets it.
|
||||
*
|
||||
* {
|
||||
* type: CLEAR_REACTION_MESSAGE
|
||||
* type: FLUSH_REACTION_BUFFER
|
||||
* }
|
||||
*/
|
||||
export const CLEAR_REACTIONS_MESSAGE = 'CLEAR_REACTIONS_MESSAGE';
|
||||
export const FLUSH_REACTION_BUFFER = 'FLUSH_REACTION_BUFFER';
|
||||
|
||||
/**
|
||||
* The type of the action which adds a new reaction message to the chat.
|
||||
*
|
||||
* {
|
||||
* type: ADD_REACTION_MESSAGE,
|
||||
* message: string,
|
||||
* }
|
||||
*/
|
||||
export const ADD_REACTION_MESSAGE = 'ADD_REACTION_MESSAGE';
|
||||
|
||||
/**
|
||||
* The type of the action which sets the reactions queue.
|
||||
|
@ -42,14 +52,9 @@ export const SET_REACTION_QUEUE = 'SET_REACTION_QUEUE';
|
|||
/**
|
||||
* The type of the action which signals a send reaction to everyone in the conference.
|
||||
*/
|
||||
export const SEND_REACTION = 'SEND_REACTION';
|
||||
export const SEND_REACTIONS = 'SEND_REACTIONS';
|
||||
|
||||
/**
|
||||
* The type of the action to add a reaction message to the chat.
|
||||
* The type of action to adds reactions to the queue.
|
||||
*/
|
||||
export const ADD_REACTIONS_MESSAGE = 'ADD_REACTIONS_MESSAGE';
|
||||
|
||||
/**
|
||||
* The type of action to add a reaction to the queue.
|
||||
*/
|
||||
export const PUSH_REACTION = 'PUSH_REACTION';
|
||||
export const PUSH_REACTIONS = 'PUSH_REACTIONS';
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// @flow
|
||||
|
||||
import {
|
||||
ADD_REACTIONS_MESSAGE,
|
||||
CLEAR_REACTIONS_MESSAGE,
|
||||
PUSH_REACTION,
|
||||
SEND_REACTION,
|
||||
SET_REACTIONS_MESSAGE,
|
||||
ADD_REACTION_BUFFER,
|
||||
ADD_REACTION_MESSAGE,
|
||||
FLUSH_REACTION_BUFFER,
|
||||
PUSH_REACTIONS,
|
||||
SEND_REACTIONS,
|
||||
SET_REACTION_QUEUE
|
||||
} from './actionTypes';
|
||||
import { type ReactionEmojiProps } from './constants';
|
||||
|
@ -23,42 +23,6 @@ export function setReactionQueue(value: Array<ReactionEmojiProps>) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the reactions message to the chat and resets the state.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
export function flushReactionsToChat() {
|
||||
return {
|
||||
type: CLEAR_REACTIONS_MESSAGE
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new reaction to the reactions message.
|
||||
*
|
||||
* @param {boolean} value - The new reaction.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function addReactionsMessage(value: string) {
|
||||
return {
|
||||
type: SET_REACTIONS_MESSAGE,
|
||||
reaction: value
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new reaction to the reactions message.
|
||||
*
|
||||
* @param {boolean} value - Reaction to be added to queue.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function pushReaction(value: string) {
|
||||
return {
|
||||
type: PUSH_REACTION,
|
||||
reaction: value
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a reaction from the queue.
|
||||
|
@ -76,33 +40,75 @@ export function removeReaction(uid: number) {
|
|||
|
||||
|
||||
/**
|
||||
* Sends a reaction message to everyone in the conference.
|
||||
* Sends the reactions buffer to everyone in the conference.
|
||||
*
|
||||
* @param {string} reaction - The reaction to send out.
|
||||
* @returns {{
|
||||
* type: SEND_REACTION,
|
||||
* type: SEND_REACTION
|
||||
* }}
|
||||
*/
|
||||
export function sendReactions() {
|
||||
return {
|
||||
type: SEND_REACTIONS
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a reaction to the local buffer.
|
||||
*
|
||||
* @param {string} reaction - The reaction to be added.
|
||||
* @returns {{
|
||||
* type: ADD_REACTION_BUFFER,
|
||||
* reaction: string
|
||||
* }}
|
||||
*/
|
||||
export function sendReaction(reaction: string) {
|
||||
export function addReactionToBuffer(reaction: string) {
|
||||
return {
|
||||
type: SEND_REACTION,
|
||||
type: ADD_REACTION_BUFFER,
|
||||
reaction
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a reactions message to the chat.
|
||||
* Clears the reaction buffer.
|
||||
*
|
||||
* @param {string} message - The reactions message to add to chat.
|
||||
* @returns {{
|
||||
* type: ADD_REACTIONS_MESSAGE,
|
||||
* type: FLUSH_REACTION_BUFFER
|
||||
* }}
|
||||
*/
|
||||
export function flushReactionBuffer() {
|
||||
return {
|
||||
type: FLUSH_REACTION_BUFFER
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a reaction message to the chat.
|
||||
*
|
||||
* @param {string} message - The reaction message.
|
||||
* @returns {{
|
||||
* type: ADD_REACTION_MESSAGE,
|
||||
* message: string
|
||||
* }}
|
||||
*/
|
||||
export function addReactionsMessageToChat(message: string) {
|
||||
export function addReactionsToChat(message: string) {
|
||||
return {
|
||||
type: ADD_REACTIONS_MESSAGE,
|
||||
type: ADD_REACTION_MESSAGE,
|
||||
message
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds reactions to the animation queue.
|
||||
*
|
||||
* @param {Array} reactions - The reactions to be animated.
|
||||
* @returns {{
|
||||
* type: PUSH_REACTIONS,
|
||||
* reactions: Array
|
||||
* }}
|
||||
*/
|
||||
export function pushReactions(reactions: Array<string>) {
|
||||
return {
|
||||
type: PUSH_REACTIONS,
|
||||
reactions
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,9 +4,10 @@ import React from 'react';
|
|||
import { Text, TouchableHighlight } from 'react-native';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { createReactionMenuEvent, sendAnalytics } from '../../../analytics';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import type { StyleType } from '../../../base/styles';
|
||||
import { sendReaction } from '../../actions.any';
|
||||
import { addReactionToBuffer } from '../../actions.any';
|
||||
import { REACTIONS } from '../../constants';
|
||||
|
||||
|
||||
|
@ -78,7 +79,8 @@ function ReactionButton({
|
|||
* @returns {void}
|
||||
*/
|
||||
function _onClick() {
|
||||
dispatch(sendReaction(reaction));
|
||||
dispatch(addReactionToBuffer(reaction));
|
||||
sendAnalytics(createReactionMenuEvent(reaction));
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -4,6 +4,7 @@ import React, { Component } from 'react';
|
|||
import { bindActionCreators } from 'redux';
|
||||
|
||||
import {
|
||||
createReactionMenuEvent,
|
||||
createToolbarEvent,
|
||||
sendAnalytics
|
||||
} from '../../../analytics';
|
||||
|
@ -11,7 +12,7 @@ import { translate } from '../../../base/i18n';
|
|||
import { getLocalParticipant, getParticipantCount, participantUpdated } from '../../../base/participants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { dockToolbox } from '../../../toolbox/actions.web';
|
||||
import { sendReaction } from '../../actions.any';
|
||||
import { addReactionToBuffer } from '../../actions.any';
|
||||
import { toggleReactionsMenuVisibility } from '../../actions.web';
|
||||
import { REACTIONS } from '../../constants';
|
||||
|
||||
|
@ -144,6 +145,13 @@ class ReactionsMenu extends Component<Props> {
|
|||
*/
|
||||
_getReactionButtons() {
|
||||
const { t, dispatch } = this.props;
|
||||
let modifierKey = 'Alt';
|
||||
|
||||
if (window.navigator?.platform) {
|
||||
if (window.navigator.platform.indexOf('Mac') !== -1) {
|
||||
modifierKey = '⌥';
|
||||
}
|
||||
}
|
||||
|
||||
return Object.keys(REACTIONS).map(key => {
|
||||
/**
|
||||
|
@ -151,17 +159,18 @@ class ReactionsMenu extends Component<Props> {
|
|||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function sendMessage() {
|
||||
dispatch(sendReaction(key));
|
||||
function doSendReaction() {
|
||||
dispatch(addReactionToBuffer(key));
|
||||
sendAnalytics(createReactionMenuEvent(key));
|
||||
}
|
||||
|
||||
return (<ReactionButton
|
||||
accessibilityLabel = { t(`toolbar.accessibilityLabel.${key}`) }
|
||||
icon = { REACTIONS[key].emoji }
|
||||
key = { key }
|
||||
onClick = { sendMessage }
|
||||
onClick = { doSendReaction }
|
||||
toggled = { false }
|
||||
tooltip = { t(`toolbar.${key}`) } />);
|
||||
tooltip = { `${t(`toolbar.${key}`)} (${modifierKey} + ${REACTIONS[key].shortcutChar})` } />);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
// @flow
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { IconRaisedHand } from '../../../base/icons';
|
||||
import { getLocalParticipant } from '../../../base/participants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import ToolbarButton from '../../../toolbox/components/web/ToolbarButton';
|
||||
import { sendReaction } from '../../actions.any';
|
||||
import { toggleReactionsMenuVisibility } from '../../actions.web';
|
||||
import { REACTIONS, type ReactionEmojiProps } from '../../constants';
|
||||
import { type ReactionEmojiProps } from '../../constants';
|
||||
import { getReactionsQueue } from '../../functions.any';
|
||||
import { getReactionsMenuVisibility } from '../../functions.web';
|
||||
|
||||
|
@ -65,32 +64,6 @@ function ReactionsMenuButton({
|
|||
dispatch
|
||||
}: Props) {
|
||||
|
||||
useEffect(() => {
|
||||
const KEYBOARD_SHORTCUTS = Object.keys(REACTIONS).map(key => {
|
||||
return {
|
||||
character: REACTIONS[key].shortcutChar,
|
||||
exec: () => dispatch(sendReaction(key)),
|
||||
helpDescription: t(`toolbar.reaction${key.charAt(0).toUpperCase()}${key.slice(1)}`),
|
||||
altKey: true
|
||||
};
|
||||
});
|
||||
|
||||
KEYBOARD_SHORTCUTS.forEach(shortcut => {
|
||||
APP.keyboardshortcut.registerShortcut(
|
||||
shortcut.character,
|
||||
null,
|
||||
shortcut.exec,
|
||||
shortcut.helpDescription,
|
||||
shortcut.altKey);
|
||||
});
|
||||
|
||||
return () => {
|
||||
Object.keys(REACTIONS).map(key => REACTIONS[key].shortcutChar)
|
||||
.forEach(letter =>
|
||||
APP.keyboardshortcut.unregisterShortcut(letter, true));
|
||||
};
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Toggles the reactions menu visibility.
|
||||
*
|
||||
|
|
|
@ -11,7 +11,7 @@ export const REACTIONS = {
|
|||
emoji: '👏',
|
||||
shortcutChar: 'C'
|
||||
},
|
||||
joy: {
|
||||
laugh: {
|
||||
message: ':grinning_face:',
|
||||
emoji: '😀',
|
||||
shortcutChar: 'L'
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import uuid from 'uuid';
|
||||
|
||||
import { getLocalParticipant } from '../base/participants';
|
||||
import { extractFqnFromPath } from '../dynamic-branding/functions';
|
||||
|
||||
|
@ -17,28 +19,28 @@ export function getReactionsQueue(state: Object) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns reaction key from the reaction message.
|
||||
* Returns chat message from reactions buffer.
|
||||
*
|
||||
* @param {string} message - The reaction message.
|
||||
* @param {Array} buffer - The reactions buffer.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getReactionKeyByMessage(message: string): ?string {
|
||||
return Object.keys(REACTIONS).find(key => REACTIONS[key].message === `:${message}:`);
|
||||
export function getReactionMessageFromBuffer(buffer: Array<string>) {
|
||||
return buffer.map(reaction => REACTIONS[reaction].message).reduce((acc, val) => `${acc}${val}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets reactions key array from concatenated message.
|
||||
* Returns reactions array with uid.
|
||||
*
|
||||
* @param {string} message - The reaction message.
|
||||
* @param {Array} buffer - The reactions buffer.
|
||||
* @returns {Array}
|
||||
*/
|
||||
export function messageToKeyArray(message: string) {
|
||||
let formattedMessage = message.replace(/::/g, '-');
|
||||
|
||||
formattedMessage = formattedMessage.replace(/:/g, '');
|
||||
const messageArray = formattedMessage.split('-');
|
||||
|
||||
return messageArray.map<?string>(getReactionKeyByMessage);
|
||||
export function getReactionsWithId(buffer: Array<string>) {
|
||||
return buffer.map<Object>(reaction => {
|
||||
return {
|
||||
reaction,
|
||||
uid: uuid.v4()
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
// @flow
|
||||
|
||||
import { batch } from 'react-redux';
|
||||
|
||||
import { ENDPOINT_REACTION_NAME } from '../../../modules/API/constants';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
import { isVpaasMeeting } from '../jaas/functions';
|
||||
|
||||
import {
|
||||
SET_REACTIONS_MESSAGE,
|
||||
CLEAR_REACTIONS_MESSAGE,
|
||||
SEND_REACTION,
|
||||
PUSH_REACTION
|
||||
ADD_REACTION_BUFFER,
|
||||
FLUSH_REACTION_BUFFER,
|
||||
SEND_REACTIONS,
|
||||
PUSH_REACTIONS
|
||||
} from './actionTypes';
|
||||
import {
|
||||
addReactionsMessage,
|
||||
addReactionsMessageToChat,
|
||||
flushReactionsToChat,
|
||||
pushReaction,
|
||||
addReactionsToChat,
|
||||
flushReactionBuffer,
|
||||
pushReactions,
|
||||
sendReactions,
|
||||
setReactionQueue
|
||||
} from './actions.any';
|
||||
import { REACTIONS } from './constants';
|
||||
import { messageToKeyArray, sendReactionsWebhook } from './functions.any';
|
||||
import { getReactionMessageFromBuffer, getReactionsWithId, sendReactionsWebhook } from './functions.any';
|
||||
|
||||
|
||||
declare var APP: Object;
|
||||
|
@ -34,56 +35,57 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
const { dispatch, getState } = store;
|
||||
|
||||
switch (action.type) {
|
||||
case SET_REACTIONS_MESSAGE: {
|
||||
const { timeoutID, message } = getState()['features/reactions'];
|
||||
case ADD_REACTION_BUFFER: {
|
||||
const { timeoutID, buffer } = getState()['features/reactions'];
|
||||
const { reaction } = action;
|
||||
|
||||
clearTimeout(timeoutID);
|
||||
action.message = `${message}${reaction}`;
|
||||
buffer.push(reaction);
|
||||
action.buffer = buffer;
|
||||
action.timeoutID = setTimeout(() => {
|
||||
dispatch(flushReactionsToChat());
|
||||
dispatch(flushReactionBuffer());
|
||||
}, 500);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CLEAR_REACTIONS_MESSAGE: {
|
||||
case FLUSH_REACTION_BUFFER: {
|
||||
const state = getState();
|
||||
const { message } = state['features/reactions'];
|
||||
const { buffer } = state['features/reactions'];
|
||||
|
||||
batch(() => {
|
||||
dispatch(sendReactions());
|
||||
dispatch(addReactionsToChat(getReactionMessageFromBuffer(buffer)));
|
||||
dispatch(pushReactions(buffer));
|
||||
});
|
||||
|
||||
if (isVpaasMeeting(state)) {
|
||||
sendReactionsWebhook(state, messageToKeyArray(message));
|
||||
sendReactionsWebhook(state, buffer);
|
||||
}
|
||||
|
||||
dispatch(addReactionsMessageToChat(message));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SEND_REACTION: {
|
||||
const state = store.getState();
|
||||
case SEND_REACTIONS: {
|
||||
const state = getState();
|
||||
const { buffer } = state['features/reactions'];
|
||||
const { conference } = state['features/base/conference'];
|
||||
|
||||
if (conference) {
|
||||
conference.sendEndpointMessage('', {
|
||||
name: ENDPOINT_REACTION_NAME,
|
||||
reaction: action.reaction,
|
||||
reactions: buffer,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
dispatch(addReactionsMessage(REACTIONS[action.reaction].message));
|
||||
dispatch(pushReaction(action.reaction));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PUSH_REACTION: {
|
||||
case PUSH_REACTIONS: {
|
||||
const queue = store.getState()['features/reactions'].queue;
|
||||
const reaction = action.reaction;
|
||||
const reactions = action.reactions;
|
||||
|
||||
dispatch(setReactionQueue([ ...queue, {
|
||||
reaction,
|
||||
uid: window.Date.now()
|
||||
} ]));
|
||||
dispatch(setReactionQueue([ ...queue, ...getReactionsWithId(reactions) ]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ import { ReducerRegistry } from '../base/redux';
|
|||
|
||||
import {
|
||||
TOGGLE_REACTIONS_VISIBLE,
|
||||
SET_REACTIONS_MESSAGE,
|
||||
CLEAR_REACTIONS_MESSAGE,
|
||||
SET_REACTION_QUEUE
|
||||
SET_REACTION_QUEUE,
|
||||
ADD_REACTION_BUFFER,
|
||||
FLUSH_REACTION_BUFFER
|
||||
} from './actionTypes';
|
||||
|
||||
/**
|
||||
|
@ -30,11 +30,11 @@ function _getInitialState() {
|
|||
visible: false,
|
||||
|
||||
/**
|
||||
* A string that contains the message to be added to the chat.
|
||||
* An array that contains the reactions buffer to be sent.
|
||||
*
|
||||
* @type {string}
|
||||
* @type {Array}
|
||||
*/
|
||||
message: '',
|
||||
buffer: [],
|
||||
|
||||
/**
|
||||
* A number, non-zero value which identifies the timer created by a call
|
||||
|
@ -64,17 +64,17 @@ ReducerRegistry.register(
|
|||
visible: !state.visible
|
||||
};
|
||||
|
||||
case SET_REACTIONS_MESSAGE:
|
||||
case ADD_REACTION_BUFFER:
|
||||
return {
|
||||
...state,
|
||||
message: action.message,
|
||||
buffer: action.buffer,
|
||||
timeoutID: action.timeoutID
|
||||
};
|
||||
|
||||
case CLEAR_REACTIONS_MESSAGE:
|
||||
case FLUSH_REACTION_BUFFER:
|
||||
return {
|
||||
...state,
|
||||
message: '',
|
||||
buffer: [],
|
||||
timeoutID: null
|
||||
};
|
||||
|
||||
|
|
|
@ -36,7 +36,9 @@ import {
|
|||
} from '../../../participants-pane/actions';
|
||||
import ParticipantsPaneButton from '../../../participants-pane/components/ParticipantsPaneButton';
|
||||
import { getParticipantsPaneOpen } from '../../../participants-pane/functions';
|
||||
import { addReactionToBuffer } from '../../../reactions/actions.any';
|
||||
import { ReactionsMenuButton } from '../../../reactions/components';
|
||||
import { REACTIONS } from '../../../reactions/constants';
|
||||
import {
|
||||
LiveStreamButton,
|
||||
RecordButton
|
||||
|
@ -268,7 +270,7 @@ class Toolbox extends Component<Props> {
|
|||
* @returns {void}
|
||||
*/
|
||||
componentDidMount() {
|
||||
const { _toolbarButtons } = this.props;
|
||||
const { _toolbarButtons, t, dispatch } = this.props;
|
||||
const KEYBOARD_SHORTCUTS = [
|
||||
isToolbarButtonEnabled('videoquality', _toolbarButtons) && {
|
||||
character: 'A',
|
||||
|
@ -316,6 +318,31 @@ class Toolbox extends Component<Props> {
|
|||
shortcut.helpDescription);
|
||||
}
|
||||
});
|
||||
|
||||
const REACTION_SHORTCUTS = Object.keys(REACTIONS).map(key => {
|
||||
const onShortcutSendReaction = () => {
|
||||
dispatch(addReactionToBuffer(key));
|
||||
sendAnalytics(createShortcutEvent(
|
||||
`reaction.${key}`
|
||||
));
|
||||
};
|
||||
|
||||
return {
|
||||
character: REACTIONS[key].shortcutChar,
|
||||
exec: onShortcutSendReaction,
|
||||
helpDescription: t(`toolbar.reaction${key.charAt(0).toUpperCase()}${key.slice(1)}`),
|
||||
altKey: true
|
||||
};
|
||||
});
|
||||
|
||||
REACTION_SHORTCUTS.forEach(shortcut => {
|
||||
APP.keyboardshortcut.registerShortcut(
|
||||
shortcut.character,
|
||||
null,
|
||||
shortcut.exec,
|
||||
shortcut.helpDescription,
|
||||
shortcut.altKey);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -346,6 +373,10 @@ class Toolbox extends Component<Props> {
|
|||
componentWillUnmount() {
|
||||
[ 'A', 'C', 'D', 'R', 'S' ].forEach(letter =>
|
||||
APP.keyboardshortcut.unregisterShortcut(letter));
|
||||
|
||||
Object.keys(REACTIONS).map(key => REACTIONS[key].shortcutChar)
|
||||
.forEach(letter =>
|
||||
APP.keyboardshortcut.unregisterShortcut(letter, true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue