From d207b512a3da5e3acacdae3154c978ecb28455ad Mon Sep 17 00:00:00 2001 From: Rogerio Chaves Date: Wed, 8 Apr 2020 08:44:23 +0200 Subject: [PATCH] Add private vanishing messages --- app/lib/express.js | 33 ++++++++++++++---- app/lib/queries.js | 61 +++++++++++++++++++++++++++++++++ app/lib/ssb.js | 3 +- app/package-lock.json | 12 +++++++ app/package.json | 1 + app/public/js/index.js | 22 ++++++++++++ app/public/style.css | 72 ++++++++++++++++++++++++++++++++++++++- app/views/_footer.ejs | 1 + app/views/_post.ejs | 13 +++++++ app/views/index.ejs | 77 +++++++++++++++++++++++++++++++----------- app/views/profile.ejs | 30 ++++++++-------- 11 files changed, 281 insertions(+), 44 deletions(-) create mode 100644 app/public/js/index.js create mode 100644 app/views/_post.ejs diff --git a/app/lib/express.js b/app/lib/express.js index ea395b6..16ee151 100644 --- a/app/lib/express.js +++ b/app/lib/express.js @@ -66,11 +66,17 @@ router.get("/", async (_req, res) => { res.redirect("/about"); } - const [posts, friends] = await Promise.all([ + const [posts, friends, vanishingMessages] = await Promise.all([ queries.getPosts(ssbServer, context.profile), queries.getFriends(ssbServer, context.profile), + queries.getVanishingMessages(ssbServer, context.profile), ]); - res.render("index", { posts, friends }); + res.render("index", { + posts, + friends, + vanishingMessages, + profile: context.profile, + }); }); router.get("/profile/:id", async (req, res) => { @@ -101,12 +107,25 @@ router.post("/publish", async (req, res) => { router.post("/profile/:id/publish", async (req, res) => { const id = req.params.id; + const visibility = req.body.visibility; + console.log("req.body", req.body); - await ssbServer.publish({ - type: "post", - text: req.body.message, - root: id, - }); + if (visibility == "vanishing") { + await ssbServer.private.publish( + { + type: "post", + text: req.body.message, + root: id, + }, + [id] + ); + } else { + await ssbServer.publish({ + type: "post", + text: req.body.message, + root: id, + }); + } res.redirect("/profile/" + id); }); diff --git a/app/lib/queries.js b/app/lib/queries.js index 3e27bed..68ef990 100644 --- a/app/lib/queries.js +++ b/app/lib/queries.js @@ -76,6 +76,7 @@ const getPosts = (ssbServer, profile) => { $filter: { value: { + private: { $not: true }, content: { root: profile.id, }, @@ -92,6 +93,7 @@ const getPosts = (ssbServer, profile) => $filter: { value: { author: profile.id, + private: { $not: true }, content: { type: "post", root: { $not: true }, @@ -115,6 +117,64 @@ const getPosts = (ssbServer, profile) => ); }); +const getVanishingMessages = (ssbServer, profile) => + debug("Fetching vanishing messages") || + new Promise((resolve, reject) => { + pull( + // @ts-ignore + cat([ + ssbServer.query.read({ + reverse: true, + query: [ + { + $filter: { + value: { + private: true, + content: { + root: profile.id, + }, + }, + }, + }, + ], + limit: 100, + }), + ssbServer.query.read({ + reverse: true, + query: [ + { + $filter: { + value: { + author: profile.id, + private: true, + content: { + type: "post", + root: { $not: true }, + }, + }, + }, + }, + ], + limit: 100, + }), + ]), + pull.filter( + (msg) => + msg.value.content.type == "post" && + (msg.value.content.root || + msg.value.content.recps.includes(profile.id)) + ), + paramap(mapProfiles(ssbServer)), + pull.collect((err, msgs) => { + debug("Done fetching vanishing messages"); + const entries = msgs.map((x) => x.value); + + if (err) return reject(err); + return resolve(entries); + }) + ); + }); + const searchPeople = (ssbServer, search) => debug("Searching people") || new Promise((resolve, reject) => { @@ -242,4 +302,5 @@ module.exports = { getFriends, getAllEntries, getProfile, + getVanishingMessages, }; diff --git a/app/lib/ssb.js b/app/lib/ssb.js index 567c19a..9484a71 100644 --- a/app/lib/ssb.js +++ b/app/lib/ssb.js @@ -16,7 +16,8 @@ Server.use(require("ssb-master")) .use(require("ssb-device-address")) .use(require("ssb-identities")) .use(require("ssb-peer-invites")) - .use(require("ssb-blobs")); + .use(require("ssb-blobs")) + .use(require("ssb-private")); const server = Server(config); console.log("SSB server started at", config.port); diff --git a/app/package-lock.json b/app/package-lock.json index b7efaff..067f313 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -2711,6 +2711,18 @@ } } }, + "ssb-private": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/ssb-private/-/ssb-private-0.2.3.tgz", + "integrity": "sha512-SiLBKOB1hxkrohzOrRWURlzj6HvPFvr9LLd5P5I5C5KU/RtaWe79nYuFgjUFJFnjWw7X4szCy32/EZMihV1l/Q==", + "requires": { + "base64-url": "^2.2.0", + "explain-error": "^1.0.4", + "flumeview-query": "^6.1.0", + "pull-stream": "^3.6.7", + "ssb-keys": "^7.0.14" + } + }, "ssb-query": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/ssb-query/-/ssb-query-2.4.3.tgz", diff --git a/app/package.json b/app/package.json index 9706b3f..9d9cd26 100644 --- a/app/package.json +++ b/app/package.json @@ -30,6 +30,7 @@ "ssb-keys": "^7.2.2", "ssb-master": "^1.0.3", "ssb-peer-invites": "^2.0.2", + "ssb-private": "^0.2.3", "ssb-query": "^2.4.3", "ssb-replicate": "^1.3.2", "ssb-server": "^15.2.0" diff --git a/app/public/js/index.js b/app/public/js/index.js new file mode 100644 index 0000000..4e51ee0 --- /dev/null +++ b/app/public/js/index.js @@ -0,0 +1,22 @@ +const messages = document.querySelectorAll(".vanishing-message"); +messages.forEach((message) => { + message.addEventListener("click", () => { + const overlay = message.parentElement.querySelector(".overlay"); + const modal = message.parentElement.querySelector(".modal"); + const closeButton = message.parentElement.querySelector(".modal-close"); + + overlay.style.display = "block"; + modal.style.display = "block"; + + const onClose = () => { + const parent = modal.parentElement; + parent.parentElement.removeChild(parent); + if (document.querySelectorAll(".vanishing-message").length == 0) { + document.querySelector(".vanishing-messages").style.display = "none"; + } + }; + + overlay.addEventListener("click", onClose); + closeButton.addEventListener("click", onClose); + }); +}); diff --git a/app/public/style.css b/app/public/style.css index 103ad85..c974fad 100644 --- a/app/public/style.css +++ b/app/public/style.css @@ -1,9 +1,25 @@ +* { + box-sizing: border-box; +} body { font-family: sans-serif; margin: 0; line-height: 1.3em; word-wrap: break-word; } +button { + font-size: 14px; + background: #ddd; + color: #5f5f5f; + border-radius: 3px; + padding: 8px 10px; + border: none; + cursor: pointer; +} +button:hover { + background: #959eab; + color: #fff; +} header { padding: 0 30px; border-bottom: 1px solid #666; @@ -70,7 +86,7 @@ h1 { } .wall { - padding: 20px; + padding: 0 20px; flex-grow: 1; } @@ -106,3 +122,57 @@ h1 { .profile-pic { width: 300px; } + +button.vanishing-message { + background: none; + width: 84px; + text-align: center; + border: 1px solid #333; + padding: 10px; + cursor: pointer; + color: #000; +} + +.overlay { + display: none; + position: fixed; + z-index: 1; + background: rgba(0, 0, 0, 0.5); + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.modal { + display: none; + position: fixed; + z-index: 2; + background: #fff; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + min-width: 400px; +} + +.modal-header { + display: flex; + align-items: center; + padding: 10px; + padding-bottom: 0; + font-weight: bold; +} + +.modal-body { + padding: 10px; +} + +.modal-footer { + padding: 10px; + background: #fffbf4; + border-top: 1px solid #ddd; + font-size: 12px; + display: flex; + align-items: center; + justify-content: space-between; +} diff --git a/app/views/_footer.ejs b/app/views/_footer.ejs index 3f2c2d5..6ca4e0f 100644 --- a/app/views/_footer.ejs +++ b/app/views/_footer.ejs @@ -1,3 +1,4 @@ + \ No newline at end of file diff --git a/app/views/_post.ejs b/app/views/_post.ejs new file mode 100644 index 0000000..28f647b --- /dev/null +++ b/app/views/_post.ejs @@ -0,0 +1,13 @@ +
+
+ +
+
+
+ <%= post.authorProfile.name %> +
+
+ <%= post.content.text.slice(0, 140) %> +
+
+
\ No newline at end of file diff --git a/app/views/index.ejs b/app/views/index.ejs index b4f535b..7654b17 100644 --- a/app/views/index.ejs +++ b/app/views/index.ejs @@ -1,27 +1,66 @@ <%- include('_header') %> -

Home

+
+
+ +

<%= profile.name %>

-
- - -
+ <%= profile.description %> -<% posts.map(entry => { %> -
<%= entry.authorProfile.name %> (<%= entry.author.slice(0, 8) %>): <%= entry.content.text %>
-
-<% }) %> +

Friends

-

Friends

+ - +
+ +
+ <% if (vanishingMessages.length > 0) { %> +
+

Vanishing Messages

+ <% vanishingMessages.map(post => { %> + + +
+ +
+ <% }) %> +
+ <% } %> + +

Your Wall

+ +
+ + +
+ + <% posts.map(post => { %> + <%- include('_post', { post }) %> + <% }) %> +
+
<%- include('_footer') %> \ No newline at end of file diff --git a/app/views/profile.ejs b/app/views/profile.ejs index c8f694a..4c5dedc 100644 --- a/app/views/profile.ejs +++ b/app/views/profile.ejs @@ -22,27 +22,25 @@

<%= profile.name %>'s Wall

- + - <% posts.map(entry => { %> -
-
- -
-
-
- <%= entry.authorProfile.name %> -
-
- <%= entry.content.text.slice(0, 140) %> -
-
-
+ <% posts.map(post => { %> + <%- include('_post', { post }) %> <% }) %>