summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--backend/index.ts23
-rw-r--r--backend/modules/dummy.ts3
-rw-r--r--dist/static/jquery/scrollbar-jquery/scrollbar.css6
-rw-r--r--package.json1
-rw-r--r--src/index.html87
-rw-r--r--src/index.ts168
-rw-r--r--src/modules/helpers.ts41
-rw-r--r--src/modules/messages.ts47
-rw-r--r--tsconfig.json2
-rw-r--r--webpack.config.ts8
-rw-r--r--yarn.lock5
11 files changed, 210 insertions, 181 deletions
diff --git a/backend/index.ts b/backend/index.ts
index 140e7b9..724be05 100644
--- a/backend/index.ts
+++ b/backend/index.ts
@@ -1,36 +1,27 @@
import express from "express";
import cors from "cors";
-import * as dotenv from "dotenv";
-// import abc from "./modules/dummy";
-// abc();
-
-// const global = { stop: false };
-
-dotenv.config();
const app = express();
const PORT = 5000;
-
app.use(express.json());
app.use(cors());
app.use("/", express.static("../dist"));
const longpoll = require("express-longpoll")(app);
longpoll.create("/poll", cors());
-var data = { text: "Some data" };
app.post("/send", (req, res) => {
- console.log(JSON.stringify(req));
- longpoll.publish("/poll", req.body)
- res.send("OK");
+ console.log(req.body);
+ longpoll.publish("/poll", req.body)
+ res.send("OK");
});
app.listen(PORT, () => {
console.log(`[server]: Server is running at https://localhost:${PORT}`);
});
-// longpoll.publish("/poll", data);
-setInterval(function () {
- longpoll.publish("/poll", data);
-}, 1000); \ No newline at end of file
+// const data: Message = { text: "Some data", color: "#654321", username: "maks" };
+// setInterval(function () {
+// longpoll.publish("/poll", data);
+// }, 5000); \ No newline at end of file
diff --git a/backend/modules/dummy.ts b/backend/modules/dummy.ts
deleted file mode 100644
index 00aaa4c..0000000
--- a/backend/modules/dummy.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function abc() {
- console.log("abc from module");
-} \ No newline at end of file
diff --git a/dist/static/jquery/scrollbar-jquery/scrollbar.css b/dist/static/jquery/scrollbar-jquery/scrollbar.css
index 0efd57d..4f94db1 100644
--- a/dist/static/jquery/scrollbar-jquery/scrollbar.css
+++ b/dist/static/jquery/scrollbar-jquery/scrollbar.css
@@ -1,10 +1,10 @@
#chatlist {
- width: 570px;
+ width: 970px;
clear: both;
margin: 5px auto;
}
#chatlist .viewport {
- width: 550px;
+ width: 950px;
height: 600px;
overflow: hidden;
position: relative;
@@ -14,6 +14,8 @@
position: absolute;
left: 0;
top: 0;
+ overflow-wrap: break-word;
+ font-size: 25px;
}
#chatlist .thumb .end,
#chatlist .thumb {
diff --git a/package.json b/package.json
index 29e88b9..c2bab16 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,6 @@
"webpack-dev-server": "^3.11.2"
},
"dependencies": {
- "dotenv": "^9.0.2",
"express": "^4.17.1",
"express-longpoll": "^0.0.6"
}
diff --git a/src/index.html b/src/index.html
index 8341455..8fa72e0 100644
--- a/src/index.html
+++ b/src/index.html
@@ -13,7 +13,7 @@
<!-- BLOAT -->
<script src="<%= htmlWebpackPlugin.options.staticPath %>/jquery/jquery.js"></script>
- <script src="<%= htmlWebpackPlugin.options.staticPath %>/jquery/emoticons-jquery/jquery.cssemoticons.js"></script>
+ <script src="<%= htmlWebpackPlugin.options.staticPath %>/jquery/emoticons-jquery/jquery.cssemoticons.min.js"></script>
<link href="<%= htmlWebpackPlugin.options.staticPath %>/jquery/emoticons-jquery/jquery.cssemoticons.css"
rel="stylesheet">
</link>
@@ -35,92 +35,11 @@
</div>
<div class="viewport">
<div class="overview">
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
- <div><span>[12:02]</span> <span>&lt;@maks&gt;</span> <span>Hello world</span></div>
</div>
</div>
</div>
- <input type="text" name="msg" id="msg" style="width: 570px; display: block; margin: 5px auto;">
+ <input type="text" name="msg" id="msg" style="width: 970px; display: block; margin: 5px auto;">
+ <span id="error" class="text-center" style="width: 970px; display: block; margin: 5px auto; font-size: 2em; color: red;"></span>
</body>
</html> \ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
index b074be1..670e861 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,64 +1,108 @@
-type Message = {
- text: string;
- user: string;
- color: string;
-};
-const url = "http://localhost:5000/";
-const input = document.getElementById("msg") as HTMLInputElement;
-let username: string;
-let color: string;
-color = "#123456";
-// @ts-ignore
-const chatListScroll = $("#chatlist").tinyscrollbar();
-function init() {
- const username = prompt("Gimme your name: ");
- if (username === null) {
- document.body.innerHTML = "You should give me your name!";
- return;
+import Messages, { Message } from "Modules/messages";
+import Helpers from "Modules/helpers";
+
+export default class Irc {
+ private username: string;
+ private color: string;
+ private readonly messages = new Messages();
+ private readonly helpers = new Helpers();
+
+ readonly input = document.getElementById("msg") as HTMLInputElement;
+ readonly divError = document.getElementById("error") as HTMLDivElement;
+
+ constructor() {
+ this.username = this.helpers.getUsername;
+ this.color = this.helpers.getRandomColor;
+
+ if (this.input === null) throw new Error("NoInputError");
+
+ this.input.onkeyup = (e: KeyboardEvent) => {
+ if (e.code === "Enter") {
+ if (this.messageExe(this.input.value) === true) {
+ if (this.input.value === "") return;
+ const msg = {
+ text: this.input.value,
+ username: this.username,
+ color: this.color,
+ time: Date.now(),
+ };
+ this.input.value = "";
+ this.messages.sendMessage(msg);
+ }
+ }
+ };
+
+ this.poll();
+ }
+
+ poll(): void {
+ console.log("polling");
+ $.ajax({
+ url: this.messages.url + "poll",
+ success: msg => {
+ this.messages.addMessage(msg);
+ const update =
+ document.activeElement === this.input ? "bottom" : "relative";
+
+ this.helpers.updateScrollbar(update);
+ this.poll();
+ },
+ error: () => {
+ this.poll();
+ },
+ timeout: 30000, // 30 seconds
+ });
+ }
+
+ messageExe(msg: string): boolean {
+ if (msg[0] !== "/") return true;
+
+ const msgToSend: Message = {
+ time: Date.now(),
+ color: "black",
+ username: "Server",
+ text: "",
+ };
+
+ msg = msg.slice(1);
+
+ if (msg.startsWith("quit") === true) {
+ msgToSend.text = `User ${this.username} has left the chat`;
+ this.messages.sendMessage(msgToSend);
+
+ this.helpers.suicide(
+ "Thank you for using this site, you can now safely close it."
+ );
+ } else if (msg.startsWith("color") === true) {
+ const color = msg.split(" ")[1];
+
+ if (this.helpers.isColor(color) === true) {
+ msgToSend.text = `User ${this.username} has changed his color to ${color}`;
+ this.messages.sendMessage(msgToSend);
+
+ this.color = color;
+ } else {
+ this.divError.innerText = "You need to give correct color!";
+ }
+ } else if (msg.startsWith("nick") === true) {
+ const username = msg.slice(4).trim();
+
+ if (username === "Server") {
+ this.divError.innerText = "You have to give legal nick!";
+ } else {
+ msgToSend.text = `User ${this.username} has changed his nick to ${username}`;
+ this.messages.sendMessage(msgToSend);
+
+ this.username = username;
+ }
+ } else {
+ this.divError.innerText = "Wrong command!";
+ }
+
+ setTimeout(() => (this.divError.innerText = ""), 3000);
+ this.input.value = "";
+ return false;
}
- // @ts-ignore
- // chatList.tinyscrollbar();
- // //@ts-ignore
- // $("#emot").emoticonize();
- if (input === null) return;
- input.onclick = sendMessage;
- poll();
-}
-function poll() {
- $.ajax({
- url: url + "poll",
- success: addMessage /* data => {
- console.log(data); // { text: "Some data" } -> will be printed in your browser console every 5 seconds
- poll();
- } */,
- error: () => setTimeout(() => poll(), 1000),
- timeout: 30000, // 30 seconds
- });
-}
-function sendMessage() {
- const msg = {
- text: input.value,
- user: username,
- color: color,
- };
- fetch(url + "send", {
- method: "POST",
- headers: {
- Accept: "application/json",
- "Content-Type": "application/json",
- },
- body: JSON.stringify(msg),
- });
-}
-function addMessage(msg: Message) {
- const board = $(".overview")[0];
- const div = document.createElement("div");
- div.innerHTML = JSON.stringify(msg);
- board.appendChild(div);
- console.log(msg);
- // @ts-ignore
- $(chatListScroll).data().plugin_tinyscrollbar.update("relative");
- // $(chatListScroll).data().plugin_tinyscrollbar.update("bottom");
- poll();
}
-init();
+
+new Irc();
diff --git a/src/modules/helpers.ts b/src/modules/helpers.ts
new file mode 100644
index 0000000..862f121
--- /dev/null
+++ b/src/modules/helpers.ts
@@ -0,0 +1,41 @@
+export default class Helpers {
+ //@ts-expect-error
+ readonly chatListScroll = $("#chatlist").tinyscrollbar();
+
+ isColor(strColor: string) {
+ const s = new Option().style;
+ s.color = strColor;
+ return s.color !== "";
+ }
+
+ suicide(msg: string): void {
+ document.body.innerHTML = /* html */ `
+ <div class="text-center" style="margin: 45vh auto; font-size: 3em;">${msg}</div>
+ `;
+ throw new Error(
+ "This page has committed suicide by design, that's a feature!"
+ );
+ }
+
+ updateScrollbar(update: string) {
+ $(this.chatListScroll).data().plugin_tinyscrollbar.update(update);
+ }
+
+ get getRandomColor(): string {
+ return "#" + (Math.random().toString(16) + "000000").substring(2, 8);
+ }
+
+ get getUsername(): string {
+ let username = prompt("Gimme your name: ");
+ if (username === null) {
+ this.suicide("You should give me your name!");
+ throw new Error("NoNameError");
+ }
+ username = username.trim();
+ if (username === "Server") {
+ this.suicide("That name is illegal!");
+ throw new Error("IllegalNameError");
+ }
+ return username;
+ }
+}
diff --git a/src/modules/messages.ts b/src/modules/messages.ts
new file mode 100644
index 0000000..4a4b48a
--- /dev/null
+++ b/src/modules/messages.ts
@@ -0,0 +1,47 @@
+// import Irc from "@/index";
+
+export default class Messages {
+ readonly url = "http://localhost:5000/";
+
+ sendMessage(msg: Message): void {
+ fetch(this.url + "send", {
+ method: "POST",
+ headers: {
+ Accept: "application/json",
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(msg),
+ });
+ }
+
+ async addMessage(msg: Message): Promise<void> {
+ const board = $(".overview")[0],
+ time = new Date(msg.time),
+ div = document.createElement("div"),
+ spans = [
+ document.createElement("span"),
+ document.createElement("span"),
+ document.createElement("span"),
+ ];
+
+ let min = new Date().getMinutes().toString();
+ min = min.length === 1 ? "0" + min : min;
+
+ spans[0].innerText = `[${time.getHours()}:${min}] `;
+ spans[1].innerText = `<@${msg.username}> `;
+ spans[1].style.color = msg.color;
+ spans[2].innerText = msg.text;
+
+ // @ts-expect-error
+ $(spans[2]).emoticonize();
+ spans.forEach(span => div.appendChild(span));
+
+ board.appendChild(div);
+ }
+}
+export interface Message {
+ text: string;
+ color: string;
+ username: string;
+ time: number;
+}
diff --git a/tsconfig.json b/tsconfig.json
index 3464fd0..80e3ba9 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,7 +5,7 @@
/* Basic Options */
"incremental": true, /* Enable incremental compilation */
"target": "ESNEXT", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
- "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
+ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"lib": [ "esnext", "dom" ], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
diff --git a/webpack.config.ts b/webpack.config.ts
index 9ba1cd7..a516d18 100644
--- a/webpack.config.ts
+++ b/webpack.config.ts
@@ -1,9 +1,6 @@
import path from "path";
import HtmlWebpackPlugin from "html-webpack-plugin";
import TsconfigPathsPlugin from "tsconfig-paths-webpack-plugin";
-import dotenv from "dotenv";
-
-dotenv.config();
const absolutePath = (relativePath: string) =>
path.resolve(__dirname, relativePath);
@@ -29,10 +26,7 @@ module.exports = {
extensions: [".ts", "..."],
plugins: [new TsconfigPathsPlugin()],
},
- devtool:
- process.env.MODE === "development"
- ? "eval-cheap-module-source-map"
- : undefined,
+ devtool:"eval-cheap-module-source-map",
output: {
filename: "bundle.js",
path: absolutePath("dist"),
diff --git a/yarn.lock b/yarn.lock
index 1c9b845..f52122e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1288,11 +1288,6 @@ dot-prop@^5.2.0:
dependencies:
is-obj "^2.0.0"
-dotenv@^9.0.2:
- version "9.0.2"
- resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05"
- integrity sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==
-
duplexer3@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"