done chat
This commit is contained in:
parent
60e093f123
commit
37c170b265
|
@ -97,13 +97,14 @@ canvas {
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-container {
|
.chat-container {
|
||||||
overflow: scroll;
|
|
||||||
border: black solid
|
border: black solid
|
||||||
}
|
}
|
||||||
|
|
||||||
.messages-container {
|
.messages-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 75%;
|
height: 75%;
|
||||||
|
overflow: scroll;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
border: gray solid;
|
border: gray solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,4 +126,11 @@ canvas {
|
||||||
font-size: 15pt;
|
font-size: 15pt;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0
|
padding: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-message {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
margin-left: 8px;
|
||||||
|
margin-right: 16px;
|
||||||
}
|
}
|
|
@ -4,21 +4,50 @@ function getCookie(name) {
|
||||||
if (parts.length === 2) return parts.pop().split(';').shift();
|
if (parts.length === 2) return parts.pop().split(';').shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(() => {
|
$(document).ready(async () => {
|
||||||
//prod
|
const wsConnectionString = (await fetch(`/api/websocketConnection`)).text()
|
||||||
// const socket = new WebSocket('wss://auth.foxarmy.org');
|
const socket = new WebSocket(wsConnectionString);
|
||||||
//dev
|
let lastMessageNumber = 0;
|
||||||
const socket = new WebSocket('ws://localhost:3000');
|
let page = 20;
|
||||||
|
const fetchMoreMessages = async () => {
|
||||||
|
if (lastMessageNumber < 0 ) return [];
|
||||||
|
let messages = await (await fetch(`/api/getChatMessages/${lastMessageNumber}/${page}`)).json();
|
||||||
|
lastMessageNumber = messages.length < page? -1 : lastMessageNumber + messages.length
|
||||||
|
return messages
|
||||||
|
}
|
||||||
|
|
||||||
const appendMessageToChat = (author, content) => {
|
const appendMessageToChat = (author, content) => {
|
||||||
const messageDiv = document.createElement('div')//`<div class="chat-message" ><${message.author}> ${message.content}</div><br/>`
|
const messageDiv = document.createElement('div')
|
||||||
messageDiv.className = "chat-message"
|
messageDiv.className = "chat-message"
|
||||||
messageDiv.textContent = `<${author}> ${content}`
|
messageDiv.textContent = `<${author}> ${content}`
|
||||||
document.getElementsByClassName("messages-container")[0].appendChild(messageDiv)
|
document.getElementsByClassName("messages-container")[0].appendChild(messageDiv)
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.onmessage = message => {
|
const prependMessageToChat = (author, content) => {
|
||||||
|
const messageDiv = document.createElement('div')
|
||||||
|
messageDiv.className = "chat-message"
|
||||||
|
messageDiv.textContent = `<${author}> ${content}`
|
||||||
|
const messageContainer = document.getElementsByClassName("messages-container")[0]
|
||||||
|
messageContainer.firstChild.insertAdjacentElement('afterend', messageDiv)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onFetchMessageButtonClick = async () => {
|
||||||
|
let messages = await fetchMoreMessages(lastMessageNumber, page);
|
||||||
|
if (messages.length == 0) return;
|
||||||
|
|
||||||
|
messages.forEach(message => {
|
||||||
|
prependMessageToChat(message.author, message.content);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#fetch-messages-button").click(onFetchMessageButtonClick);
|
||||||
|
|
||||||
|
await onFetchMessageButtonClick();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
socket.onmessage = message => {
|
||||||
try {
|
try {
|
||||||
message = JSON.parse(message.data)
|
message = JSON.parse(message.data)
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
@ -40,6 +69,8 @@ $(document).ready(() => {
|
||||||
socket.send(JSON.stringify(message));
|
socket.send(JSON.stringify(message));
|
||||||
appendMessageToChat(message.author, message.content)
|
appendMessageToChat(message.author, message.content)
|
||||||
$("#chat-input").val("")
|
$("#chat-input").val("")
|
||||||
|
let messageContainer = $(".messages-container")
|
||||||
|
messageContainer.animate({ scrollTop: messageContainer.prop("scrollHeight")}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#send-message-button").click(sendData);
|
$("#send-message-button").click(sendData);
|
||||||
|
|
|
@ -6,4 +6,5 @@ DBPORT=5432
|
||||||
DBPASS=GENERATE_A_STRONG_PASSWORD_HERE
|
DBPASS=GENERATE_A_STRONG_PASSWORD_HERE
|
||||||
PORT=3000
|
PORT=3000
|
||||||
REQUIRE_TOKEN=false
|
REQUIRE_TOKEN=false
|
||||||
DELETE_TOKEN_ON_USE=true
|
DELETE_TOKEN_ON_USE=true
|
||||||
|
WS_CONNECTION_STRING=wss://auth.foxarmy.org
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import ApiService from "../services/api.js";
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
|
||||||
|
dotenv.config({path: ".env"});
|
||||||
|
|
||||||
|
class ApiController {
|
||||||
|
async getChatMessages(req, res) {
|
||||||
|
const {limit, offset} = req.params;
|
||||||
|
|
||||||
|
const messages = await ApiService.getChatMessages(limit, offset);
|
||||||
|
|
||||||
|
return res.status(200).send(messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getWebsocketConnection(req, res) {
|
||||||
|
return res.status(200).send(process.env.WS_CONNECTION_STRING)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new ApiController();
|
|
@ -91,6 +91,8 @@ const startChat = async () => {
|
||||||
origin: "website"
|
origin: "website"
|
||||||
})
|
})
|
||||||
}]
|
}]
|
||||||
|
}).catch(e => {
|
||||||
|
console.log(e)
|
||||||
});
|
});
|
||||||
// we are not sending this message to all websockets right now, because plugin will emit
|
// we are not sending this message to all websockets right now, because plugin will emit
|
||||||
// a chat event once it'll catch this message from kafka, triggering a new message
|
// a chat event once it'll catch this message from kafka, triggering a new message
|
||||||
|
|
|
@ -26,7 +26,6 @@ const validateInviteToken = async (req, res, next) => {
|
||||||
let tokenValid = false;
|
let tokenValid = false;
|
||||||
|
|
||||||
inviteTokens.forEach((token) => {
|
inviteTokens.forEach((token) => {
|
||||||
console.log(`${token} == ${inviteToken}`)
|
|
||||||
if (token == inviteToken) tokenValid = true;
|
if (token == inviteToken) tokenValid = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import auth from '../middlewares/auth.js';
|
||||||
|
|
||||||
import utils from '../utils.js';
|
import utils from '../utils.js';
|
||||||
import UserController from '../controllers/user.js';
|
import UserController from '../controllers/user.js';
|
||||||
|
import ApiController from '../controllers/api.js';
|
||||||
|
|
||||||
const ApiRouter = new Router();
|
const ApiRouter = new Router();
|
||||||
|
|
||||||
|
@ -16,5 +17,7 @@ ApiRouter.post('/changepassword', auth.authenticate, existance.userExist, UserCo
|
||||||
ApiRouter.post('/uploadSkin', existance.userExist, auth.authenticate, utils.upload.single('file'), requiredParameters.requireFile, UserController.uploadSkin);
|
ApiRouter.post('/uploadSkin', existance.userExist, auth.authenticate, utils.upload.single('file'), requiredParameters.requireFile, UserController.uploadSkin);
|
||||||
ApiRouter.post('/uploadCape', existance.userExist, auth.authenticate, auth.canHaveCloak, utils.upload.single('file'), requiredParameters.requireFile, UserController.uploadCape);
|
ApiRouter.post('/uploadCape', existance.userExist, auth.authenticate, auth.canHaveCloak, utils.upload.single('file'), requiredParameters.requireFile, UserController.uploadCape);
|
||||||
ApiRouter.get('/getUsername', existance.userExist, auth.authenticate, UserController.getUsername);
|
ApiRouter.get('/getUsername', existance.userExist, auth.authenticate, UserController.getUsername);
|
||||||
|
ApiRouter.get('/getChatMessages/:offset/:limit', auth.authenticate, ApiController.getChatMessages);
|
||||||
|
ApiRouter.get('/webSocketConnection', auth.authenticate, ApiController.getWebsocketConnection)
|
||||||
|
|
||||||
export default ApiRouter;
|
export default ApiRouter;
|
|
@ -0,0 +1,15 @@
|
||||||
|
import db from '../db.js';
|
||||||
|
|
||||||
|
class ApiService {
|
||||||
|
async getChatMessages(limit, offset) {
|
||||||
|
try {
|
||||||
|
const messages = (await db.query("SELECT * FROM chat_messages ORDER BY ID DESC LIMIT $1 OFFSET $2", [limit, offset])).rows
|
||||||
|
|
||||||
|
return messages
|
||||||
|
} catch(e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new ApiService();
|
|
@ -15,7 +15,7 @@ html
|
||||||
h1 Чат
|
h1 Чат
|
||||||
div(class="chat-container")
|
div(class="chat-container")
|
||||||
div(class="messages-container")
|
div(class="messages-container")
|
||||||
|
button(id="fetch-messages-button") Загрузить ещё
|
||||||
div(class="input-container")
|
div(class="input-container")
|
||||||
input(type="text" id="chat-input")
|
input(type="text" id="chat-input")
|
||||||
button(id="send-message-button") Отправить
|
button(id="send-message-button") Отправить
|
Loading…
Reference in New Issue