From 36969fa9f55c73f4ac5c5689967326a94e6a57c1 Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Wed, 22 Nov 2017 20:23:03 +0100 Subject: [PATCH 01/15] add basic remote behaviour to client scripts this commit adds the ability to read the sameAs attribute of portal.json portal.sameAs is an array of portal dat:// addresses that state that this portal is the same as those portals, and that we should load their messages under our name this makes it possible to effectively post to the same account from different machines note: port_1 needs to have port_2 in its sameAs array, and port_2 needs to have port_1 in its sameAs array, i.e. the relationship needs to be mutual --- scripts/feed.js | 3 ++- scripts/portal.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/scripts/feed.js b/scripts/feed.js index 73c5aca..1e1686a 100644 --- a/scripts/feed.js +++ b/scripts/feed.js @@ -138,7 +138,8 @@ function Feed(feed_urls) r.home.feed.next(); return; } - portal.connect() + // if everything went well loading the portal, let's try to load its remotes + portal.connect().then(portal.load_remotes) r.home.feed.update_log(); } diff --git a/scripts/portal.js b/scripts/portal.js index 3950d07..623310b 100644 --- a/scripts/portal.js +++ b/scripts/portal.js @@ -62,6 +62,38 @@ function Portal(url) setTimeout(r.home.feed.next, r.home.feed.connection_delay); } + this.load_remotes = async function() { + if (p.json && p.json.sameAs && p.json.sameAs.length > 0) { + // naive solution while testing + var remote_promises = p.json.sameAs.map((remote_url) => { + return new Promise((resolve, reject) => { + console.log("remote url", remote_url) + var remote = new Portal(remote_url) + remote.start().then(() => { + console.log("loaded remote") + if (remote.json.sameAs && remote.json.sameAs.indexOf(p.dat) >= 0) { + console.log(remote.dat + "has a mutual relationship w/ us :)") + // set remote name + remote.json.name = `${p.json.name} (${remote.json.name})` + // remote.url = p.url + r.home.feed.register(remote); + } else { + console.log(remote.dat + " wasn't a mutual with us :<") + } + }).then(resolve).catch((err) => { + console.error("something went wrong when loading remotes") + console.error(err) + reject() + }) + }) + }) + + Promise.all(remote_promises).then(() => { + console.log("all remotes have been handled?") + }) + } + } + this.discover = async function() { console.log('connecting to: ', p.url); From 23cd854016f680a6abeede4d5b2f56f55c38edb1 Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Wed, 22 Nov 2017 20:49:13 +0100 Subject: [PATCH 02/15] make it possible to replace a portal's icon this adds a bit of kludge to portal.js, but it was the simplest way i could see of making it possible to render the same icon for remotes as the source of the remotes --- scripts/entry.js | 2 +- scripts/portal.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/entry.js b/scripts/entry.js index eea6aca..1934eaf 100644 --- a/scripts/entry.js +++ b/scripts/entry.js @@ -102,7 +102,7 @@ function Entry(data,host) if (desc){ title += "\n" + desc; } - return ""; + return ""; } this.header = function() diff --git a/scripts/portal.js b/scripts/portal.js index 623310b..7da1209 100644 --- a/scripts/portal.js +++ b/scripts/portal.js @@ -4,6 +4,7 @@ function Portal(url) this.url = url; this.file = null; + this.icon = url + "/media/content/icon.svg" this.json = null; this.archive = new DatArchive(this.url); // Resolve "masked" (f.e. hashbase) dat URLs to "hashed" (dat://0123456789abcdef/) one. @@ -64,7 +65,6 @@ function Portal(url) this.load_remotes = async function() { if (p.json && p.json.sameAs && p.json.sameAs.length > 0) { - // naive solution while testing var remote_promises = p.json.sameAs.map((remote_url) => { return new Promise((resolve, reject) => { console.log("remote url", remote_url) @@ -75,7 +75,7 @@ function Portal(url) console.log(remote.dat + "has a mutual relationship w/ us :)") // set remote name remote.json.name = `${p.json.name} (${remote.json.name})` - // remote.url = p.url + remote.icon = p.url + "/media/content/icon.svg" r.home.feed.register(remote); } else { console.log(remote.dat + " wasn't a mutual with us :<") From e9779718fc1f8cb6ad07f17cd194036e346488f5 Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Wed, 22 Nov 2017 21:31:22 +0100 Subject: [PATCH 03/15] add icon to dummy_portal --- scripts/entry.js | 2 +- scripts/portal.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/entry.js b/scripts/entry.js index 1934eaf..f4366eb 100644 --- a/scripts/entry.js +++ b/scripts/entry.js @@ -27,7 +27,7 @@ function Entry(data,host) this.quote = data.quote; if(data.quote && this.target && this.target[0]){ - var dummy_portal = {"url":this.target[0],"json":{"name":r.escape_html(portal_from_hash(this.target[0].toString())).substring(1)}}; + var dummy_portal = {"url":this.target[0], "icon": this.target[0].replace(/\/$/, "") + "/media/content/icon.svg", "json":{"name":r.escape_html(portal_from_hash(this.target[0].toString())).substring(1)}}; this.quote = new Entry(data.quote, dummy_portal); } diff --git a/scripts/portal.js b/scripts/portal.js index 7da1209..888dd6c 100644 --- a/scripts/portal.js +++ b/scripts/portal.js @@ -3,8 +3,8 @@ function Portal(url) var p = this; this.url = url; + this.icon = url.replace(/\/$/, "") + "/media/content/icon.svg"; this.file = null; - this.icon = url + "/media/content/icon.svg" this.json = null; this.archive = new DatArchive(this.url); // Resolve "masked" (f.e. hashbase) dat URLs to "hashed" (dat://0123456789abcdef/) one. @@ -74,7 +74,7 @@ function Portal(url) if (remote.json.sameAs && remote.json.sameAs.indexOf(p.dat) >= 0) { console.log(remote.dat + "has a mutual relationship w/ us :)") // set remote name - remote.json.name = `${p.json.name} (${remote.json.name})` + remote.json.name = `${p.json.name}@${remote.json.name}` remote.icon = p.url + "/media/content/icon.svg" r.home.feed.register(remote); } else { @@ -89,7 +89,7 @@ function Portal(url) }) Promise.all(remote_promises).then(() => { - console.log("all remotes have been handled?") + console.log("all remotes appear to have been handled?") }) } } From 698079e524afad1d4ec62782fcd90754c0c186ae Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Thu, 23 Nov 2017 00:10:18 +0100 Subject: [PATCH 04/15] change rune for remotes --- scripts/portal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/portal.js b/scripts/portal.js index cbf9509..00d67dc 100644 --- a/scripts/portal.js +++ b/scripts/portal.js @@ -77,7 +77,7 @@ function Portal(url) if (remote.json.sameAs && remote.json.sameAs.indexOf(p.dat) >= 0) { console.log(remote.dat + "has a mutual relationship w/ us :)") // set remote name - remote.json.name = `${p.json.name}@${remote.json.name}` + remote.json.name = `${p.json.name}=${remote.json.name}` remote.icon = p.url + "/media/content/icon.svg" r.home.feed.register(remote); } else { From e5636613ca720d42e77a1d6732bcba3fcbf512f5 Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Thu, 23 Nov 2017 00:10:34 +0100 Subject: [PATCH 05/15] add mirror & unmirror to add/remove remotes --- scripts/operator.js | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/scripts/operator.js b/scripts/operator.js index 954fddb..ebeecb1 100644 --- a/scripts/operator.js +++ b/scripts/operator.js @@ -184,6 +184,50 @@ function Operator(el) r.home.feed.refresh("unfollowing: "+option); } + this.commands.mirror = function(p,option) + { + var remote = p; + if(remote.slice(-1) !== "/") { remote += "/" } + + for(id in r.home.portal.json.sameAs) { + var port_url = r.home.portal.json.sameAs[id]; + if(port_url.indexOf(remote) > -1){ + return; + } + } + r.home.portal.json.sameAs.push(remote); + r.home.feed.queue.push(remote); + r.home.feed.connect(); + r.home.save(); + } + + this.commands.unmirror = function(p,option) + { + var remote = p; + if(remote.slice(-1) !== "/") { remote += "/" } + + // Remove + if (r.home.portal.json.sameAs.indexOf(remote) > -1) { + r.home.portal.json.sameAs.splice(r.home.portal.json.sameAs.indexOf(remote), 1); + } else { + console.log("could not find",remote); + return; + } + + var portal = r.home.feed.get_portal(remote); + if (portal) { + r.home.feed.portals.splice(portal.id, 1)[0]; + for (var id in r.home.feed.portals) { + r.home.feed.portals[id].id = id; + } + portal.badge_remove(); + portal.entries_remove(); + } + + r.home.save(); + r.home.feed.refresh("unfollowing: "+option); + } + this.commands.dat = function(p,option) { option = to_hash(option); From 790f69aaf979490d2a0b78a89ebd803277fe9f9d Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Thu, 23 Nov 2017 13:37:34 +0100 Subject: [PATCH 06/15] improve robustness of attr check --- scripts/entry.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/entry.js b/scripts/entry.js index 529c662..c7ad1d5 100644 --- a/scripts/entry.js +++ b/scripts/entry.js @@ -29,8 +29,8 @@ function Entry(data,host) if(data.quote && this.target && this.target[0]){ var icon = this.target[0].replace(/\/$/, "") + "/media/content/icon.svg" // set the source's icon for quotes of remotes - if (host.json.sameAs && host.json.sameAs.indexOf(this.target[0]) >= 0) { - var icon = host.icon + if (host && host.json && host.json.sameAs && host.json.sameAs.indexOf(this.target[0]) >= 0) { + icon = host.icon } var dummy_portal = {"url":this.target[0], "icon": icon, "json":{"name":r.escape_html(portal_from_hash(this.target[0].toString())).substring(1)}}; this.quote = new Entry(data.quote, dummy_portal); From 7eb43558d4d1fcbcada10ff90dffc1e91ce68b82 Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Thu, 23 Nov 2017 14:01:40 +0100 Subject: [PATCH 07/15] fix issue with remote names being reset --- scripts/operator.js | 2 ++ scripts/portal.js | 27 +++++++++++++++++---------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/scripts/operator.js b/scripts/operator.js index ebeecb1..69d5598 100644 --- a/scripts/operator.js +++ b/scripts/operator.js @@ -195,6 +195,8 @@ function Operator(el) return; } } + // create the array if it doesn't exist + if (!r.home.portal.json.sameAs) { r.home.portal.json.sameAs = [] } r.home.portal.json.sameAs.push(remote); r.home.feed.queue.push(remote); r.home.feed.connect(); diff --git a/scripts/portal.js b/scripts/portal.js index 00d67dc..632c57c 100644 --- a/scripts/portal.js +++ b/scripts/portal.js @@ -9,6 +9,7 @@ function Portal(url) } this.file = null; this.json = null; + this.is_remove = false; this.archive = new DatArchive(this.url); // Resolve "masked" (f.e. hashbase) dat URLs to "hashed" (dat://0123456789abcdef/) one. DatArchive.resolveName(this.url).then(hash => { @@ -70,23 +71,24 @@ function Portal(url) if (p.json && p.json.sameAs && p.json.sameAs.length > 0) { var remote_promises = p.json.sameAs.map((remote_url) => { return new Promise((resolve, reject) => { - console.log("remote url", remote_url) - var remote = new Portal(remote_url) + console.log("remote url", remote_url); + var remote = new Portal(remote_url); + remote.is_remote = true; remote.start().then(() => { console.log("loaded remote") - if (remote.json.sameAs && remote.json.sameAs.indexOf(p.dat) >= 0) { - console.log(remote.dat + "has a mutual relationship w/ us :)") + if (remote.json && remote.json.sameAs && remote.json.sameAs.indexOf(p.dat) >= 0) { + console.log(remote.dat + "has a mutual relationship w/ us :)"); // set remote name - remote.json.name = `${p.json.name}=${remote.json.name}` - remote.icon = p.url + "/media/content/icon.svg" + remote.json.name = `${p.json.name}=${remote.json.name}`; + remote.icon = p.url + "/media/content/icon.svg"; r.home.feed.register(remote); } else { - console.log(remote.dat + " wasn't a mutual with us :<") + console.log(remote.dat + " wasn't a mutual with us :<"); } }).then(resolve).catch((err) => { - console.error("something went wrong when loading remotes") - console.error(err) - reject() + console.error("something went wrong when loading remotes"); + console.error(err); + reject(); }) }) }) @@ -159,7 +161,12 @@ function Portal(url) } try { + var oldName = p.json.name; p.json = JSON.parse(p.file); + // don't replace name for remotes + if (p.is_remote) { + p.json.name = oldName; + } p.file = null; } catch (err) { console.log('parsing failed: ', p.url); From 63c0e0487f3c2bc4cd7eade817b54d9bbbfc7c50 Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Thu, 23 Nov 2017 14:01:53 +0100 Subject: [PATCH 08/15] improve behaviour when adding remotes --- scripts/operator.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/operator.js b/scripts/operator.js index 69d5598..80314f3 100644 --- a/scripts/operator.js +++ b/scripts/operator.js @@ -198,8 +198,12 @@ function Operator(el) // create the array if it doesn't exist if (!r.home.portal.json.sameAs) { r.home.portal.json.sameAs = [] } r.home.portal.json.sameAs.push(remote); - r.home.feed.queue.push(remote); - r.home.feed.connect(); + try { + var remote_portal = new Portal(remote) + remote_portal.start().then(r.home.portal.load_remotes) + } catch (err) { + console.error("Error when connecting to remote", err) + } r.home.save(); } From 128c266e7f71922673ff5b8e9d5155e4f0afbd9a Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Thu, 23 Nov 2017 14:26:29 +0100 Subject: [PATCH 09/15] make mentions work with sameAs --- scripts/entry.js | 13 +++++++++++-- scripts/feed.js | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/scripts/entry.js b/scripts/entry.js index c7ad1d5..e2a4cde 100644 --- a/scripts/entry.js +++ b/scripts/entry.js @@ -484,9 +484,18 @@ function Entry(data,host) } if(this.target && this.target.length > 0){ - return has_hash(r.home.portal, this.target); + var has_mention = false; + var ports = [r.home.portal.dat]; + if (r.home.portal.json && r.home.portal.json.sameAs) { + ports = ports.concat(r.home.portal.json.sameAs); + } + ports.forEach((port) => { + this.target.forEach((t) => { + has_mention = has_mention || t === port; + }) + }) + return has_mention; } - return false; } diff --git a/scripts/feed.js b/scripts/feed.js index d109698..f5f076e 100644 --- a/scripts/feed.js +++ b/scripts/feed.js @@ -152,7 +152,7 @@ function Feed(feed_urls) return; } // if everything went well loading the portal, let's try to load its remotes - portal.connect().then(portal.load_remotes) + portal.connect().then(portal.load_remotes); r.home.feed.update_log(); } From e758a8f58cb12037db6de67ca3365258aaa9edea Mon Sep 17 00:00:00 2001 From: Maik Macho Date: Thu, 23 Nov 2017 15:16:08 +0100 Subject: [PATCH 10/15] Add very basic "event" handling in Portal.js; Build sameAs on it --- scripts/entry.js | 8 ++--- scripts/feed.js | 30 +++++++++++++---- scripts/operator.js | 27 ++++++++------- scripts/portal.js | 80 ++++++++++++++++++++++++++++----------------- 4 files changed, 90 insertions(+), 55 deletions(-) diff --git a/scripts/entry.js b/scripts/entry.js index e2a4cde..5719a2f 100644 --- a/scripts/entry.js +++ b/scripts/entry.js @@ -29,14 +29,14 @@ function Entry(data,host) if(data.quote && this.target && this.target[0]){ var icon = this.target[0].replace(/\/$/, "") + "/media/content/icon.svg" // set the source's icon for quotes of remotes - if (host && host.json && host.json.sameAs && host.json.sameAs.indexOf(this.target[0]) >= 0) { + if (host && host.json && host.json.sameAs && has_hash(host.json.sameAs, this.target[0])) { icon = host.icon } var dummy_portal = {"url":this.target[0], "icon": icon, "json":{"name":r.escape_html(portal_from_hash(this.target[0].toString())).substring(1)}}; this.quote = new Entry(data.quote, dummy_portal); } - this.is_seed = this.host ? r.home.portal.json.port.indexOf(this.host.url) > -1 : false; + this.is_seed = this.host && has_hash(r.home.portal.json.port, this.host.url); } this.update(data, host); @@ -363,8 +363,8 @@ function Entry(data,host) space = m.length; var word = m.substring(c, space); - if (word.length > 1 && word[0] == "@") { - var name_match = r.operator.name_pattern.exec(word); + var name_match; + if (word.length > 1 && word[0] == "@" && (name_match = r.operator.name_pattern.exec(word))) { var remnants = word.substr(name_match[0].length); if (name_match[1] == r.home.portal.json.name) { n += ""+name_match[0]+""+remnants; diff --git a/scripts/feed.js b/scripts/feed.js index f5f076e..696a35f 100644 --- a/scripts/feed.js +++ b/scripts/feed.js @@ -139,7 +139,11 @@ function Feed(feed_urls) return; } - var url = r.home.feed.queue[0]; + var entry = r.home.feed.queue[0]; + var url = entry; + if (entry.url) { + url = entry.url; + } r.home.feed.queue = r.home.feed.queue.slice(1); @@ -151,8 +155,12 @@ function Feed(feed_urls) r.home.feed.next(); return; } - // if everything went well loading the portal, let's try to load its remotes - portal.connect().then(portal.load_remotes); + + if (entry.oncreate) + portal.fire(entry.oncreate); + if (entry.onparse) + portal.onparse.push(entry.onparse); + portal.connect(); r.home.feed.update_log(); } @@ -178,6 +186,10 @@ function Feed(feed_urls) this.__get_portal_cache__[hashes[id]] = portal; } + if (!portal.is_remote) { + portal.load_remotes(); + } + // Invalidate the collected network cache and recollect. r.home.collect_network(true); @@ -263,6 +275,8 @@ function Feed(feed_urls)         var portal = r.home.feed.portals[id];         await portal.refresh();       } + if (r.home.feed.portal_rotonde) + await r.home.feed.portal_rotonde.connect_service();       r.home.feed.refresh('delayed: ' + why);     }, 750);      return; @@ -284,7 +298,9 @@ function Feed(feed_urls) var portal = r.home.feed.portals[id]; entries.push.apply(entries, portal.entries()); } - + if (r.home.feed.portal_rotonde) + entries.push.apply(entries, r.home.feed.portal_rotonde.entries()); + this.mentions = 0; this.whispers = 0; @@ -320,7 +336,7 @@ function Feed(feed_urls) } var now = new Date(); - var entries_now = new Set(); + var entries_now = []; for (id in sorted_entries){ var entry = sorted_entries[id]; @@ -339,7 +355,7 @@ function Feed(feed_urls) c = -2; var elem = !entry ? null : entry.to_element(timeline, c, cmin, cmax, coffset); if (elem != null) { - entries_now.add(entry); + entries_now.push(entry); } if (c >= 0) ca++; @@ -348,7 +364,7 @@ function Feed(feed_urls) // Remove any "zombie" entries - removed entries not belonging to any portal. for (id in this.entries_prev) { var entry = this.entries_prev[id]; - if (entries_now.has(entry)) + if (entries_now.indexOf(entry) > -1) continue; entry.remove_element(); } diff --git a/scripts/operator.js b/scripts/operator.js index 80314f3..3981aba 100644 --- a/scripts/operator.js +++ b/scripts/operator.js @@ -163,9 +163,6 @@ function Operator(el) if(r.home.portal.json.port.indexOf(path) > -1){ r.home.portal.json.port.splice(r.home.portal.json.port.indexOf(path), 1); } - else if(r.home.portal.json.port.indexOf(path+"/") > -1){ - r.home.portal.json.port.splice(r.home.portal.json.port.indexOf(path+"/"), 1); - } else{ console.log("could not find",path) } @@ -177,7 +174,6 @@ function Operator(el) r.home.feed.portals[id].id = id; } portal.badge_remove(); - portal.entries_remove(); } r.home.save(); @@ -189,12 +185,12 @@ function Operator(el) var remote = p; if(remote.slice(-1) !== "/") { remote += "/" } - for(id in r.home.portal.json.sameAs) { - var port_url = r.home.portal.json.sameAs[id]; - if(port_url.indexOf(remote) > -1){ - return; - } - } + if (!r.home.portal.json.sameAs) + r.home.portal.json.sameAs = []; + + if (has_hash(r.home.portal.json.sameAs, remote)) + return; + // create the array if it doesn't exist if (!r.home.portal.json.sameAs) { r.home.portal.json.sameAs = [] } r.home.portal.json.sameAs.push(remote); @@ -212,6 +208,9 @@ function Operator(el) var remote = p; if(remote.slice(-1) !== "/") { remote += "/" } + if (!r.home.portal.json.sameAs) + r.home.portal.json.sameAs = []; + // Remove if (r.home.portal.json.sameAs.indexOf(remote) > -1) { r.home.portal.json.sameAs.splice(r.home.portal.json.sameAs.indexOf(remote), 1); @@ -221,17 +220,15 @@ function Operator(el) } var portal = r.home.feed.get_portal(remote); - if (portal) { + if (portal && portal.is_remote) { r.home.feed.portals.splice(portal.id, 1)[0]; for (var id in r.home.feed.portals) { r.home.feed.portals[id].id = id; } - portal.badge_remove(); - portal.entries_remove(); } r.home.save(); - r.home.feed.refresh("unfollowing: "+option); + r.home.feed.refresh("mirroring: "+option); } this.commands.dat = function(p,option) @@ -674,6 +671,8 @@ function Operator(el) this.lookup_name = function(name) { + if (r.home.feed.portal_rotonde && name === r.home.feed.portal_rotonde.json.name) + return [r.home.feed.portal_rotonde]; // We return an array since multiple people might be using the same name. var results = []; for(var url in r.home.feed.portals){ diff --git a/scripts/portal.js b/scripts/portal.js index 632c57c..a32a9fb 100644 --- a/scripts/portal.js +++ b/scripts/portal.js @@ -17,16 +17,43 @@ function Portal(url) this.dat = "dat://"+hash+"/"; }); + this.is_remote = false; + this.remote_parent = null; + this.last_entry = null; this.badge_element = null; this.badge_element_html = null; + this.onparse = []; // Contains functions of format json => {...} + this.fire = function(event) { + var handlers; + if (typeof(event) === "function") + handlers = [event]; + else if (event.length && typeof(event[0]) === "function") + handlers = event; + else + handlers = this["on"+event]; + if (!handlers || handlers.length === 0) return true; // Return true by default. + var args = Array.prototype.splice.call(arguments, 1); + for (var id in handlers) { + var result = handlers[id].apply(this, args); + if (result === true) // We only want true, not truly values. + continue; // If the handler returned true, continue to the next handler. + else if (result === false) // We only want false, not falsy values. + return false; // Exit early. + else if (result !== undefined) + return result; // If the handler returned something, return it early. + } + return true; + } + this.start = async function() { var file = await this.archive.readFile('/portal.json',{timeout: 2000}).then(console.log("done!")); this.json = JSON.parse(file); + if (!this.fire("parse", this.json)) throw new Error("onparse returned false!"); this.maintenance(); } @@ -58,6 +85,7 @@ function Portal(url) try { p.json = JSON.parse(p.file); + if (!p.fire("parse", p.json)) throw new Error("onparse returned false!"); p.file = null; r.home.feed.register(p); } catch (err) { @@ -68,35 +96,25 @@ function Portal(url) } this.load_remotes = async function() { - if (p.json && p.json.sameAs && p.json.sameAs.length > 0) { - var remote_promises = p.json.sameAs.map((remote_url) => { - return new Promise((resolve, reject) => { - console.log("remote url", remote_url); - var remote = new Portal(remote_url); - remote.is_remote = true; - remote.start().then(() => { - console.log("loaded remote") - if (remote.json && remote.json.sameAs && remote.json.sameAs.indexOf(p.dat) >= 0) { - console.log(remote.dat + "has a mutual relationship w/ us :)"); - // set remote name - remote.json.name = `${p.json.name}=${remote.json.name}`; - remote.icon = p.url + "/media/content/icon.svg"; - r.home.feed.register(remote); - } else { - console.log(remote.dat + " wasn't a mutual with us :<"); - } - }).then(resolve).catch((err) => { - console.error("something went wrong when loading remotes"); - console.error(err); - reject(); - }) - }) - }) - - Promise.all(remote_promises).then(() => { - console.log("all remotes appear to have been handled?") - }) + if (!p.json || !p.json.sameAs || p.json.sameAs.length === 0) { + return; } + + r.home.feed.queue.push.apply(r.home.feed.queue, p.json.sameAs.map((remote_url) => { + return { + url: remote_url, + oncreate: function() { + this.is_remote = true; + this.remote_parent = p; + this.icon = p.url + "/media/content/icon.svg"; + }, + onparse: function(json) { + this.json.name = `${p.json.name}=${json.name}` + return this.json.sameAs && has_hash(this.json.sameAs, p.hashes()); + } + } + })); + r.home.feed.connect(); } this.connect_service = async function() @@ -113,8 +131,9 @@ function Portal(url) try { p.json = JSON.parse(p.file); + if (!p.fire("parse", p.json)) throw new Error("onparse returned false!"); p.file = null; - r.home.feed.portals.push(r.home.feed.portal_rotonde = this); + r.home.feed.portal_rotonde = this; } catch (err) { console.log('parsing failed: ', p.url); } @@ -134,6 +153,7 @@ function Portal(url) try { p.json = JSON.parse(p.file); + if (!p.fire("parse", p.json)) throw new Error("onparse returned false!"); p.file = null; } catch (err) { console.log('parsing failed: ', p.url); @@ -210,7 +230,7 @@ function Portal(url) this.relationship = function(target = r.home.portal.hashes_set()) { - if (this === r.home.feed.portal_rotonde) return create_rune("portal", "rotonde"); + if (this.url === r.client_url) return create_rune("portal", "rotonde"); if (has_hash(this, target)) return create_rune("portal", "self"); if (has_hash(this.json.port, target)) return create_rune("portal", "both"); From 9dae054b10c3f4755652435f97d042b5352a9ce4 Mon Sep 17 00:00:00 2001 From: Maik Macho Date: Thu, 23 Nov 2017 15:29:21 +0100 Subject: [PATCH 11/15] Fix quoting from portals with - in name --- scripts/operator.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/scripts/operator.js b/scripts/operator.js index 3981aba..520a870 100644 --- a/scripts/operator.js +++ b/scripts/operator.js @@ -270,8 +270,7 @@ function Operator(el) this.commands.quote = function(p,option) { var message = p; - var name = option.split("-")[0]; - var ref = parseInt(option.split("-")[1]); + var {name, ref} = r.operator.split_nameref(option); var portals = r.operator.lookup_name(name); @@ -409,8 +408,7 @@ function Operator(el) this.commands.expand = function(p, option) { - var name = option.split("-")[0]; - var ref = parseInt(option.split("-")[1]); + var {name, ref} = r.operator.split_nameref(option); var portals = r.operator.lookup_name(name); @@ -424,8 +422,7 @@ function Operator(el) this.commands.collapse = function(p, option) { - var name = option.split("-")[0]; - var ref = parseInt(option.split("-")[1]); + var {name, ref} = r.operator.split_nameref(option); var portals = r.operator.lookup_name(name); @@ -444,8 +441,7 @@ function Operator(el) return; } - var name = option.split("-")[0]; - var ref = parseInt(option.split("-")[1]); + var {name, ref} = r.operator.split_nameref(option); var portals = r.operator.lookup_name(name); @@ -681,6 +677,13 @@ function Operator(el) } return results; } + + this.split_nameref = function(option) + { + var index = option.lastIndexOf("-"); + if (index < 0) return; + return { name: option.substring(0, index), ref: parseInt(option.substring(index + 1)) }; + } } r.confirm("script","operator"); From f49b5fe4a7d38e29d40bc3f165771ed68bf0c56b Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Thu, 23 Nov 2017 19:10:54 +0100 Subject: [PATCH 12/15] improve mention detection code, thx 0ade! --- scripts/entry.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/scripts/entry.js b/scripts/entry.js index 5719a2f..c1b0139 100644 --- a/scripts/entry.js +++ b/scripts/entry.js @@ -483,17 +483,12 @@ function Entry(data,host) return true; } - if(this.target && this.target.length > 0){ - var has_mention = false; - var ports = [r.home.portal.dat]; + // check for mentions of our portal or of one of our remotes in sameAs + if (this.target && this.target.length > 0) { + var has_mention = has_hash(r.home.portal, this.target); if (r.home.portal.json && r.home.portal.json.sameAs) { - ports = ports.concat(r.home.portal.json.sameAs); + has_mention = has_mention || has_hash(r.home.portal.json.sameAs, this.target); } - ports.forEach((port) => { - this.target.forEach((t) => { - has_mention = has_mention || t === port; - }) - }) return has_mention; } return false; From 71f855f04b7263267aff47a085ba808c9029263c Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Thu, 23 Nov 2017 20:05:25 +0100 Subject: [PATCH 13/15] show the same feed as your remotes for each portal in sameAs, we add their list of ports to our feed --- scripts/portal.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/scripts/portal.js b/scripts/portal.js index a32a9fb..5cadb87 100644 --- a/scripts/portal.js +++ b/scripts/portal.js @@ -110,6 +110,14 @@ function Portal(url) }, onparse: function(json) { this.json.name = `${p.json.name}=${json.name}` + if (has_hash(r.home.portal, this.remote_parent)) { + Array.prototype.push.apply(r.home.feed.queue, this.json.port.map((port) => { + return { + url: port, + onparse: function() { return true} + } + })) + } return this.json.sameAs && has_hash(this.json.sameAs, p.hashes()); } } From 3ecbe05cbb216691c0c218ea8ab9cb293a822b89 Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Thu, 23 Nov 2017 20:57:25 +0100 Subject: [PATCH 14/15] use hashes() instead --- scripts/portal.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/portal.js b/scripts/portal.js index 5cadb87..91ca78a 100644 --- a/scripts/portal.js +++ b/scripts/portal.js @@ -106,7 +106,8 @@ function Portal(url) oncreate: function() { this.is_remote = true; this.remote_parent = p; - this.icon = p.url + "/media/content/icon.svg"; + var hash = p.hashes()[0] + this.icon = "dat://" + hash + "/media/content/icon.svg"; }, onparse: function(json) { this.json.name = `${p.json.name}=${json.name}` From a9be6a1a15cd96cd9d5128a5ec5141c0c6a36247 Mon Sep 17 00:00:00 2001 From: Alexander Cobleigh Date: Thu, 23 Nov 2017 21:28:30 +0100 Subject: [PATCH 15/15] fix bug from converting to new evt system has_hash should maybe have some harder checks, what happened was this.json.sameAs didn't exist but has_hash still went through (kinda strange) and so the resulting bool wasn't a bool, but undefined! --- scripts/portal.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/portal.js b/scripts/portal.js index 91ca78a..f278227 100644 --- a/scripts/portal.js +++ b/scripts/portal.js @@ -119,7 +119,10 @@ function Portal(url) } })) } - return this.json.sameAs && has_hash(this.json.sameAs, p.hashes()); + if (this.json && this.json.sameAs) { + return has_hash(this.json.sameAs, p.hashes()); + } + return false } } }));