Consistency / some clean-up

This commit is contained in:
Evert Prants 2020-02-05 23:04:19 +02:00
parent 6c6aa85bf4
commit 43a136d293
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
8 changed files with 192 additions and 241 deletions

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "teemantirc",
"version": "2.0.1",
"version": "2.0.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "teemantirc",
"version": "2.0.1",
"version": "2.0.2",
"description": "A Web-based IRC client",
"main": "index.js",
"scripts": {

View File

@ -4,17 +4,16 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>TeemantIRC</title>
<script src="//twemoji.maxcdn.com/2/twemoji.min.js?11.2"></script>
<script src="//twemoji.maxcdn.com/v/latest/twemoji.min.js" crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="style/layout.css">
<link rel="stylesheet" type="text/css" href="style/theme_default.css" id="theme_stylesheet">
</head>
<!-- Codepony Diamond -->
<body>
<section class="ircclient">
<div class="coverwindow" id="authdialog">
<div class="wrapper">
<h1 class="grade1">Teemant</h1>
<h1 class="grade1" title="Teemant"><img src="/image/diamond.svg" alt="Teemant"/></h1>
<i class="grade3" id="connmsg">Think of a nickname</i>
<form action="" id="IRCConnector">
<label for="nickname">Nickname</label>

View File

@ -1,4 +1,5 @@
/* global WebSocket */
/* eslint-disable no-control-regex */
import { EventEmitter } from 'events'
import parse from './parser'
import { format } from 'util'
@ -69,7 +70,7 @@ class FakeSocket {
}
}
async function _waitOpen (s) {
async function waitForSocketOpen (s) {
let o
let c
@ -92,7 +93,7 @@ async function _waitOpen (s) {
return true
}
async function _trySocket (address, port, ssl, useTranslator) {
async function createSocket (address, port, ssl, useTranslator) {
// Attempt a direct ws connection
let proto = 'ws'
if (ssl) proto = 'wss'
@ -104,10 +105,10 @@ async function _trySocket (address, port, ssl, useTranslator) {
}
let tSock = new WebSocket(proto + '://' + conn)
try {
await _waitOpen(tSock)
await waitForSocketOpen(tSock)
} catch (e) {
console.error(e)
return _trySocket(address, port, ssl, true)
return createSocket(address, port, ssl, true)
}
tSock.open = true
@ -123,7 +124,7 @@ async function _trySocket (address, port, ssl, useTranslator) {
translatorSocket = new WebSocket(`ws${window.location.protocol === 'https:' ? 's' : ''}://${window.location.host}`)
console.log('Opening translator socket')
await _waitOpen(translatorSocket)
await waitForSocketOpen(translatorSocket)
return new FakeSocket(address, translatorSocket)
}
@ -152,11 +153,11 @@ class IRCConnectionHandler {
break
case 'quit':
this.conn.write('%s :%s', data.command.toUpperCase(), (data.message === ''
? this.conn.globalConfig.default_quit_msg : data.message))
? this.conn.defaultParams.default_quit_msg : data.message))
break
case 'privmsg':
this.conn.write('PRIVMSG %s :%s', data.arguments[0], data.message)
this.conn.emit('pass_to_client', {
this.conn.emit('fromServer', {
type: 'message',
messageType: 'privmsg',
to: data.arguments[0],
@ -169,7 +170,7 @@ class IRCConnectionHandler {
break
case 'notice':
this.conn.write('NOTICE %s :%s', data.arguments[0], data.message)
this.conn.emit('pass_to_client', {
this.conn.emit('fromServer', {
type: 'message',
messageType: 'notice',
to: data.arguments[0],
@ -193,9 +194,9 @@ class IRCConnectionHandler {
}
this.conn.write('PRIVMSG %s :\x01%s\x01', data.arguments[0], ctcpmsg)
this.conn.emit('pass_to_client', {
this.conn.emit('fromServer', {
type: 'message',
messageType: 'ctcp_request',
messageType: 'ctcpRequest',
to: this.conn.config.nickname,
user: {
nickname: data.arguments[0]
@ -209,7 +210,7 @@ class IRCConnectionHandler {
}
if (data.targetType === 'channel' || data.targetType === 'message') {
this.conn.write('PRIVMSG %s :%s', data.target, data.message)
this.conn.emit('pass_to_client', {
this.conn.emit('fromServer', {
type: 'message',
messageType: 'privmsg',
to: data.target,
@ -283,7 +284,12 @@ class IRCConnectionHandler {
let list = null
switch (line.command) {
case 'error':
this.conn.emit('connerror', { type: 'irc_error', raw: line.raw })
this.conn.emit('connectionError', new Error('IRCError' + line.raw))
break
case 'PONG':
this.conn.ping = Date.now() - this.conn.pingSent
this.conn.pingSent = 0
this.conn.emit('ping', this.conn.ping)
break
case '001':
this.conn.data.actualServer = line.user.hostname
@ -321,16 +327,16 @@ class IRCConnectionHandler {
break
case 'JOIN':
if (line.trailing) {
this.conn.emit('pass_to_client', {
type: 'event_join_channel',
this.conn.emit('fromServer', {
type: 'joinChannel',
user: line.user,
channel: line.trailing,
server: serverName
})
} else {
for (let i in line.arguments) {
this.conn.emit('pass_to_client', {
type: 'event_join_channel',
this.conn.emit('fromServer', {
type: 'joinChannel',
user: line.user,
channel: line.arguments[i],
server: serverName
@ -339,8 +345,8 @@ class IRCConnectionHandler {
}
break
case 'PART':
this.conn.emit('pass_to_client', {
type: 'event_part_channel',
this.conn.emit('fromServer', {
type: 'partChannel',
user: line.user,
channel: line.arguments[0],
reason: line.trailing,
@ -348,8 +354,8 @@ class IRCConnectionHandler {
})
break
case 'QUIT':
this.conn.emit('pass_to_client', {
type: 'event_quit',
this.conn.emit('fromServer', {
type: 'quit',
user: line.user,
reason: line.trailing,
server: serverName
@ -375,8 +381,8 @@ class IRCConnectionHandler {
case '366':
if (!this.conn.queue['names']) break
if (this.conn.queue['names'][line.arguments[1]]) {
this.conn.emit('pass_to_client', {
type: 'channel_nicks',
this.conn.emit('fromServer', {
type: 'nicks',
channel: line.arguments[1],
nicks: this.conn.queue['names'][line.arguments[1]],
server: serverName
@ -395,7 +401,7 @@ class IRCConnectionHandler {
}
if (line.user.nickname !== '') {
this.conn.emit('pass_to_client', {
this.conn.emit('fromServer', {
type: 'message',
messageType: 'privmsg',
to: line.arguments[0],
@ -404,8 +410,8 @@ class IRCConnectionHandler {
server: serverName
})
} else {
this.conn.emit('pass_to_client', {
type: 'server_message',
this.conn.emit('fromServer', {
type: 'serverMessage',
messageType: 'privmsg',
message: line.trailing,
server: serverName,
@ -423,9 +429,9 @@ class IRCConnectionHandler {
message = Math.floor(Date.now() / 1000) - composethis[1] + 's'
}
this.conn.emit('pass_to_client', {
this.conn.emit('fromServer', {
type: 'message',
messageType: 'ctcp_response',
messageType: 'ctcpResponse',
to: line.arguments[0],
user: line.user,
message: message,
@ -435,7 +441,7 @@ class IRCConnectionHandler {
}
if (line.user.nickname !== '') {
this.conn.emit('pass_to_client', {
this.conn.emit('fromServer', {
type: 'message',
messageType: 'notice',
to: line.arguments[0],
@ -444,8 +450,8 @@ class IRCConnectionHandler {
server: serverName
})
} else {
this.conn.emit('pass_to_client', {
type: 'server_message',
this.conn.emit('fromServer', {
type: 'serverMessage',
messageType: 'notice',
message: line.trailing,
server: serverName,
@ -458,35 +464,35 @@ class IRCConnectionHandler {
this.conn.config.nickname = line.arguments[0]
}
this.conn.emit('pass_to_client', {
type: 'nick_change', nick: line.user.nickname, newNick: line.arguments[0], server: serverName
this.conn.emit('fromServer', {
type: 'nick', nick: line.user.nickname, newNick: line.arguments[0], server: serverName
})
break
case 'KICK':
this.conn.emit('pass_to_client', {
type: 'event_kick_channel', user: line.user, channel: line.arguments[0], reason: line.trailing, kickee: line.arguments[1], server: serverName
this.conn.emit('fromServer', {
type: 'kickedFromChannel', user: line.user, channel: line.arguments[0], reason: line.trailing, kickee: line.arguments[1], server: serverName
})
break
case 'TOPIC':
this.conn.emit('pass_to_client', {
type: 'channel_topic', channel: line.arguments[0], set_by: line.user.nickname, topic: line.trailing, server: serverName
this.conn.emit('fromServer', {
type: 'topic', channel: line.arguments[0], setBy: line.user.nickname, topic: line.trailing, server: serverName
})
break
case '332':
this.conn.emit('pass_to_client', {
type: 'channel_topic', channel: line.arguments[1], topic: line.trailing, server: serverName
this.conn.emit('fromServer', {
type: 'topic', channel: line.arguments[1], topic: line.trailing, server: serverName
})
break
case '333':
this.conn.emit('pass_to_client', {
type: 'channel_topic', channel: line.arguments[1], set_by: line.arguments[2], time: (line.arguments[3] || line.trailing), server: serverName
this.conn.emit('fromServer', {
type: 'topic', channel: line.arguments[1], setBy: line.arguments[2], time: (line.arguments[3] || line.trailing), server: serverName
})
break
case '375':
case '372':
case '376':
this.conn.emit('pass_to_client', {
type: 'server_message', messageType: 'motd', message: line.trailing, server: serverName, from: realServerName
this.conn.emit('fromServer', {
type: 'serverMessage', messageType: 'motd', message: line.trailing, server: serverName, from: realServerName
})
break
case '006':
@ -500,16 +506,16 @@ class IRCConnectionHandler {
case '351':
case '381':
case '489':
this.conn.emit('pass_to_client', {
type: 'server_message', messageType: 'regular', message: line.trailing, server: serverName, from: realServerName
this.conn.emit('fromServer', {
type: 'serverMessage', messageType: 'regular', message: line.trailing, server: serverName, from: realServerName
})
break
case '252':
case '254':
case '396':
case '042':
this.conn.emit('pass_to_client', {
type: 'server_message', messageType: 'regular', message: line.arguments[1] + ' ' + line.trailing, server: serverName, from: realServerName
this.conn.emit('fromServer', {
type: 'serverMessage', messageType: 'regular', message: line.arguments[1] + ' ' + line.trailing, server: serverName, from: realServerName
})
break
case '501':
@ -519,7 +525,7 @@ class IRCConnectionHandler {
case '482':
case '331':
case '432':
this.conn.emit('pass_to_client', {
this.conn.emit('fromServer', {
type: 'message',
to: null,
message: line.arguments[1] + ': ' + line.trailing,
@ -556,8 +562,8 @@ class IRCConnectionHandler {
for (let i in modes) {
let mode = modes[i]
if (this.conn.data.supportedModes[mode]) {
this.conn.emit('pass_to_client', {
type: 'mode_' + (method === '+' ? 'add' : 'del'),
this.conn.emit('fromServer', {
type: 'mode' + (method === '+' ? 'Add' : 'Del'),
target: line.arguments[0],
mode: mode,
modeTarget: line.arguments[2 + parseInt(i)],
@ -575,7 +581,7 @@ class IRCConnectionHandler {
}
if (pass.length > 0) {
this.conn.emit('pass_to_client', {
this.conn.emit('fromServer', {
type: 'mode',
target: line.arguments[0],
message: method + pass.join(''),
@ -622,7 +628,7 @@ class IRCConnectionHandler {
case '312':
list = {
server: line.arguments[2],
server_name: line.trailing || ''
serverName: line.trailing || ''
}
this.whoisManage(line.arguments[1], list)
break
@ -666,7 +672,7 @@ class IRCConnectionHandler {
case '318':
if (!this.conn.queue.whois || !this.conn.queue.whois[line.arguments[1]]) return
this.conn.emit('pass_to_client', {
this.conn.emit('fromServer', {
type: 'whoisResponse',
whois: this.conn.queue.whois[line.arguments[1]],
server: serverName,
@ -676,8 +682,8 @@ class IRCConnectionHandler {
delete this.conn.queue.whois[line.arguments[1]]
break
case '321':
this.conn.emit('pass_to_client', {
type: 'listedchan',
this.conn.emit('fromServer', {
type: 'listedChannel',
channel: 'Channel',
users: 'Users',
topic: 'Topic',
@ -686,8 +692,8 @@ class IRCConnectionHandler {
})
break
case '322':
this.conn.emit('pass_to_client', {
type: 'listedchan',
this.conn.emit('fromServer', {
type: 'listedChannel',
channel: line.arguments[1],
users: line.arguments[2],
topic: line.trailing,
@ -699,27 +705,37 @@ class IRCConnectionHandler {
// might come in the future, who knows
this.conn.write('CAP END')
break
default:
let argc = line.arguments
if (argc.indexOf(this.conn.config.nickname) === 0) argc = argc.slice(1)
this.conn.emit('fromServer', {
type: 'serverMessage',
messageType: 'unknown',
message: (argc.length ? argc.join(' ') + ' :' : '') + line.trailing,
server: serverName,
from: realServerName
})
}
}
}
class IRCConnection extends EventEmitter {
constructor (providedInfo, globalConfig, extras) {
constructor (providedInfo, defaultParams, extras) {
super()
this.globalConfig = globalConfig
this.defaultParams = defaultParams
this.extras = extras || { authenticationSteps: [], ctcps: {} }
this.config = {
nickname: 'teemant',
username: globalConfig.username,
realname: globalConfig.realname,
username: defaultParams.username,
realname: defaultParams.realname,
server: 'localhost',
port: 6667,
autojoin: [],
secure: globalConfig.secure_by_default,
secure: defaultParams.secure_by_default,
password: '',
address: providedInfo.server,
rejectUnauthorized: globalConfig.rejectUnauthorizedCertificates
rejectUnauthorized: defaultParams.rejectUnauthorizedCertificates
}
for (let a in providedInfo) {
@ -739,21 +755,19 @@ class IRCConnection extends EventEmitter {
maxChannelLength: 64,
supportedModes: {}
}
this.authorizationError = ''
this.queue = {}
this.pingSent = 0
this.ping = 0
}
connect () {
async function wrapped (argument) {
try {
this.socket = await _trySocket(this.config.server, this.config.port, this.config.secure)
} catch (e) {
this.emit('connerror', { type: 'sock_error', message: 'A socket error occured.' })
throw e
}
this.socket = await createSocket(this.config.server, this.config.port, this.config.secure)
this.socket.addEventListener('message', (e) => {
let line = e.data
// Handle from-server pings
if (line.indexOf('PING') === 0) {
this.write('PONG %s', line.substring(4))
return
@ -774,7 +788,7 @@ class IRCConnection extends EventEmitter {
this.socket.addEventListener('close', (data) => {
if (!this.queue['close']) {
this.emit('closed', { type: 'sock_closed', raw: data, message: 'Connection closed.' })
this.emit('connectionClosed', new Error('Socket has been closed.'))
}
this.connected = false
@ -804,35 +818,37 @@ class IRCConnection extends EventEmitter {
this.write('NICK %s', this.config.nickname)
this.bindFinal()
this.sendPing()
}
bindFinal () {
this.on('userinput', (data) => {
this.on('userInput', (data) => {
return this.handler.handleUserLine(data)
})
this.once('authenticated', () => this.sendPing())
}
sendPing () {
if (!this.connected) return
this.write('PING :' + this.data.actualServer)
this.pingSent = Date.now()
setTimeout(() => this.sendPing(), 5000)
}
disconnect (message) {
if (!this.connected) {
this.emit('connerror', { type: 'sock_closed', message: 'Connection already closed.' })
this.emit('connectionError', new Error('SocketError: Socket is already closed.'))
return
}
this.queue['close'] = true
this.write('QUIT :%s', (message != null ? message : this.globalConfig.default_quit_msg))
this.write('QUIT :%s', (message != null ? message : this.defaultParams.default_quit_msg))
}
write () {
let message = format.apply(null, arguments)
if (!this.connected) {
return this.emit('connerror', { type: 'sock_closed', message: 'Connection is closed.' })
return this.emit('connectionError', new Error('SocketError: Socket is closed.'))
}
this.socket.send(message + '\r\n')

View File

@ -38,13 +38,16 @@ const customCTCPs = {
},
SOURCE: function (data, connection) {
return 'https://gitlab.icynet.eu/IcyNetwork/teemant'
},
TIME: function (data, connection) {
return new Date()
}
}
const clientdom = { connector: {}, settings: {} }
const colorizer = {
get_random_color: function (nickname) {
getRandomColor: function (nickname) {
let themefunc = themes.available[irc.config.theme].nick_pallete
let randgen = seedrandom(nickname)
@ -61,9 +64,8 @@ const colorizer = {
// Utilities
const validators = {}
validators.iporhost = function (str) {
const validators = {
iporhost: function (str) {
let valid = false
if (str.match(/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/i)) {
@ -73,26 +75,22 @@ validators.iporhost = function (str) {
}
return valid
}
validators.nickname = function (str) {
},
nickname: function (str) {
if (str.match(/[a-z_\-\[\]\\^{}|`][a-z0-9_\-\[\]\\^{}|`]*/i)) {
return true
}
return false
}
validators.escapeHTML = function (str) {
},
escapeHTML: function (str) {
return str.replace(/</g, '&lt;').replace(/>/, '&gt;')
}
}
const processors = {
inline_color: function (text) {
// TODO: Figure out how to make hex colors behave
// const hexRegex = /(^|[^&])(\#[0-9a-f]{6};?)(?!\w)/gmi
inlineColor: function (text) {
const rgbRegex = /(.?)(rgba?\((?:\s*\d+\s*,){2}\s*\d+\s*(?:,\s*[\d.]+\s*)?\);?)/gmi
const substitute = '$1$2 <div class="color_sample" style="background-color:$2"></div>'
// text = text.replace(hexRegex, substitute)
text = text.replace(rgbRegex, substitute)
return text
},
@ -156,9 +154,9 @@ function whoisMessage (whoisData, buffer) {
break
case 'server':
let adfd = sf('is on %s', span(whoisData[key], ['server', 'nick']))
if (whoisData['server_name']) {
if (whoisData['serverName']) {
adfd += '&nbsp;'
adfd += span(validators.escapeHTML(whoisData['server_name']), ['hostmask'])
adfd += span(validators.escapeHTML(whoisData['serverName']), ['hostmask'])
}
messages.push(adfd)
break
@ -198,7 +196,7 @@ let composer = {
message = colorizer.strip(message)
}
message = processors.inline_color(message)
message = processors.inlineColor(message)
message = processors.channelify(message)
message = processors.linkify(message)
message = processors.emojify(message)
@ -220,11 +218,11 @@ let composer = {
case 'join':
element.innerHTML += arrowin + '&nbsp;' + span(span(sender, ['actionee', 'nick']) + '&nbsp;' + message, ['content'])
break
case 'ctcp_response':
case 'ctcpResponse':
element.innerHTML += asterisk + '&nbsp;CTCP response from ' + span(sender, ['actionee', 'nick']) + '&nbsp;'
element.innerHTML += span(message, ['content'])
break
case 'ctcp_request':
case 'ctcpRequest':
element.innerHTML += asterisk + '&nbsp;CTCP request to ' + span(sender, ['actionee', 'nick']) + '&nbsp;'
element.innerHTML += span(message, ['content'])
break
@ -241,7 +239,7 @@ let composer = {
if (sender) {
let sndr1 = element.querySelector('.sender')
if (sndr1) {
sndr1.style.color = colorizer.get_random_color(sndr1.innerHTML)
sndr1.style.color = colorizer.getRandomColor(sndr1.innerHTML)
}
}
@ -249,7 +247,7 @@ let composer = {
if (sndr2.length > 0) {
for (let a in sndr2) {
if (sndr2[a] && sndr2[a]['style']) {
sndr2[a].style.color = colorizer.get_random_color(sndr2[a].innerHTML)
sndr2[a].style.color = colorizer.getRandomColor(sndr2[a].innerHTML)
}
}
}
@ -286,7 +284,7 @@ let composer = {
if (defaultNick) params.nickname = defaultNick
if (port && port !== 6667) params.port = port
if (useSSL) params.secure = 1
if (hideServerData) params.server_data = 0
if (hideServerData) params.extras = 0
if (Object.keys(params).length > 0) builder += '?' + serialize(params)
if (channels) {
@ -318,7 +316,7 @@ let composer = {
function sendToServer (server, obj) {
let i = irc.handler.getClientByActualServer(server)
if (!i) throw new Error('Invalid connection ' + server)
i.emit('userinput', obj)
i.emit('userInput', obj)
}
// onclick food
@ -509,7 +507,7 @@ let commands = {
arguments: [buffer.name]
})
},
description: '<message> - act as yourself',
description: '<message> - Act as yourself. (CTCP ACTION)',
aliases: ['me']
},
@ -524,14 +522,14 @@ let commands = {
execute: function (buffer, handler, command, message, listargs) {
if (!listargs[1]) {
if (buffer.server !== '' && irc.serverData[buffer.server] != null) {
let mynick = irc.serverData[buffer.server].my_nick
let mynick = irc.serverData[buffer.server].userNick
buffer.addMessage('Your nickname is: <span class="nick">' + mynick + '</span>', null, 'help')
}
return
}
sendToServer(buffer.server, { command: 'nick', message: '', arguments: listargs.splice(1) })
},
description: '- List all channels on the current server.',
description: '[<nickname>] - Set/display your nickname.',
aliases: ['nickname']
},
@ -587,6 +585,14 @@ let commands = {
description: '- Create a new connection.'
},
ping: {
execute: function (buffer, handler, command, message, listargs) {
let server = irc.handler.getClientByActualServer(buffer.server)
buffer.addMessage('Connection latency: ' + server.ping + 'ms', null, 'help')
},
aliases: ['latency', 'lag']
},
help: {
execute: function (buffer, handler, command, message, listargs) {
if (!listargs[1]) {
@ -677,7 +683,7 @@ class Nicklist {
}
if (irc.config.colorNicklist) {
construct += '<span class="nickname" style="color: ' + colorizer.get_random_color(nick.nickname) + ';">' + nick.nickname + '</span>'
construct += '<span class="nickname" style="color: ' + colorizer.getRandomColor(nick.nickname) + ';">' + nick.nickname + '</span>'
} else {
construct += span(nick.nickname, ['nickname'])
}
@ -700,7 +706,7 @@ class Nicklist {
this.appendToList(nick)
}
irc.chat.input_handler.searchNicknames = this.simplifiedNicksList
irc.chat.inputHandler.searchNicknames = this.simplifiedNicksList
}
nickAdd (nickname) {
@ -965,7 +971,7 @@ class ChatBuffer {
clientdom.letterbox.scrollTop = this.lastscroll
}
clientdom.currentNickname.innerHTML = irc.serverData[this.server] ? irc.serverData[this.server].my_nick
clientdom.currentNickname.innerHTML = irc.serverData[this.server] ? irc.serverData[this.server].userNick
: el('i', 'Disconnected')
irc.chat.changeTitle('TeemantIRC - ' + this.title)
@ -1001,7 +1007,7 @@ class ChatBuffer {
let mesgConstr = composer.message[irc.chatType](meta.time, meta.sender, meta.message, meta.type, this.server)
if (irc.serverData[this.server]) {
let mynick = irc.serverData[this.server].my_nick
let mynick = irc.serverData[this.server].userNick
if ((meta.type === 'privmsg' || meta.type === 'notice' || meta.type === 'action') &&
meta.message.toLowerCase().indexOf(mynick.toLowerCase()) !== -1 && meta.sender !== mynick) {
addClass(mesgConstr, 'mentioned')
@ -1040,7 +1046,7 @@ class ChatBuffer {
} else {
this.unreadCount += 1
if (irc.serverData[this.server]) {
let mynick = irc.serverData[this.server].my_nick
let mynick = irc.serverData[this.server].userNick
if ((type === 'privmsg' || type === 'notice' || type === 'action') &&
message.toLowerCase().indexOf(mynick.toLowerCase()) !== -1 && sender !== mynick) {
// TODO: notify user of mentioned
@ -1056,7 +1062,7 @@ class ChatBuffer {
}
switchOff () {
irc.chat.input_handler.searchNicknames = []
irc.chat.inputHandler.searchNicknames = []
let lFactor = clientdom.letterbox.offsetHeight + clientdom.letterbox.scrollTop
if (lFactor > clientdom.letterbox.scrollHeight - 100) {
@ -1196,16 +1202,14 @@ class Settings extends AppletChatBuffer {
switchTheme () {
if (this.themeSelection !== '') {
themes.change_theme(this.themeSelection)
themes.changeTheme(this.themeSelection)
irc.config.theme = this.themeSelection
this.themeSelector.setActiveSelection(this.themeSelection)
}
}
saveSpecified () {
if (this.timeout) {
clearTimeout(this.timeout)
}
if (this.timeout) clearTimeout(this.timeout)
this.switchTheme()
@ -1317,29 +1321,26 @@ class ConnectionHandler {
bindAll (srv, client) {
let server = client.data.actualServer
client.on('closed', () => {
this.clients[srv] = null
})
client.on('pass_to_client', (data) => {
client.on('fromServer', (data) => {
switch (data.type) {
case 'event_join_channel':
if (data.user.nickname === irc.serverData[server].my_nick) {
case 'joinChannel':
if (data.user.nickname === irc.serverData[server].userNick) {
irc.chat.createChatBuffer(server, data.channel, 'channel', true)
}
irc.chat.handleJoin(server, data.user, data.channel)
break
case 'event_kick_channel':
case 'kickedFromChannel':
irc.chat.handleLeave(server, data.kickee, data.channel, data.reason, data.user)
break
case 'event_part_channel':
case 'partChannel':
irc.chat.handleLeave(server, data.user, data.channel, data.reason)
break
case 'event_quit':
case 'quit':
irc.chat.handleQuit(server, data.user, data.reason)
break
case 'message':
if (data.to === irc.serverData[server].my_nick) {
if (data.to === irc.serverData[server].userNick) {
irc.chat.messageChatBuffer(data.user.nickname, server, { message: data.message, type: data.messageType, from: data.user.nickname })
} else if (data.to == null) {
let atest = irc.chat.getActiveChatBuffer()
@ -1353,31 +1354,31 @@ class ConnectionHandler {
irc.chat.messageChatBuffer(data.to, server, { message: data.message, type: data.messageType, from: data.user.nickname })
}
break
case 'channel_nicks':
case 'nicks':
irc.chat.buildNicklist(data.channel, server, data.nicks)
break
case 'channel_topic':
if (data['topic'] && data['set_by']) {
irc.chat.topicChange(data.channel, server, data.topic, data['set_by'])
case 'topic':
if (data['topic'] && data['setBy']) {
irc.chat.topicChange(data.channel, server, data.topic, data['setBy'])
} else if (data['topic']) {
irc.chat.topicChange(data.channel, server, data.topic, null)
} else if (data['set_by']) {
} else if (data['setBy']) {
irc.chat.messageChatBuffer(data.channel, server, {
message: 'Topic set by ' + data.set_by + ' on ' + (new Date(data.time * 1000)),
message: 'Topic set by ' + data.setBy + ' on ' + (new Date(data.time * 1000)),
type: 'topic',
from: null
})
}
break
case 'nick_change':
case 'nick':
irc.chat.nickChange(server, data.nick, data.newNick)
break
case 'mode_add':
case 'mode_del':
case 'modeAdd':
case 'modeDel':
case 'mode':
irc.chat.handleMode(server, data)
break
case 'server_message':
case 'serverMessage':
if (data['error']) data.messageType = 'error'
if (irc.chat.getServerChatBuffer(server) == null) {
if (!irc.serverChatQueue[server]) {
@ -1389,13 +1390,13 @@ class ConnectionHandler {
irc.chat.messageChatBuffer(server, server, { message: data.message, type: data.messageType, from: data.from || null })
}
break
case 'connect_message':
case 'connectMessage':
irc.auther.authMessage(data.message, data.error)
break
case 'whoisResponse':
whoisMessage(data.whois, irc.chat.getActiveChatBuffer())
break
case 'listedchan':
case 'listedChannel':
irc.chat.messageChatBuffer(server, server,
{
message: span(data.channel, ['channel']) + '&nbsp;' +
@ -1408,7 +1409,7 @@ class ConnectionHandler {
}
})
client.on('closed', () => {
client.on('connectionClosed', () => {
let serverz = irc.chat.getChatBuffersByServer(server)
for (let a in serverz) {
let serv = serverz[a]
@ -1421,6 +1422,7 @@ class ConnectionHandler {
}
stopWarnings()
this.clients[srv] = null
})
}
}
@ -1495,7 +1497,7 @@ class IRCConnector {
clientdom.connector.server.value = value
}
break
case 'server_data':
case 'serverinfo':
case 'extra':
case 'extras':
case 'connection':
@ -1809,7 +1811,7 @@ class IRCChatWindow {
this.buffers = []
this.firstServer = true
this.currentChatBuffer = null
this.input_handler = new InputHandler()
this.inputHandler = new InputHandler()
clientdom.frame.style.display = 'none'
@ -1908,7 +1910,7 @@ class IRCChatWindow {
if (this.firstServer) {
clientdom.frame.style.display = 'block'
window.onbeforeunload = function (e) {
return 'IRC will disconnect.'
return 'You will be disconnected from all the channels you\'re currently in.'
}
}
@ -1922,8 +1924,8 @@ class IRCChatWindow {
modeTranslation: serverinfo.data.supportedModes,
supportedPrefixes: prefixes,
network: serverinfo.data.network,
my_nick: serverinfo.config.nickname,
max_channel_length: serverinfo.data.max_channel_length
userNick: serverinfo.config.nickname,
maxChannelLength: serverinfo.data.maxChannelLength
}
let newServer = new ChatBuffer(serverinfo.data.actualServer, serverinfo.data.actualServer, serverinfo.data.network, 'server')
@ -2038,8 +2040,8 @@ class IRCChatWindow {
nickChange (server, oldNick, newNick) {
let buffers = this.getChatBuffersByServer(server)
if (irc.serverData[server].my_nick === oldNick) {
irc.serverData[server].my_nick = newNick
if (irc.serverData[server].userNick === oldNick) {
irc.serverData[server].userNick = newNick
let activeBuf = this.getActiveChatBuffer()
@ -2092,7 +2094,7 @@ class IRCChatWindow {
if (!buffer) return
if (user.nickname === irc.serverData[server].my_nick) {
if (user.nickname === irc.serverData[server].userNick) {
buffer.setAliveStatus(true)
} else {
buffer.nicklist.nickAdd(user.nickname)
@ -2107,11 +2109,11 @@ class IRCChatWindow {
if (!buffer) return
if (user['nickname']) {
if (irc.serverData[server] && user.nickname === irc.serverData[server].my_nick) {
if (irc.serverData[server] && user.nickname === irc.serverData[server].userNick) {
buffer.setAliveStatus(false)
}
} else {
if (irc.serverData[server] && user === irc.serverData[server].my_nick) {
if (irc.serverData[server] && user === irc.serverData[server].userNick) {
buffer.setAliveStatus(false)
}
}
@ -2131,7 +2133,7 @@ class IRCChatWindow {
handleMode (server, data) {
let buf = null
if (data.target === irc.serverData[server].my_nick) {
if (data.target === irc.serverData[server].userNick) {
buf = this.getServerChatBuffer(server)
} else {
buf = this.getChatBufferByServerName(server, data.target)
@ -2139,11 +2141,11 @@ class IRCChatWindow {
if (!buf) return
if (data.type === 'mode_add') {
if (data.type === 'modeAdd') {
buf.nicklist.modeAdded(data.modeTarget, data.mode)
buf.addMessage('set mode ' + span(data.target, ['channel']) + ' ' + span(sf('+%s %s', data.mode, data.modeTarget), ['mode']),
data.user.nickname, 'mode')
} else if (data.type === 'mode_del') {
} else if (data.type === 'modeDel') {
buf.nicklist.modeRemoved(data.modeTarget, data.mode)
buf.addMessage('set mode ' + span(data.target, ['channel']) + ' ' + span(sf('-%s %s', data.mode, data.modeTarget), ['mode']),
data.user.nickname, 'mode')
@ -2189,7 +2191,7 @@ class IRCChatWindow {
render (buffer) {
let activeNow = this.getActiveChatBuffer()
this.input_handler.tabCompleteReset()
this.inputHandler.tabCompleteReset()
if (activeNow) {
activeNow.switchOff()
@ -2256,7 +2258,7 @@ window.onload = function () {
clientdom['frame'] = irc.primaryFrame.querySelector('#chat')
clientdom['letterbox'] = clientdom.frame.querySelector('.letterbox')
clientdom['nicklist'] = clientdom.frame.querySelector('.nicklist')
clientdom['currentNickname'] = clientdom.frame.querySelector('.my_nickname')
clientdom['currentNickname'] = clientdom.frame.querySelector('.userNickname')
clientdom['input'] = clientdom.frame.querySelector('.userinput')
clientdom['send'] = clientdom.frame.querySelector('.sendbutton')
clientdom['chat'] = clientdom.frame.querySelector('.chatarea')
@ -2265,12 +2267,11 @@ window.onload = function () {
clientdom.settings['open'] = irc.primaryFrame.querySelector('.open_settings')
irc.settings = new Settings()
irc.settings.setInitialValues()
irc.handler = new ConnectionHandler()
irc.auther = new IRCConnector()
irc.chat = new IRCChatWindow()
irc.settings.setInitialValues()
parseURL()
window.onpopstate = parseURL
}

View File

@ -1,73 +0,0 @@
const imgs = ['.png', '.jpg', '.jpeg', '.svg']
const embeds = [
{
match: /youtu.?be\//is,
exec: function (pgurl) {
let dat = pgurl.match(/(?:be|com)\/([^?&#]+)/i)
if (!dat) {
dat = pgurl.match('[\\?&]v=([^&#]*)')
}
if (!dat) return null
return 'https://www.youtube.com/embed/' + dat[1] + '?autoplay=1'
}
}
]
export function handleUrlElement (elem) {
let cover = null
let ext = elem.href.split('.')
ext = ext[ext.length - 1]
if (ext && imgs.indexOf(ext) !== -1) {
cover = document.createElement('img')
cover.src = elem.href
}
if (!cover) {
for (let a in embeds) {
if (cover) break
let fn = embeds[a]
if (elem.href.match(fn.match)) {
let r = fn.exec(elem.href)
if (r) {
cover = document.createElement('iframe')
cover.src = r
}
}
}
}
if (cover) {
cover.className = 'preview'
let contelem = document.createElement('span')
contelem.className = 'preview-box'
let contbutton = document.createElement('button')
contbutton.className = 'preview-btn'
contbutton.innerHTML = 'Show Preview'
elem.parentNode.appendChild(contelem)
contelem.appendChild(elem)
contelem.appendChild(contbutton)
contbutton.addEventListener('click', function (e) {
e.preventDefault()
if (cover.parentNode) {
cover.remove()
contbutton.innerHTML = 'Show Preview'
} else {
contelem.appendChild(cover)
contbutton.innerHTML = 'Hide Preview'
}
}, false)
return contelem
}
return elem
}

View File

@ -37,7 +37,7 @@ window.themes = module.exports = {
}
},
change_theme: function (name) {
changeTheme: function (name) {
if (name in window.themes.available) {
swapSheet(window.themes.available[name].stylesheet)
window.irc.config.theme = name

View File

@ -19,6 +19,14 @@ body
margin-top: 0
display: block
text-align: center
position: relative
img
max-width: 64px
top: -50px;
position: absolute
left: 0
right: 0
margin: auto
.grade2
margin-bottom: 0