diff --git a/app/lib/express.js b/app/lib/express.js index 1be5fc7..a7f4104 100644 --- a/app/lib/express.js +++ b/app/lib/express.js @@ -2,11 +2,11 @@ const express = require("express"); const app = express(); const port = process.env.EXPRESS_PORT || 3000; const bodyParser = require("body-parser"); -const pull = require("pull-stream"); const Client = require("ssb-client"); const ssbKeys = require("ssb-keys"); const ssbConfig = require("./ssb-config"); const { promisify, asyncRouter } = require("./utils"); +const queries = require("./queries"); let ssbServer; let profile; @@ -37,7 +37,7 @@ app.use(express.static("public")); const router = asyncRouter(app); -router.get("/", (_req, res) => { +router.get("/", async (_req, res) => { if (!ssbServer) { setTimeout(() => { res.redirect("/"); @@ -49,56 +49,12 @@ router.get("/", (_req, res) => { res.redirect("/about"); } - const getAuthorName = (data, callback) => { - let promises = []; - - const authorNamePromise = promisify(ssbServer.about.latestValue, { - key: "name", - dest: data.value.author, - }); - promises.push(authorNamePromise); - - if (data.value.content.type == "contact") { - const contactNamePromise = promisify(ssbServer.about.latestValue, { - key: "name", - dest: data.value.content.contact, - }); - promises.push(contactNamePromise); - } - - Promise.all(promises) - .then(([authorName, contactName]) => { - data.value.authorName = authorName; - if (contactName) { - data.value.content.contactName = contactName; - } - - callback(null, data); - }) - .catch((err) => callback(err, null)); - }; - - pull( - ssbServer.query.read({ - reverse: true, - query: [ - { - $filter: { - value: { - content: { type: { $in: ["post", "contact"] } }, - }, - }, - }, - ], - limit: 500, - }), - pull.asyncMap(getAuthorName), - pull.collect((_err, msgs) => { - const entries = msgs.map((x) => x.value); - - res.render("index", { entries, profile }); - }) - ); + const [posts, people, friends] = await Promise.all([ + queries.getPosts(ssbServer), + queries.getPeople(ssbServer), + queries.getFriends(profile, ssbServer), + ]); + res.render("index", { profile, posts, people, friends }); }); router.post("/publish", async (req, res) => { @@ -141,6 +97,12 @@ router.post("/about", async (req, res) => { res.redirect("/"); }); +router.get("/debug", async (_req, res) => { + const entries = await queries.getAllEntries(ssbServer); + + res.render("debug", { profile, entries }); +}); + const expressServer = app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`) ); diff --git a/app/lib/queries.js b/app/lib/queries.js new file mode 100644 index 0000000..c1358be --- /dev/null +++ b/app/lib/queries.js @@ -0,0 +1,144 @@ +const { promisify } = require("./utils"); +const pull = require("pull-stream"); + +const mapAuthorName = (ssbServer) => (data, callback) => { + let promises = []; + + const authorNamePromise = promisify(ssbServer.about.latestValue, { + key: "name", + dest: data.value.author, + }); + promises.push(authorNamePromise); + + if (data.value.content.type == "contact") { + const contactNamePromise = promisify(ssbServer.about.latestValue, { + key: "name", + dest: data.value.content.contact, + }); + promises.push(contactNamePromise); + } + + return Promise.all(promises) + .then(([authorName, contactName]) => { + data.value.authorName = authorName; + if (contactName) { + data.value.content.contactName = contactName; + } + + callback(null, data); + }) + .catch((err) => callback(err, null)); +}; + +const getPosts = (ssbServer) => + new Promise((resolve, reject) => { + pull( + ssbServer.query.read({ + reverse: true, + query: [ + { + $filter: { + value: { + content: { type: "post" }, + }, + }, + }, + ], + limit: 500, + }), + pull.asyncMap(mapAuthorName(ssbServer)), + pull.collect((err, msgs) => { + const entries = msgs.map((x) => x.value); + + if (err) return reject(err); + return resolve(entries); + }) + ); + }); + +const getPeople = (ssbServer) => + new Promise((resolve, reject) => { + pull( + ssbServer.query.read({ + reverse: true, + query: [ + { + $filter: { + value: { + content: { + type: "about", + name: { $is: "string" }, + }, + }, + }, + }, + ], + limit: 500, + }), + pull.collect((err, msgs) => { + let people = {}; + for (let person of msgs) { + const author = person.value.author; + if (author == person.value.content.about && !people[author]) { + people[author] = person.value; + } + } + + if (err) return reject(err); + return resolve(Object.values(people)); + }) + ); + }); + +const getFriends = (profile, ssbServer) => + new Promise((resolve, reject) => { + pull( + ssbServer.query.read({ + reverse: true, + query: [ + { + $filter: { + value: { + author: profile.id, + content: { + type: "contact", + }, + }, + }, + }, + ], + limit: 500, + }), + pull.asyncMap(mapAuthorName(ssbServer)), + pull.collect((err, msgs) => { + const entries = msgs.map((x) => x.value); + + if (err) return reject(err); + return resolve(entries); + }) + ); + }); + +const getAllEntries = (ssbServer) => + new Promise((resolve, reject) => { + pull( + ssbServer.query.read({ + reverse: true, + limit: 100, + }), + pull.collect((err, msgs) => { + const entries = msgs.map((x) => x.value); + + if (err) return reject(err); + return resolve(entries); + }) + ); + }); + +module.exports = { + mapAuthorName, + getPosts, + getPeople, + getFriends, + getAllEntries, +}; diff --git a/app/package.json b/app/package.json index ca81d75..ded4147 100644 --- a/app/package.json +++ b/app/package.json @@ -6,7 +6,8 @@ "scripts": { "start": "electron .", "start:user-2": "SSB_PORT=8009 EXPRESS_PORT=3001 CONFIG_FOLDER=social-user2 electron .", - "clear": "rm -rf ~/.social; rm -rf ~/.social-user2" + "start:user-3": "SSB_PORT=8010 EXPRESS_PORT=3002 CONFIG_FOLDER=social-user3 electron .", + "clear": "rm -rf ~/.social; rm -rf ~/.social-user2; rm -rf ~/.social-user3" }, "author": "", "license": "ISC", diff --git a/app/views/_footer.ejs b/app/views/_footer.ejs index 1fd5f4f..3f2c2d5 100644 --- a/app/views/_footer.ejs +++ b/app/views/_footer.ejs @@ -1,2 +1,3 @@ + \ No newline at end of file diff --git a/app/views/_header.ejs b/app/views/_header.ejs index 0f46892..671a9ec 100644 --- a/app/views/_header.ejs +++ b/app/views/_header.ejs @@ -4,6 +4,23 @@ Social + <% if (profile.name) { %> @@ -15,6 +32,8 @@ Home About me Pubs + Debug <% } %> +
diff --git a/app/views/debug.ejs b/app/views/debug.ejs new file mode 100644 index 0000000..051c38e --- /dev/null +++ b/app/views/debug.ejs @@ -0,0 +1,8 @@ +<%- include('_header') %> + +<% entries.map(entry => { %> + <%= JSON.stringify(entry) %> +
+<% }) %> + +<%- include('_footer') %> \ No newline at end of file diff --git a/app/views/index.ejs b/app/views/index.ejs index 3863e93..3decd6f 100644 --- a/app/views/index.ejs +++ b/app/views/index.ejs @@ -5,12 +5,25 @@ -<% entries.map(entry => { %> - <% if (entry.content.type == "post") { %> -
<%= entry.authorName %>: <%= entry.content.text %>
- <% } else if (entry.content.type == "contact") { %> -
<%= entry.authorName %> followed <%= entry.content.contactName %>
- <% } %> +<% posts.map(entry => { %> +
<%= entry.authorName %>: <%= entry.content.text %>
+
<% }) %> +

All People

+ + + +

Friends

+ + + <%- include('_footer') %> \ No newline at end of file