409 lines
12 KiB
JavaScript
Executable File
409 lines
12 KiB
JavaScript
Executable File
import _ from 'lodash';
|
|
import React, { useEffect, useState } from 'react';
|
|
import { defineMessages, injectIntl } from 'react-intl';
|
|
import injectWbResizeEvent from '/imports/ui/components/presentation/resize-wrapper/component';
|
|
import UserAvatar from '/imports/ui/components/user-avatar/component';
|
|
import TextInput from '/imports/ui/components/text-input/component';
|
|
import Styled from './styles';
|
|
import { PANELS, ACTIONS } from '../layout/enums';
|
|
import Settings from '/imports/ui/services/settings';
|
|
import browserInfo from '/imports/utils/browserInfo';
|
|
import Header from '/imports/ui/components/common/control-header/component';
|
|
import { notify } from '/imports/ui/services/notification';
|
|
|
|
const intlMessages = defineMessages({
|
|
waitingUsersTitle: {
|
|
id: 'app.userList.guest.waitingUsersTitle',
|
|
description: 'Title for the notes list',
|
|
},
|
|
title: {
|
|
id: 'app.userList.guest.waitingUsers',
|
|
description: 'Label for the waiting users',
|
|
},
|
|
optionTitle: {
|
|
id: 'app.userList.guest.optionTitle',
|
|
description: 'Label above the options',
|
|
},
|
|
allowAllAuthenticated: {
|
|
id: 'app.userList.guest.allowAllAuthenticated',
|
|
description: 'Title for the waiting users',
|
|
},
|
|
allowAllGuests: {
|
|
id: 'app.userList.guest.allowAllGuests',
|
|
description: 'Title for the waiting users',
|
|
},
|
|
allowEveryone: {
|
|
id: 'app.userList.guest.allowEveryone',
|
|
description: 'Title for the waiting users',
|
|
},
|
|
denyEveryone: {
|
|
id: 'app.userList.guest.denyEveryone',
|
|
description: 'Title for the waiting users',
|
|
},
|
|
pendingUsers: {
|
|
id: 'app.userList.guest.pendingUsers',
|
|
description: 'Title for the waiting users',
|
|
},
|
|
pendingGuestUsers: {
|
|
id: 'app.userList.guest.pendingGuestUsers',
|
|
description: 'Title for the waiting users',
|
|
},
|
|
noPendingUsers: {
|
|
id: 'app.userList.guest.noPendingUsers',
|
|
description: 'Label for no users waiting',
|
|
},
|
|
rememberChoice: {
|
|
id: 'app.userList.guest.rememberChoice',
|
|
description: 'Remember label for checkbox',
|
|
},
|
|
emptyMessage: {
|
|
id: 'app.userList.guest.emptyMessage',
|
|
description: 'Empty guest lobby message label',
|
|
},
|
|
inputPlaceholder: {
|
|
id: 'app.userList.guest.inputPlaceholder',
|
|
description: 'Placeholder to guest lobby message input',
|
|
},
|
|
privateMessageLabel: {
|
|
id: 'app.userList.guest.privateMessageLabel',
|
|
description: 'Private message button label',
|
|
},
|
|
privateInputPlaceholder: {
|
|
id: 'app.userList.guest.privateInputPlaceholder',
|
|
description: 'Private input placeholder',
|
|
},
|
|
accept: {
|
|
id: 'app.userList.guest.acceptLabel',
|
|
description: 'Accept guest button label',
|
|
},
|
|
deny: {
|
|
id: 'app.userList.guest.denyLabel',
|
|
description: 'Deny guest button label',
|
|
},
|
|
feedbackMessage: {
|
|
id: 'app.userList.guest.feedbackMessage',
|
|
description: 'Feedback message moderator action',
|
|
},
|
|
});
|
|
|
|
const ALLOW_STATUS = 'ALLOW';
|
|
const DENY_STATUS = 'DENY';
|
|
const { animations } = Settings.application;
|
|
|
|
const getNameInitials = (name) => {
|
|
const nameInitials = name.slice(0, 2);
|
|
|
|
return nameInitials.replace(/^\w/, (c) => c.toUpperCase());
|
|
};
|
|
|
|
const renderGuestUserItem = (
|
|
name, color, handleAccept, handleDeny, role, sequence, userId, avatar, intl,
|
|
privateMessageVisible, setPrivateGuestLobbyMessage, privateGuestLobbyMessage, isGuestLobbyMessageEnabled,
|
|
) => (
|
|
<React.Fragment key={`user-${userId}`}>
|
|
<Styled.ListItem key={`userlist-item-${userId}`} animations={animations}>
|
|
<Styled.UserContentContainer key={`user-content-container-${userId}`}>
|
|
<Styled.UserAvatarContainer key={`user-avatar-container-${userId}`}>
|
|
<UserAvatar
|
|
key={`user-avatar-${userId}`}
|
|
moderator={role === 'MODERATOR'}
|
|
avatar={avatar}
|
|
color={color}
|
|
>
|
|
{getNameInitials(name)}
|
|
</UserAvatar>
|
|
</Styled.UserAvatarContainer>
|
|
<Styled.UserName key={`user-name-${userId}`}>
|
|
{`[${sequence}] ${name}`}
|
|
</Styled.UserName>
|
|
</Styled.UserContentContainer>
|
|
|
|
<Styled.ButtonContainer key={`userlist-btns-${userId}`}>
|
|
{ isGuestLobbyMessageEnabled ? (
|
|
<Styled.WaitingUsersButton
|
|
key={`userbtn-message-${userId}`}
|
|
color="primary"
|
|
size="lg"
|
|
ghost
|
|
label={intl.formatMessage(intlMessages.privateMessageLabel)}
|
|
onClick={privateMessageVisible}
|
|
data-test="privateMessageGuest"
|
|
/>
|
|
) : null}
|
|
|
|
|
<Styled.WaitingUsersButton
|
|
key={`userbtn-accept-${userId}`}
|
|
color="primary"
|
|
size="lg"
|
|
ghost
|
|
label={intl.formatMessage(intlMessages.accept)}
|
|
onClick={handleAccept}
|
|
data-test="acceptGuest"
|
|
/>
|
|
|
|
|
<Styled.WaitingUsersButton
|
|
key={`userbtn-deny-${userId}`}
|
|
color="danger"
|
|
size="lg"
|
|
ghost
|
|
label={intl.formatMessage(intlMessages.deny)}
|
|
onClick={handleDeny}
|
|
data-test="denyGuest"
|
|
/>
|
|
</Styled.ButtonContainer>
|
|
</Styled.ListItem>
|
|
{ isGuestLobbyMessageEnabled ? (
|
|
<Styled.PrivateLobbyMessage
|
|
id={`privateMessage-${userId}`}
|
|
data-test="privateLobbyMessage">
|
|
<TextInput
|
|
maxLength={128}
|
|
placeholder={intl.formatMessage(intlMessages.privateInputPlaceholder,
|
|
{ 0: name })}
|
|
send={setPrivateGuestLobbyMessage} />
|
|
<p>
|
|
<i>
|
|
"
|
|
{privateGuestLobbyMessage.length > 0
|
|
? privateGuestLobbyMessage
|
|
: intl.formatMessage(intlMessages.emptyMessage)}
|
|
"
|
|
</i>
|
|
</p>
|
|
</Styled.PrivateLobbyMessage>
|
|
) : null}
|
|
</React.Fragment>
|
|
);
|
|
|
|
const renderNoUserWaitingItem = (message) => (
|
|
<Styled.PendingUsers>
|
|
<Styled.NoPendingUsers>
|
|
{message}
|
|
</Styled.NoPendingUsers>
|
|
</Styled.PendingUsers>
|
|
);
|
|
|
|
const renderPendingUsers = (message, usersArray, action, intl,
|
|
privateMessageVisible, setPrivateGuestLobbyMessage,
|
|
privateGuestLobbyMessage, isGuestLobbyMessageEnabled
|
|
) => {
|
|
if (!usersArray.length) return null;
|
|
return (
|
|
<Styled.PendingUsers>
|
|
<Styled.MainTitle>{message}</Styled.MainTitle>
|
|
<Styled.UsersWrapper>
|
|
<Styled.Users>
|
|
{usersArray.map((user, idx) => renderGuestUserItem(
|
|
user.name,
|
|
user.color,
|
|
() => action([user], ALLOW_STATUS),
|
|
() => action([user], DENY_STATUS),
|
|
user.role,
|
|
idx + 1,
|
|
user.intId,
|
|
user.avatar,
|
|
intl,
|
|
() => privateMessageVisible(`privateMessage-${user.intId}`),
|
|
(message) => setPrivateGuestLobbyMessage(message, user.intId),
|
|
privateGuestLobbyMessage(user.intId),
|
|
isGuestLobbyMessageEnabled,
|
|
))}
|
|
</Styled.Users>
|
|
</Styled.UsersWrapper>
|
|
</Styled.PendingUsers>
|
|
);
|
|
};
|
|
|
|
const WaitingUsers = (props) => {
|
|
const [rememberChoice, setRememberChoice] = useState(false);
|
|
|
|
const {
|
|
intl,
|
|
authenticatedUsers,
|
|
privateMessageVisible,
|
|
guestUsers,
|
|
guestUsersCall,
|
|
changeGuestPolicy,
|
|
isGuestLobbyMessageEnabled,
|
|
setGuestLobbyMessage,
|
|
guestLobbyMessage,
|
|
setPrivateGuestLobbyMessage,
|
|
privateGuestLobbyMessage,
|
|
authenticatedGuest,
|
|
layoutContextDispatch,
|
|
allowRememberChoice,
|
|
} = props;
|
|
|
|
const existPendingUsers = authenticatedUsers.length > 0 || guestUsers.length > 0;
|
|
|
|
const closePanel = () => {
|
|
layoutContextDispatch({
|
|
type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN,
|
|
value: false,
|
|
});
|
|
layoutContextDispatch({
|
|
type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL,
|
|
value: PANELS.NONE,
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
const {
|
|
isWaitingRoomEnabled,
|
|
} = props;
|
|
if (!isWaitingRoomEnabled && !existPendingUsers) {
|
|
closePanel();
|
|
}
|
|
});
|
|
|
|
const onCheckBoxChange = (e) => {
|
|
const { checked } = e.target;
|
|
setRememberChoice(checked);
|
|
};
|
|
|
|
const changePolicy = (shouldExecutePolicy, policyRule, cb, message) => () => {
|
|
if (shouldExecutePolicy) {
|
|
changeGuestPolicy(policyRule);
|
|
}
|
|
|
|
closePanel();
|
|
|
|
notify(intl.formatMessage(intlMessages.feedbackMessage) + message.toUpperCase(), 'success');
|
|
|
|
return cb();
|
|
};
|
|
|
|
const renderButton = (message, { key, color, policy, action, dataTest }) => (
|
|
<Styled.CustomButton
|
|
key={key}
|
|
color={color}
|
|
label={message}
|
|
size="lg"
|
|
onClick={changePolicy(rememberChoice, policy, action, message)}
|
|
data-test={dataTest}
|
|
/>
|
|
);
|
|
|
|
const authGuestButtonsData = [
|
|
{
|
|
messageId: intlMessages.allowAllAuthenticated,
|
|
action: () => guestUsersCall(authenticatedUsers, ALLOW_STATUS),
|
|
key: 'allow-all-auth',
|
|
color: 'primary',
|
|
policy: 'ALWAYS_ACCEPT_AUTH',
|
|
},
|
|
{
|
|
messageId: intlMessages.allowAllGuests,
|
|
action: () => guestUsersCall(
|
|
[...guestUsers].concat(rememberChoice ? authenticatedUsers : []),
|
|
ALLOW_STATUS,
|
|
),
|
|
key: 'allow-all-guest',
|
|
color: 'primary',
|
|
policy: 'ALWAYS_ACCEPT',
|
|
},
|
|
];
|
|
|
|
const guestButtonsData = [
|
|
{
|
|
messageId: intlMessages.allowEveryone,
|
|
action: () => guestUsersCall([...guestUsers, ...authenticatedUsers], ALLOW_STATUS),
|
|
key: 'allow-everyone',
|
|
color: 'primary',
|
|
policy: 'ALWAYS_ACCEPT',
|
|
dataTest: 'allowEveryone',
|
|
},
|
|
{
|
|
messageId: intlMessages.denyEveryone,
|
|
action: () => guestUsersCall([...guestUsers, ...authenticatedUsers], DENY_STATUS),
|
|
key: 'deny-everyone',
|
|
color: 'danger',
|
|
policy: 'ALWAYS_DENY',
|
|
dataTest: 'denyEveryone',
|
|
},
|
|
];
|
|
|
|
const buttonsData = authenticatedGuest
|
|
? _.concat(authGuestButtonsData, guestButtonsData)
|
|
: guestButtonsData;
|
|
|
|
const { isChrome } = browserInfo;
|
|
|
|
return (
|
|
<Styled.Panel data-test="note" isChrome={isChrome}>
|
|
<Header
|
|
leftButtonProps={{
|
|
onClick: () => closePanel(),
|
|
label: intl.formatMessage(intlMessages.title),
|
|
}}
|
|
/>
|
|
<Styled.ScrollableArea>
|
|
{isGuestLobbyMessageEnabled ? (
|
|
<Styled.LobbyMessage data-test="lobbyMessage">
|
|
<TextInput
|
|
maxLength={128}
|
|
placeholder={intl.formatMessage(intlMessages.inputPlaceholder)}
|
|
send={setGuestLobbyMessage}
|
|
/>
|
|
<p>
|
|
<i>
|
|
"
|
|
{
|
|
guestLobbyMessage.length > 0
|
|
? guestLobbyMessage
|
|
: intl.formatMessage(intlMessages.emptyMessage)
|
|
}
|
|
"
|
|
</i>
|
|
</p>
|
|
</Styled.LobbyMessage>
|
|
) : null}
|
|
<Styled.ModeratorActions>
|
|
<Styled.MainTitle>{intl.formatMessage(intlMessages.optionTitle)}</Styled.MainTitle>
|
|
{
|
|
buttonsData.map((buttonData) => renderButton(
|
|
intl.formatMessage(buttonData.messageId),
|
|
buttonData,
|
|
))
|
|
}
|
|
{allowRememberChoice ? (
|
|
<Styled.RememberContainer>
|
|
<input id="rememberCheckboxId" type="checkbox" onChange={onCheckBoxChange} />
|
|
<label htmlFor="rememberCheckboxId">
|
|
{intl.formatMessage(intlMessages.rememberChoice)}
|
|
</label>
|
|
</Styled.RememberContainer>
|
|
) : null}
|
|
</Styled.ModeratorActions>
|
|
{renderPendingUsers(
|
|
intl.formatMessage(intlMessages.pendingUsers,
|
|
{ 0: authenticatedUsers.length }),
|
|
authenticatedUsers,
|
|
guestUsersCall,
|
|
intl,
|
|
privateMessageVisible,
|
|
setPrivateGuestLobbyMessage,
|
|
privateGuestLobbyMessage,
|
|
isGuestLobbyMessageEnabled,
|
|
)}
|
|
{renderPendingUsers(
|
|
intl.formatMessage(intlMessages.pendingGuestUsers,
|
|
{ 0: guestUsers.length }),
|
|
guestUsers,
|
|
guestUsersCall,
|
|
intl,
|
|
privateMessageVisible,
|
|
setPrivateGuestLobbyMessage,
|
|
privateGuestLobbyMessage,
|
|
isGuestLobbyMessageEnabled,
|
|
)}
|
|
{!existPendingUsers && (
|
|
renderNoUserWaitingItem(intl.formatMessage(intlMessages.noPendingUsers))
|
|
)}
|
|
</Styled.ScrollableArea>
|
|
</Styled.Panel>
|
|
);
|
|
};
|
|
|
|
export default injectWbResizeEvent(injectIntl(WaitingUsers));
|