Added chat
This commit is contained in:
parent
a71e551310
commit
56af0926d7
13 changed files with 645 additions and 21 deletions
37
src/chat/chat.js
Normal file
37
src/chat/chat.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { Server } from 'socket.io'
|
||||
import { backendProxy } from '../lib/db/db.js'
|
||||
|
||||
function configureServer(server) {
|
||||
const io = new Server(server.httpServer)
|
||||
|
||||
io.on('connection', (socket) => {
|
||||
socket.on('join', async (id) => {
|
||||
socket.join(id);
|
||||
|
||||
let api = await backendProxy({
|
||||
route: 'chatGet',
|
||||
backendParams: {
|
||||
room: id,
|
||||
token: 1
|
||||
}
|
||||
});
|
||||
|
||||
socket.emit('load',api.data);
|
||||
})
|
||||
socket.on('chat', async (content,room,token) => {
|
||||
let api = await backendProxy({
|
||||
route: 'chatAdd',
|
||||
backendParams: {
|
||||
token,
|
||||
content,
|
||||
room
|
||||
}
|
||||
})
|
||||
io.to(room).emit('chat',api.data);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
configureServer
|
||||
};
|
|
@ -59,6 +59,9 @@
|
|||
<a href='/new_post'>
|
||||
Create
|
||||
</a>
|
||||
<a href='/chat/main'>
|
||||
Chat
|
||||
</a>
|
||||
{:else}
|
||||
<a href='/account/login'>
|
||||
Log in
|
||||
|
|
|
@ -7,7 +7,8 @@ const AUTH_ACTIONS = [
|
|||
'vote',
|
||||
'postDelete',
|
||||
'pfp',
|
||||
'follow'
|
||||
'follow',
|
||||
'chatAdd'
|
||||
];
|
||||
|
||||
const FILE_DIRS = [
|
||||
|
@ -62,6 +63,13 @@ async function initDb() {
|
|||
time INTEGER \
|
||||
)');
|
||||
|
||||
await db.run('CREATE TABLE IF NOT EXISTS chat ( \
|
||||
username CHAR(64), \
|
||||
content CHAR(10240), \
|
||||
time INTEGER, \
|
||||
room CONTENT(64) \
|
||||
)');
|
||||
|
||||
await db.run('CREATE TABLE IF NOT EXISTS vote ( \
|
||||
id CHAR(64), \
|
||||
username CHAR(64), \
|
||||
|
@ -99,7 +107,12 @@ let backendProxy = async ({route, backendParams}) => {
|
|||
|
||||
extraParams['db'] = db;
|
||||
|
||||
let user = (await backend.token({cookies: backendParams.cookies},extraParams)) || {};
|
||||
let jason = {cookies: backendParams.cookies};
|
||||
|
||||
if (backendParams.token)
|
||||
jason.token = backendParams.token;
|
||||
|
||||
let user = (await backend.token(jason,extraParams)) || {};
|
||||
|
||||
user = user.data;
|
||||
|
||||
|
|
|
@ -178,8 +178,6 @@ backend.postCreate = async ({content}, {user,db}) => {
|
|||
if (lengthCheck)
|
||||
return lengthCheck;
|
||||
|
||||
if (!content) return {'success': 'There is no post!' };
|
||||
|
||||
var id = randomBytes(10).toString('hex');
|
||||
|
||||
var postFlatten = formatPost(content).flat();
|
||||
|
@ -378,8 +376,13 @@ backend.vote = async ({id, vote}, {user, db}) => {
|
|||
return {data: {up,down}};
|
||||
}
|
||||
|
||||
backend.token = async ({cookies}, {db}) => {
|
||||
var tokenIn = cookies.get('token');
|
||||
backend.token = async ({cookies, token}, {db}) => {
|
||||
var tokenIn;
|
||||
if (token) {
|
||||
tokenIn = token;
|
||||
} else {
|
||||
tokenIn = cookies.get('token');
|
||||
}
|
||||
|
||||
var existingAccounts = await db.all('SELECT username from token WHERE token = ?',[
|
||||
tokenIn
|
||||
|
@ -388,7 +391,7 @@ backend.token = async ({cookies}, {db}) => {
|
|||
if (!existingAccounts || existingAccounts.length < 1)
|
||||
return false;
|
||||
|
||||
return {data: existingAccounts[0].username};
|
||||
return {data: existingAccounts[0].username, token: tokenIn};
|
||||
}
|
||||
|
||||
backend.follow = async ({target}, {user, db}) => {
|
||||
|
@ -451,6 +454,33 @@ backend.messages = async ({isRead}, {user, db}) => {
|
|||
return {'data': {msg, read}};
|
||||
};
|
||||
|
||||
backend.chatAdd = async ({content, room}, {user,db}) => {
|
||||
if (!content) return {'success': 'No message provided.'}
|
||||
|
||||
var lengthCheck = checkLength(content,'Post content',1,10240);
|
||||
|
||||
if (lengthCheck)
|
||||
return lengthCheck;
|
||||
|
||||
let time = Math.floor(new Date() * 1000);
|
||||
|
||||
await db.run('INSERT INTO chat (username, content, time, room) VALUES (?, ?, ?, ?)', [
|
||||
user,
|
||||
content,
|
||||
time,
|
||||
room
|
||||
])
|
||||
|
||||
return {'data': {content, username: user, time, room}};
|
||||
}
|
||||
|
||||
backend.chatGet = async ({room}, {user,db}) => {
|
||||
let messages = await db.all('SELECT * from chat WHERE room = ? ORDER BY time LIMIT 1000', [
|
||||
room
|
||||
])
|
||||
|
||||
return {'data': messages};
|
||||
}
|
||||
|
||||
export {
|
||||
backend,
|
||||
|
|
|
@ -13,6 +13,12 @@ const formats = [
|
|||
'bolditalic'
|
||||
];
|
||||
|
||||
const postTypes = {
|
||||
'@': 'users',
|
||||
'#': 'post',
|
||||
'%': 'chat'
|
||||
}
|
||||
|
||||
let checkLength = function(string, field, lowerBound, upperBound) {
|
||||
if (string.length < lowerBound) {
|
||||
if (string.length == 0) {
|
||||
|
@ -133,10 +139,10 @@ let formatPost = function(post, ignoreImg) {
|
|||
|
||||
return splitPost;
|
||||
}
|
||||
} else if (subPost[0] == '@' || subPost[0] == '#') {
|
||||
} else if (postTypes[subPost[0] + '']) {
|
||||
var subPostIn = safeName(subPost.substring(0));
|
||||
|
||||
var type = (subPost[0] == '@') ? 'users' : 'post';
|
||||
var type = postTypes[subPost[0]];
|
||||
|
||||
splitPost = {'type': 'link', 'display': subPost, 'subtype': type, 'url': `/${type}/${subPostIn}`};
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
export let data;
|
||||
|
||||
import Header from '$lib/components/Header.svelte';
|
||||
|
||||
</script>
|
||||
|
||||
<div id='content'>
|
||||
|
|
11
src/routes/chat/[chat]/+page.js
Normal file
11
src/routes/chat/[chat]/+page.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { redirect } from '@sveltejs/kit';
|
||||
|
||||
/** @type {import('./$types').PageLoad} */
|
||||
export async function load({ fetch, params, url }) {
|
||||
|
||||
var id = params.chat;
|
||||
|
||||
const token = await fetch(`/api/token`).then(x => x.json());
|
||||
|
||||
return {id, token: token.token};
|
||||
}
|
100
src/routes/chat/[chat]/+page.svelte
Normal file
100
src/routes/chat/[chat]/+page.svelte
Normal file
|
@ -0,0 +1,100 @@
|
|||
<script>
|
||||
import { io } from 'socket.io-client'
|
||||
import PostBody from '$lib/components/PostBody.svelte';
|
||||
|
||||
/** @type {import('./$types').PageData} */
|
||||
export let data;
|
||||
|
||||
let id = data.id;
|
||||
let messages = [];
|
||||
let input;
|
||||
|
||||
const socket = io();
|
||||
|
||||
socket.emit('join',id);
|
||||
|
||||
function scroll() {
|
||||
setTimeout(function() {
|
||||
input.lastChild.scrollIntoView()
|
||||
},200);
|
||||
}
|
||||
|
||||
socket.on('load', (message) => {
|
||||
messages = message;
|
||||
scroll();
|
||||
})
|
||||
|
||||
socket.on('chat', (message) => {
|
||||
messages = [...messages, message];
|
||||
scroll();
|
||||
})
|
||||
|
||||
function inputHandler(e) {
|
||||
if(e.key == "Enter" && !e.shiftKey) {
|
||||
socket.emit('chat',e.target.textContent, id, data.token)
|
||||
e.preventDefault();
|
||||
e.target.innerText = '';
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#mainChat {
|
||||
height: calc(100% - 160px);
|
||||
width: calc(100vw - 30px);
|
||||
padding: 15px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#mainInput {
|
||||
height: 40px;
|
||||
width: calc(100vw - 30px);
|
||||
padding: 15px;
|
||||
|
||||
background: var(--dark-2);
|
||||
}
|
||||
|
||||
#header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.pfp {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-right: 10px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 0.8rem;
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id='mainChat' bind:this={input}>
|
||||
{#each messages as message}
|
||||
<div class='message'>
|
||||
<div id='header'>
|
||||
<img class='pfp' src='/img/pfp/{message.username}.png'/>
|
||||
<div><a href='/users/{message.username}'>
|
||||
{message.username}
|
||||
</a></div>
|
||||
<div class='date'>
|
||||
{(new Date(message.time / 1000) + '').split('GMT')[0]}
|
||||
</div>
|
||||
</div>
|
||||
<PostBody content={message.content}></PostBody>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div id="mainInput" contenteditable="" autocomplete="off" on:keydown={inputHandler}></div>
|
|
@ -90,6 +90,9 @@
|
|||
<p>
|
||||
<b>#post</b> replies to a post by ID
|
||||
</p>
|
||||
<p>
|
||||
<b>%chat</b> links to a chatroom
|
||||
</p>
|
||||
<p>
|
||||
<b>*x*</b> produces italic text
|
||||
</p>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue