mirror of
https://github.com/owncast/owncast.git
synced 2024-10-10 19:16:02 +00:00
Add user chat message badges. Closes #1988
This commit is contained in:
parent
eac7e81a9c
commit
3cfcad7a93
@ -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}
|
||||
/>
|
||||
);
|
||||
|
@ -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;
|
||||
}
|
18
web/components/chat/ChatUserMessage/ChatUserBadge.tsx
Normal file
18
web/components/chat/ChatUserMessage/ChatUserBadge.tsx
Normal 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>
|
||||
);
|
||||
}
|
@ -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}>
|
||||
|
28
web/stories/ChatUserBadge.stories.tsx
Normal file
28
web/stories/ChatUserBadge.stories.tsx
Normal 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',
|
||||
};
|
@ -92,6 +92,7 @@ export const FromAuthenticatedUser = Template.bind({});
|
||||
FromAuthenticatedUser.args = {
|
||||
message: authenticatedUserMessage,
|
||||
showModeratorMenu: false,
|
||||
isAuthorAuthenticated: true,
|
||||
};
|
||||
|
||||
export const WithStringHighlighted = Template.bind({});
|
||||
|
Loading…
x
Reference in New Issue
Block a user