diff --git a/content/sv/messages/index.html b/content/sv/messages/index.html
new file mode 100644
index 0000000..c3d7313
--- /dev/null
+++ b/content/sv/messages/index.html
@@ -0,0 +1,31 @@
+---
+title: Meddelanden
+linkTitle: test
+menu: {main: {weight: 50}}
+---
+ Loading...Senaste meddelanden
+
+
+
-{{% blocks/section color="white" %}}
-## Senaste meddelanden
-{{% iframe src="https://map.sthlm-mesh.se/api/v1/text-messages/embed?gateway_id=3663385928" width="100%" style="min-height:65vh;overflow: hidden;" %}}
-{{% /blocks/section %}}
\ No newline at end of file
diff --git a/static/js/messages.js b/static/js/messages.js
new file mode 100644
index 0000000..5afc74f
--- /dev/null
+++ b/static/js/messages.js
@@ -0,0 +1,145 @@
+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()
+ );
+
+ // 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 = ` +