Displaying location info from websocket

This commit is contained in:
metacryst
2025-10-31 21:54:57 -05:00
parent 152faaecee
commit 620d50cad7
9 changed files with 222 additions and 6 deletions

View File

@@ -1,11 +1,19 @@
import "./LocationList.js"
class Home extends Shadow {
render() {
ZStack(() => {
p("BLOCKCATCHER")
.x(2, em).y(1, em)
.fontSize(1.2, em)
.fontFamily("Arial")
LocationList()
})
.backgroundColor("#aebdff")
.display("block")
.width(100, vw).height(100, vh)
.color("#60759f")
}
}

View File

@@ -0,0 +1,26 @@
class LocationList extends Shadow {
list = []
render() {
VStack(() => {
this.list.forEach((update) => {
console.log(update.name)
HStack(() => {
p(update.timestamp)
p(update.name)
p(update.latitude)
p(update.longitude)
})
.gap(1, em)
})
})
.onEvent("update-location", (e) => {
console.log("location received: ", e.detail)
this.list.unshift(e.detail)
this.rerender()
})
.x(2, em).y(5, em)
}
}
window.registerShadow(LocationList)

View File

@@ -1,2 +1,5 @@
import ConnectionHandler from "./ws/Connection.js"
window.ConnectionHandler = new ConnectionHandler()
import "./components/Home.js"
Home()

120
ui/app/ws/Connection.js Normal file
View File

@@ -0,0 +1,120 @@
class Connection {
connectionTries = 0
ws;
linkCreated;
wsStatus;
constructor() {
this.init()
}
init() {
if(window.location.hostname === "localhost") {
this.ws = new WebSocket("ws://" + "localhost:3008")
} else {
this.ws = new WebSocket("wss://" + window.location.hostname + window.location.pathname)
}
this.ws.addEventListener('open', () => {
this.connectionTries = 0
console.log("Websocket connection established.");
this.ws.addEventListener('message', this.onMessage)
});
this.ws.addEventListener("close", () => {
this.checkOpen();
console.log('Websocket Closed')
})
}
onMessage = (event) => {
let message = event.data;
const [reqType, payload] = message.split('|');
switch(reqType) {
case 'update-location':
window.dispatchEvent(new CustomEvent('update-location', {detail: JSON.parse(payload)}))
break;
default:
console.log('Websocket message:', message);
break;
}
}
async checkOpen() {
if (this.ws.readyState === WebSocket.OPEN) {
return true
} else {
await this.sleep(this.connectionTries < 20 ? 5000 : 60000)
this.connectionTries++
console.log('Reestablishing connection')
this.init()
}
}
sleep = (time) => {
return new Promise(resolve => {
setTimeout(resolve, time);
});
}
sendMessage = (msg) => {
if (this.ws.readyState === WebSocket.OPEN) {
this.ws.send(msg);
}
else {
console.log('No websocket connection: Cannot send message');
}
}
updateCSS = async (updateStyle, newValue) => {
let currentSpace = window.wrapper.getAttribute("name").replace(/ /g,'%20')
let currentFolder = window.location.pathname;
//create the inital link
this.linkCreated = false;
let cssIncomingText = ""
Array.from(document.styleSheets).forEach(el => {
if(el?.href?.includes?.(`.${currentSpace}.css`)) {
this.linkCreated = true;
}
})
let currentSpaceDataAttr = window.wrapper.getAttribute("name");
let cssInit = `parchment-page[name="${currentSpaceDataAttr}"] {background-color: #e9c9a0;} parchment-page[name="${currentSpaceDataAttr}"] > p.text {font-family: ${newValue};} parchment-page[name="${currentSpaceDataAttr}"] > file-::before, parchment-page[name="${currentSpaceDataAttr}"] > image-::before, parchment-page[name="${currentSpaceDataAttr}"] > parchment-page::before {font-family: ${newValue};font-weight: 400;} parchment-page[name="${currentSpaceDataAttr}"] > space-select-outline > file-::before, parchment-page[name="${currentSpaceDataAttr}"] > select-outline > *, parchment-page[name="${currentSpaceDataAttr}"] > select-outline > image-::before ,parchment-page[name="${currentSpaceDataAttr}"] > space-select-outline > parchment-page::before, parchment-page[name="${currentSpaceDataAttr}"] > a, parchment-page[name="${currentSpaceDataAttr}"] > input-box {font-family: ${newValue}; font-weight: 400;}`
cssIncomingText += cssInit
let CSSRawData = `REQUEST|update-css|${currentFolder}|${cssIncomingText}|`
await this.checkOpen()
this.ws.send(CSSRawData)
}
createCSSLink = (wsMessage) => {
let retrieveHref = wsMessage;
var link = document.createElement("link");
link.rel = "stylesheet";
link.id = window.wrapper.getAttribute('name')+"-css"
link.href = retrieveHref;
let retrieveStyleLinks = document.querySelectorAll(`[href='${retrieveHref}']`);
if (retrieveStyleLinks[0] !== undefined) {
retrieveStyleLinks[0].remove();
}
window.wrapper.prepend(link);
}
scrapeExternalHTMLTitle = async (href) => {
let req = `REQUEST|scrape-title|${href}|`
await this.checkOpen()
this.ws.send(req)
}
updateLinkTitle = (title) => {
let link = document.querySelectorAll('.convert-to-title')[0]
if (title !=="") {
link.innerHTML += title;
} else {
link.innerHTML += link.getAttribute('href')
}
link.classList.remove('convert-to-title')
}
}
export default Connection

View File

@@ -0,0 +1,22 @@
import Connection from "./Connection.js";
export default class ConnectionHandler {
connection;
disabled = true;
constructor() {
this.connection = new Connection();
}
isOpen() {
if(this.connection.checkOpen()) {
return true;
} else {
return false;
}
}
send(msg) {
this.connection.sendMessage(msg)
}
}