Add user chat message badges. Closes #1988

This commit is contained in:
Gabe Kangas 2022-08-21 14:04:16 -07:00
parent eac7e81a9c
commit 3cfcad7a93
No known key found for this signature in database
GPG Key ID: 9A56337728BC81EA
6 changed files with 70 additions and 2 deletions

View File

@ -88,6 +88,7 @@ export default function ChatContainer(props: Props) {
sentBySelf={message.user?.id === chatUserId} // The local user sent this message
sameUserAsLast={shouldCollapseMessages(messages, index)}
isAuthorModerator={(message as ChatMessage).user.scopes?.includes('MODERATOR')}
isAuthorAuthenticated={message.user?.authenticated}
key={message.id}
/>
);

View File

@ -0,0 +1,13 @@
@import 'styles/mixins.scss';
.badge {
font-family: var(--theme-header-font-family);
font-weight: 500;
font-size: 0.4em;
text-transform: uppercase;
padding: 2px;
border-radius: 3px;
border-width: 1px;
border-style: solid;
margin-left: 3px;
}

View File

@ -0,0 +1,18 @@
import s from './ChatUserBadge.module.scss';
interface Props {
badge: string;
userColor: number;
}
export default function ChatUserBadge(props: Props) {
const { badge, userColor } = props;
const color = `var(--theme-user-colors-${userColor})`;
const style = { color, borderColor: color };
return (
<span style={style} className={s.badge}>
{badge}
</span>
);
}

View File

@ -6,8 +6,8 @@ import cn from 'classnames';
import s from './ChatUserMessage.module.scss';
import { formatTimestamp } from './messageFmt';
import { ChatMessage } from '../../../interfaces/chat-message.model';
import { ModIcon } from '../../ui';
import ChatModerationActionMenu from '../ChatModerationActionMenu/ChatModerationActionMenu';
import ChatUserBadge from './ChatUserBadge';
interface Props {
message: ChatMessage;
@ -16,6 +16,7 @@ interface Props {
sentBySelf: boolean;
sameUserAsLast: boolean;
isAuthorModerator: boolean;
isAuthorAuthenticated: boolean;
}
export default function ChatUserMessage({
@ -25,6 +26,7 @@ export default function ChatUserMessage({
sentBySelf, // Move the border to the right and render a background
sameUserAsLast,
isAuthorModerator,
isAuthorAuthenticated,
}: Props) {
const { id: messageId, body, user, timestamp } = message;
const { id: userId, displayName, displayColor } = user;
@ -33,6 +35,11 @@ export default function ChatUserMessage({
const formattedTimestamp = `Sent at ${formatTimestamp(timestamp)}`;
const [formattedMessage, setFormattedMessage] = useState<string>(body);
const badgeStrings = [isAuthorModerator && 'mod', isAuthorAuthenticated && 'auth'];
const badges = badgeStrings
.filter(badge => !!badge)
.map(badge => <ChatUserBadge key={badge} badge={badge} userColor={displayColor} />);
useEffect(() => {
setFormattedMessage(he.decode(body));
}, [message]);
@ -49,7 +56,7 @@ export default function ChatUserMessage({
{!sameUserAsLast && (
<div className={s.user} style={{ color }}>
<span className={s.userName}>{displayName}</span>
{isAuthorModerator && <ModIcon />}
<span>{badges}</span>
</div>
)}
<Highlight search={highlightString}>

View File

@ -0,0 +1,28 @@
import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import ChatUserBadge from '../components/chat/ChatUserMessage/ChatUserBadge';
export default {
title: 'owncast/Chat/Messages/User Flag',
component: ChatUserBadge,
argTypes: {
userColor: {
options: ['0', '1', '2', '3', '4', '5', '6', '7'],
control: { type: 'select' },
},
},
} as ComponentMeta<typeof ChatUserBadge>;
const Template: ComponentStory<typeof ChatUserBadge> = args => <ChatUserBadge {...args} />;
export const Moderator = Template.bind({});
Moderator.args = {
badge: 'mod',
userColor: '5',
};
export const Authenticated = Template.bind({});
Authenticated.args = {
badge: 'auth',
userColor: '6',
};

View File

@ -92,6 +92,7 @@ export const FromAuthenticatedUser = Template.bind({});
FromAuthenticatedUser.args = {
message: authenticatedUserMessage,
showModeratorMenu: false,
isAuthorAuthenticated: true,
};
export const WithStringHighlighted = Template.bind({});