Inline chat moderation UI (#1331)
* - mock detect when user turns into moderator - add moderator indicator to display on messages and username changer * also mock moderator flag in message payload about user to display indicator * add some menu looking icons and a menu of actions * WIP chat moderators * Add support for admin promoting a user to moderator * WIP- open a more info panel of user+message info; add some a11y to buttons * style the details panel * adjust positioning of menus * Merge fixes. ChatClient->Client ChatServer->Server * Remove moderator bool placeholders to use real state * Support inline hiding of messages by moderators * Support inline banning of chat users * Cleanup linter warnings * Puppeteer tests fail after typing take place * Manually resolve conflicts in chat between moderator feature and develop Co-authored-by: Gabe Kangas <gabek@real-ity.com>
This commit is contained in:
@@ -6,7 +6,10 @@ import Message from './message.js';
|
||||
import ChatInput from './chat-input.js';
|
||||
import { CALLBACKS, SOCKET_MESSAGE_TYPES } from '../../utils/websocket.js';
|
||||
import { jumpToBottom, debounce } from '../../utils/helpers.js';
|
||||
import { extraUserNamesFromMessageHistory } from '../../utils/chat.js';
|
||||
import {
|
||||
extraUserNamesFromMessageHistory,
|
||||
checkIsModerator,
|
||||
} from '../../utils/chat.js';
|
||||
import {
|
||||
URL_CHAT_HISTORY,
|
||||
MESSAGE_JUMPTOBOTTOM_BUFFER,
|
||||
@@ -21,6 +24,7 @@ export default class Chat extends Component {
|
||||
messages: [],
|
||||
newMessagesReceived: false,
|
||||
webSocketConnected: true,
|
||||
isModerator: false,
|
||||
};
|
||||
|
||||
this.scrollableMessagesContainer = createRef();
|
||||
@@ -191,31 +195,34 @@ export default class Chat extends Component {
|
||||
(item) => item.id === messageId
|
||||
);
|
||||
|
||||
// check moderator status
|
||||
if (messageType === SOCKET_MESSAGE_TYPES.CONNECTED_USER_INFO) {
|
||||
const modStatusUpdate = checkIsModerator(message);
|
||||
if (modStatusUpdate !== this.state.isModerator) {
|
||||
this.setState({
|
||||
isModerator: modStatusUpdate,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const updatedMessageList = [...curMessages];
|
||||
|
||||
// Change the visibility of messages by ID.
|
||||
if (messageType === 'VISIBILITY-UPDATE') {
|
||||
const idsToUpdate = message.ids;
|
||||
const visible = message.visible;
|
||||
|
||||
updatedMessageList.forEach((item) => {
|
||||
if (idsToUpdate.includes(item.id)) {
|
||||
item.visible = visible;
|
||||
}
|
||||
|
||||
this.forceRender = true;
|
||||
this.setState({
|
||||
messages: updatedMessageList,
|
||||
});
|
||||
});
|
||||
return;
|
||||
this.forceRender = true;
|
||||
} else if (existingIndex === -1 && messageVisible) {
|
||||
// insert message at timestamp
|
||||
const convertedMessage = {
|
||||
...message,
|
||||
type: 'CHAT',
|
||||
};
|
||||
|
||||
// insert message at timestamp
|
||||
const insertAtIndex = curMessages.findIndex((item, index) => {
|
||||
const time = item.timestamp || messageTimestamp;
|
||||
const nextMessage =
|
||||
@@ -252,7 +259,11 @@ export default class Chat extends Component {
|
||||
}
|
||||
|
||||
// if window is blurred and we get a new message, add 1 to title
|
||||
if (!readonly && messageType === 'CHAT' && this.windowBlurred) {
|
||||
if (
|
||||
!readonly &&
|
||||
messageType === SOCKET_MESSAGE_TYPES.CHAT &&
|
||||
this.windowBlurred
|
||||
) {
|
||||
this.numMessagesSinceBlur += 1;
|
||||
}
|
||||
}
|
||||
@@ -366,10 +377,9 @@ export default class Chat extends Component {
|
||||
}
|
||||
|
||||
render(props, state) {
|
||||
const { username, readonly, chatInputEnabled, inputMaxBytes } = props;
|
||||
const { messages, chatUserNames, webSocketConnected } = state;
|
||||
|
||||
this.forceRender = false;
|
||||
const { username, readonly, chatInputEnabled, inputMaxBytes, accessToken } =
|
||||
props;
|
||||
const { messages, chatUserNames, webSocketConnected, isModerator } = state;
|
||||
|
||||
const messageList = messages
|
||||
.filter((message) => message.visible !== false)
|
||||
@@ -379,6 +389,8 @@ export default class Chat extends Component {
|
||||
message=${message}
|
||||
username=${username}
|
||||
key=${message.id}
|
||||
isModerator=${isModerator}
|
||||
accessToken=${accessToken}
|
||||
/>`
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user