From e065914a6fea70c25e117d8aaca466b59bcad5c6 Mon Sep 17 00:00:00 2001 From: s-ol Date: Thu, 13 Jan 2022 17:25:07 +0100 Subject: Menu, DiscDAG loading --- src/index.js | 309 ++++++++++++++--------------------------------------------- 1 file changed, 73 insertions(+), 236 deletions(-) (limited to 'src/index.js') diff --git a/src/index.js b/src/index.js index 8cad259..a30dbf1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,208 +1,9 @@ import 'preact/debug'; import 'core-js/stable'; import 'regenerator-runtime/runtime'; -import * as jsonld from 'jsonld'; import { h, Fragment, Component, render } from 'preact'; -import { Discussion, Selection } from './ui'; - -const context = [ - 'https://www.w3.org/ns/activitystreams', - { - replies: { '@id': 'as:replies', '@container': '@set' }, - inReplyTo: { '@id': 'as:inReplyTo', '@container': '@set' }, - }, -]; - - -const corsPrefix = process.env.CORS_PREFIX || `${location.origin}/remote`; -console.log(corsPrefix); -const cors = (url) => `${corsPrefix}/${url}`; - -function wrapCache(target) { - const orig = target.descriptor.value; - - target.descriptor.value = function (id, ...args) { - this.cache[id] ||= orig.call(this, id, ...args); - return this.cache[id]; - }; - - return target; -}; - -class GraphContainer extends Component { - state = { - name: "loading…", - items: {}, - error: null, - }; - - cache = {}; - - constructor(props) { - super(props); - - if (this.props.graph.startsWith('http')) - this.loadDataMastodon(this.props.graph) - .catch(error => { - console.error(`Error loading Mastodon graph ${this.props.graph}:`, error); - this.setState({ - name: "error loading", - error, - }); - }); - else - this.loadData(this.props.graph) - .catch(error => { - console.error("Error loading default graph:", error); - this.setState({ - name: "error loading", - error, - }); - }); - } - - @wrapCache - async loadCollection(id, ...args) { - const collection = await jsonld.compact(cors(id), context); - let items = []; - - const addItems = (i) => { - if (Array.isArray(i)) - items = items.concat(i); - else if (i) - items.push(i); - }; - - // discover items - if (collection.items) { - addItems(collection.items); - } else { - let page = collection.first; - const seen = []; - while (page && seen.indexOf(page.id) < 0) { - seen.push(page.id); - addItems(page.items); - - page = page.next && await jsonld.compact(cors(page.next), context); - } - } - - // dereference items - return await Promise.all(items.map(item => this.loadNote(item.id ?? item, ...args))); - } - - @wrapCache - async loadNote(id, items, inReplyTo) { - let item; - try { - item = await jsonld.frame( - cors(id), - { - '@context': context, - type: 'Note', - context: { '@embed': '@never' }, - replies: { '@embed': '@always' }, - inReplyTo: { '@embed': '@never' }, - }, - { omitGraph: true } - ); - - if (item.replies.length) - item.replies = await this.loadCollection(item.replies[0].id, items, [id]); - } catch (error) { - console.error(`Error loading note '${id}':`, error); - item = { - '@context': context, - id, - type: 'Tombstone', - formerType: 'Note', - attributedTo: 'https://dag.s-ol.nu/users/unknown', - published: '1970-01-01T00:00:00Z', - content: `Error loading note: ${error.toString()}`, - replies: [], - inReplyTo, - }; - } - - item.attributedTo = await this.loadUser(item.attributedTo); - items[item.id] = item; - return item; - } - - async loadDataMastodon(url) { - const items = {}; - const root = await this.loadNote(url, items, []); - - this.setState({ - name: root.name || root.content, - items, - }); - } - - async loadData(url) { - const response = await fetch(url, { - headers: { 'Accept': 'application/json' }, - }); - const discussion = await jsonld.frame( - await response.json(), - { - '@context': context, - type: 'Document', - first: { '@embed': '@never' }, - items: { - context: { '@embed': '@never' }, - replies: { '@embed': '@never' }, - inReplyTo: { '@embed': '@never' }, - attributedTo: { '@embed': '@always' }, - }, - }, - { omitGraph: true } - ); - - const indexedItems = {}; - await Promise.all(discussion.items.map(async (item) => { - item.attributedTo = await this.loadUser(item.attributedTo); - indexedItems[item.id] = item; - })); - - discussion.items = indexedItems; - - this.setState(discussion); - } - - @wrapCache - async loadUser(id) { - if (id === "https://dag.s-ol.nu/users/unknown") { - return { - '@context': context, - id, - type: 'Person', - name: 'unknown', - summary: 'unknown user', - }; - } - - try { - const user = await jsonld.compact(id, context); - user.id = id; - return user; - } catch (error) { - console.error(`Error loading user '${id}':`, error); - return { - '@context': context, - id, - type: 'Person', - name: id, - summary: 'failed to load user information', - }; - } - } - - render() { - window.state = this.state; - return this.props.render(this.state); - } -} +import { GraphContainerJSONLD, GraphContainerMastodon } from './graph'; +import { Menu, Discussion, Selection } from './ui'; class SelectionContainer extends Component { state = { @@ -280,46 +81,82 @@ class CollapseContainer extends Component { } } -const search = new URLSearchParams(window.location.search); -const graph = search.has('graph') ? search.get('graph') : 'lib/graph.json'; -const app = ( - { - if (error) { - return ( -
-

{name}

+const graphRender = ({ loading, error, name, items }) => { + if (loading) { + return ( +
+
loading...
+
+ ); + } + + if (error) { + return ( +
+

error loading

+

{error.toString()}

 						
 							{error.stack}
 						
 					
-
- ); - } - - return ( - ( - <> - ( - - )} - /> - items[id])} - toggleSelected={toggleSelected} - /> - - )} /> + +
); - }} /> -); + } + + return ( + ( + <> + ( + + )} + /> + items[id])} + toggleSelected={toggleSelected} + /> + + )} /> + ); +}; + +const search = new URLSearchParams(window.location.search); +const graph = search.has('graph') ? search.get('graph') : 'lib/graph.json'; + +let app; +if (search.has('document')) { + app = ( + + ); +} else if (search.has('note')) { + app = ( + + ); +} else if (search.has('graph')) { + app = ( + + ); +} else { + app = ; +} + render(app, document.body); -- cgit v1.2.3