2023-06-14 01:51:42 +08:00
|
|
|
import React, { useState } from 'react';
|
2021-10-14 22:11:37 +08:00
|
|
|
import { defineMessages } from 'react-intl';
|
|
|
|
import PropTypes from 'prop-types';
|
2023-04-28 05:31:11 +08:00
|
|
|
import BBBMenu from '/imports/ui/components/common/menu/component';
|
2023-08-31 02:59:05 +08:00
|
|
|
import { convertRemToPixels } from '/imports/utils/dom-utils';
|
2023-11-14 02:36:49 +08:00
|
|
|
import data from '@emoji-mart/data';
|
|
|
|
import { init } from 'emoji-mart';
|
2024-10-15 00:16:59 +08:00
|
|
|
import { SET_REACTION_EMOJI } from '/imports/ui/core/graphql/mutations/userMutations';
|
2024-04-24 01:56:23 +08:00
|
|
|
import { SET_AWAY } from '/imports/ui/components/user-list/user-list-content/user-participants/user-list-participants/user-actions/mutations';
|
2023-12-07 03:30:30 +08:00
|
|
|
import { useMutation } from '@apollo/client';
|
2024-04-24 01:56:23 +08:00
|
|
|
import Toggle from '/imports/ui/components/common/switch/component';
|
|
|
|
import useToggleVoice from '/imports/ui/components/audio/audio-graphql/hooks/useToggleVoice';
|
|
|
|
import {
|
2024-04-25 04:06:53 +08:00
|
|
|
muteAway,
|
2024-04-24 01:56:23 +08:00
|
|
|
} from '/imports/ui/components/audio/audio-graphql/audio-controls/input-stream-live-selector/service';
|
2023-08-04 02:48:47 +08:00
|
|
|
import Styled from './styles';
|
2021-10-14 22:11:37 +08:00
|
|
|
|
2023-07-18 19:54:36 +08:00
|
|
|
const ReactionsButton = (props) => {
|
2021-10-14 22:11:37 +08:00
|
|
|
const {
|
|
|
|
intl,
|
2023-06-23 20:32:55 +08:00
|
|
|
actionsBarRef,
|
2024-04-24 01:56:23 +08:00
|
|
|
away,
|
|
|
|
muted,
|
2023-06-27 22:08:49 +08:00
|
|
|
isMobile,
|
2023-07-19 22:36:34 +08:00
|
|
|
currentUserReaction,
|
2023-08-11 03:28:21 +08:00
|
|
|
autoCloseReactionsBar,
|
2021-10-14 22:11:37 +08:00
|
|
|
} = props;
|
|
|
|
|
2024-05-29 21:26:11 +08:00
|
|
|
const REACTIONS = window.meetingClientSettings.public.userReaction.reactions;
|
|
|
|
|
2023-11-14 02:36:49 +08:00
|
|
|
// initialize emoji-mart data, need for the new version
|
|
|
|
init({ data });
|
|
|
|
|
2024-04-24 01:56:23 +08:00
|
|
|
const [setAway] = useMutation(SET_AWAY);
|
2023-12-07 21:57:21 +08:00
|
|
|
const [setReactionEmoji] = useMutation(SET_REACTION_EMOJI);
|
2023-12-07 03:30:30 +08:00
|
|
|
|
2021-10-14 22:11:37 +08:00
|
|
|
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
|
|
|
|
|
2024-04-24 01:56:23 +08:00
|
|
|
const voiceToggle = useToggleVoice();
|
|
|
|
|
2021-10-14 22:11:37 +08:00
|
|
|
const intlMessages = defineMessages({
|
2023-07-18 19:54:36 +08:00
|
|
|
reactionsLabel: {
|
|
|
|
id: 'app.actionsBar.reactions.reactionsButtonLabel',
|
|
|
|
description: 'reactions Label',
|
2021-10-14 22:11:37 +08:00
|
|
|
},
|
2024-04-24 01:56:23 +08:00
|
|
|
setAwayLabel: {
|
|
|
|
id: 'app.actionsBar.reactions.setAway',
|
|
|
|
description: 'setAway Label',
|
|
|
|
},
|
|
|
|
setActiveLabel: {
|
|
|
|
id: 'app.actionsBar.reactions.setActive',
|
|
|
|
description: 'setActive Label',
|
|
|
|
},
|
2021-10-14 22:11:37 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
const handleClose = () => {
|
|
|
|
setShowEmojiPicker(false);
|
2023-06-27 20:50:04 +08:00
|
|
|
setTimeout(() => {
|
|
|
|
document.activeElement.blur();
|
|
|
|
}, 0);
|
2021-10-14 22:11:37 +08:00
|
|
|
};
|
|
|
|
|
2023-06-14 01:51:42 +08:00
|
|
|
const handleReactionSelect = (reaction) => {
|
2024-08-17 00:31:25 +08:00
|
|
|
setReactionEmoji({ variables: { reactionEmoji: reaction } });
|
2023-06-27 20:50:04 +08:00
|
|
|
};
|
|
|
|
|
2024-04-24 01:56:23 +08:00
|
|
|
const handleToggleAFK = () => {
|
2024-04-25 04:06:53 +08:00
|
|
|
muteAway(muted, away, voiceToggle);
|
2024-04-24 01:56:23 +08:00
|
|
|
setAway({
|
|
|
|
variables: {
|
|
|
|
away: !away,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const ToggleAFKLabel = () => (away
|
|
|
|
? intl.formatMessage(intlMessages.setActiveLabel)
|
|
|
|
: intl.formatMessage(intlMessages.setAwayLabel));
|
|
|
|
|
2023-08-04 02:48:47 +08:00
|
|
|
const customStyles = {
|
|
|
|
top: '-1rem',
|
|
|
|
borderRadius: '1.7rem',
|
|
|
|
};
|
2021-10-14 22:11:37 +08:00
|
|
|
|
2023-08-04 02:48:47 +08:00
|
|
|
const actionCustomStyles = {
|
|
|
|
paddingLeft: 0,
|
|
|
|
paddingRight: 0,
|
|
|
|
paddingTop: isMobile ? '0' : '0.5rem',
|
|
|
|
paddingBottom: isMobile ? '0' : '0.5rem',
|
|
|
|
};
|
|
|
|
|
|
|
|
const emojiProps = {
|
2023-08-31 02:59:05 +08:00
|
|
|
size: convertRemToPixels(1.5),
|
2023-08-09 02:28:05 +08:00
|
|
|
padding: '4px',
|
2023-08-04 02:48:47 +08:00
|
|
|
};
|
|
|
|
|
2024-04-24 01:56:23 +08:00
|
|
|
const awayReaction = {
|
|
|
|
id: 'clock7',
|
|
|
|
native: '⏰',
|
|
|
|
};
|
|
|
|
|
2023-08-04 02:48:47 +08:00
|
|
|
let actions = [];
|
|
|
|
|
2023-11-14 02:36:49 +08:00
|
|
|
REACTIONS.forEach(({ id, native }) => {
|
2023-08-04 02:48:47 +08:00
|
|
|
actions.push({
|
2023-11-14 02:36:49 +08:00
|
|
|
label: <Styled.ButtonWrapper active={currentUserReaction === native}><em-emoji key={native} native={native} {...emojiProps} /></Styled.ButtonWrapper>,
|
2023-08-04 02:48:47 +08:00
|
|
|
key: id,
|
|
|
|
onClick: () => handleReactionSelect(native),
|
|
|
|
customStyles: actionCustomStyles,
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2024-04-24 01:56:23 +08:00
|
|
|
actions.push({
|
2024-10-02 21:20:03 +08:00
|
|
|
label: <Styled.ToggleButtonWrapper isMobile={isMobile}>
|
|
|
|
{isMobile ? (
|
|
|
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
|
|
|
{ToggleAFKLabel()}
|
|
|
|
<Toggle
|
|
|
|
icons={false}
|
2024-10-03 08:10:26 +08:00
|
|
|
checked={away}
|
2024-10-02 21:20:03 +08:00
|
|
|
onChange={handleToggleAFK}
|
|
|
|
ariaLabel={ToggleAFKLabel()}
|
|
|
|
showToggleLabel={false}
|
|
|
|
isMobile={isMobile}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
) : (
|
|
|
|
<>
|
|
|
|
<Toggle
|
|
|
|
icons={false}
|
2024-10-03 08:10:26 +08:00
|
|
|
checked={away}
|
2024-10-02 21:20:03 +08:00
|
|
|
onChange={handleToggleAFK}
|
|
|
|
ariaLabel={ToggleAFKLabel()}
|
|
|
|
showToggleLabel={false}
|
|
|
|
/>
|
|
|
|
{ToggleAFKLabel()}
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</Styled.ToggleButtonWrapper>,
|
2024-04-24 01:56:23 +08:00
|
|
|
key: 'none',
|
|
|
|
isToggle: true,
|
2024-10-02 21:20:03 +08:00
|
|
|
customStyles: { ...actionCustomStyles, width: 'auto' },
|
2024-04-24 01:56:23 +08:00
|
|
|
});
|
|
|
|
|
2024-10-15 00:16:59 +08:00
|
|
|
const svgIcon = !away && currentUserReaction === 'none' ? 'reactions' : null;
|
2023-11-14 02:36:49 +08:00
|
|
|
const currentUserReactionEmoji = REACTIONS.find(({ native }) => native === currentUserReaction);
|
2023-09-05 02:28:47 +08:00
|
|
|
|
|
|
|
let customIcon = null;
|
|
|
|
|
2024-10-15 00:16:59 +08:00
|
|
|
if (!svgIcon) {
|
|
|
|
customIcon = <em-emoji key={currentUserReactionEmoji?.id} native={currentUserReactionEmoji?.native} emoji={{ id: currentUserReactionEmoji?.id }} {...emojiProps} />;
|
2023-09-05 02:28:47 +08:00
|
|
|
}
|
2023-08-11 22:01:50 +08:00
|
|
|
|
2024-04-24 01:56:23 +08:00
|
|
|
if (away) {
|
|
|
|
customIcon = <em-emoji key={awayReaction.id} native={awayReaction.native} emoji={awayReaction} {...emojiProps} />;
|
|
|
|
}
|
|
|
|
|
2021-10-14 22:11:37 +08:00
|
|
|
return (
|
|
|
|
<BBBMenu
|
|
|
|
trigger={(
|
2023-11-14 02:36:49 +08:00
|
|
|
<Styled.ReactionsDropdown id="interactionsButton">
|
2024-10-15 00:16:59 +08:00
|
|
|
<Styled.ReactionsButton
|
2023-07-25 05:07:51 +08:00
|
|
|
data-test="reactionsButton"
|
2024-08-21 19:28:06 +08:00
|
|
|
svgIcon={svgIcon}
|
2023-08-11 22:01:50 +08:00
|
|
|
customIcon={customIcon}
|
2023-07-18 19:54:36 +08:00
|
|
|
label={intl.formatMessage(intlMessages.reactionsLabel)}
|
|
|
|
description="Reactions"
|
2024-10-02 21:20:03 +08:00
|
|
|
onKeyPress={() => { }}
|
2023-06-14 01:51:42 +08:00
|
|
|
onClick={() => setShowEmojiPicker(true)}
|
2023-08-11 22:01:50 +08:00
|
|
|
color={showEmojiPicker || customIcon ? 'primary' : 'default'}
|
2021-10-14 22:11:37 +08:00
|
|
|
hideLabel
|
|
|
|
circle
|
|
|
|
size="lg"
|
|
|
|
/>
|
2023-07-18 19:54:36 +08:00
|
|
|
</Styled.ReactionsDropdown>
|
2021-10-14 22:11:37 +08:00
|
|
|
)}
|
2023-08-04 02:48:47 +08:00
|
|
|
actions={actions}
|
2021-10-14 22:11:37 +08:00
|
|
|
onCloseCallback={() => handleClose()}
|
2023-06-27 22:08:49 +08:00
|
|
|
customAnchorEl={!isMobile ? actionsBarRef.current : null}
|
2023-06-14 01:51:42 +08:00
|
|
|
customStyles={customStyles}
|
2023-06-27 20:50:04 +08:00
|
|
|
open={showEmojiPicker}
|
2023-06-15 03:35:44 +08:00
|
|
|
hasRoundedCorners
|
2023-06-27 22:08:49 +08:00
|
|
|
overrideMobileStyles
|
2023-08-04 02:48:47 +08:00
|
|
|
isHorizontal={!isMobile}
|
|
|
|
isMobile={isMobile}
|
2024-10-02 21:20:03 +08:00
|
|
|
isEmoji
|
2024-10-15 00:16:59 +08:00
|
|
|
roundButtons
|
2023-08-11 03:28:21 +08:00
|
|
|
keepOpen={!autoCloseReactionsBar}
|
2021-10-14 22:11:37 +08:00
|
|
|
opts={{
|
2023-06-14 01:51:42 +08:00
|
|
|
id: 'reactions-dropdown-menu',
|
2022-09-27 02:38:45 +08:00
|
|
|
keepMounted: true,
|
2021-10-14 22:11:37 +08:00
|
|
|
transitionDuration: 0,
|
|
|
|
elevation: 3,
|
2023-07-20 00:22:50 +08:00
|
|
|
getcontentanchorel: null,
|
2023-06-14 01:51:42 +08:00
|
|
|
anchorOrigin: { vertical: 'top', horizontal: 'center' },
|
|
|
|
transformOrigin: { vertical: 'bottom', horizontal: 'center' },
|
2021-10-14 22:11:37 +08:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const propTypes = {
|
|
|
|
intl: PropTypes.shape({
|
|
|
|
formatMessage: PropTypes.func.isRequired,
|
|
|
|
}).isRequired,
|
|
|
|
userId: PropTypes.string.isRequired,
|
|
|
|
sidebarContentPanel: PropTypes.string.isRequired,
|
|
|
|
layoutContextDispatch: PropTypes.func.isRequired,
|
2024-04-24 01:56:23 +08:00
|
|
|
muted: PropTypes.bool.isRequired,
|
2021-10-14 22:11:37 +08:00
|
|
|
};
|
|
|
|
|
2023-07-18 19:54:36 +08:00
|
|
|
ReactionsButton.propTypes = propTypes;
|
2021-10-14 22:11:37 +08:00
|
|
|
|
2024-10-15 00:16:59 +08:00
|
|
|
export default ReactionsButton;
|