-
-
Save InfiniteLee/da41284d7e14781370f50934cbe4883b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//file assets/js/chat_client.js | |
import {Socket, Presence} from "phoenix" | |
let ChatClient = { | |
init() { | |
let username = "Anonymous" | |
let encode = function(msg, callback) { | |
let builder = new flatbuffers.Builder(1024) | |
let body, sender, join_ref | |
if(msg.payload.body) | |
body = builder.createString(msg.payload.body) | |
if(msg.payload.sender) | |
sender = builder.createString(msg.payload.sender) | |
Chat.Payload.startPayload(builder) | |
if(body) | |
Chat.Payload.addBody(builder, body) | |
if(sender) | |
Chat.Payload.addSender(builder, sender) | |
let payload = Chat.Payload.endPayload(builder) | |
if(msg.join_ref) | |
join_ref = builder.createString(msg.join_ref) | |
let ref = builder.createString(msg.ref) | |
let topic = builder.createString(msg.topic) | |
let event = builder.createString(msg.event) | |
Chat.Message.startMessage(builder) | |
if(join_ref) | |
Chat.Message.addJoinRef(builder, join_ref) | |
Chat.Message.addRef(builder, ref) | |
Chat.Message.addTopic(builder, topic) | |
Chat.Message.addEvent(builder, event) | |
Chat.Message.addPayload(builder, payload) | |
let message = Chat.Message.endMessage(builder) | |
Chat.Message.finishMessageBuffer(builder, message) | |
let buf = builder.asUint8Array() | |
return callback(buf) | |
} | |
let decode = function(rawPayload, callback) { | |
let bytes = new Uint8Array(rawPayload) | |
let buf = new flatbuffers.ByteBuffer(bytes) | |
let msgBuf = Chat.Message.getRootAsMessage(buf) | |
let payload = msgBuf.payload() | |
let resp = { | |
join_ref: msgBuf.joinRef(), | |
ref: msgBuf.ref(), | |
topic: msgBuf.topic(), | |
event: msgBuf.event(), | |
status: msgBuf.status(), | |
payload: { | |
body: payload.body(), | |
sender: payload.sender(), | |
timestamp: payload.timestamp(), | |
status: payload.status(), | |
joins: {}, | |
leaves: {}, | |
state: {} | |
} | |
} | |
parse_presence(resp, payload, "joins") | |
parse_presence(resp, payload, "leaves") | |
parse_presence(resp, payload, "state") | |
return callback(resp) | |
} | |
let parse_presence = function(resp, payload, name) { | |
for (let i = 0; i < payload[name + "Length"](); i++) { | |
let payloadRoot = payload[name](i) | |
let respRoot = resp.payload[name] | |
let user = payloadRoot.user() | |
respRoot[user] = {metas: []} | |
for (let j = 0; j < payloadRoot.metasLength(); j++) { | |
respRoot[user].metas[j] = { | |
online_at: payloadRoot.metas(j).onlineAt(), | |
phx_ref: payloadRoot.metas(j).phxRef() | |
} | |
} | |
} | |
} | |
// Socket | |
let socket = new Socket("/socket", { | |
params: { | |
username: username, | |
room_id: window.room_id | |
}, | |
encode: encode, | |
decode: decode | |
}) | |
socket.connect() | |
socket.conn.binaryType = 'arraybuffer' | |
// Presence | |
let presences = {} | |
let formatTimestamp = (timestamp) => { | |
let date = new Date(timestamp * 1000) | |
return date.toLocaleTimeString() | |
} | |
let listBy = (user, {metas: metas}) => { | |
return { | |
user: user, | |
onlineAt: formatTimestamp(metas[0].online_at) | |
} | |
} | |
let userList = document.getElementById("UserList") | |
let render = (presences, list) => { | |
list['innerHTML'] = Presence.list(presences, listBy) | |
.map(presence => ` | |
<li id="${list.id + ":" + presence.user}"> | |
<b>${presence.user}</b> | |
<br><small>online since ${presence.onlineAt}</small> | |
</li> | |
`) | |
.join("") | |
} | |
// Channels | |
let room = socket.channel("room:lobby") | |
room.on("presence_state", state => { | |
presences = Presence.syncState(presences, state.state) | |
render(presences, userList) | |
}) | |
room.on("presence_diff", diff => { | |
presences = Presence.syncDiff(presences, {joins: diff.joins, leaves: diff.leaves}) | |
render(presences, userList) | |
}) | |
room.join() | |
//Messages | |
let messageInput = document.getElementById("NewMessage") | |
messageInput.addEventListener("keypress", (e) => { | |
if (e.keyCode == 13 && messageInput.value != "") { | |
let message = { | |
body: messageInput.value, | |
sender: username, | |
} | |
room.push("message:new", message) | |
messageInput.value = "" | |
} | |
}) | |
let messageList = document.getElementById("MessageList") | |
let renderMessage = (message) => { | |
let messageElement = document.createElement("li") | |
messageElement.innerHTML = ` | |
<b>${message.sender}</b> | |
<i>${formatTimestamp(message.timestamp)}</i> | |
<p>${message.body}</p> | |
` | |
messageList.appendChild(messageElement) | |
messageList.scrollTop = messageList.scrollHeight; | |
} | |
room.on("message:new", message => renderMessage(message)) | |
} | |
} | |
export default ChatClient |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment