I made it work like this:
function js.func(args, body)
-- load a js module inline that exposes an asycn function constructor
local constructFunc = js.import([[data:text/javascript,
export const funcConstructor = (args, body) => new (async () => {}).constructor(args, body);
]]).funcConstructor
-- construct the function with the specified argument list and body
return constructFunc(args, body)
end
function js.run(code)
return js.func("", code)()
end
-- Evaluate a JavaScript expression
function js.expr(code)
return js.run("return (" .. code .. ")")
end
function currentGpsCoords()
return js.run([[
const getPos = () => new Promise((resolve, reject) =>
navigator.geolocation.getCurrentPosition(resolve, reject, { timeout: 3_000 }));
const { coords } = await getPos();
return [coords.latitude, coords.longitude];
]])
end
function gspCoordsToNiceString(coords)
return js.expr([[(coords) => {
// copied from: https://stackoverflow.com/questions/5786025/decimal-degrees-to-degrees-minutes-and-seconds-in-javascript#5786281
function convertDDToDMS(D, lng) {
return {
dir: D < 0 ? (lng ? "W" : "S") : lng ? "E" : "N",
deg: 0 | (D < 0 ? (D = -D) : D),
min: 0 | (((D += 1e-9) % 1) * 60),
sec: (0 | (((D * 60) % 1) * 6000)) / 100,
};
}
function convertDDToDMSString(D, lng) {
const obj = convertDDToDMS(D, lng);
return `${obj.deg}° ${obj.min}' ${obj.sec}" ${obj.dir}`
}
return coords.map((coord, i) => convertDDToDMSString(coord, i === 1)).join(" ");
}]])(coords)
end
slashCommand.define {
name = "gps",
run = function()
editor.insertAtCursor(gspCoordsToNiceString(currentGpsCoords()) .. "|^|", false, true)
end
}
slashCommand.define {
name = "gpsAttr",
run = function()
editor.insertAtCursor("[gps: [" .. table.concat(currentGpsCoords(), ", ") .. "]]|^|", false, true)
end
}
By using an async function in JavaScript and awaiting the result of getCurrentPosition within this function it can return the current position (so there is no callback in lua necessary), which fixes the issue with this other attempt, however I also get the same error for chromium on desktop, on a smartphone it works for me. On the other hand I have not yet experienced the issue of the client becoming unresponsive.
Here an example for a Page Template:
---
description: "Creates a note for the current gps position"
tags: meta/template/page
suggestedName: "Inbox/${table.concat(currentGpsCoords(), ', '):gsub('%.', '_')}"
confirmName: false
openIfExists: true
command: "Note for GPS Position"
frontmatter: "gps: [${table.concat(currentGpsCoords(), ', ')}]"
---
create at: ${gspCoordsToNiceString(currentGpsCoords())}
|^|