Creating Discord #31

This commit is contained in:
ADAMJR 2021-09-29 14:20:23 +01:00
parent 2fa3d37b61
commit 030362afb6
7 changed files with 34 additions and 30 deletions

View File

@ -24,11 +24,6 @@
"got": "^11.7.0",
"helmet": "^4.4.1",
"jsonwebtoken": "^8.5.1",
"metascraper": "^5.14.14",
"metascraper-description": "^5.14.14",
"metascraper-image": "^5.14.14",
"metascraper-title": "^5.14.14",
"metascraper-url": "^5.14.14",
"mongoose": "^5.10.7",
"mongoose-unique-validator": "^2.0.3",
"node-fetch": "^2.6.1",

View File

@ -35,7 +35,7 @@ export const Message = model<MessageDocument>('message', new Schema({
},
embed: new Schema<MessageTypes.Embed>({
description: String,
image: String,
imageURL: String,
title: String,
url: String,
}),

View File

@ -1,16 +1,11 @@
import { Socket } from 'socket.io';
import { Message } from '../../data/models/message';
import { generateSnowflake } from '../../data/snowflake-entity';
import { WebSocket } from '../websocket';
import { WSEvent, } from './ws-event';
import Deps from '../../utils/deps';
import { WSGuard } from '../modules/ws-guard';
import Messages from '../../data/messages';
import Pings from '../../data/pings';
import Channels from '../../data/channels';
import Users from '../../data/users';
import { Channel } from '../../data/models/channel';
import { User } from '../../data/models/user';
import { WS } from '../../types/ws';
export default class implements WSEvent<'MESSAGE_CREATE'> {
@ -22,12 +17,12 @@ export default class implements WSEvent<'MESSAGE_CREATE'> {
private users = Deps.get<Users>(Users),
) {}
public async invoke(ws: WebSocket, client: Socket, { channelId, content }: WS.Params.MessageCreate) {
public async invoke(ws: WebSocket, client: Socket, { channelId, content, embed }: WS.Params.MessageCreate) {
const authorId = ws.sessions.userId(client);
const [_, message, author] = await Promise.all([
this.guard.canAccessChannel(client, channelId, true),
this.messages.create(authorId, channelId, { content }),
this.messages.create(authorId, channelId, { content, embed }),
this.users.getSelf(authorId),
]);

View File

@ -23,28 +23,16 @@ export default class implements WSEvent<'MESSAGE_UPDATE'> {
private messages = Deps.get<Messages>(Messages),
) {}
public async invoke(ws: WebSocket, client: Socket, { messageId, content, withEmbed }: WS.Params.MessageUpdate) {
public async invoke(ws: WebSocket, client: Socket, { messageId, content, embed }: WS.Params.MessageUpdate) {
const message = await this.messages.get(messageId);
this.guard.validateIsUser(client, message.authorId);
this.guard.validateKeys('message', { content });
if (content) message.content = content;
// TODO: replace 'withEmbed' with 'embed'
message.embed = (withEmbed) ? await this.getEmbed(message) : undefined;
message.updatedAt = new Date();
await message.save();
ws.to(message.channelId)
.emit('MESSAGE_UPDATE', { message });
}
public async getEmbed(message: MessageDocument): Promise<MessageTypes.Embed | undefined> {
try {
const targetURL = /([https://].*)/.exec(message.content)?.[0];
if (!targetURL) return;
const { body: html, url } = await got(targetURL);
return await metascraper({ html, url });
} catch {}
}
}

View File

@ -77,7 +77,8 @@ const Message: React.FunctionComponent<MessageProps> = ({ message }: MessageProp
className="rounded-full cursor-pointer w-10 h-10"
src={`${process.env.REACT_APP_CDN_URL}${author.avatarURL}`}
alt={author.username} />;
// TODO: refactor to new file
const MessageHeader = () => {
if (isActuallyExtra) return null;
@ -103,7 +104,8 @@ const Message: React.FunctionComponent<MessageProps> = ({ message }: MessageProp
</div>
);
}
// TODO: refactor to new file
const MessageContent = () => (editingMessageId === message.id)
? <MessageBox
content={message.content}
@ -117,6 +119,23 @@ const Message: React.FunctionComponent<MessageProps> = ({ message }: MessageProp
</div>
</div>;
// TODO: refactor to new file
const MessageEmbed = ({ embed }) => (embed) ? (
<div style={{ borderLeft: '5px solid var(--muted)' }}
className="block float-none bg-bg-secondary">
<a href={embed.url} target="_blank">
<h2>{embed.title}</h2>
</a>
<p>{embed.description}</p>
<a href={embed.url} target="_blank">
<img
src={embed.imageURL}
alt={embed.title}
className="w-96" />
</a>
</div>
) : null;
return (
<ContextMenuTrigger key={message.id} id={message.id}>
<div className={classNames('message flex', { 'mt-4': !isActuallyExtra })}>
@ -127,6 +146,12 @@ const Message: React.FunctionComponent<MessageProps> = ({ message }: MessageProp
</div>
<MessageHeader />
<MessageContent />
{/* <MessageEmbed embed={{
title: 'Never Gonna Give You Up',
description: 'Never going to let you down',
imageURL: 'https://discord.club/img/preview.480aa21a.png',
url: 'https://discord.club/img/preview.480aa21a.png',
}} /> */}
</div>
<div className="right-side w-12" />
</div>

2
types/entity.d.ts vendored
View File

@ -103,7 +103,7 @@ declare namespace InviteTypes {
declare namespace MessageTypes {
export interface Embed {
description: string;
image: string;
imageURL: string;
title: string;
url: string;
}

3
types/ws.d.ts vendored
View File

@ -176,6 +176,7 @@ declare namespace WS {
export interface MessageCreate {
channelId: string;
content: string;
embed?: MessageTypes.Embed;
}
export interface MessageDelete {
messageId: string;
@ -183,7 +184,7 @@ declare namespace WS {
export interface MessageUpdate {
messageId: string;
content?: string;
withEmbed: boolean;
embed?: MessageTypes.Embed;
}
export interface MessageCreate {
content: string;