<html> <head> <style> img.marker { height: 1em; vertical-align: middle; } span.username:hover { font-weight: bold; } </style> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://cdn.alemi.dev/web/alemi.css"> <title>mumble stats</title> </head> <body> <div class="container"> <h3 id="loading">loading...</h3> <p style="margin:0"><table id="stats" class="w-100 align"></table></p> </div> </body> <script> let loading = document.getElementById("loading"); let stats = document.getElementById("stats"); let user_count = 0; let user_list = []; function htmlUser(user) { let output = `<span style="margin-left: 2em">`; if (user.user_id != null) { output += `<img class="marker" src="https://cdn.fantabos.co/logo-color.png"> `; } else { output += `<img class="marker" src="https://cdn.fantabos.co/logo-gray.png"> `; } if (user.comment != null) { output += `<span class="username" title="${user.comment}">${user.name}</span>`; } else { output += user.name; } return output + `</span>`; } async function pingServer() { try { let res = await fetch("https://api.alemi.dev/mumble/ping?host=<<REPLACE_ME>>"); let doc = await res.json(); if (doc.users != user_count) { let tmp = await fetch("https://api.alemi.dev/mumble/users?host=<<REPLACE_ME>>"); user_list = await tmp.json(); user_count = user_list.length; } let user_list_html = ""; for (let user of user_list) { user_list_html += htmlUser(user) + ' '; } stats.innerHTML = ` <tr> <td><code>users</code> ${doc.users}/${doc.max_users}</td> <td><code>net</code> ${doc.bandwidth/1000}kbps ~ ${doc.latency}ms</td> <td><code>version</code> ${doc.version}</td> </tr> <tr> <td colspan="3" class="pt-1"> ${user_list_html} </td> </tr>`; } catch (e) { stats.innerHTML = `<tr><td><b>error reaching api</b>: <code>${e}</code></td></tr>`; } loading.remove(); } pingServer() setInterval(pingServer, 1000 * 60); </script> </html>