All checks were successful
Build Tilde Friends / Build-All (push) Successful in 29m37s
101 lines
2.4 KiB
JavaScript
101 lines
2.4 KiB
JavaScript
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();
|