Add Fediverse event chat views. Closes #2679

This commit is contained in:
Gabe Kangas 2023-02-05 19:58:24 -08:00
parent 922c68bcf7
commit 313a81359a
No known key found for this signature in database
GPG key ID: 4345B2060657F330
7 changed files with 586 additions and 15 deletions

File diff suppressed because one or more lines are too long

View file

@ -3,6 +3,7 @@ import { useState, useMemo, useRef, CSSProperties, FC, useEffect } from 'react';
import dynamic from 'next/dynamic';
import {
ConnectedClientInfoEvent,
FediverseEvent,
MessageType,
NameChangeEvent,
} from '../../../interfaces/socket-events';
@ -16,6 +17,7 @@ import { ChatSystemMessage } from '../ChatSystemMessage/ChatSystemMessage';
import { ChatJoinMessage } from '../ChatJoinMessage/ChatJoinMessage';
import { ScrollToBotBtn } from './ScrollToBotBtn';
import { ChatActionMessage } from '../ChatActionMessage/ChatActionMessage';
import { ChatSocialMessage } from '../ChatSocialMessage/ChatSocialMessage';
// Lazy loaded components
@ -105,6 +107,8 @@ export const ChatContainer: FC<ChatContainerProps> = ({
);
};
const getFediverseMessage = (message: FediverseEvent) => <ChatSocialMessage message={message} />;
const getUserJoinedMessage = (message: ChatMessage) => {
const {
user: { displayName, displayColor },
@ -138,7 +142,7 @@ export const ChatContainer: FC<ChatContainerProps> = ({
const getViewForMessage = (
index: number,
message: ChatMessage | NameChangeEvent | ConnectedClientInfoEvent,
message: ChatMessage | NameChangeEvent | ConnectedClientInfoEvent | FediverseEvent,
) => {
switch (message.type) {
case MessageType.CHAT:
@ -147,18 +151,18 @@ export const ChatContainer: FC<ChatContainerProps> = ({
message={message as ChatMessage}
showModeratorMenu={isModerator} // Moderators have access to an additional menu
highlightString={usernameToHighlight} // What to highlight in the message
sentBySelf={message.user?.id === chatUserId} // The local user sent this message
sentBySelf={(message as ChatMessage).user?.id === chatUserId} // The local user sent this message
sameUserAsLast={shouldCollapseMessages(messages, index)}
isAuthorModerator={(message as ChatMessage).user.scopes?.includes('MODERATOR')}
isAuthorBot={(message as ChatMessage).user.scopes?.includes('BOT')}
isAuthorAuthenticated={message.user?.authenticated}
isAuthorAuthenticated={(message as ChatMessage).user?.authenticated}
key={message.id}
/>
);
case MessageType.NAME_CHANGE:
return getNameChangeViewForMessage(message as NameChangeEvent);
case MessageType.CONNECTED_USER_INFO:
return getConnectedInfoMessage(message);
return getConnectedInfoMessage(message as ConnectedClientInfoEvent);
case MessageType.USER_JOINED:
return getUserJoinedMessage(message as ChatMessage);
case MessageType.CHAT_ACTION:
@ -171,6 +175,12 @@ export const ChatContainer: FC<ChatContainerProps> = ({
key={message.id}
/>
);
case MessageType.FEDIVERSE_ENGAGEMENT_FOLLOW:
return getFediverseMessage(message as FediverseEvent);
case MessageType.FEDIVERSE_ENGAGEMENT_LIKE:
return getFediverseMessage(message as FediverseEvent);
case MessageType.FEDIVERSE_ENGAGEMENT_REPOST:
return getFediverseMessage(message as FediverseEvent);
default:
return null;

View file

@ -7,6 +7,7 @@
height: 85px;
width: 300px;
overflow: hidden;
background-color: var(--theme-color-background-main);
&:hover {
border-color: var(--theme-text-link);
@ -23,6 +24,7 @@
.body {
color: var(--theme-color-components-text-on-light);
text-overflow: ellipsis;
line-height: 1.2rem;
}
.account {
@ -37,8 +39,8 @@
height: 25px;
top: -20px;
left: 40px;
border-color: white;
border-width: 1px;
border-color: var(--theme-color-background-main);
border-width: 2px;
border-style: solid;
border-radius: 50%;
background-size: cover;

View file

@ -13,7 +13,7 @@ const Template: ComponentStory<typeof ChatSocialMessage> = args => <ChatSocialMe
export const Follow = Template.bind({});
Follow.args = {
message: {
type: 'follow',
type: 'FEDIVERSE_ENGAGEMENT_FOLLOW',
body: 'james followed this live stream.',
title: 'james@mastodon.social',
image: 'https://mastodon.social/avatars/original/missing.png',
@ -24,7 +24,7 @@ Follow.args = {
export const Like = Template.bind({});
Like.args = {
message: {
type: 'like',
type: 'FEDIVERSE_ENGAGEMENT_LIKE',
body: 'james liked that this stream went live.',
title: 'james@mastodon.social',
image: 'https://mastodon.social/avatars/original/missing.png',
@ -35,7 +35,7 @@ Like.args = {
export const Repost = Template.bind({});
Repost.args = {
message: {
type: 'repost',
type: 'FEDIVERSE_ENGAGEMENT_REPOST',
body: 'james shared this stream with their followers.',
title: 'james@mastodon.social',
image: 'https://mastodon.social/avatars/original/missing.png',

View file

@ -25,13 +25,13 @@ export const ChatSocialMessage: FC<ChatSocialMessageProps> = ({ message }) => {
let Icon;
switch (type.toString()) {
case 'follow':
case 'FEDIVERSE_ENGAGEMENT_FOLLOW':
Icon = FollowIcon;
break;
case 'like':
case 'FEDIVERSE_ENGAGEMENT_LIKE':
Icon = LikeIcon;
break;
case 'repost':
case 'FEDIVERSE_ENGAGEMENT_REPOST':
Icon = RepostIcon;
break;
default:

View file

@ -20,6 +20,7 @@ import {
ChatEvent,
MessageVisibilityEvent,
SocketEvent,
FediverseEvent,
} from '../../interfaces/socket-events';
import { mergeMeta } from '../../utils/helpers';
import handleConnectedClientInfoMessage from './eventhandlers/connected-client-info-handler';
@ -160,7 +161,7 @@ export const ClientConfigStore: FC = () => {
const [clientConfig, setClientConfig] = useRecoilState<ClientConfig>(clientConfigStateAtom);
const [, setServerStatus] = useRecoilState<ServerStatus>(serverStatusState);
const setClockSkew = useSetRecoilState<Number>(clockSkewAtom);
const [chatMessages, setChatMessages] = useRecoilState<ChatMessage[]>(chatMessagesAtom);
const [chatMessages, setChatMessages] = useRecoilState<SocketEvent[]>(chatMessagesAtom);
const [accessToken, setAccessToken] = useRecoilState<string>(accessTokenAtom);
const setAppState = useSetRecoilState<AppStateOptions>(appStateAtom);
const setGlobalFatalErrorMessage = useSetRecoilState<DisplayableError>(fatalErrorStateAtom);
@ -307,6 +308,15 @@ export const ClientConfigStore: FC = () => {
case MessageType.CHAT_ACTION:
setChatMessages(currentState => [...currentState, message as ChatEvent]);
break;
case MessageType.FEDIVERSE_ENGAGEMENT_FOLLOW:
setChatMessages(currentState => [...currentState, message as FediverseEvent]);
break;
case MessageType.FEDIVERSE_ENGAGEMENT_LIKE:
setChatMessages(currentState => [...currentState, message as FediverseEvent]);
break;
case MessageType.FEDIVERSE_ENGAGEMENT_REPOST:
setChatMessages(currentState => [...currentState, message as FediverseEvent]);
break;
case MessageType.VISIBILITY_UPDATE:
handleMessageVisibilityChange(message as MessageVisibilityEvent);
break;

View file

@ -42,3 +42,10 @@ export interface MessageVisibilityEvent extends SocketEvent {
visible: boolean;
ids: string[];
}
export interface FediverseEvent extends SocketEvent {
title: string;
image: string;
link: string;
body: string;
}