diff --git a/apps/cory/docs.json b/apps/cory/docs.json index 42ec69e6..12275138 100644 --- a/apps/cory/docs.json +++ b/apps/cory/docs.json @@ -1 +1 @@ -{"type":"tildefriends-app","files":{"app.js":"&rLwYqurncmnUyGeWY+FLEGS2EIJmqw2cutl1gyGiVSk=.sha256","index.md":"&082vPjenwI6mL2vXwQDVEFquyl2jW9t767sGuCFvVNA=.sha256","todo.md":"&u4lmFlYFB5zQNfVXVB8t8NMT2jFAeE8ivWfwIiiTKxQ=.sha256","structure.md":"&T+CBfT9XP6ooKFvD1ZCI9hsutqsNIamfBxtAho0HtlU=.sha256","guide.md":"&SgnGL0+rjetY2o9A2+lVRbNvHIkqKwMnZr9gXWneIlc=.sha256","id_refactor.md":"&8yoYd14gX2Z3ppktVrPYf4qR78fuwAlvrtsWkSCkWUA=.sha256","ssb.md":"&WMvYIpp4CMZACwXJlX8HMDplJ+XeJB04BYf8zasrL4g=.sha256"}} \ No newline at end of file +{"type":"tildefriends-app","files":{"app.js":"&rLwYqurncmnUyGeWY+FLEGS2EIJmqw2cutl1gyGiVSk=.sha256","index.md":"&082vPjenwI6mL2vXwQDVEFquyl2jW9t767sGuCFvVNA=.sha256","todo.md":"&+z52vxpbZs5+HoLnQoDNkYt4objcPwF7F1PIwvZ3E3k=.sha256","structure.md":"&T+CBfT9XP6ooKFvD1ZCI9hsutqsNIamfBxtAho0HtlU=.sha256","guide.md":"&SgnGL0+rjetY2o9A2+lVRbNvHIkqKwMnZr9gXWneIlc=.sha256","id_refactor.md":"&8yoYd14gX2Z3ppktVrPYf4qR78fuwAlvrtsWkSCkWUA=.sha256","ssb.md":"&WMvYIpp4CMZACwXJlX8HMDplJ+XeJB04BYf8zasrL4g=.sha256"}} \ No newline at end of file diff --git a/apps/cory/docs/todo.md b/apps/cory/docs/todo.md index 00b533b1..f2921e21 100644 --- a/apps/cory/docs/todo.md +++ b/apps/cory/docs/todo.md @@ -9,7 +9,6 @@ - update README - update docs - audit + document API exposed to apps -- emoji reaction picker - fix weird HTTP warnings - ssb from child process? - channels @@ -26,6 +25,8 @@ - jwt for session tokens ## Maybe Done +- linkify https://... +- emoji reaction picker - expose loads of stats - confirm posting all new messages - multiple identities per user, in database diff --git a/apps/cory/ssblit.json b/apps/cory/ssblit.json index 85bded97..efb93cfd 100644 --- a/apps/cory/ssblit.json +++ b/apps/cory/ssblit.json @@ -1 +1 @@ -{"type":"tildefriends-app","files":{"app.js":"&Y01AAZJWUjOXzzcIPHTzeEWvgrBsBgcL34QcNdOtLpA=.sha256","lit-all.min.js":"&N4A12AsifdQgwdpII0SFtG513BfoLpmPjdJ9VTDftpg=.sha256","index.html":"&NQfp81Ve+FpMPRzPS1UcoXEkn7BW+yz/XArGQbLSmPg=.sha256","script.js":"&vnCSRIvjb0kS+QOmkJP+ISB6wJdXDp/lOn6FJn2esKk=.sha256","lit-all.min.js.map":"&oFY9wO4MnujgfGNGv4VggHc5V5JwX4C8csqKZ6KJYbE=.sha256","tf-id-picker.js":"&ewIlLZNhaHm2dztxqj2Ft38WZkNPQxYfOGBrwTDUhds=.sha256","tf-app.js":"&HOqvQvHjzGv94YSqPQWVOr9fTNMVRZk+vO7Dd+/LcEA=.sha256","tf-message.js":"&E98rTMtN1Ok3gBVbe54uqv6P45wHoMicdA/+gHVP7BM=.sha256","tf-user.js":"&hsIveVMRVMRNJfrTN1hkVQgO4VdRurMATfV2EXnIk/0=.sha256","tf-utils.js":"&MPINm55jkpz2rrNbwsYl09PKGvbgL3nwgBy6CMQkSnw=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&oo0iWvT+c2rU91zWpBIfPePRzmU8qmSnVOm+QCQqG/I=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&htPMi2z6Bmgi3f9jCnECCDZRCHACnDRjOl1kgPm+W80=.sha256","tf-styles.js":"&BkvFkMpGyL0DYP6FISFKR4pe6ZBOp8t6tQEzWZ4IQYs=.sha256","tf-profile.js":"&OmDTn4Bhu6kV4PzJ0wfaExyuLOO/7bPmbRNHD5yp02w=.sha256"}} \ No newline at end of file +{"type":"tildefriends-app","files":{"app.js":"&b8IFBOMDtcvY5XNtUQIUeoE+++/TO8LDp86xNFIaux8=.sha256","lit-all.min.js":"&N4A12AsifdQgwdpII0SFtG513BfoLpmPjdJ9VTDftpg=.sha256","index.html":"&WH8A5tF25xlfPDGei2TCQc2/HJFJf5DuRN1GRSYQhhk=.sha256","script.js":"&diQfpbxjgd/jSPnIoAoWT75B8Pll1I5JYXhu+/phj9k=.sha256","lit-all.min.js.map":"&oFY9wO4MnujgfGNGv4VggHc5V5JwX4C8csqKZ6KJYbE=.sha256","tf-id-picker.js":"&ewIlLZNhaHm2dztxqj2Ft38WZkNPQxYfOGBrwTDUhds=.sha256","tf-app.js":"&4Z6k1bR9LUPUZGyJTEKOqPkNKqHtnvG8ScgkFoSTf1Y=.sha256","tf-message.js":"&KE1fWTqPMZR0yIRXPBGy8u1chR6LTguSK6swo+lFgE4=.sha256","tf-user.js":"&L6+7BnBq+UOoTMO6o8+u5JFTl0UBtCPDw8bb8ppDrkA=.sha256","tf-utils.js":"&N2yKZwFnb2GbPeipgQtu6xFvezENNOgud9G7EhCQ/K0=.sha256","commonmark.min.js":"&bfBaMLU19d1p/vPBF9hlARqDX002KXG/UOfxOahZhe4=.sha256","tf-compose.js":"&oo0iWvT+c2rU91zWpBIfPePRzmU8qmSnVOm+QCQqG/I=.sha256","emojis.json":"&h3P4pez+AI4aYdsN0dJ3pbUEFR0276t9AM20caj/W/s=.sha256","emojis.js":"&htPMi2z6Bmgi3f9jCnECCDZRCHACnDRjOl1kgPm+W80=.sha256","tf-styles.js":"&BkvFkMpGyL0DYP6FISFKR4pe6ZBOp8t6tQEzWZ4IQYs=.sha256","tf-profile.js":"&vRKjsnYvOiHCQahzEfznCvP5YDwUPtltlpWf+pxwZ1Y=.sha256","commonmark-linkify.js":"&X+hNNkmSRvKY86khyAun+cXksquXbMakZdINbGbx30g=.sha256","tf-connections.js":"&YUD4n/r95AwD2fA63HHE2eQt4E/27gF+4/MYrdvoasw=.sha256"}} \ No newline at end of file diff --git a/apps/cory/ssblit/app.js b/apps/cory/ssblit/app.js index 39f77164..c06d8d28 100644 --- a/apps/cory/ssblit/app.js +++ b/apps/cory/ssblit/app.js @@ -18,6 +18,15 @@ tfrpc.register(async function databaseSet(key, value) { tfrpc.register(async function getIdentities() { return ssb.getIdentities(); }); +tfrpc.register(async function getAllIdentities() { + return ssb.getAllIdentities(); +}); +tfrpc.register(async function getBroadcasts() { + return ssb.getBroadcasts(); +}); +tfrpc.register(async function getConnections() { + return ssb.connections(); +}); tfrpc.register(async function query(sql, args) { let result = []; await ssb.sqlStream(sql, args, function callback(row) { @@ -46,6 +55,13 @@ tfrpc.register(async function store_blob(blob) { } return await ssb.blobStore(blob); }); +ssb.addEventListener('broadcasts', async function() { + await tfrpc.rpc.set('broadcasts', await ssb.getBroadcasts()); +}); + +core.register('onConnectionsChanged', async function() { + await tfrpc.rpc.set('connections', await ssb.connections()); +}); async function main() { if (typeof(database) !== 'undefined') { diff --git a/apps/cory/ssblit/commonmark-linkify.js b/apps/cory/ssblit/commonmark-linkify.js new file mode 100644 index 00000000..decdbf0b --- /dev/null +++ b/apps/cory/ssblit/commonmark-linkify.js @@ -0,0 +1,91 @@ +function textNode(text) { + const node = new commonmark.Node("text", undefined); + node.literal = text; + return node; +} + +function linkNode(text, url) { + const urlNode = new commonmark.Node("link", undefined); + urlNode.destination = url; + urlNode.appendChild(textNode(text)); + + return urlNode; +} + +function splitMatches(text, regexp) { + // Regexp must be sticky. + regexp = new RegExp(regexp, "gm"); + + let i = 0; + const result = []; + + let match = regexp.exec(text); + while (match) { + const matchText = match[0]; + + if (match.index > i) { + result.push([text.substring(i, match.index), false]); + } + + result.push([matchText, true]); + i = match.index + matchText.length; + + match = regexp.exec(text); + } + + if (i < text.length) { + result.push([text.substring(i, text.length), false]); + } + + return result; +} + +const urlRegexp = new RegExp("https?://[^ ]+[^ .,]"); + +function splitURLs(textNodes) { + const text = textNodes.map(n => n.literal).join(""); + const parts = splitMatches(text, urlRegexp); + + return parts.map(part => { + if (part[1]) { + return linkNode(part[0], part[0]); + } else { + return textNode(part[0]); + } + }); +} + +export function transform(parsed) { + const walker = parsed.walker(); + let event; + + let nodes = []; + while ((event = walker.next())) { + const node = event.node; + if (event.entering && node.type === "text") { + nodes.push(node); + } else { + if (nodes.length > 0) { + splitURLs(nodes) + .reverse() + .forEach(newNode => { + nodes[0].insertAfter(newNode); + }); + + nodes.forEach(n => n.unlink()); + nodes = []; + } + } + } + + if (nodes.length > 0) { + splitURLs(nodes) + .reverse() + .forEach(newNode => { + nodes[0].insertAfter(newNode); + }); + nodes.forEach(n => n.unlink()); + } + + return parsed; +} diff --git a/apps/cory/ssblit/index.html b/apps/cory/ssblit/index.html index 30f53e4c..837846f7 100644 --- a/apps/cory/ssblit/index.html +++ b/apps/cory/ssblit/index.html @@ -2,12 +2,14 @@