feat: add javascript linter format

This commit is contained in:
leokontente 2025-06-03 12:12:48 +02:00
parent 3b3aaf29af
commit 7ce9f2dd93
13 changed files with 1561 additions and 1557 deletions

3
.prettierrc Normal file
View file

@ -0,0 +1,3 @@
{
"singleQuote": true
}

View file

@ -2,4 +2,4 @@
Web-based memos that support real-time collaboration. Inspired by scrumblr. Web-based memos that support real-time collaboration. Inspired by scrumblr.
test Léo Run 'bun install' for installing deps and 'redis-server --daemonize yes && bun run start' to start the servers

BIN
bun.lockb

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/*exports.database = { /* exports.database = {
type: 'mongodb', type: 'mongodb',
hostname: 'localhost', hostname: 'localhost',
port: 27017, port: 27017,
@ -6,7 +6,7 @@
}; };
*/ */
var argv = require("yargs").usage( const { argv } = require('yargs').usage(
'Usage: $0 [--port INTEGER [8080]] \ 'Usage: $0 [--port INTEGER [8080]] \
[--baseurl STRING ["/"]] \ [--baseurl STRING ["/"]] \
[--redis STRING:INT [127.0.0.1:6379]] \ [--redis STRING:INT [127.0.0.1:6379]] \
@ -16,28 +16,27 @@ var argv = require("yargs").usage(
[--logoUrl STRING] \ [--logoUrl STRING] \
[--faviconUrl STRING] \ ' [--faviconUrl STRING] \ '
)
).argv
exports.server = { exports.server = {
port: argv.port || 8080, port: argv.port || 8080,
baseurl: argv.baseurl || "/", baseurl: argv.baseurl || '/'
} }
exports.googleanalytics = { exports.googleanalytics = {
enabled: argv["gaEnabled"] || false, enabled: argv.gaEnabled || false,
account: argv["gaAccount"] || "UA-2069672-4", account: argv.gaAccount || 'UA-2069672-4'
} }
var redis_conf = argv.redis || "127.0.0.1:6379" const redis_conf = argv.redis || '127.0.0.1:6379'
exports.database = { exports.database = {
sock: argv["sock"] || false, sock: argv.sock || false,
type: "redis", type: 'redis',
prefix: "#scrumblr#", prefix: '#scrumblr#',
host: redis_conf.split(":")[0] || "127.0.0.1", host: redis_conf.split(':')[0] || '127.0.0.1',
port: redis_conf.split(":")[1] || 6379, port: redis_conf.split(':')[1] || 6379
} }
exports.headerBarUrl = argv['headerBarUrl'] || null /* example url with appropriate json markup : 'https://colibris-lemouvement.org/archipel-markup?domain=colibris-outilslibres.org' */ exports.headerBarUrl = argv.headerBarUrl || null /* example url with appropriate json markup : 'https://colibris-lemouvement.org/archipel-markup?domain=colibris-outilslibres.org' */
exports.logoUrl = argv['logoUrl'] || null /* example logo url : 'https://postit.colibris-outilslibres.org/images/logo-Post-it.svg' */ exports.logoUrl = argv.logoUrl || null /* example logo url : 'https://postit.colibris-outilslibres.org/images/logo-Post-it.svg' */
exports.faviconUrl = argv['faviconUrl'] || null /* example favicon url : 'https://postit.colibris-outilslibres.org/images/favicon.png' */ exports.faviconUrl = argv.faviconUrl || null /* example favicon url : 'https://postit.colibris-outilslibres.org/images/favicon.png' */

49
eslint.config.mjs Normal file
View file

@ -0,0 +1,49 @@
import { defineConfig, globalIgnores } from 'eslint/config'
import globals from 'globals'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import js from '@eslint/js'
import { FlatCompat } from '@eslint/eslintrc'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all
})
export default defineConfig([globalIgnores([
'node_modules',
'client/lib'
]), {
extends: compat.extends('airbnb-base'),
languageOptions: { ecmaVersion: 13 },
rules: {
semi: ['error', 'never'],
'max-len': ['error', { code: 104 }],
'vars-on-top': 'off',
'class-methods-use-this': 'off',
'import/no-unresolved': 'off',
'import/extensions': ['error', 'always'],
'import/prefer-default-export': ['off'],
'no-use-before-define': ['off'],
eqeqeq: ['error', 'smart'],
'comma-dangle': ['error', 'never'],
'object-curly-newline': ['error', { multiline: true }],
'func-names': ['error', 'never'],
'space-before-function-paren': ['error', 'never'],
'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
'no-new': 'off',
'no-restricted-syntax': 'off',
'guard-for-in': 'off'
}
}])

