import { Socket } from 'socket.io' ; import { Request , Response , NextFunction } from 'express' ; import { SocketAction , Message , PrivateMessage , SocketClientList } from './types/types' ; import express from 'express' ; import dotenv from 'dotenv' ; import cors from 'cors' ; import { connection as sql } from './db/db' ; import * as http from 'http' ; let app = express ( ) ; let server = http . createServer ( app ) ; let io = require ( 'socket.io' ) ( server ) ; import { router as userRouter } from './routes/user' ; import { router as serverRouter } from './routes/server' ; import { router as channelRouter } from './routes/channel' ; async function main ( ) { dotenv . config ( ) ; const PORT = process . env . PORT || 3001 ; let clients = [ ] ; io . on ( 'connection' , function ( socket ) { let sessionUserId = '' ; let action ; socket . on ( 'simple-chat-message' , async ( msg ) => { var date = new Date ( ) ; let sqlQuery = `INSERT INTO messages (channel_id, user_name, msg, date_time) VALUES (${ sql . escape ( msg . channel . split ( '-' ) [ 1 ] ) }, ${ sql . escape ( msg . from ) }, ${ sql . escape ( msg . msg ) }, ${ sql . escape ( date ) })` ; sql . query ( sqlQuery ) ; const serverId = msg . server . split ( '-' ) [ 1 ] ; action = { type : 'message' , payload : msg } ; io . to ( serverId ) . emit ( 'update' , action ) ; } ) ; socket . on ( 'simple-chat-private-message' , async ( message ) => { const from = await sql . query ( `SELECT user_id from users WHERE user_name = ${ sql . escape ( message . from ) }` ) ; const to = await sql . query ( `SELECT user_id from users WHERE user_name = ${ sql . escape ( message . to ) }` ) ; let date = new Date ( ) ; sql . query ( `INSERT INTO user_messages (user_from, user_to, msg, date_time) VALUES (${ sql . escape ( from [ 0 ] . user_id ) }, ${ sql . escape ( to [ 0 ] . user_id ) }, ${ sql . escape ( message . msg ) }, ${ sql . escape ( date ) })` ) ; action = { type : 'private-message' , payload : { from : message . from , to : message . to , msg : message . msg , user : message . from . toLowerCase ( ) } } ; clients . find ( client => { if ( client . userId === to [ 0 ] . user_id ) { io . to ( client . id ) . emit ( 'update' , action ) ; } } ) ; action = { type : 'private-message' , payload : { from : message . from , to : message . to , msg : message . msg , user : message . to . toLowerCase ( ) } } ; clients . find ( client => { if ( client . userId === from [ 0 ] . user_id ) { io . to ( client . id ) . emit ( 'update' , action ) ; } } ) ; } ) ; socket . on ( 'simple-chat-sign-in' , ( data ) => { sessionUserId = data . userId ; clients . push ( { userId : sessionUserId , id : socket . id , userName : data . userName } ) ; let date = new Date ( ) ; sql . query ( `UPDATE users SET user_last_active = ${ sql . escape ( date ) } WHERE user_id = ${ sql . escape ( sessionUserId ) }` ) ; } ) ; socket . on ( 'subscribe' , ( serverId ) => { socket . join ( serverId ) ; } ) ; socket . on ( 'update-active' , ( ) => { let date = new Date ( ) ; sql . query ( `UPDATE users SET user_last_active = ${ sql . escape ( date ) } WHERE user_id = ${ sql . escape ( sessionUserId ) }` ) ; } ) ; socket . on ( 'voice-signal' , ( data ) => { const toId = data . userId ; data . userId = sessionUserId ; let action = { type : 'voice-signal' , payload : data } ; clients . find ( client => { if ( client . userId === toId ) { io . to ( client . id ) . emit ( 'update' , action ) ; } } ) ; } ) ; socket . on ( 'user-join-voice' , ( data ) => { socket . join ( data . channelId ) ; const socketIdsInChannel = Object . keys ( io . sockets . in ( data . channelId ) . sockets ) ; const userIdsInChannel = [ ] ; clients . forEach ( client => { socketIdsInChannel . forEach ( socketId => { if ( client . id === socketId ) userIdsInChannel . push ( { userId : client . userId , userName : client . userName } ) ; } ) ; } ) ; let action = { type : 'user-join-voice' , payload : { userId : data . userId , clients : userIdsInChannel } } ; io . to ( data . channelId ) . emit ( 'update' , action ) ; } ) ; socket . on ( 'user-leave-voice' , ( data ) => { socket . leave ( data . channelId ) ; const userIdsInChannel = [ ] ; io . in ( data . channelId ) . clients ( ( error , socketClients ) => { socketClients . forEach ( ( socketClientId ) => { clients . forEach ( client => { if ( client . id === socketClientId ) { userIdsInChannel . push ( { userId : client . userId , userName : client . userName } ) ; } } ) ; } ) ; let action = { type : 'user-leave-voice' , payload : { userId : data . userId , clients : userIdsInChannel } } ; io . to ( data . channelId ) . emit ( 'update' , action ) ; } ) ; } ) ; socket . on ( 'disconnect' , ( ) => { clients . find ( ( client , i ) => { if ( client . userId === sessionUserId ) { let action = { type : 'user-leave-voice' , payload : { userId : client . userId } } ; socket . emit ( 'update' , action ) ; return clients . splice ( i , 1 ) ; } } ) ; } ) ; } ) ; server . listen ( PORT , function ( ) { console . log ( `API Listening on ${ PORT }` ) ; } ) ; app . disable ( 'x-powered-by' ) ; app . use ( cors ( ) ) ; app . use ( ( req , res , next ) => { console . log ( `${ new Date ( ) . toString ( ) } => ${ req . originalUrl }` ) ; next ( ) ; } ) ; app . use ( userRouter ) ; app . use ( serverRouter ) ; app . use ( channelRouter ) ; } main ( ) ;