From c4f057eded74319cd3929956c6b6fb06ecb72710 Mon Sep 17 00:00:00 2001 From: Gabe Kangas Date: Fri, 3 Mar 2023 21:54:01 -0800 Subject: [PATCH] Make testing for moderator state centralized in User class --- .../chat/ChatContainer/ChatContainer.tsx | 11 +++---- web/components/chat/chat.js | 12 -------- web/components/stores/ClientConfigStore.tsx | 13 +++++---- web/interfaces/socket-events.ts | 19 +++++++++++- web/interfaces/user.fixture.ts | 2 ++ web/interfaces/user.model.ts | 29 ++++++++++++++++++- 6 files changed, 59 insertions(+), 27 deletions(-) diff --git a/web/components/chat/ChatContainer/ChatContainer.tsx b/web/components/chat/ChatContainer/ChatContainer.tsx index 1199d51b1..93cc23a27 100644 --- a/web/components/chat/ChatContainer/ChatContainer.tsx +++ b/web/components/chat/ChatContainer/ChatContainer.tsx @@ -17,6 +17,7 @@ import { ScrollToBotBtn } from './ScrollToBotBtn'; import { ChatActionMessage } from '../ChatActionMessage/ChatActionMessage'; import { ChatSocialMessage } from '../ChatSocialMessage/ChatSocialMessage'; import { ChatNameChangeMessage } from '../ChatNameChangeMessage/ChatNameChangeMessage'; +import { User } from '../../../interfaces/user.model'; export type ChatContainerProps = { messages: ChatMessage[]; @@ -75,15 +76,11 @@ function shouldCollapseMessages( } function checkIsModerator(message: ChatMessage | ConnectedClientInfoEvent) { - const { - user: { scopes }, - } = message; + const { user } = message; - if (!scopes || scopes.length === 0) { - return false; - } + const u = new User(user); - return scopes.includes('MODERATOR'); + return u.isModerator(); } export const ChatContainer: FC = ({ diff --git a/web/components/chat/chat.js b/web/components/chat/chat.js index 5436899b4..5e49babde 100644 --- a/web/components/chat/chat.js +++ b/web/components/chat/chat.js @@ -140,15 +140,3 @@ export function emojify(HTML, emojiList) { } return HTML; } - -// MODERATOR UTILS -export function checkIsModerator(message) { - const { user } = message; - const { scopes } = user; - - if (!scopes || scopes.length === 0) { - return false; - } - - return scopes.includes('MODERATOR'); -} diff --git a/web/components/stores/ClientConfigStore.tsx b/web/components/stores/ClientConfigStore.tsx index fd3bc5fa0..81c0fe60b 100644 --- a/web/components/stores/ClientConfigStore.tsx +++ b/web/components/stores/ClientConfigStore.tsx @@ -292,13 +292,14 @@ export const ClientConfigStore: FC = () => { setChatAuthenticated, setCurrentUser, ); - if ( - !hasBeenModeratorNotified && - (message as ChatEvent).user?.scopes.includes('MODERATOR') - ) { - setChatMessages(currentState => [...currentState, message as ChatEvent]); - hasBeenModeratorNotified = true; + if (message as ChatEvent) { + const m = new ChatEvent(message); + if (!hasBeenModeratorNotified && m.user?.isModerator()) { + setChatMessages(currentState => [...currentState, message as ChatEvent]); + hasBeenModeratorNotified = true; + } } + break; case MessageType.CHAT: setChatMessages(currentState => [...currentState, message as ChatEvent]); diff --git a/web/interfaces/socket-events.ts b/web/interfaces/socket-events.ts index 18d833fd8..4cd9bb872 100644 --- a/web/interfaces/socket-events.ts +++ b/web/interfaces/socket-events.ts @@ -28,8 +28,25 @@ export interface SocketEvent { export interface ConnectedClientInfoEvent extends SocketEvent { user: User; } -export interface ChatEvent extends SocketEvent { +export class ChatEvent implements SocketEvent { + constructor(message) { + this.id = message.id; + this.timestamp = message.timestamp; + this.type = message.type; + this.body = message.body; + if (message.user) { + this.user = new User(message.user); + } + } + + timestamp: Date; + + type: MessageType; + + id: string; + user: User; + body: string; } diff --git a/web/interfaces/user.fixture.ts b/web/interfaces/user.fixture.ts index c56f1619d..7f7e8fac9 100644 --- a/web/interfaces/user.fixture.ts +++ b/web/interfaces/user.fixture.ts @@ -9,6 +9,8 @@ export const createUser = (name: string, color: number, createdAt: Date): User = nameChangedAt: createdAt, previousNames: [], scopes: [], + + isModerator: () => false, }); export const spidermanUser = createUser('Spiderman', 1, new Date(2020, 1, 2)); diff --git a/web/interfaces/user.model.ts b/web/interfaces/user.model.ts index c96fdd777..b48f418e5 100644 --- a/web/interfaces/user.model.ts +++ b/web/interfaces/user.model.ts @@ -1,10 +1,37 @@ -export interface User { +/* eslint-disable import/prefer-default-export */ +export class User { + constructor(u) { + this.id = u.id; + this.displayName = u.displayName; + this.displayColor = u.displayColor; + this.createdAt = u.createdAt; + this.previousNames = u.previousNames; + this.nameChangedAt = u.nameChangedAt; + this.scopes = u.scopes; + this.authenticated = u.authenticated; + } + id: string; + displayName: string; + displayColor: number; + createdAt: Date; + previousNames: string[]; + nameChangedAt: Date; + scopes: string[]; + authenticated: boolean; + + public isModerator = (): boolean => { + if (!this.scopes || this.scopes.length === 0) { + return false; + } + + return this.scopes.includes('moderator'); + }; }