forked from cory/tildefriends
apps: Add a very wip web app.
This commit is contained in:
85
apps/web/app.js
Normal file
85
apps/web/app.js
Normal file
@ -0,0 +1,85 @@
|
||||
let g_hash;
|
||||
|
||||
async function query(sql, params) {
|
||||
let results = [];
|
||||
await ssb.sqlAsync(sql, params, function(row) {
|
||||
results.push(row);
|
||||
});
|
||||
return results;
|
||||
}
|
||||
|
||||
async function resolve(id) {
|
||||
try {
|
||||
let blob = await ssb.blobGet(id);
|
||||
if (blob) {
|
||||
let json;
|
||||
try {
|
||||
json = JSON.parse(utf8Decode(blob));
|
||||
} catch {
|
||||
return {id: utf8Decode(blob)};
|
||||
}
|
||||
if (json?.links) {
|
||||
for (let [key, value] of Object.entries(json.links)) {
|
||||
json.links[key] = await resolve(value);
|
||||
}
|
||||
return json;
|
||||
} else {
|
||||
return 'huh?' + json;
|
||||
}
|
||||
} else {
|
||||
return `missing<${id}>`;
|
||||
}
|
||||
} catch (e) {
|
||||
return id + ': ' + e.message;
|
||||
}
|
||||
}
|
||||
|
||||
async function get_names(identities) {
|
||||
return Object.fromEntries((await query(`
|
||||
SELECT author, name FROM (
|
||||
SELECT
|
||||
messages.author,
|
||||
RANK() OVER (PARTITION BY messages.author ORDER BY messages.sequence DESC) AS author_rank,
|
||||
messages.content ->> 'name' AS name
|
||||
FROM messages
|
||||
JOIN json_each(?) AS identities ON identities.value = messages.author
|
||||
WHERE
|
||||
json_extract(messages.content, '$.type') = 'about' AND
|
||||
content ->> 'about' = messages.author AND name IS NOT NULL)
|
||||
WHERE author_rank = 1
|
||||
`, [JSON.stringify(identities)])).map(x => [x.author, x.name]));
|
||||
}
|
||||
|
||||
async function render(hash) {
|
||||
g_hash = hash;
|
||||
if (!hash) {
|
||||
let sites = (await query(`
|
||||
SELECT site.author, site.id
|
||||
FROM messages site
|
||||
WHERE site.content ->> 'type' = 'web-init'
|
||||
`, []));
|
||||
let names = await get_names(sites.map(x => x.author));
|
||||
if (hash === g_hash) {
|
||||
await app.setDocument(`<ul style="background-color: #ddd">${sites.map(x => `<li><a target="_top" href="#${encodeURIComponent(x.id)}">${names[x.author] ?? x.author} - ${x.id}</a></li>`).join('\n')}</ul>`);
|
||||
}
|
||||
} else {
|
||||
let site_id = hash.charAt(0) == '#' ? decodeURIComponent(hash.substring(1)) : decodeURIComponent(hash);
|
||||
await app.setDocument(`<html style="margin: 0; padding: 0; width: 100vw; height: 100vh; margin: 0; padding: 0">
|
||||
<body style="display: flex; flex-direction: column; width: 100vw; height: 100vh">
|
||||
<iframe src="${encodeURIComponent(site_id)}/index.html" style="flex: 1 1; border: 0; background-color: #fff"></iframe>
|
||||
</body>
|
||||
</html>`);
|
||||
}
|
||||
}
|
||||
|
||||
core.register('message', async function message_handler(message) {
|
||||
if (message.event == 'hashChange') {
|
||||
await render(message.hash);
|
||||
}
|
||||
});
|
||||
|
||||
async function main() {
|
||||
render(null);
|
||||
}
|
||||
|
||||
main();
|
Reference in New Issue
Block a user