improve frontend
This commit is contained in:
parent
b9d0f0b548
commit
caf67bf618
@ -9,6 +9,7 @@
|
||||
#message-list {
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
max-height: 100%;
|
||||
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
@ -11,4 +11,6 @@ body {
|
||||
#content {
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
max-height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
|
||||
</select>
|
||||
<input id="message-input" />
|
||||
<input type="file" id="sendfile" disabled/>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@ -22,6 +23,7 @@
|
||||
let message_list = document.getElementById("message-list")
|
||||
let peers = document.getElementById("peers")
|
||||
let inputbox = document.getElementById("message-input")
|
||||
let sendfile = document.getElementById("sendfile")
|
||||
|
||||
let search = new URLSearchParams(location.search);
|
||||
let sender = search.get("name") || "";
|
||||
@ -41,10 +43,62 @@
|
||||
const MessageSessionAnswer = "SessionAnswer";
|
||||
const MessageICECandidate = "IceCandidate";
|
||||
|
||||
const display = (message) => {
|
||||
let newNode = document.createElement("div")
|
||||
newNode.innerHTML = `${new Date().toTimeString()}: ${message}`;
|
||||
message_list.appendChild(newNode)
|
||||
let updateSendfile = () => {
|
||||
if (peers.value != "") {
|
||||
sendfile.removeAttribute("disabled")
|
||||
} else {
|
||||
sendfile.setAttribute("disabled", "")
|
||||
}
|
||||
}
|
||||
peers.addEventListener("change", updateSendfile)
|
||||
sendfile.addEventListener("change", async (ev) => {
|
||||
let file = sendfile.files[0]
|
||||
sendfile.value = ""
|
||||
|
||||
let peer = peerMap.get(peers.value)
|
||||
if (!peer) {
|
||||
return
|
||||
}
|
||||
display(`你给 ${peers.value} 传了一个文件: ${file.name}。传输中...`)
|
||||
|
||||
let reader = new FileReader()
|
||||
let dc = peer.createDataChannel(`file:${file.name}`)
|
||||
reader.addEventListener("load", (ev) => {
|
||||
dc.send(reader.result)
|
||||
dc.close()
|
||||
})
|
||||
dc.addEventListener("open", () => {
|
||||
reader.readAsArrayBuffer(file)
|
||||
})
|
||||
})
|
||||
|
||||
const createNode = (tag, ...children) => {
|
||||
let node = document.createElement(tag)
|
||||
children.forEach(child => {
|
||||
if(typeof child === "string") {
|
||||
let inner = document.createElement("span")
|
||||
inner.innerHTML = child
|
||||
node.appendChild(inner)
|
||||
} else if (child instanceof HTMLElement) {
|
||||
node.appendChild(child)
|
||||
} else {
|
||||
console.log("child is not a node: ", child, typeof child)
|
||||
}
|
||||
})
|
||||
return node
|
||||
}
|
||||
|
||||
const display = (...message) => {
|
||||
let scrollToBottom = Math.abs(message_list.scrollHeight - message_list.scrollTop - message_list.clientHeight) < 1;
|
||||
message_list.appendChild(createNode("div",
|
||||
`${new Date().toTimeString()}: `,
|
||||
...message
|
||||
))
|
||||
if(scrollToBottom) {
|
||||
message_list.scrollTo({
|
||||
top: message_list.scrollHeight
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
inputbox.addEventListener("keyup", (e) => {
|
||||
@ -59,30 +113,34 @@
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`You -> ${peers.value}: ${inputbox.value}`)
|
||||
display(`You -> ${peers.value}: ${inputbox.value}`)
|
||||
display(`你 -> ${peers.value}: ${inputbox.value}`)
|
||||
channel.send(inputbox.value)
|
||||
inputbox.value = ""
|
||||
})
|
||||
|
||||
const addPeer = (peerName) => {
|
||||
display(`连接上了 ${peerName}`)
|
||||
|
||||
let newNode = document.createElement("option")
|
||||
newNode.id = peerName
|
||||
newNode.setAttribute("value", peerName)
|
||||
newNode.innerText = peerName;
|
||||
newNode.innerHTML = peerName;
|
||||
peers.appendChild(newNode)
|
||||
|
||||
updateSendfile()
|
||||
}
|
||||
const removePeer = (peerName) => {
|
||||
display(`${peerName} 走了...`)
|
||||
let el = document.getElementById(peerName);
|
||||
if(el) el.remove()
|
||||
|
||||
updateSendfile()
|
||||
}
|
||||
|
||||
let timeout;
|
||||
|
||||
let reconnect = () => {
|
||||
if(ws && (ws.readyState == WebSocket.CONNECTING || ws.readyState == WebSocket.OPEN)) {
|
||||
console.log("ws ok", ws)
|
||||
return;
|
||||
}
|
||||
|
||||
@ -99,7 +157,7 @@
|
||||
handle_ws_message(JSON.parse(data))
|
||||
})
|
||||
ws.addEventListener("open", () => {
|
||||
display("server connected. waiting for a name to be assigned for you...")
|
||||
display("服务器连上啦。你等等,给你起个名字...")
|
||||
ws.send(JSON.stringify({
|
||||
message: {
|
||||
type: MessageBootstrap,
|
||||
@ -108,7 +166,6 @@
|
||||
sender,
|
||||
}))
|
||||
})
|
||||
console.log("connecting...")
|
||||
}
|
||||
|
||||
let handle_ws_message = (wsMessage) => {
|
||||
@ -154,17 +211,37 @@
|
||||
console.log("gather", peer.iceGatheringState)
|
||||
})
|
||||
peer.addEventListener("datachannel", ({channel}) => {
|
||||
channelMap.set(peerName, channel);
|
||||
channel.addEventListener("open", (ev) => {
|
||||
display("connected in event")
|
||||
addPeer(peerName)
|
||||
})
|
||||
channel.addEventListener("message", (ev) => {
|
||||
display(`${peerName} -> You: ${ev.data}`)
|
||||
})
|
||||
channel.addEventListener("close", () => {
|
||||
removePeer(peerName)
|
||||
})
|
||||
if(channel.label === "chat") {
|
||||
channelMap.set(peerName, channel);
|
||||
channel.addEventListener("open", (ev) => {
|
||||
addPeer(peerName)
|
||||
})
|
||||
channel.addEventListener("message", (ev) => {
|
||||
display(`${peerName} -> You: ${ev.data}`)
|
||||
})
|
||||
channel.addEventListener("close", () => {
|
||||
removePeer(peerName)
|
||||
})
|
||||
} else if (channel.label.startsWith("file:")) {
|
||||
let filename = channel.label.substr(5)
|
||||
let buffers = [];
|
||||
channel.addEventListener("open", ev => {
|
||||
display(`${peerName} 给你发了一个文件: ${filename}。 接收中...`)
|
||||
})
|
||||
channel.addEventListener("message", ev => {
|
||||
buffers.push(ev.data)
|
||||
})
|
||||
channel.addEventListener("close", () => {
|
||||
var link = document.createElement('a');
|
||||
link.href = window.URL.createObjectURL(new Blob(buffers));
|
||||
link.download = filename;
|
||||
link.innerHTML = filename
|
||||
display(
|
||||
"文件:",
|
||||
link,
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
peerMap.set(peerName, peer);
|
||||
@ -175,11 +252,10 @@
|
||||
if(wsMessage.message.type === MessageDiscoverResponse) {
|
||||
let channel = peer.createDataChannel("chat");
|
||||
channel.addEventListener("open", (ev) => {
|
||||
display("connected in event")
|
||||
addPeer(peerName)
|
||||
})
|
||||
channel.addEventListener("message", (ev) => {
|
||||
display(`${peerName} -> You: ${ev.data}`)
|
||||
display(`${peerName} -> 你: ${ev.data}`)
|
||||
})
|
||||
channel.addEventListener("close", () => {
|
||||
removePeer(peerName)
|
||||
@ -225,10 +301,10 @@
|
||||
room,
|
||||
sender: wsMessage.sender,
|
||||
}))
|
||||
display(`You are ${sender}. Searching for peers...`)
|
||||
display(`决定了,就叫 ${sender}. 我们等等小伙伴吧...`)
|
||||
break;
|
||||
case MessageDiscoverRequest:
|
||||
display("connecting to peer " + wsMessage.sender)
|
||||
display(`正在尝试连接 ${wsMessage.sender}`)
|
||||
ws.send(JSON.stringify({
|
||||
message: {
|
||||
type: MessageDiscoverResponse,
|
||||
@ -245,7 +321,6 @@
|
||||
recreateAndSetupPeer(wsMessage.sender)
|
||||
break
|
||||
case MessageSessionAnswer:
|
||||
display("receiving connection to peer: " + wsMessage.sender)
|
||||
console.log("set remote answer")
|
||||
peer.setRemoteDescription(JSON.parse(wsMessage.message.sdp))
|
||||
peer.restartIce()
|
||||
@ -261,7 +336,6 @@
|
||||
}
|
||||
|
||||
reconnect()
|
||||
console.log("document loaded")
|
||||
})()
|
||||
</script>
|
||||
{% endblock %}
|
Loading…
x
Reference in New Issue
Block a user