Skip to content

Commit

Permalink
Merge pull request #18 from Programmer-Network/ws-structure-refactor
Browse files Browse the repository at this point in the history
Implement Web Sockets, improve file structure
  • Loading branch information
agjs committed Oct 26, 2023
2 parents 5ebef2e + fa22b17 commit 4635df5
Show file tree
Hide file tree
Showing 37 changed files with 490 additions and 337 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
dist
chrome-extension/dist
node_modules
pnpm-lock.yaml
.todo
.env
messages.json
links.json
api/*.js
api/*.js
types.js
108 changes: 53 additions & 55 deletions api/server.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
import fastify, {
FastifyInstance,
FastifyReply,
FastifyRequest,
} from "fastify";
import cors from "@fastify/cors";
import fs from "fs";
import fastify, { FastifyReply, FastifyRequest } from "fastify";
import FastifySocketIO from "fastify-socket.io";
import cors from "@fastify/cors";
import { Socket } from "socket.io";

import { getRandomHexColor, parseLinks, saveLinks } from "./utils";
import { CustomFastifyInstance, IMessage, SocketType } from "../types";

export interface IMessage {
sessionId: string;
id: string;
platform: string;
content: string;
emojis: string[];
author: string;
badges: string[];
authorColor: string;
}

const server: FastifyInstance = fastify({ logger: true });
const server = fastify({ logger: true }) as CustomFastifyInstance;
const messages: IMessage[] = [];
const savedMessages: IMessage[] = [];
const userColors: { [key: string]: string } = {};
Expand All @@ -27,43 +16,12 @@ server.register(cors, {
origin: true,
});

server.post(
"/api/messages",
async (request: FastifyRequest, reply: FastifyReply) => {
const message = request.body as IMessage;
if (
messages.length > 0 &&
messages[messages.length - 1].sessionId !== message.sessionId
) {
messages.push({
sessionId: message.sessionId,
id: Math.random().toString(36).substr(2, 9),
platform: message.platform,
content: "Chat reload",
author: "System",
emojis: [],
badges: [],
authorColor: "text-indigo-500",
});
}

if (!userColors[message.author]) {
userColors[message.author] = getRandomHexColor();
}

const links = parseLinks(message.content);
if (links.length > 0) {
await saveLinks(links);
}

messages.push({
...message,
authorColor: userColors[message.author],
});

reply.code(201).send();
}
);
server.register(FastifySocketIO, {
cors: {
origin: "*",
methods: ["GET", "POST"],
},
});

server.get("/api/messages", async (_: FastifyRequest, reply: FastifyReply) => {
reply.send(messages);
Expand All @@ -85,6 +43,46 @@ server.post(
}
);

let reactSocket: Socket | null = null;
let extensionSocket: Socket | null = null;

server.ready((serverError) => {
if (serverError) {
console.log(serverError);
process.exit(1);
}

server.io?.on("connection", (socket: Socket) => {
socket.on("register", (type) => {
if (type === SocketType.REACT) {
reactSocket = socket;
} else if (type === SocketType.EXTENSION) {
extensionSocket = socket;
}
});

socket.on("message", async (message) => {
if (socket === reactSocket) {
extensionSocket?.emit("message", message);
} else if (socket === extensionSocket) {
if (!userColors[message.author]) {
userColors[message.author] = getRandomHexColor();
}

const links = parseLinks(message.content);
if (links.length > 0) {
await saveLinks(links);
}

reactSocket?.emit("message", {
...message,
authorColor: userColors[message.author],
});
}
});
});
});

const start = async () => {
try {
await server.listen({
Expand Down
20 changes: 10 additions & 10 deletions chat/index.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Chat Fusion</title>
</head>
<body class="bg-[#1b1f23]">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Chat Fusion</title>
</head>
<body class="bg-[#1b1f23]">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
22 changes: 11 additions & 11 deletions chat/public/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<script type="module" crossorigin src="./popup.js"></script>
<link rel="stylesheet" href="./popup.css" />
</head>
<body>
<div id="root"></div>
</body>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
<script type="module" crossorigin src="./popup.js"></script>
<link rel="stylesheet" href="./popup.css" />
</head>
<body>
<div id="root"></div>
</body>
</html>
13 changes: 9 additions & 4 deletions chat/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { createContext, useEffect, useState } from "react";
import { Chat } from "./Components/Chat";
import { useMessageListener } from "./Hooks/UseMessageListener";
import { IMessage } from "./types";
import classNames from "classnames";
import { IMessage } from "../../types";

export const LevelContext = createContext(null);

function App() {
const messages = useMessageListener();
const { messages, sendMessage } = useMessageListener();
const [focusedMessage, setFocusedMessage] = useState<IMessage | null>(null);
const [filter, setFilter] = useState("");
const [filtered, setFiltered] = useState<IMessage[]>([]);
Expand All @@ -17,7 +17,9 @@ function App() {
setFiltered(
filter
? []
: messages.filter((message) => message.author === filter)
: messages.filter(
(message: IMessage) => message.author === filter
)
);
};

Expand All @@ -33,7 +35,9 @@ function App() {
return;
}

setFiltered(messages.filter((message) => message.author === filter));
setFiltered(
messages.filter((message: IMessage) => message.author === filter)
);
}, [messages, filter]);

return (
Expand All @@ -45,6 +49,7 @@ function App() {
>
<div>
<Chat
sendMessage={sendMessage}
messages={filtered.length ? filtered : messages}
focusedMessage={focusedMessage}
setFocusedMessage={setFocusedMessage}
Expand Down
10 changes: 7 additions & 3 deletions chat/src/Components/Chat/Chat.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useEffect, useRef, FC, useState } from "react";
import { IMessage } from "../../types";
import { Message } from "../Message";
import classNames from "classnames";
import { ReloadIcon } from "../../assets/Icons/Reload";
import { IMessage } from "../../../../types";

export const Chat: FC<{
messages: IMessage[];
sendMessage: (message: string) => void;
focusedMessage: IMessage | null;
setFocusedMessage: (message: IMessage | null) => void;
onAction: (action: string, data: unknown) => void;
Expand All @@ -19,9 +20,11 @@ export const Chat: FC<{
};

const scrollToBottom = () => {
if (messagesEndRef.current) {
messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
if (!messagesEndRef.current) {
return;
}

messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
};

useEffect(() => {
Expand Down Expand Up @@ -56,6 +59,7 @@ export const Chat: FC<{
<div ref={messagesEndRef}></div>
</div>
</div>

{!focusedMessage && (
<div className="flex items-center justify-center pb-8">
<ReloadIcon
Expand Down
18 changes: 9 additions & 9 deletions chat/src/Components/ChatDivider/ChatDivider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { FC } from "react";
import { IMessage } from "../../types";

export const ChatDivider: FC<{
message: IMessage;
message: IMessage;
}> = ({ message }) => {
const { platform } = message;
const { platform } = message;

return (
<div className="w-100 border-b border-b-gray-700 text-center h-5 my-12">
<span className="text-white text-xs mb-2 bg-indigo-700 p-2 uppercase">
<b className="-tracking-tight">{platform}</b> reloaded
</span>
</div>
);
return (
<div className="w-100 border-b border-b-gray-700 text-center h-5 my-12">
<span className="text-white text-xs mb-2 bg-indigo-700 p-2 uppercase">
<b className="-tracking-tight">{platform}</b> reloaded
</span>
</div>
);
};
26 changes: 19 additions & 7 deletions chat/src/Components/Message/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ import { IMessage } from "../../types";
import classNames from "classnames";
import { SaveIcon } from "../../assets/Icons/Save";
import { FilterToggle } from "../FilterToggle/FilterToggle";
import { TwitchIcon } from "../../assets/Icons/Twitch";
import { YouTubeIcon } from "../../assets/Icons/YouTube";
import { KickIcon } from "../../assets/Icons/Kick";

const getIcon = (platform: string) => {
switch (platform) {
case "twitch":
return <TwitchIcon className="text-indigo-700 w-8 mr-4" />;
case "youtube":
return <YouTubeIcon className="text-rose-700 w-9 mr-4" />;
case "kick":
return <KickIcon className="text-green-700 w-9 mr-4" />;
default:
return null;
}
};

export const Message: FC<{
message: IMessage;
Expand Down Expand Up @@ -32,7 +48,7 @@ export const Message: FC<{
onMouseOver={() => setHoveredId(message.id)}
onMouseLeave={() => setHoveredId("")}
className={classNames(
"flex flex-col cursor-pointer relative border-l-4 border-dotted border-gray-500 px-4 py-2",
"flex flex-col cursor-pointer relative border-gray-500 px-4 py-2",
{
"px-16 py-16 w-4/12 border-8 border-l-8":
focusedMessage && focusedMessage.id === message.id,
Expand All @@ -48,6 +64,7 @@ export const Message: FC<{
"flex-col !items-start !justify-start p-4": focusedMessage,
})}
>
<span>{getIcon(message.platform)}</span>
<div
style={{ color: message.authorColor }}
className={classNames(
Expand All @@ -61,12 +78,7 @@ export const Message: FC<{
>
<div className="flex gap-1 items-center">
{badges?.map((badge, index) => (
<img
key={index}
className="w-7 h-7"
src={badge}
alt={badge}
/>
<img key={index} src={badge} alt={badge} />
))}
</div>
{author}
Expand Down
Loading

0 comments on commit 4635df5

Please sign in to comment.