mirror of
https://codeberg.org/emersion/gamja.git
synced 2024-11-14 19:05:01 -05:00
Add connect form, add /join command
This commit is contained in:
parent
cbf64e56a0
commit
f66c7c52f3
3 changed files with 195 additions and 60 deletions
200
assets/client.js
200
assets/client.js
|
@ -1,19 +1,23 @@
|
|||
var server = {
|
||||
name: "chat.freenode.net",
|
||||
url: "ws://localhost:8080",
|
||||
username: "soju-test-user/chat.freenode.net",
|
||||
realname: "soju-test-user",
|
||||
nick: "soju-test-user",
|
||||
pass: "soju-test-user",
|
||||
username: null,
|
||||
realname: null,
|
||||
nick: null,
|
||||
pass: null,
|
||||
};
|
||||
|
||||
var ws = null;
|
||||
|
||||
var buffers = {};
|
||||
var activeBuffer = null;
|
||||
var serverBuffer = null;
|
||||
|
||||
var bufferListElt = document.querySelector("#buffer-list");
|
||||
var bufferElt = document.querySelector("#buffer");
|
||||
var composerElt = document.querySelector("#composer");
|
||||
var composerInputElt = document.querySelector("#composer input");
|
||||
var connectElt = document.querySelector("#connect");
|
||||
var connectFormElt = document.querySelector("#connect form");
|
||||
|
||||
function djb2(s) {
|
||||
var hash = 5381;
|
||||
|
@ -160,78 +164,156 @@ function switchBuffer(buf) {
|
|||
}
|
||||
}
|
||||
|
||||
var serverBuffer = createBuffer(server.name);
|
||||
serverBuffer.readOnly = true;
|
||||
switchBuffer(serverBuffer);
|
||||
function showConnectForm() {
|
||||
setConnectFormDisabled(false);
|
||||
connectElt.style.display = "block";
|
||||
}
|
||||
|
||||
var ws = new WebSocket(server.url);
|
||||
|
||||
ws.onopen = function() {
|
||||
console.log("Connection opened");
|
||||
|
||||
if (server.pass) {
|
||||
ws.send(formatMessage({ command: "PASS", params: [server.pass] }));
|
||||
function connect() {
|
||||
try {
|
||||
ws = new WebSocket(server.url);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
showConnectForm();
|
||||
return;
|
||||
}
|
||||
ws.send(formatMessage({ command: "NICK", params: [server.nick] }));
|
||||
ws.send(formatMessage({
|
||||
command: "USER",
|
||||
params: [server.username, "0", "*", server.realname],
|
||||
}));
|
||||
};
|
||||
|
||||
ws.onmessage = function(event) {
|
||||
var msg = parseMessage(event.data);
|
||||
console.log(msg);
|
||||
ws.onopen = function() {
|
||||
console.log("Connection opened");
|
||||
|
||||
switch (msg.command) {
|
||||
case "NOTICE":
|
||||
case "PRIVMSG":
|
||||
var target = msg.params[0];
|
||||
if (target == server.nick) {
|
||||
target = msg.prefix.name;
|
||||
// TODO: wait for RPL_WELCOME
|
||||
connectElt.style.display = "none";
|
||||
|
||||
if (server.pass) {
|
||||
ws.send(formatMessage({ command: "PASS", params: [server.pass] }));
|
||||
}
|
||||
var buf;
|
||||
if (target == "*") {
|
||||
buf = serverBuffer;
|
||||
} else {
|
||||
buf = createBuffer(target);
|
||||
}
|
||||
buf.addMessage(msg);
|
||||
break;
|
||||
case "JOIN":
|
||||
var channel = msg.params[0];
|
||||
if (msg.prefix.name == server.nick) {
|
||||
createBuffer(channel);
|
||||
} else {
|
||||
ws.send(formatMessage({ command: "NICK", params: [server.nick] }));
|
||||
ws.send(formatMessage({
|
||||
command: "USER",
|
||||
params: [server.username, "0", "*", server.realname],
|
||||
}));
|
||||
};
|
||||
|
||||
ws.onmessage = function(event) {
|
||||
var msg = parseMessage(event.data);
|
||||
console.log(msg);
|
||||
|
||||
switch (msg.command) {
|
||||
case "NOTICE":
|
||||
case "PRIVMSG":
|
||||
var target = msg.params[0];
|
||||
if (target == server.nick) {
|
||||
target = msg.prefix.name;
|
||||
}
|
||||
var buf;
|
||||
if (target == "*") {
|
||||
buf = serverBuffer;
|
||||
} else {
|
||||
buf = createBuffer(target);
|
||||
}
|
||||
buf.addMessage(msg);
|
||||
break;
|
||||
case "JOIN":
|
||||
var channel = msg.params[0];
|
||||
if (msg.prefix.name == server.nick) {
|
||||
createBuffer(channel);
|
||||
} else {
|
||||
createBuffer(channel).addMessage(msg);
|
||||
}
|
||||
break;
|
||||
case "PART":
|
||||
var channel = msg.params[0];
|
||||
createBuffer(channel).addMessage(msg);
|
||||
break;
|
||||
default:
|
||||
serverBuffer.addMessage(msg);
|
||||
}
|
||||
break;
|
||||
case "PART":
|
||||
var channel = msg.params[0];
|
||||
createBuffer(channel).addMessage(msg);
|
||||
};
|
||||
|
||||
ws.onclose = function() {
|
||||
console.log("Connection closed");
|
||||
showConnectForm();
|
||||
};
|
||||
|
||||
ws.onerror = function() {
|
||||
console.error("Connection error");
|
||||
};
|
||||
|
||||
serverBuffer = createBuffer(server.name);
|
||||
serverBuffer.readOnly = true;
|
||||
switchBuffer(serverBuffer);
|
||||
}
|
||||
|
||||
function sendMessage(msg) {
|
||||
ws.send(formatMessage(msg));
|
||||
}
|
||||
|
||||
function executeCommand(s) {
|
||||
var parts = s.split(" ");
|
||||
var cmd = parts[0].toLowerCase().slice(1);
|
||||
var args = parts.slice(1);
|
||||
switch (cmd) {
|
||||
case "join":
|
||||
var channel = args[0];
|
||||
var msg = { command: "JOIN", params: [channel] };
|
||||
sendMessage(msg);
|
||||
break;
|
||||
default:
|
||||
serverBuffer.addMessage(msg);
|
||||
console.error("Unknwon command '" + cmd + "'");
|
||||
}
|
||||
};
|
||||
|
||||
ws.onclose = function() {
|
||||
console.log("Connection closed");
|
||||
};
|
||||
}
|
||||
|
||||
composerElt.onsubmit = function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
var text = composerInputElt.value;
|
||||
composerInputElt.value = "";
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (text.startsWith("//")) {
|
||||
text = text.slice(1);
|
||||
} else if (text.startsWith("/")) {
|
||||
executeCommand(text);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!activeBuffer || activeBuffer.readOnly) {
|
||||
return;
|
||||
}
|
||||
var target = activeBuffer.name;
|
||||
var text = composerInputElt.value;
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
|
||||
var msg = { command: "PRIVMSG", params: [target, text] };
|
||||
ws.send(formatMessage(msg));
|
||||
sendMessage(msg);
|
||||
msg.prefix = { name: server.nick };
|
||||
activeBuffer.addMessage(msg);
|
||||
composerInputElt.value = "";
|
||||
};
|
||||
|
||||
function setConnectFormDisabled(disabled) {
|
||||
connectElt.querySelectorAll("input, button").forEach(function(elt) {
|
||||
elt.disabled = disabled;
|
||||
});
|
||||
}
|
||||
|
||||
connectFormElt.onsubmit = function(event) {
|
||||
event.preventDefault();
|
||||
setConnectFormDisabled(true);
|
||||
|
||||
server.url = connectFormElt.elements.url.value;
|
||||
server.nick = connectFormElt.elements.nick.value;
|
||||
server.pass = connectFormElt.elements.password.value;
|
||||
server.username = connectFormElt.elements.username.value || server.nick;
|
||||
server.realname = connectFormElt.elements.realname.value || server.nick;
|
||||
|
||||
connect();
|
||||
};
|
||||
|
||||
window.onkeydown = function(event) {
|
||||
if (activeBuffer && activeBuffer.readOnly && event.key == "/" && document.activeElement != composerInputElt) {
|
||||
// Allow typing commands even in read-only buffers
|
||||
composerElt.classList.remove("read-only");
|
||||
composerInputElt.focus();
|
||||
composerInputElt.value = "";
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,7 +12,8 @@ body {
|
|||
font-family: monospace;
|
||||
}
|
||||
|
||||
#sidebar, #buffer {
|
||||
#sidebar, #buffer, #connect {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
@ -49,6 +50,22 @@ body {
|
|||
display: none;
|
||||
}
|
||||
|
||||
#connect {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
background: white;
|
||||
}
|
||||
#connect form {
|
||||
margin: 0 auto;
|
||||
max-width: 300px;
|
||||
}
|
||||
#connect input {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
color: green;
|
||||
}
|
||||
|
|
36
index.html
36
index.html
|
@ -22,6 +22,42 @@
|
|||
<input type="text" placeholder="Type a message">
|
||||
</form>
|
||||
|
||||
<section id="connect">
|
||||
<form>
|
||||
<h2>Connect to IRC</h2>
|
||||
|
||||
<label for="connect-url">URL:</label><br/>
|
||||
<input type="url" name="url" id="connect-url" value="ws://localhost:8080"/>
|
||||
<br/><br/>
|
||||
|
||||
<label for="connect-nick">Nickname:</label><br/>
|
||||
<input type="username" name="nick" id="connect-nick" autofocus required/>
|
||||
<br/><br/>
|
||||
|
||||
<label for="connect-password">Password:</label><br/>
|
||||
<input type="password" name="password" id="connect-password"/>
|
||||
<br/><br/>
|
||||
|
||||
<details>
|
||||
<summary>More options</summary>
|
||||
|
||||
<br/>
|
||||
|
||||
<label for="connect-username">Username:</label><br/>
|
||||
<input type="username" name="username" id="connect-username" placeholder="Same as nickname"/>
|
||||
<br/><br/>
|
||||
|
||||
<label for="connect-realname">Real name:</label><br/>
|
||||
<input type="text" name="realname" id="connect-realname" placeholder="Same as nickname"/>
|
||||
<br/>
|
||||
</details>
|
||||
|
||||
<br/>
|
||||
|
||||
<button>Connect</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<script src="assets/irc.js"></script>
|
||||
<script src="assets/client.js"></script>
|
||||
</body>
|
||||
|
|
Loading…
Reference in a new issue