document.addEventListener("DOMContentLoaded", async function () { const messagesContainer = document.getElementById("messages"); const radioButtons = document.querySelectorAll("input[name='btnradio']"); const loadingDiv = document.getElementById("loading"); const messagesList = document.createElement("div"); messagesList.style="max-height:70vh;overflow: auto;" messagesContainer.appendChild(messagesList); const state = { messages: [], nodesById: {}, }; radioButtons.forEach(radio => { radio.addEventListener("change", fetchMessages); }); async function fetchMessages() { try { let url = "https://map.sthlm-mesh.se/api/v1/text-messages?order=desc"; const selectedRadio = document.querySelector("input[name='btnradio']:checked"); //If all is not selected we get 15 messages. If not we get 35 due to duplicates if (selectedRadio.id !== "all") { url += `&gateway_id=${selectedRadio.id}`; url += `&count=15`; } else { url += `&count=35`; } const response = await fetch(url); const data = await response.json(); //Filter duplicate messages state.messages = Array.from( new Map(data.text_messages.map(msg => [msg.packet_id, msg])).values() ); // Sort the messages, for some reason with multiple mqtt gateways they are unsorted. state.messages.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); // fetch node info for(const message of state.messages){ await fetchNodeInfo(message.to); await fetchNodeInfo(message.from); await fetchNodeInfo(message.gateway_id); } updateUI(); } catch (error) { console.error("Error fetching messages", error); loadingDiv.innerHTML = `
Error fetching messages: ${error.message}
`; } } async function fetchNodeInfo(nodeId) { // do nothing if already fetched if(nodeId in state.nodesById){ return; } // do nothing if broadcast address if(nodeId.toString() === "4294967295"){ return; } try { const response = await fetch(`https://map.sthlm-mesh.se/api/v1/nodes/${nodeId}`); const data = await response.json(); const node = data.node; if(node){ state.nodesById[node.node_id] = node; } } catch(e) { // do nothing } } function updateUI() { loadingDiv.innerHTML = ""; // Clear the loading message messagesList.innerHTML = ""; state.messages.slice().reverse().forEach(message => { const messageDiv = document.createElement("div"); messageDiv.className = "d-flex mb-2"; messageDiv.innerHTML = `