View file

@ -1,6 +1,6 @@
var conf = require('../config.js').database; const conf = require('../config.js').database
exports.db = require('./data/'+conf.type+'.js').db; exports.db = require(`./data/${conf.type}.js`).db
/* /*
var db = function(callback) { } var db = function(callback) { }

View file

@ -1,195 +1,181 @@
var Db = require('mongodb').Db; const { Db } = require('mongodb')
Server = require('mongodb').Server, Server = require('mongodb').Server,
BSON = require('mongodb').BSONNative, BSON = require('mongodb').BSONNative,
conf = require('../../config.js').database; conf = require('../../config.js').database
var db = function(callback) const db = function(callback) {
{ this.rooms = false
this.rooms = false; const t = this
var t = this;
var db = new Db(conf.database, new Server(conf.hostname, conf.port), {native_parser:true}); const db = new Db(conf.database, new Server(conf.hostname, conf.port), { native_parser: true })
db.open(function(err, db) { db.open((err, db) => {
db.collection('rooms', function(err, collection) { db.collection('rooms', (err, collection) => {
// make sure we have an index on name // make sure we have an index on name
collection.ensureIndex([['name',1]],false,function() {}); collection.ensureIndex([['name', 1]], false, () => {})
t.rooms = collection; t.rooms = collection
}); })
callback(); callback()
}); })
} }
db.prototype = { db.prototype = {
clearRoom: function(room, callback) clearRoom(room, callback) {
{ this.rooms.remove({ name: room }, callback)
this.rooms.remove({name:room},callback); },
},
// theme commands // theme commands
setTheme: function(room, theme) setTheme(room, theme) {
{ this.rooms.update(
this.rooms.update( { name: room },
{name:room}, { $set: { theme } }
{$set:{theme:theme}} )
); },
},
getTheme: function(room, callback) getTheme(room, callback) {
{ this.rooms.findOne(
this.rooms.findOne( { name: room },
{name:room}, { theme: true },
{theme:true}, (err, room) => {
function(err, room) { if (room) {
if(room) { callback(room.theme)
callback(room.theme); } else {
} else { callback()
callback(); }
} }
} )
); },
},
// revision commands // revision commands
setRevisions: function(room, revisions) { setRevisions(room, revisions) {
this.rooms.update( this.rooms.update(
{name:room}, { name: room },
{$set:{revisions:revisions}} { $set: { revisions } }
); )
}, },
getRevisions: function(room, callback) { getRevisions(room, callback) {
this.rooms.findOne( this.rooms.findOne(
{name:room}, { name: room },
{revisions:true}, { revisions: true },
function(err, room) { (err, room) => {
if(room) { if (room) {
callback(room.revisions); callback(room.revisions)
} else { } else {
callback(); callback()
} }
} }
); )
}, },
// Column commands // Column commands
createColumn: function(room, name, callback) createColumn(room, name, callback) {
{ this.rooms.update(
this.rooms.update( { name: room },
{name:room}, { $push: { columns: name } },
{$push:{columns:name}}, { upsert: true },
{upsert:true} callback
,callback )
); },
},
getAllColumns: function(room, callback) getAllColumns(room, callback) {
{ this.rooms.findOne({ name: room }, { columns: true }, (err, room) => {
this.rooms.findOne({name:room},{columns:true},function(err, room) { if (room) {
if(room) { callback(room.columns)
callback(room.columns); } else {
} else { callback()
callback(); }
} })
}); },
},
deleteColumn: function(room) deleteColumn(room) {
{ this.rooms.update(
this.rooms.update( { name: room },
{name:room}, { $pop: { columns: 1 } }
{$pop:{columns:1}} )
); },
},
setColumns: function(room, columns) setColumns(room, columns) {
{ this.rooms.update(
this.rooms.update( { name: room },
{name:room}, { $set: { columns } },
{$set:{columns:columns}}, { upsert: true }
{upsert:true} )
); },
},
// Card commands // Card commands
createCard: function(room, id, card) createCard(room, id, card) {
{ const doc = {}
var doc = {}; doc[`cards.${id}`] = card
doc['cards.'+id] = card; this.rooms.update(
this.rooms.update( { name: room },
{name:room}, { $set: doc },
{$set:doc}, { upsert: true }
{upsert:true} )
); },
},
getAllCards: function(room, callback) getAllCards(room, callback) {
{ this.rooms.findOne({ name: room }, { cards: true }, (err, room) => {
this.rooms.findOne({name:room},{cards:true},function(err, room) { if (room) {
if(room) { callback(room.cards)
callback(room.cards); } else {
} else { callback()
callback(); }
} })
}); },
},
cardEdit: function(room, id, text) cardEdit(room, id, text) {
{ const doc = {}
var doc = {}; doc[`cards.${id}.text`] = text
doc['cards.'+id+'.text'] = text; this.rooms.update(
this.rooms.update( { name: room },
{name:room}, { $set: doc }
{$set:doc} )
); },
},
cardSetXY: function(room, id, x, y) cardSetXY(room, id, x, y) {
{ const doc = {}
var doc = {}; doc[`cards.${id}.x`] = x
doc['cards.'+id+'.x'] = x; doc[`cards.${id}.y`] = y
doc['cards.'+id+'.y'] = y; this.rooms.update(
this.rooms.update( { name: room },
{name:room}, { $set: doc }
{$set:doc} )
); },
},
deleteCard: function(room, id) deleteCard(room, id) {
{ const doc = {}
var doc = {}; doc[`cards.${id}`] = true
doc['cards.'+id] = true; this.rooms.update(
this.rooms.update( { name: room },
{name:room}, { $unset: doc }
{$unset:doc} )
); },
},
addSticker: function(room, cardId, stickerId) addSticker(room, cardId, stickerId) {
{ const doc = {}
var doc = {}; doc[`cards.${cardId}.sticker`] = stickerId
doc['cards.'+cardId+'.sticker'] = stickerId; this.rooms.update(
this.rooms.update( { name: room },
{name:room}, { $set: doc }
{$set:doc} )
); },
}, getBoardSize(room, callback) {
getBoardSize: function(room, callback) { this.rooms.findOne(
this.rooms.findOne( { name: room },
{name:room}, (err, room) => {
function(err, room) { if (room) {
if(room) { callback(room.size)
callback(room.size); } else {
} else { callback()
callback(); }
} }
} )
); },
}, setBoardSize(room, size) {
setBoardSize: function(room, size) { this.rooms.update(
this.rooms.update( { name: room },
{name:room}, { $set: { size } }
{$set:{'size':size}} )
); }
} }
}; exports.db = db
exports.db = db;

View file

@ -1,202 +1,197 @@
var conf = require('../../config.js').database; const conf = require('../../config.js').database
var redis = require("redis"), const redis = require('redis')
redisClient = null; //redis.createClient();
var async = require("async"); let redisClient = null // redis.createClient();
var sets = require('simplesets');
const async = require('async')
const sets = require('simplesets')
// If you want Memory Store instead... // If you want Memory Store instead...
// var MemoryStore = require('connect/middleware/session/memory'); // var MemoryStore = require('connect/middleware/session/memory');
// var session_store = new MemoryStore(); // var session_store = new MemoryStore();
var REDIS_PREFIX = '#scrumblr#'; const REDIS_PREFIX = '#scrumblr#'
//For Redis Debugging // For Redis Debugging
const db = function(callback) {
if (conf.sock) {
console.log(`Opening redis connection to socket ${conf.host}`)
redisClient = redis.createClient(conf.host)
} else {
console.log(`Opening redis connection to ${conf.host}:${conf.port}`)
redisClient = redis.createClient(conf.port, conf.host, {})
}
redisClient.on('connect', (err) => {
callback()
})
var db = function(callback) { redisClient.on('error', (err) => {
if (conf.sock) { console.log(`Redis error: ${err}`)
console.log('Opening redis connection to socket ' + conf.host); })
redisClient = redis.createClient(conf.host); }
} else {
console.log('Opening redis connection to ' + conf.host + ':' + conf.port);
redisClient = redis.createClient(conf.port, conf.host, {});
}
redisClient.on("connect", function (err) {
callback();
});
redisClient.on("error", function (err) {
console.log("Redis error: " + err);
});
};
db.prototype = { db.prototype = {
clearRoom: function(room, callback) { clearRoom(room, callback) {
redisClient.del(REDIS_PREFIX + '-room:/demo-cards', function (err, res) { redisClient.del(`${REDIS_PREFIX}-room:/demo-cards`, (err, res) => {
redisClient.del(REDIS_PREFIX + '-room:/demo-columns', function (err, res) { redisClient.del(`${REDIS_PREFIX}-room:/demo-columns`, (err, res) => {
callback(); callback()
}); })
}); })
}, },
// theme commands // theme commands
setTheme: function(room, theme) { setTheme(room, theme) {
redisClient.set(REDIS_PREFIX + '-room:' + room + '-theme', theme); redisClient.set(`${REDIS_PREFIX}-room:${room}-theme`, theme)
}, },
getTheme: function(room, callback) { getTheme(room, callback) {
redisClient.get(REDIS_PREFIX + '-room:' + room + '-theme', function (err, res) { redisClient.get(`${REDIS_PREFIX}-room:${room}-theme`, (err, res) => {
callback(res); callback(res)
}); })
}, },
// revision commands // revision commands
setRevisions: function(room, revisions) { setRevisions(room, revisions) {
if (Object.keys(revisions).length === 0) { if (Object.keys(revisions).length === 0) {
redisClient.del(REDIS_PREFIX + '-room:' + room + '-revisions'); redisClient.del(`${REDIS_PREFIX}-room:${room}-revisions`)
} else { } else {
redisClient.set(REDIS_PREFIX + '-room:' + room + '-revisions', JSON.stringify(revisions)); redisClient.set(`${REDIS_PREFIX}-room:${room}-revisions`, JSON.stringify(revisions))
} }
}, },
getRevisions: function(room, callback) { getRevisions(room, callback) {
redisClient.get(REDIS_PREFIX + '-room:' + room + '-revisions', function (err, res) { redisClient.get(`${REDIS_PREFIX}-room:${room}-revisions`, (err, res) => {
callback(JSON.parse(res)); callback(JSON.parse(res))
}); })
}, },
// Column commands // Column commands
createColumn: function(room, name, callback) { createColumn(room, name, callback) {
redisClient.rpush(REDIS_PREFIX + '-room:' + room + '-columns', name, redisClient.rpush(
function (err, res) { `${REDIS_PREFIX}-room:${room}-columns`,
if (typeof callback != "undefined" && callback !== null) callback(); name,
} (err, res) => {
); if (typeof callback != 'undefined' && callback !== null) callback()
}, }
)
},
getAllColumns: function(room, callback) { getAllColumns(room, callback) {
redisClient.lrange(REDIS_PREFIX + '-room:' + room + '-columns', 0, -1, function(err, res) { redisClient.lrange(`${REDIS_PREFIX}-room:${room}-columns`, 0, -1, (err, res) => {
callback(res); callback(res)
}); })
}, },
deleteColumn: function(room) { deleteColumn(room) {
redisClient.rpop(REDIS_PREFIX + '-room:' + room + '-columns'); redisClient.rpop(`${REDIS_PREFIX}-room:${room}-columns`)
}, },
setColumns: function(room, columns) { setColumns(room, columns) {
//1. first delete all columns // 1. first delete all columns
redisClient.del(REDIS_PREFIX + '-room:' + room + '-columns', function () { redisClient.del(`${REDIS_PREFIX}-room:${room}-columns`, () => {
//2. now add columns for each thingy // 2. now add columns for each thingy
async.forEachSeries( async.forEachSeries(
columns, columns,
function( item, callback ) { (item, callback) => {
//console.log('rpush: ' + REDIS_PREFIX + '-room:' + room + '-columns' + ' -- ' + item); // console.log('rpush: ' + REDIS_PREFIX + '-room:' + room + '-columns' + ' -- ' + item);
redisClient.rpush(REDIS_PREFIX + '-room:' + room + '-columns', item, redisClient.rpush(
function (err, res) { `${REDIS_PREFIX}-room:${room}-columns`,
callback(); item,
} (err, res) => {
); callback()
}, }
function() { )
//this happens when the series is complete },
} () => {
); // this happens when the series is complete
}); }
}, )
})
},
// Card commands // Card commands
createCard: function(room, id, card) { createCard(room, id, card) {
var cardString = JSON.stringify(card); const cardString = JSON.stringify(card)
redisClient.hset( redisClient.hset(
REDIS_PREFIX + '-room:' + room + '-cards', `${REDIS_PREFIX}-room:${room}-cards`,
id, id,
cardString cardString
); )
}, },
getAllCards: function(room, callback) { getAllCards(room, callback) {
redisClient.hgetall(REDIS_PREFIX + '-room:' + room + '-cards', function (err, res) { redisClient.hgetall(`${REDIS_PREFIX}-room:${room}-cards`, (err, res) => {
const cards = []
var cards = []; for (const i in res) {
cards.push(JSON.parse(res[i]))
}
// console.dir(cards);
for (var i in res) { callback(cards)
cards.push( JSON.parse(res[i]) ); })
} },
//console.dir(cards);
callback(cards); cardEdit(room, id, text) {
}); redisClient.hget(`${REDIS_PREFIX}-room:${room}-cards`, id, (err, res) => {
}, const card = JSON.parse(res)
if (card !== null) {
card.text = text
redisClient.hset(`${REDIS_PREFIX}-room:${room}-cards`, id, JSON.stringify(card))
}
})
},
cardEdit: function(room, id, text) { cardSetXY(room, id, x, y) {
redisClient.hget(REDIS_PREFIX + '-room:' + room + '-cards', id, function(err, res) { redisClient.hget(`${REDIS_PREFIX}-room:${room}-cards`, id, (err, res) => {
var card = JSON.parse(res); const card = JSON.parse(res)
if (card !== null) { if (card !== null) {
card.text = text; card.x = x
redisClient.hset(REDIS_PREFIX + '-room:' + room + '-cards', id, JSON.stringify(card)); card.y = y
} redisClient.hset(`${REDIS_PREFIX}-room:${room}-cards`, id, JSON.stringify(card))
}); }
}, })
},
cardSetXY: function(room, id, x, y) { deleteCard(room, id) {
redisClient.hget(REDIS_PREFIX + '-room:' + room + '-cards', id, function(err, res) { redisClient.hdel(
var card = JSON.parse(res); `${REDIS_PREFIX}-room:${room}-cards`,
if (card !== null) { id
card.x = x; )
card.y = y; },
redisClient.hset(REDIS_PREFIX + '-room:' + room + '-cards', id, JSON.stringify(card));
}
});
},
deleteCard: function(room, id) { addSticker(room, cardId, stickerId) {
redisClient.hdel( redisClient.hget(`${REDIS_PREFIX}-room:${room}-cards`, cardId, (err, res) => {
REDIS_PREFIX + '-room:' + room + '-cards', const card = JSON.parse(res)
id if (card !== null) {
); if (stickerId === 'nosticker') {
}, card.sticker = null
addSticker: function(room, cardId, stickerId) { redisClient.hset(`${REDIS_PREFIX}-room:${room}-cards`, cardId, JSON.stringify(card))
redisClient.hget(REDIS_PREFIX + '-room:' + room + '-cards', cardId, function(err, res) { } else {
var card = JSON.parse(res); if (card.sticker !== null) { stickerSet = new sets.Set(card.sticker) } else { stickerSet = new sets.Set() }
if (card !== null) {
if (stickerId === "nosticker")
{
card.sticker = null;
redisClient.hset(REDIS_PREFIX + '-room:' + room + '-cards', cardId, JSON.stringify(card)); stickerSet.add(stickerId)
}
else
{
if (card.sticker !== null)
stickerSet = new sets.Set( card.sticker );
else
stickerSet = new sets.Set();
stickerSet.add(stickerId); card.sticker = stickerSet.array()
card.sticker = stickerSet.array(); redisClient.hset(`${REDIS_PREFIX}-room:${room}-cards`, cardId, JSON.stringify(card))
}
}
})
},
redisClient.hset(REDIS_PREFIX + '-room:' + room + '-cards', cardId, JSON.stringify(card)); setBoardSize(room, size) {
} redisClient.set(`${REDIS_PREFIX}-room:${room}-size`, JSON.stringify(size))
},
} getBoardSize(room, callback) {
}); redisClient.get(`${REDIS_PREFIX}-room:${room}-size`, (err, res) => {
}, callback(JSON.parse(res))
})
}
setBoardSize: function(room, size) { }
redisClient.set(REDIS_PREFIX + '-room:' + room + '-size', JSON.stringify(size)); exports.db = db
},
getBoardSize: function(room, callback) {
redisClient.get(REDIS_PREFIX + '-room:' + room + '-size', function (err, res) {
callback(JSON.parse(res));
});
}
};
exports.db = db;

View file

@ -3,153 +3,137 @@
// PubSubCore: Simple pub/sub library for Node.js and Socket.IO // PubSubCore: Simple pub/sub library for Node.js and Socket.IO
var util = require('util'); const util = require('util')
var sets = require('simplesets'); const sets = require('simplesets')
var io = require('socket.io'); const io = require('socket.io')
var net = require('net'); const net = require('net')
////////////////////////////// /// ///////////////////////////
// Tracking who's in what room // Tracking who's in what room
////////////////////////////// /// ///////////////////////////
// Dict mapping room names with people to sets of client objects. // Dict mapping room names with people to sets of client objects.
var rooms = {}; const rooms = {}
// Dict mapping room names with people to sets of usernames. // Dict mapping room names with people to sets of usernames.
var room_users = {}; const room_users = {}
// Dict mapping sids to sets of rooms. // Dict mapping sids to sets of rooms.
var sid_rooms = {}; const sid_rooms = {}
// Add a client to a room and return the sid:client mapping. // Add a client to a room and return the sid:client mapping.
exports.add_to_room = function (client, room, callback) { exports.add_to_room = function(client, room, callback) {
//console.log('Client ' + client.username + ' (' + client.id + ') added to room ' + room); // console.log('Client ' + client.username + ' (' + client.id + ') added to room ' + room);
if (!(sid_rooms.hasOwnProperty(client.id))) sid_rooms[client.id] = new sets.Set(); if (!(sid_rooms.hasOwnProperty(client.id))) sid_rooms[client.id] = new sets.Set()
sid_rooms[client.id].add(room); sid_rooms[client.id].add(room)
if (!(rooms.hasOwnProperty(room))) rooms[room] = new sets.Set(); if (!(rooms.hasOwnProperty(room))) rooms[room] = new sets.Set()
rooms[room].add(client); rooms[room].add(client)
if (!(room_users.hasOwnProperty(room))) room_users[room] = new sets.Set(); if (!(room_users.hasOwnProperty(room))) room_users[room] = new sets.Set()
room_users[room].add(client.username); room_users[room].add(client.username)
callback(rooms[room].array()); callback(rooms[room].array())
}; }
// Remove a client from all rooms and return the username:client // Remove a client from all rooms and return the username:client
// mapping for everybody in those rooms. // mapping for everybody in those rooms.
exports.remove_from_all_rooms = function (client, callback) { exports.remove_from_all_rooms = function(client, callback) {
var affected_clients = new sets.Set(); const affected_clients = new sets.Set()
if (sid_rooms.hasOwnProperty(client.id)) { if (sid_rooms.hasOwnProperty(client.id)) {
var client_rooms = sid_rooms[client.id].array(); const client_rooms = sid_rooms[client.id].array()
for (var i = 0; i < client_rooms.length; i++) { for (let i = 0; i < client_rooms.length; i++) {
var room = client_rooms[i]; const room = client_rooms[i]
if (rooms.hasOwnProperty(room)) { if (rooms.hasOwnProperty(room)) {
rooms[room].remove(client); rooms[room].remove(client)
if (rooms[room].size() === 0) if (rooms[room].size() === 0) { delete rooms[room] }
delete rooms[room];
} }
if (room_users.hasOwnProperty(room)) { if (room_users.hasOwnProperty(room)) {
room_users[room].remove(client.username); room_users[room].remove(client.username)
if (room_users[room].size() === 0) if (room_users[room].size() === 0) { delete room_users[room] }
delete room_users[room];
} }
if (rooms.hasOwnProperty(room)) { if (rooms.hasOwnProperty(room)) {
var this_room = rooms[room].array(); const this_room = rooms[room].array()
for (var j = 0; j < this_room.length; j++) for (let j = 0; j < this_room.length; j++) { affected_clients.add(this_room[j]) }
affected_clients.add(this_room[j]);
} }
}
} }
//console.log('Client ' + client.username + ' (' + client.id + ') disconnected.'); }
delete sid_rooms[client.id]; // console.log('Client ' + client.username + ' (' + client.id + ') disconnected.');
callback(affected_clients.array()); delete sid_rooms[client.id]
}; callback(affected_clients.array())
}
// Remove a client from a room and return the username:client mapping // Remove a client from a room and return the username:client mapping
// for everybody in that room. Returns [] if the room does not exist, // for everybody in that room. Returns [] if the room does not exist,
// or if the client was not in the room to begin with. // or if the client was not in the room to begin with.
function remove_from_room(client, room, callback) { function remove_from_room(client, room, callback) {
if (!rooms.hasOwnProperty(room) || !rooms[room].has(client)) { if (!rooms.hasOwnProperty(room) || !rooms[room].has(client)) {
callback([]); callback([])
return; return
} }
// Delete from the room // Delete from the room
rooms[room].remove(client); rooms[room].remove(client)
if (rooms[room].size() === 0) if (rooms[room].size() === 0) { delete rooms[room] }
delete rooms[room]; if (room_users.hasOwnProperty(room)) {
if (room_users.hasOwnProperty(room)) { room_users[room].remove(client.username)
room_users[room].remove(client.username); if (room_users[room].size() === 0) { delete room_users[room] }
if (room_users[room].size() === 0) }
delete room_users[room];
}
callback(exports.room_clients(room)); callback(exports.room_clients(room))
} }
// Return list of clients in the given room. // Return list of clients in the given room.
exports.room_clients = function(room) { exports.room_clients = function(room) {
return rooms.hasOwnProperty(room) ? rooms[room].array() : []; return rooms.hasOwnProperty(room) ? rooms[room].array() : []
}; }
// Return true if room contains the given client, false otherwise. // Return true if room contains the given client, false otherwise.
exports.client_in_room = function(room, client) { exports.client_in_room = function(room, client) {
return rooms.hasOwnProperty(room) && rooms[room].has(client); return rooms.hasOwnProperty(room) && rooms[room].has(client)
}; }
// Return list of usernames in given room // Return list of usernames in given room
exports.users_in_room = function(room) { exports.users_in_room = function(room) {
return room_users.hasOwnProperty(room) ? room_users[room].array() : []; return room_users.hasOwnProperty(room) ? room_users[room].array() : []
}; }
// Return list of usernames in given room // Return list of usernames in given room
exports.room_clients_other_than_me = function(room, client) { exports.room_clients_other_than_me = function(room, client) {
if (rooms.hasOwnProperty(room)) if (rooms.hasOwnProperty(room)) {
{ const clients = rooms[room]
var clients = rooms[room]; // console.dir(clients.array());
//console.dir(clients.array());
clients.remove(client); clients.remove(client)
//console.dir(clients.array()); // console.dir(clients.array());
return clients.array(); return clients.array()
} }
else
{
return [];
}
};
//gets the current room of the client (assumes one room -- will select first one if in multiple) return []
exports.get_room = function (client) { }
var client_rooms = null;
if (sid_rooms.hasOwnProperty(client.id)) // gets the current room of the client (assumes one room -- will select first one if in multiple)
{ exports.get_room = function(client) {
client_rooms = sid_rooms[client.id].array(); let client_rooms = null
}
if ( client_rooms !== null ) if (sid_rooms.hasOwnProperty(client.id)) {
return client_rooms[0]; client_rooms = sid_rooms[client.id].array()
else }
return null;
};
if (client_rooms !== null) { return client_rooms[0] }
return null
}
// Generic server code // Generic server code
exports.add_to_room_and_announce = function (client, room, msg) { exports.add_to_room_and_announce = function(client, room, msg) {
// Add user info to the current dramatis personae
// Add user info to the current dramatis personae exports.add_to_room(client, room, (clients) => {
exports.add_to_room(client, room, function(clients) {
// Broadcast new-user notification // Broadcast new-user notification
for (var i = 0; i < clients.length; i++) for (let i = 0; i < clients.length; i++) {
{ if (clients[i].id != client.id) { clients[i].json.send(msg) }
if (clients[i].id != client.id) }
clients[i].json.send(msg); })
} }
});
};
/* /*
exports.on_leave_room = function (client, room) { exports.on_leave_room = function (client, room) {
@ -165,67 +149,58 @@ exports.on_leave_room = function (client, room) {
}); });
}); });
}*/ } */
//remember that this announces to all rooms that this client was a member of // remember that this announces to all rooms that this client was a member of
exports.remove_from_all_rooms_and_announce = function (client, msg) { exports.remove_from_all_rooms_and_announce = function(client, msg) {
exports.remove_from_all_rooms(client, function(clients) { exports.remove_from_all_rooms(client, (clients) => {
for (var i = 0; i < clients.length; i++) for (let i = 0; i < clients.length; i++) {
{ if (clients[i].id != client.id) { clients[i].json.send(msg) }
if (clients[i].id != client.id) }
clients[i].json.send(msg); })
} }
});
};
////////////////////////////// /// ///////////////////////////
// Broadcasting functions // Broadcasting functions
////////////////////////////// /// ///////////////////////////
// Broadcast message to all clients // Broadcast message to all clients
exports.broadcast = function(msg) { exports.broadcast = function(msg) {
if (socket) socket.broadcast(msg); if (socket) socket.broadcast(msg)
net_server_streams.each(function(stream) { net_server_streams.each((stream) => {
stream.write(JSON.stringify(msg)+'\r\n'); stream.write(`${JSON.stringify(msg)}\r\n`)
}); })
}; }
// Broadcast message to all clients in a given room. // Broadcast message to all clients in a given room.
exports.broadcast_room = function(room, msg) { exports.broadcast_room = function(room, msg) {
var clients = exports.room_clients(room); const clients = exports.room_clients(room)
for (var i = 0; i < clients.length; i++) for (let i = 0; i < clients.length; i++) { clients[i].json.send(msg) }
clients[i].json.send(msg); }
};
// Broadcast message to all the other clients that are in rooms with this client // Broadcast message to all the other clients that are in rooms with this client
exports.broadcast_to_roommates = function (client, msg) { exports.broadcast_to_roommates = function(client, msg) {
var roommates = new sets.Set(); let roommates = new sets.Set()
if (sid_rooms.hasOwnProperty(client.id)) if (sid_rooms.hasOwnProperty(client.id)) {
{ const client_rooms = sid_rooms[client.id].array()
var client_rooms = sid_rooms[client.id].array(); for (let i = 0; i < client_rooms.length; i++) {
for (var i = 0; i < client_rooms.length; i++) const room = client_rooms[i]
{ if (rooms.hasOwnProperty(room)) {
var room = client_rooms[i]; const this_room = rooms[room].array()
if (rooms.hasOwnProperty(room)) for (let j = 0; j < this_room.length; j++) { roommates.add(this_room[j]) }
{
var this_room = rooms[room].array();
for (var j = 0; j < this_room.length; j++)
roommates.add(this_room[j]);
} }
} }
} }
//remove self from the set // remove self from the set
roommates.remove(client); roommates.remove(client)
roommates = roommates.array(); roommates = roommates.array()
//console.log('client: ' + client.id + " is broadcasting to: "); // console.log('client: ' + client.id + " is broadcasting to: ");
for (let k = 0; k < roommates.length; k++) {
for (var k = 0; k < roommates.length; k++) // console.log(' - ' + roommates[i].id);
{ roommates[k].json.send(msg)
//console.log(' - ' + roommates[i].id); }
roommates[k].json.send(msg); }
}
};

View file

@ -8,6 +8,7 @@
}, },
"author": "Florian Schmitt", "author": "Florian Schmitt",
"scripts": { "scripts": {
"lint-js": "eslint --fix --ext .js,.ts .",
"start": "nodemon server.js -e js,css,jade,json" "start": "nodemon server.js -e js,css,jade,json"
}, },
"nodemonConfig": { "nodemonConfig": {
@ -34,6 +35,13 @@
"yargs": "~2.3.0" "yargs": "~2.3.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3.3.0",
"@eslint/js": "^9.22.0",
"eslint": "^9.22.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.31",
"globals": "^16.0.0",
"prettier": "^3.5",
"forever": "^0.15.3", "forever": "^0.15.3",
"nodemon": "^2.0.16" "nodemon": "^2.0.16"
} }

1140
server.js

File diff suppressed because it is too large Load diff