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();
 |