moebius-web

web based ansi art editor

moebius-web

public/scripts/worker.js


var socket;
var sessionID;
var joint;
var connected = false;

function send(cmd, msg) {
    socket.send(JSON.stringify([cmd, msg]));
}

function onOpen() {
    postMessage({"cmd": "connected"});
}

function onClose(evt) {
    postMessage({"cmd": "disconnected"});
}

function onChat(handle, text, showNotification) {
    postMessage({"cmd": "chat", "handle": handle, "text": text, "showNotification": showNotification});
}

function onStart(msg, newSessionID) {
    joint = msg;
    sessionID = newSessionID;
    msg.chat.forEach((msg) => {
        onChat(msg[0], msg[1], false);
    });
}

function onJoin(handle, joinSessionID, showNotification) {
    if (joinSessionID === sessionID) {
        showNotification = false;
    }
    postMessage({"cmd": "join", "sessionID": joinSessionID, "handle": handle, "showNotification": showNotification});
}

function onNick(handle, nickSessionID) {
    postMessage({"cmd": "nick", "sessionID": nickSessionID, "handle": handle, "showNotification": (nickSessionID !== sessionID)});
}

function onPart(sessionID) {
    postMessage({"cmd": "part", "sessionID": sessionID});
}

function onDraw(blocks) {
    var outputBlocks = new Array();
    var index;
    blocks.forEach((block) => {
        index = block >> 16;
        outputBlocks.push([index, block & 0xffff, index % joint.columns, Math.floor(index / joint.columns)]);
    });
    postMessage({"cmd": "draw", "blocks": outputBlocks});
}

function onMessage(evt) {
    var data = evt.data;
    if (typeof(data) === "object") {
        var fr = new FileReader();
        fr.addEventListener("load", (evt) => {
            postMessage({"cmd": "imageData", "data": evt.target.result, "columns": joint.columns, "rows": joint.rows, "iceColours": joint.iceColours, "letterSpacing": joint.letterSpacing});
            connected = true;
        });
        fr.readAsArrayBuffer(data);
    } else {
        data = JSON.parse(data);
        switch(data[0]) {
        case "start":
            sessionID = data[2];
            var userList = data[3];
            Object.keys(userList).forEach((userSessionID) => {
                onJoin(userList[userSessionID], userSessionID, false);
            });
            onStart(data[1], data[2]);
            break;
        case "join":
            onJoin(data[1], data[2], true);
            break;
        case "nick":
            onNick(data[1], data[2]);
            break;
        case "draw":
            onDraw(data[1]);
            break;
        case "part":
            onPart(data[1]);
            break;
        case "chat":
            onChat(data[1], data[2], true);
            break;
        default:
            break;
        }
    }
}

function removeDuplicates(blocks) {
    var indexes = [];
    var index;
    blocks = blocks.reverse();
    blocks = blocks.filter((block) => {
        index = block >> 16;
        if (indexes.lastIndexOf(index) === -1) {
            indexes.push(index);
            return true;
        }
        return false;
    });
    return blocks.reverse();
}

self.onmessage = function (msg) {
    var data = msg.data;
    switch(data.cmd) {
    case "connect":
        socket = new WebSocket(data.url);
        socket.addEventListener("open", onOpen);
        socket.addEventListener("message", onMessage);
        socket.addEventListener("close", onClose);
        break;
    case "join":
        send("join", data.handle);
        break;
    case "nick":
        send("nick", data.handle);
        break;
    case "chat":
        send("chat", data.text);
        break;
    case "draw":
        send("draw", removeDuplicates(data.blocks));
        break;
    default:
        break;
    }
};

Download

raw zip tar