diff --git a/public/quality-high.svg b/public/quality-high.svg new file mode 100644 index 0000000000000000000000000000000000000000..4ad23ecaea7a2bdf6704352e16c64f0b6d5c0d8c --- /dev/null +++ b/public/quality-high.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="green" stroke="green" d="M8.213 16.984c.97-1.028 2.308-1.664 3.787-1.664s2.817.636 3.787 1.664l-3.787 4.016-3.787-4.016zm-1.747-1.854c1.417-1.502 3.373-2.431 5.534-2.431s4.118.929 5.534 2.431l2.33-2.472c-2.012-2.134-4.793-3.454-7.864-3.454s-5.852 1.32-7.864 3.455l2.33 2.471zm-4.078-4.325c2.46-2.609 5.859-4.222 9.612-4.222s7.152 1.613 9.612 4.222l2.388-2.533c-3.071-3.257-7.313-5.272-12-5.272s-8.929 2.015-12 5.272l2.388 2.533z"/></svg> diff --git a/public/quality-low.svg b/public/quality-low.svg new file mode 100644 index 0000000000000000000000000000000000000000..258dfb67e42c9de932a87a771cfa02035db0b74f --- /dev/null +++ b/public/quality-low.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="red" d="M8.213 16.984c.97-1.028 2.308-1.664 3.787-1.664s2.817.636 3.787 1.664l-3.787 4.016-3.787-4.016zm3.787-6.78c2.387 0 4.648.876 6.461 2.485l-.969 1.028c-1.556-1.308-3.472-2.018-5.492-2.018-2.021 0-3.937.71-5.492 2.018l-.969-1.028c1.813-1.609 4.075-2.485 6.461-2.485zm0-1c-3.071 0-5.852 1.32-7.864 3.455l2.33 2.472c1.417-1.502 3.373-2.431 5.534-2.431s4.117.929 5.534 2.431l2.33-2.472c-2.012-2.135-4.793-3.455-7.864-3.455zm0-5.204c3.949 0 7.682 1.517 10.607 4.291l-1.021 1.083c-2.656-2.452-6.023-3.791-9.586-3.791s-6.93 1.339-9.586 3.791l-1.021-1.083c2.926-2.774 6.658-4.291 10.607-4.291zm0-1c-4.687 0-8.929 2.015-12 5.272l2.388 2.533c2.46-2.609 5.859-4.222 9.612-4.222 3.754 0 7.152 1.613 9.611 4.222l2.389-2.533c-3.071-3.257-7.313-5.272-12-5.272z"/></svg> diff --git a/public/quality-medium.svg b/public/quality-medium.svg new file mode 100644 index 0000000000000000000000000000000000000000..b17cacdf887e379dfc57b7a85133813eefde66c5 --- /dev/null +++ b/public/quality-medium.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="orange" d="M8.213 16.984c.97-1.028 2.308-1.664 3.787-1.664s2.817.636 3.787 1.664l-3.787 4.016-3.787-4.016zm-1.747-1.854c1.417-1.502 3.373-2.431 5.534-2.431s4.118.929 5.534 2.431l2.33-2.472c-2.012-2.134-4.793-3.454-7.864-3.454s-5.852 1.32-7.864 3.455l2.33 2.471zm5.534-11.13c3.949 0 7.681 1.517 10.607 4.291l-1.021 1.083c-2.656-2.452-6.023-3.791-9.586-3.791s-6.93 1.339-9.586 3.791l-1.021-1.083c2.926-2.774 6.658-4.291 10.607-4.291zm0-1c-4.687 0-8.929 2.015-12 5.272l2.388 2.533c2.46-2.609 5.859-4.222 9.612-4.222s7.152 1.613 9.612 4.222l2.388-2.533c-3.071-3.257-7.313-5.272-12-5.272z"/></svg> diff --git a/public/styles.css b/public/styles.css index 6bb668555e0229817ab0dfab1b00042d429b39ae..3efb678700500c45dfb826bb9db2bf46139510c8 100644 --- a/public/styles.css +++ b/public/styles.css @@ -107,6 +107,8 @@ button.selected { border-bottom: 1px solid black; padding: 4px 0; opacity: 0; + display: flex; + align-items: center; } #connected-peers li:nth-child(2) { @@ -141,24 +143,47 @@ button.selected { border-bottom-width: 0px; } +.peer-quality, .peer-status { width: 15px; height: 15px; - margin-left: 5px; - display: inline-block; + margin-right: 5px; +} + +.peer-status { border-radius: 10px; } +.peer-status::after { + font-size: 0.5em; + margin-left: 10px; + background-color: white; + border-radius: 50%; +} + +.peer-status.upload::after { + content: "â–²"; + padding: 0.5px; +} + +.peer-status.download::after { + content: "â–¼"; + padding: 1px; +} + .peer-status.unsynced { + color: gray; background-color: gray; } @keyframes peer-status-negotiating { from { + color: gray; background-color: gray; } 50%, to { + color: orange; background-color: orange; } } @@ -166,9 +191,11 @@ button.selected { .peer-status.negotiating { animation: peer-status-negotiating 0.5s step-end infinite; background-color: orange; + color: orange; } .peer-status.synced { + color: green; background-color: green; } diff --git a/src/app.js b/src/app.js index fb3cab0ac965780a0964ba46f4b3dc8352630dac..832906420a6224c7af048e7c06676b2e78a1781f 100644 --- a/src/app.js +++ b/src/app.js @@ -40,18 +40,41 @@ const onRoomConnect = (room_) => { updateOverallStatusIcon() }) + room.addEventListener("userConnection", ({ detail: { id, quality } }) => { + const high = "/quality-high.svg" + const medium = "/quality-medium.svg" + const low = "/quality-low.svg" + + const peer = getOrInsertPeerById(id).children[0] + if (quality < 0.33) { + if (!peer.src.includes(high)) { + peer.src = high + } + } else if (quality < 0.66) { + if (!peer.src.includes(medium)) { + peer.src = medium + } + } else { + if (!peer.src.includes(low)) { + peer.src = low + } + } + }) + room.addEventListener("weSyncedWithPeer", ({ detail: id }) => { - getOrInsertPeerById(id).children[1].className = "peer-status synced" + getOrInsertPeerById(id).children[1].className = "peer-status upload synced" updateOverallStatusIcon() }) room.addEventListener("waitingForSyncStep", ({ detail: id }) => { - getOrInsertPeerById(id).children[2].className = "peer-status negotiating" + getOrInsertPeerById(id).children[2].className = + "peer-status download negotiating" updateOverallStatusIcon() }) room.addEventListener("peerSyncedWithUs", ({ detail: id }) => { - getOrInsertPeerById(id).children[2].className = "peer-status synced" + getOrInsertPeerById(id).children[2].className = + "peer-status download synced" updateOverallStatusIcon() }) @@ -200,26 +223,32 @@ HTML.roomIDElem.addEventListener("keydown", (event) => { const getOrInsertPeerById = (id) => { for (const peerElem of HTML.connectedPeers.children) { - const peerId = peerElem.children[0].innerHTML + const peerId = peerElem.children[3].innerHTML if (peerId == id) { return peerElem } } const peerElem = document.createElement("li") - const peerId = document.createElement("div") - peerId.style.display = "inline" - peerId.innerHTML = id + const quality = document.createElement("img") + quality.src = "/quality-low.svg" + quality.alt = "Peer quality icon" + quality.className = "peer-quality" const ourStatus = document.createElement("div") - ourStatus.className = "peer-status unsynced" + ourStatus.className = "peer-status upload unsynced" const theirStatus = document.createElement("div") - theirStatus.className = "peer-status unsynced" + theirStatus.className = "peer-status download unsynced" - peerElem.appendChild(peerId) + const peerId = document.createElement("div") + peerId.style.marginLeft = "5px" + peerId.innerHTML = id + + peerElem.appendChild(quality) peerElem.appendChild(ourStatus) peerElem.appendChild(theirStatus) + peerElem.appendChild(peerId) HTML.connectedPeers.appendChild(peerElem) diff --git a/src/room.js b/src/room.js index 88bf53474ae64d960cc451e03ddb64e9c1ead3d3..6d7315412c1c427b2175d8c4d3553f9155ad3815 100644 --- a/src/room.js +++ b/src/room.js @@ -92,9 +92,9 @@ class Room extends EventTarget { }, onUserEvent: (event) => { if (event.action == "userConnection") { - const { quality } = event + const { id, quality } = event this.dispatchEvent( - new CustomEvent("userConnection", { detail: quality }), + new CustomEvent("userConnection", { detail: { id, quality } }), ) } else if (event.action == "userID") { const { user: id } = event diff --git a/src/y-webrtc/index.js b/src/y-webrtc/index.js index ba19f1032078541c92eb502ba87b81012f637b11..3ef2c68d222b15dd7d18d028e451dad5b83d0be6 100644 --- a/src/y-webrtc/index.js +++ b/src/y-webrtc/index.js @@ -255,6 +255,7 @@ function extend(Y) { } this.raiseUserEvent("userConnection", { + id: peer.id, quality: 1.0 - (self.webrtcOptions.heartbeat.timeout -