Add chat

This commit is contained in:
brunosimon
2017-07-30 22:49:08 +02:00
parent f8246fd60f
commit 910a63234d
5 changed files with 927 additions and 2 deletions
+152
View File
@@ -0,0 +1,152 @@
'use strict'
const ids = require('./ids.js')
const robotNames = require('./robot-names.json')
class Chat
{
constructor(_config, _options)
{
this.config = _config
this.slug = _options.slug
this.users = {}
this.messages = []
this.availableRobotNames = this.shuffle(robotNames.slice())
this.setSocket()
}
setSocket()
{
// Create a channel for this specific chjat
this.chatSocket = this.config.socket.of('/project/' + this.slug + '/chat')
// Connection event
this.chatSocket.on('connection', (socket) =>
{
// Create user
const user = this.createUser()
// Debug
if(this.config.debug >= 1)
{
console.log('chat > socket'.green.bold + ' - ' + 'connection'.cyan + ' - ' + socket.id.cyan)
console.log('chat > user'.green.bold + ' - ' + 'create'.cyan + ' - ' + user.name.cyan)
}
// Send infos
const broadcastUser = {}
broadcastUser.name = user.name
broadcastUser.color = user.color
socket.emit('infos', broadcastUser)
// On message
socket.on('message', (data) =>
{
// Add ID and save
data.id = ids.getId()
data.time = new Date()
this.messages.push(data)
// Create a broadcast message, add complementary data and send
const broadcastMessage = {}
broadcastMessage.id = data.id
broadcastMessage.time = data.time
broadcastMessage.text = data.text
broadcastMessage.file = data.file
broadcastMessage.line = data.line
broadcastMessage.user = user
this.chatSocket.emit('message', broadcastMessage)
// Debug
if(this.config.debug >= 1)
{
console.log('chat > socket'.green.bold + ' - ' + 'message'.cyan + ' - ' + user.name.cyan + ' - ' + data.text.cyan)
}
})
// On update infos
socket.on('update_infos', (data) =>
{
const newName = data.name.trim()
const oldName = user.name
// Securities
if(newName.length <= 0 || newName.length > 22 || newName === oldName)
{
return
}
// Update name
user.name = data.name
// Debug
if(this.config.debug >= 1)
{
console.log('chat > socket'.green.bold + ' - ' + 'update_infos'.cyan + ' - ' + (oldName + ' > ' + user.name).cyan)
}
})
// On disconnect
socket.on('disconnect', () =>
{
console.log('chat > socket'.green.bold + ' - ' + 'disconnect'.cyan + ' - ' + user.name.cyan)
})
})
}
createUser()
{
const user = {}
user.name = this.getRandomName()
user.color = this.getRandomColor()
user.id = ids.getId()
this.users[user.id] = user
return user
}
shuffle(a)
{
let j = null
let x = null
let i = null
for(i = a.length; i; i--)
{
j = Math.floor(Math.random() * i)
x = a[i - 1]
a[i - 1] = a[j]
a[j] = x
}
return a
}
getRandomColor()
{
const r = (Math.round(Math.random() * 127) + 127).toString(16)
const g = (Math.round(Math.random() * 127) + 127).toString(16)
const b = (Math.round(Math.random() * 127) + 127).toString(16)
const color = '#' + r + g + b
return color
}
getRandomName()
{
// Refill robot names if no more name available
if(this.availableRobotNames.length === 0)
{
this.availableRobotNames = this.shuffle(robotNames.slice())
}
const robotName = this.availableRobotNames.pop()
return robotName
}
}
module.exports = Chat
+3 -1
View File
@@ -3,6 +3,7 @@
// Dependencies
const slug = require('slug')
const Files = require('./files.js')
const Chat = require('./chat.js')
const AdmZip = require('adm-zip')
const glob = require('glob')
const fs = require('fs')
@@ -21,6 +22,7 @@ class Project
this.excludeRegex = new RegExp(_options.excludeRegex)
this.zipNeedsUpdate = true
this.files = new Files(this.config, { projectSocket: this.projectSocket })
this.chat = new Chat(this.config, { slug: this.slug })
this.date = new Date()
// Add test contents
@@ -38,7 +40,7 @@ class Project
setSocket()
{
// Save original socket and create a channel for this specific project
// Create a channel for this specific project
this.projectSocket = this.config.socket.of('/project/' + this.slug)
// Connection event
+686
View File
@@ -0,0 +1,686 @@
[
"1A",
"7-Zark-7",
"790",
"ABC Warrior",
"AIDA",
"AMEE",
"ASTAR",
"Adam Link",
"Aigis",
"Alfie",
"Alicia",
"Alisa",
"Allen",
"Alpha",
"Alpha 5",
"Alpha 6",
"Alpha 7",
"Alpha Hatsuseno",
"Alpha-Red",
"Alsatia Zevo",
"Amazo",
"Andrew",
"Andrew Martin",
"Android Andy",
"Andromeda",
"Andromon",
"Andy",
"Aniel",
"Anne Droid",
"Annihilant",
"Ant Drone",
"April",
"Aradia-bot",
"Arale Norimaki",
"Arbeitsmaschine",
"Argus",
"Ariana",
"Arthur",
"Ash",
"Ashlotte",
"Assisdroid",
"Astor",
"Astro Boy",
"Atlas",
"Atom",
"Autobot",
"Ava",
"Azaka",
"B-1",
"B-4",
"B166ER",
"BB",
"BB-8",
"BMO",
"BT-7274",
"Back-Pack",
"Banpei",
"BarBot",
"Bastion",
"Bathyscaphe",
"Battle Borg",
"Battle Droid",
"Baymax",
"Beba-2",
"Beetle Bot",
"BellBot",
"Bender",
"Berserker",
"Beta",
"Biotron",
"Bishop",
"Black Lion",
"Blinky",
"Blip",
"Blitz",
"Blitz Botz",
"Blue Lion",
"Blue Senturion",
"Bobert",
"Boilerplate",
"Bolt",
"Bopper",
"Bors",
"Bossbot",
"Bouncer",
"Box",
"Brackenridge",
"Brainbot",
"Brainiac 5",
"Braman",
"Brassneck",
"Brazen head",
"Brian the Brain",
"Browny",
"Brunonator",
"Bubo",
"Buffybot",
"Burn Bot",
"Bus Conductor",
"Buster",
"Buzzcam",
"C-3PO",
"C-Gram",
"CAST",
"CD-288",
"CHAPPiE",
"CHEFBOT-9000",
"CL4P-TP",
"CPDoom",
"Cait Sith",
"Caliban",
"Call",
"Cameron",
"Candy Droober",
"Captain Whisker",
"Carl Swangee",
"Cash Cube",
"Chani",
"Cherry 2000",
"Chi",
"Chibi-Robo",
"Chihiro",
"Chii",
"Chip",
"Chip Carson",
"Chitti",
"Chomelbot",
"Clank",
"Clanker",
"Clanks",
"Clevetron",
"Clicker",
"Coheed",
"Colossus",
"Computo",
"Conal Cochran",
"Conky 2000",
"Conroy",
"Copyroid",
"Cortana",
"Cosbytron 5000",
"Cubot",
"Curie",
"Cyanure",
"Cyber Shredder",
"Cyber Sub-Zero",
"Cyberdisc",
"Cybernaut",
"Cyborg Garth A7",
"Cyborg Noodle",
"Cybot",
"Cylon Centurion",
"Cyrax",
"Cyrus",
"Daggermouth",
"Daigunder",
"Dallas 13",
"Death Probe",
"Decimator",
"Destructo-Bot",
"Diamond Dog",
"Diana",
"Diver",
"DoorBot",
"Dor-15",
"Doraemon",
"Dorfl",
"Dorian",
"Doris",
"Dot Matrix",
"Draco",
"Drathro",
"Dreadnought",
"Drone",
"Dropkick",
"Dudy",
"ED-209",
"EDI",
"EggRobo",
"Elektrobot",
"Elettrodomestico",
"Elio",
"Elle",
"Emeralda",
"Emerl",
"Emma-2",
"Emotibot",
"Enforcer",
"Ershin",
"Evangelion",
"Eve",
"Evolver",
"Exocomp",
"Ez-27",
"Ezekiel",
"Fallbot",
"Fetcher",
"Fi",
"Fillibot",
"Fister Roboto",
"Flamingo of Doom",
"Flanders",
"Floyd",
"Flying Robot",
"Footbot",
"Frank Saunders",
"Franklin Droober",
"Franz Nukid",
"Frax",
"Freda",
"Freddy Fazbear",
"Freya",
"Frobot",
"Frost",
"Fugitoid",
"Fulker",
"Funnybot",
"Futura",
"Future Frond",
"G2",
"GERTY 3000",
"GIR",
"Gadget",
"Galaxina",
"Galen Tyrol",
"Gallegher",
"Geary",
"General Crunch",
"Ghost",
"Giant Robo",
"Giant Robot",
"Giddy",
"Gideon",
"Gnut",
"Go-bot",
"Goddard",
"Goemon Impact",
"Golem",
"Gort",
"Grag",
"Granatoid",
"Green Lion",
"Gregory",
"Guardbot",
"Gunslinger",
"Gurren Lagann",
"Gwent",
"H8",
"HCR-328",
"HK-47",
"HMX-12",
"HMX-17a",
"Hadaly",
"Harkness",
"Haro",
"Hector",
"Helen O'Loy",
"Hengar",
"Hermes",
"Huey",
"Humanoid",
"Hurt Bot",
"Hymie the Robot",
"IDAK",
"IDBot",
"IMC",
"IQ-9",
"Ice Soldier",
"Ida",
"Ilia probe",
"Interrobot",
"Interrodroid",
"Irmabot",
"Iron Avenger",
"Iron Giant",
"Iron Man",
"Irona",
"Isaacs",
"Isla",
"J-LB8",
"J5",
"Jack Hammer",
"Jade-bot",
"Jailbot",
"Jalea Bates",
"Jana",
"Jay Score",
"Jay-Dub",
"Jenkins",
"Jet Jaguar",
"Jimmy the Robot",
"Jinmay",
"Jinx",
"Johnny 5",
"Johnny Cab",
"Josef",
"Judy",
"K-2SO",
"K-Pop",
"K1 Robot",
"K9",
"K9 MkII",
"K9 MkIII",
"KARR",
"KITT",
"Kamelion",
"Karaibot",
"Karfelan",
"Kay-Em 14",
"Ken",
"Kevin",
"Kiibo",
"Kikaider",
"King Joe",
"King Nasod",
"Kitty Ko",
"Kleptobot",
"Kollege Blech",
"Krackenstein",
"Kraken",
"Krieger Bot",
"Kronos",
"Krybot",
"Kryten",
"Kudobot",
"Kurt Zisa",
"Kurumi",
"L-76",
"L-Ron",
"LUX TIZER",
"Lady Ada",
"Lance",
"LapTrap",
"Laserbot",
"Lawrence 3000",
"Leaderbot",
"Lenny",
"LiftBot",
"Linguo",
"Link",
"Living Brain",
"Loganator",
"Lomax",
"Lucas",
"Lucy",
"Lyle",
"MARK13",
"MM7",
"MO",
"Machina",
"Machine Man",
"Mahoro",
"Manders",
"Mandroid",
"Manhunter",
"Manmachine",
"Marauder Bot",
"Marcus Davenport",
"Maria",
"Marilyn",
"Mark 1",
"Mata Nui",
"Maureen Droober",
"Max",
"Max 404",
"Maxum Brain",
"MecWilly",
"Mech Eagle",
"Mecha Sonic",
"Mecha-King Ghidorah",
"Mecha-Streisand",
"Mechadrone",
"Mechagodzilla",
"Mechani-Kong",
"Mechanical Hound",
"Mechanismo",
"Mechanoid",
"Mechonoid",
"Medabot",
"Medbot",
"Medivac",
"Mega",
"Megazord",
"Meka-Zorn",
"Melfina",
"Merlin Athrawes",
"Mermadon",
"Metal Mickey",
"Metal Sonic",
"Mettaton",
"Microtron",
"Mike",
"Mildred the Maid",
"Milton",
"Mimeozone",
"Mimi",
"Mindroid",
"Miyu Greer",
"Moguera",
"Molly X",
"Moloch",
"Moravec",
"Mouser",
"Muffit Two",
"Multi",
"NEPTR",
"Nano",
"Nanotron",
"Necron-99",
"Neptune Man",
"Newman",
"Nimue Alban",
"Nindroid",
"Ninja Warrior",
"No-No",
"Nod-Bot",
"Nomad",
"Noo-Noo",
"Norby",
"Norm",
"Octobot",
"Octocat",
"Octus",
"Officer Haven",
"Oliver",
"Olympia",
"Omega",
"Omnics",
"Omnidroid",
"Optimus Prime",
"Orbot",
"Oscar",
"Otis",
"Otomo",
"Otomox",
"Otto",
"Ottobot",
"P.I.X.A.L",
"P.O.P.S.",
"Pain Bot",
"Paperboy 2000",
"Paranoid Android",
"Party-bot",
"Peepo",
"Penny Polendina",
"Perrybot",
"Personoid",
"Ping",
"Pintsize",
"Plex",
"Polyphase Avatron",
"Pong",
"Principal Howard",
"Project 2501",
"Proteus IV",
"Psycho Ranger",
"Psycho-Bot",
"Questor",
"Quote",
"R-110",
"R4-P17",
"REM",
"RFS-81",
"ROB 64",
"Rachael",
"Radbot",
"Raddion",
"RanXerox",
"Rapbot",
"Raston Warrior Robot",
"Rayna Kapec",
"Red Lion",
"Red Tornado",
"Redbot",
"Regene Regetta",
"Replicator",
"Reploid",
"Rhoda Miller",
"Ribbons Almark",
"Richard",
"Rico",
"Ridepod",
"Rin Asakura",
"Ringer",
"Ro-Man",
"Rob-Monkey",
"Roba",
"Robbi",
"Robbie",
"Robby",
"Robeast",
"Robert",
"Roberta",
"Robin",
"Robo",
"Robo Knight",
"Robo Machine",
"Robo-Kys",
"Robo-Lawyer",
"Robo-Penguin",
"Robo-Raptor",
"Robo-Shark",
"Robo-Spinosaurus",
"Robo-cop",
"RoboDoc",
"RoboGadget",
"Robocalypse",
"Robocrook",
"Roboduck",
"Robot #11",
"Robot 67",
"Robot Archie",
"Robot B-9",
"Robot John",
"Robot Jones",
"Robot Overlord",
"Robot Simon",
"Robotboy",
"Robotman",
"Roboto",
"Robotoid",
"Roboz",
"Rocket",
"Roderick",
"Rotox",
"Rotox DX",
"Rover",
"Roy Batty",
"Rubert",
"Rusty",
"Ruukoto",
"Rya Botkins",
"S1M0NE",
"SARA SARA",
"SHROUD",
"SID 6.7",
"SIMON",
"Sackbot",
"Sadie",
"Sailor Saturn",
"Sasha",
"Sasquatch",
"Sasuke",
"Saul Tigh",
"Scaramouche",
"Schniz",
"Scrapmaster",
"Scud",
"Sektor",
"Sentinel",
"Serling",
"Servbot",
"Servo Robot",
"Setaur",
"Sgt. Eve Edison",
"Shamus",
"Ship",
"Sico",
"Sillycone",
"Silver Sonic",
"Simbot",
"Simon",
"Skell",
"Slim John",
"Slix Vigma",
"Slo-Mo",
"Smiley the Robot",
"Snatcher",
"Solo",
"Sonny",
"Sparks",
"Specter",
"Spider-Slayer",
"Spongetron",
"Spot",
"Stan",
"Steed",
"Stella 4D",
"Stellar Warrior",
"Stockbot",
"Stufferbot",
"Supervoc",
"Synthoid",
"T-1",
"T-800",
"T-Bob",
"TAALR",
"THELMA",
"THX-1138",
"Tachikoma",
"Talos",
"Talus",
"Tama",
"Taran Android",
"Ted Buchanon",
"Ted-A",
"Ted-R",
"Telos",
"Terror Drone",
"Tet",
"The Machine",
"Thundercleese",
"Thursday",
"Tidy",
"Tieria Erde",
"Tigrr Jaxxon",
"Tik-Tok",
"Tilk",
"Tilly",
"Tima",
"Tin Man",
"Tina",
"Tobor",
"Tom Servo",
"Tonto",
"Tony",
"Torg",
"Tornado",
"Tory Foster",
"Totbot 3000",
"Transformer",
"Trent",
"Trex",
"Troy West",
"Trurl",
"Turtlebot",
"Twiki",
"US 47",
"Ultron",
"Ulysses",
"VIVIT",
"VR Troopertron",
"VX3 Warbot",
"Vacunator",
"Val",
"Valerie 23",
"Validate",
"Vanessa",
"Venusian robot",
"Verda",
"Victor Mancha",
"Visor Robot",
"Voltes V",
"Voltron",
"W1k1",
"WALL-E",
"Wadebot",
"Wafflebot",
"Walter the Wobot",
"War Machine",
"Warrenbot",
"Water Rotox",
"Weatherhead",
"Weebo",
"Wheatley",
"White Bomber",
"Windam",
"Woodbot",
"X-5",
"XBorg",
"XJ-9 Wakeman",
"XR",
"Xenian Android",
"Yellow Lion",
"Yeti",
"Yo-Yo",
"Yod",
"Yomguithereal",
"Young Vision",
"Yui",
"Yumemi Hoshino",
"Z-1",
"Z-2",
"Z-3",
"Zane",
"Zane Gort",
"Zarl",
"Zat",
"Zed",
"Zelda",
"Zeo Zagart",
"Zero",
"Zero one",
"Zeta"
]
+85
View File
@@ -109,6 +109,91 @@ class Site
response.send(`
<a href="/${_project.slug}/download" download>download project</a>
<a href="/${_project.slug}/files/empty.txt" download>download file</a>
<form action="#" class="infos-form">
<input type="text" class="name" value="" /> Name
<input type="submit" value="send" />
</form>
<form action="#" class="message-form">
<input type="text" class="text" value="Lorem ipsum" /> Text
<input type="number" class="file" value="1" /> File
<input type="line" class="line" value="2" /> Line
<input type="submit" value="send" />
</form>
<div class="messages"></div>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io('${this.config.domain}/project/${_project.slug}/chat')
socket.on('connect', () =>
{
console.log('connected')
})
// Infos
const $infosForm = document.querySelector('.infos-form')
const $name = $infosForm.querySelector('.name')
$infosForm.addEventListener('submit', (event) =>
{
event.preventDefault()
const name = $name.value
socket.emit('update_infos', { name })
})
socket.on('infos', (data) =>
{
console.log('infos')
console.log(data)
$name.value = data.name
})
// Messages
const $messages = document.querySelector('.messages')
const $messageForm = document.querySelector('.message-form')
const $text = $messageForm.querySelector('.text')
const $file = $messageForm.querySelector('.file')
const $line = $messageForm.querySelector('.line')
$messageForm.addEventListener('submit', (event) =>
{
event.preventDefault()
const text = $text.value
const file = $file.value
const line = $line.value
socket.emit('message', { text, file, line })
})
socket.on('message', (data) =>
{
console.log('message')
console.log(data)
$message = document.createElement('div')
const $author = document.createElement('div')
$author.style.color = data.user.color
$author.innerText = data.user.name
$message.appendChild($author)
const $info = document.createElement('div')
$info.innerText = data.file + ':' + data.line
$message.appendChild($info)
const $text = document.createElement('div')
$text.innerText = data.text
$message.appendChild($text)
$messages.appendChild($message)
})
</script>
`)
})