From a08dbede23af9c978acec3b3d864e48f7999741b Mon Sep 17 00:00:00 2001 From: s-ol Date: Wed, 27 Jan 2021 12:17:09 +0100 Subject: use jsonld framing, add discussion title --- src/graph.json | 5 +++- src/index.js | 93 +++++++++++++++++++++++++++++++++++----------------------- src/layout.js | 4 +-- src/ui.js | 2 ++ 4 files changed, 65 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/graph.json b/src/graph.json index dab6b4e..5c3fcbf 100644 --- a/src/graph.json +++ b/src/graph.json @@ -1,6 +1,9 @@ { "@context": "https://www.w3.org/ns/activitystreams", - "@graph": [ + "id": "https://dag.s-ol.nu/discussions/1", + "type": "Document", + "name": "DiscDAG's Future", + "items": [ { "id": "https://dag.s-ol.nu/users/ColinWright/notes/20200510151146a", "type": "Note", diff --git a/src/index.js b/src/index.js index 8b3cc16..911099c 100644 --- a/src/index.js +++ b/src/index.js @@ -5,18 +5,43 @@ import * as dom from './dom'; import * as layout from './layout'; import { Note } from './ui'; +window.jsonld = jsonld; + dom.css` -article { +.graph { position: relative; } -`; -const article = document.createElement('article'); -const canvas = document.createElement('canvas'); -article.appendChild(canvas); -document.body.appendChild(article); +#nodes { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} +`; -const context = 'https://www.w3.org/ns/activitystreams'; +document.body.appendChild( +
+

loading...

+
+ +
+
+
+); + +const title = document.getElementById('title'); +const canvas = document.getElementById('links'); +const nodes = document.getElementById('nodes'); + +const context = [ + 'https://www.w3.org/ns/activitystreams', + { + replies: { '@id': 'as:replies', '@container': '@set' }, + inReplyTo: { '@id': 'as:inReplyTo', '@container': '@set' }, + }, +]; const userCache = {}; const loadUser = async (id) => { @@ -32,38 +57,33 @@ const loadUser = async (id) => { const loadData = async () => { const raw = await require('./graph.json'); - const data = await (jsonld.compact(await jsonld.flatten(raw), context)); - - const indexedData = {}; - - await Promise.all(data['@graph'].map(async (entry) => { - if (entry.type !== 'Note' && entry.formerType !== 'Note') { - console.info(`entry ${entry.id} is a ${entry.type}`); - return; - } - - if (!entry.replies) entry.replies = []; - if (!Array.isArray(entry.replies)) - entry.replies = [ entry.replies ]; - - if (!entry.inReplyTo) entry.inReplyTo = []; - if (!Array.isArray(entry.inReplyTo)) - entry.inReplyTo = [ entry.inReplyTo ]; - - entry.attributedTo = await loadUser(entry.attributedTo); + const data = await jsonld.frame( + raw, + { + '@context': context, + type: 'Document', + items: { + context: { '@embed': '@never' }, + replies: { '@embed': '@never' }, + inReplyTo: { '@embed': '@never' }, + }, + }, + { omitGraph: true } + ); - indexedData[entry.id] = entry; + await Promise.all(data.items.map(async (item) => { + item.attributedTo = await loadUser(item.attributedTo); })); - return indexedData; + return data; }; -const createNotes = (graph, indexedData) => { - for (const data of Object.values(indexedData)) { +const createNotes = (graph, discussion) => { + for (const data of Object.values(discussion.items)) { if (data.id in graph) continue; - const onlyParent = data.inReplyTo.length === 1 && indexedData[data.inReplyTo[0]]; + const onlyParent = data.inReplyTo.length === 1 && discussion.items[data.inReplyTo[0].id]; const dom = ( { } /> ); - article.appendChild(dom); + nodes.appendChild(dom); graph[data.id] = { dom, data }; } @@ -101,17 +121,18 @@ const layoutNodes = async (graph) => { }; const update = async (graph) => { - const indexedData = await loadData(); - window.dagData = indexedData; + const discussion = await loadData(); + window.dagData = discussion; + title.textContent = discussion.name; - createNotes(graph, indexedData); + createNotes(graph, discussion); await layoutNodes(graph); }; const scrollToRoot = (graph) => { for (const node of Object.values(graph)) { if (node.data.inReplyTo.length === 0) { - node.dom.scrollIntoView(); + node.dom.scrollIntoView({ block: 'nearest', inline: 'nearest' }); return; } } diff --git a/src/layout.js b/src/layout.js index 95237c5..788edca 100644 --- a/src/layout.js +++ b/src/layout.js @@ -10,8 +10,8 @@ export const addNode = (dot, node) => { const id = node.data.id; dot += ` "${id}" [fixedsize=true; width=${node.dom.offsetWidth / 72}; height=${node.dom.offsetHeight / 72}];\n`; - for (const replyId of node.data.replies || []) - dot += ` "${id}" -> "${replyId}";\n`; + for (const reply of node.data.replies) + dot += ` "${id}" -> "${reply.id}";\n`; return dot; }; diff --git a/src/ui.js b/src/ui.js index 32ac5f9..6b54da9 100644 --- a/src/ui.js +++ b/src/ui.js @@ -5,6 +5,7 @@ import * as dom from './dom'; dom.css` body { --theme-backdrop: #1e1e1e; + --theme-fg: #eeeeee; --theme-note-bg: #eeeeee; --theme-note-fg: #363636; --theme-header-fg: #121212; @@ -18,6 +19,7 @@ body.darktheme { } body { + color: var(--theme-fg); background: var(--theme-backdrop); font-family: sans-serif; font-size: 11px; -- cgit v1.2.3