From 9fb8e50463d3549281cd10457da3a5fac8df845c Mon Sep 17 00:00:00 2001 From: Rogerio Chaves Date: Wed, 22 Apr 2020 22:15:18 +0200 Subject: [PATCH] Mobile reading secret --- app/lib/express.js | 27 ++++++-- app/lib/mobile.js | 0 app/lib/utils.js | 5 ++ app/public/js/{index.js => desktop.js} | 0 app/public/js/mobile.js | 88 ++++++++++++++++++++++++++ app/public/mobile_style.css | 55 ++++++++++++++++ app/views/_footer.ejs | 2 +- app/views/_posts.ejs | 46 +++++++------- app/views/home.ejs | 12 ++-- app/views/mobile/_layout.ejs | 12 ++-- app/views/mobile/home.ejs | 6 ++ app/views/mobile/secrets.ejs | 58 +++++++++++++++++ app/views/profile.ejs | 12 ++-- 13 files changed, 274 insertions(+), 49 deletions(-) delete mode 100644 app/lib/mobile.js rename app/public/js/{index.js => desktop.js} (100%) create mode 100644 app/public/js/mobile.js create mode 100644 app/views/mobile/secrets.ejs diff --git a/app/lib/express.js b/app/lib/express.js index d776f97..9707ae9 100644 --- a/app/lib/express.js +++ b/app/lib/express.js @@ -14,6 +14,7 @@ const { uploadPicture, identityFilename, ssbFolder, + isPhone, } = require("./utils"); const queries = require("./queries"); const serveBlobs = require("./serve-blobs"); @@ -26,7 +27,6 @@ const sgMail = require("@sendgrid/mail"); const ejs = require("ejs"); const cookieEncrypter = require("cookie-encrypter"); const expressLayouts = require("express-ejs-layouts"); -const isMobile = require("ismobilejs").default; let ssbServer; let mode = process.env.MODE || "client"; @@ -85,7 +85,7 @@ const cookieOptions = { httpOnly: true, signed: true, expires: new Date(253402300000000), // Friday, 31 Dec 9999 23:59:59 GMT, nice date from stackoverflow - sameSite: true, + sameSite: "Lax", }; app.use(cookieParser(cookieSecret)); app.use(cookieEncrypter(cookieSecret)); @@ -160,7 +160,7 @@ router.get("/", { public: true }, async (req, res) => { if (!req.context.profile) { return res.render("index"); } - if (isMobile(req.headers["user-agent"]).phone) { + if (isPhone(req)) { return res.redirect("/mobile"); } @@ -178,10 +178,9 @@ router.get("/", { public: true }, async (req, res) => { }); router.get("/mobile", async (req, res) => { - // TODO - // if (!isMobile(req.headers["user-agent"]).phone) { - // return res.redirect("/"); - // } + if (!isPhone(req)) { + return res.redirect("/"); + } const posts = await queries.getPosts(ssbServer, req.context.profile); @@ -192,6 +191,20 @@ router.get("/mobile", async (req, res) => { }); }); +router.get("/mobile/secrets", async (req, res) => { + if (!isPhone(req)) { + return res.redirect("/"); + } + + const secretMessages = await queries.getSecretMessages(ssbServer, req.context.profile); + + res.render("mobile/secrets", { + secretMessages, + profile: req.context.profile, + layout: "mobile/_layout", + }); +}); + router.get("/login", { public: true }, (_req, res) => { res.render("login", { mode }); }); diff --git a/app/lib/mobile.js b/app/lib/mobile.js deleted file mode 100644 index e69de29..0000000 diff --git a/app/lib/utils.js b/app/lib/utils.js index 975bb45..363ef64 100644 --- a/app/lib/utils.js +++ b/app/lib/utils.js @@ -3,6 +3,7 @@ const leftpad = require("left-pad"); // I don't believe I'm depending on this const pull = require("pull-stream"); const split = require("split-buffer"); const metrics = require("./metrics"); +const isMobile = require("ismobilejs").default; module.exports.asyncRouter = (app) => { const debug = require("debug")("router"); @@ -112,3 +113,7 @@ module.exports.promisePull = (...streams) => }); module.exports.mapValues = (x) => x.map((y) => y.value); + +module.exports.isPhone = (req) => { + return isMobile(req.headers["user-agent"]).phone; +}; diff --git a/app/public/js/index.js b/app/public/js/desktop.js similarity index 100% rename from app/public/js/index.js rename to app/public/js/desktop.js diff --git a/app/public/js/mobile.js b/app/public/js/mobile.js new file mode 100644 index 0000000..53588af --- /dev/null +++ b/app/public/js/mobile.js @@ -0,0 +1,88 @@ +/** + * Compose Post + */ + +const composePost = document.querySelector(".js-compose-post"); +if (composePost) { + const composeButton = document.querySelector(".js-publish-button"); + composePost.addEventListener("focus", () => { + composeButton.style.display = "block"; + }); +} + +/** + * Modal + */ + +const openModalFor = (elem, onConfirm, afterClose = null) => { + const overlay = elem.parentElement.querySelector(".overlay"); + const modal = elem.parentElement.querySelector(".modal"); + const confirmButtons = elem.parentElement.querySelectorAll(".modal-confirm"); + const steps = elem.parentElement.querySelectorAll(".js-step"); + + overlay.hidden = false; + modal.hidden = false; + + const onClose = () => { + overlay.hidden = true; + modal.hidden = true; + steps.forEach((step) => { + step.style.display = "none"; + }); + if (steps[0]) steps[0].style.display = "flex"; + if (afterClose) afterClose(); + }; + + const nextOrConfirm = () => { + if (steps.length == 0) { + onConfirm(); + } else { + let currentStep; + steps.forEach((step, index) => { + if (currentStep == index) { + step.style.display = "flex"; + } else if (step.style.display != "none") { + currentStep = index; + currentStep++; + if (currentStep < steps.length) step.style.display = "none"; + } + }); + if (currentStep == steps.length) { + onConfirm(); + } + } + }; + + overlay.addEventListener("click", onClose); + Array.from(confirmButtons).forEach((button) => + button.addEventListener("click", nextOrConfirm) + ); + + return { close: onClose }; +}; + +/** + * Secret Messages Reading + */ + +const messages = document.querySelectorAll(".js-secret-message"); +messages.forEach((message) => { + message.addEventListener("click", () => { + const afterClose = () => { + const parent = message.parentElement; + const composeMessage = parent.parentElement.querySelector( + ".js-compose-secret-message" + ); + composeMessage.style.display = "flex"; + parent.parentElement.removeChild(parent); + }; + + const modal = openModalFor(message, () => modal.close(), afterClose); + + fetch("/vanish", { + method: "POST", + headers: { "Content-Type": "application/x-www-form-urlencoded" }, + body: "keys=" + encodeURIComponent(message.dataset.keys), + }); + }); +}); diff --git a/app/public/mobile_style.css b/app/public/mobile_style.css index 22b6c9c..e766e64 100644 --- a/app/public/mobile_style.css +++ b/app/public/mobile_style.css @@ -1,6 +1,9 @@ body { background: #fff; padding-bottom: 70px; + display: flex; + flex-direction: column; + min-height: 100vh; } nav { @@ -42,3 +45,55 @@ nav a.selected { .post { padding: 10px; } + +.modal { + top: 100%; + left: 0; + transform: none; + min-width: auto; + width: 100%; + height: 100%; + animation: slide 0.5s forwards; +} + +@keyframes slide { + 100% { + top: 0; + } +} + +.modal-group { + height: 100%; + display: flex; + flex-direction: column; +} + +.modal-body { + flex-grow: 1; + display: flex; + align-items: center; + justify-content: center; + font-size: 30px; +} + +.modal-footer { + border-bottom: 1px solid #ddd; + background: #000; +} + +.secret-chat { + width: 100%; + max-width: none; + min-width: auto; + flex-grow: 1; + padding: 0; +} + +.secret-button { + padding: 8px 14px; + font-size: 16px; +} + +.secret-chat .link-profile-pic { + margin-right: 12px; +} diff --git a/app/views/_footer.ejs b/app/views/_footer.ejs index 6ca4e0f..4311335 100644 --- a/app/views/_footer.ejs +++ b/app/views/_footer.ejs @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/app/views/_posts.ejs b/app/views/_posts.ejs index e28a823..1071d7a 100644 --- a/app/views/_posts.ejs +++ b/app/views/_posts.ejs @@ -1,25 +1,23 @@ -
- <% posts.map(post => { %> - <% if (!post.content.text) return %> -
-
- - - -
-
- - <%= post.authorProfile.name %> - - <% let text = post.content.text %> - <% if (typeof dont_cut == "undefined") { %> - <% text = post.content.text.slice(0, 140) %> - <% if (post.content.text.length > 140) text += "..." %> - <% } %> - <% text.split("\n").map((line, index) => { %> - <%- index > 0 ? "
" : "" %><%= line %> - <% }) %> -
+<% posts.map(post => { %> + <% if (!post.content.text) return %> +
+
+ + +
- <% }) %> -
\ No newline at end of file +
+ + <%= post.authorProfile.name %> + + <% let text = post.content.text %> + <% if (typeof dont_cut == "undefined") { %> + <% text = post.content.text.slice(0, 140) %> + <% if (post.content.text.length > 140) text += "..." %> + <% } %> + <% text.split("\n").map((line, index) => { %> + <%- index > 0 ? "
" : "" %><%= line %> + <% }) %> +
+
+<% }) %> \ No newline at end of file diff --git a/app/views/home.ejs b/app/views/home.ejs index 2a51cf7..2b41143 100644 --- a/app/views/home.ejs +++ b/app/views/home.ejs @@ -27,15 +27,15 @@

Your Wall

- <% if (posts.length > 0) { %> - <%- include('_posts', { posts }) %> - <% } else { %> -
+
+ <% if (posts.length > 0) { %> + <%- include('_posts', { posts }) %> + <% } else { %>
You have no posts yet, publish something!
-
- <% } %> + <% } %> +
diff --git a/app/views/mobile/_layout.ejs b/app/views/mobile/_layout.ejs index c603a17..b7da78e 100644 --- a/app/views/mobile/_layout.ejs +++ b/app/views/mobile/_layout.ejs @@ -14,23 +14,23 @@
<%- body %> + + \ No newline at end of file diff --git a/app/views/mobile/home.ejs b/app/views/mobile/home.ejs index 378595b..fc3d09e 100644 --- a/app/views/mobile/home.ejs +++ b/app/views/mobile/home.ejs @@ -8,6 +8,12 @@ <% if (posts.length > 0) { %> +
+ +
+ +
+
<%- include('../_posts', { posts }) %> <% } else { %>
diff --git a/app/views/mobile/secrets.ejs b/app/views/mobile/secrets.ejs new file mode 100644 index 0000000..b681f84 --- /dev/null +++ b/app/views/mobile/secrets.ejs @@ -0,0 +1,58 @@ +
+
0 ? "hidden" : "" %> style="margin: 25px 0 20px 0; font-size: 14px;"> + ๐Ÿ‘ป You don't have any secret messages yet +
+ + <% secretMessages.map(chat => { %> +
+
+ + <%- include('../secrets/_compose_single', { profile: chat.authorProfile }) %> +
+ +
+ + + +
+
+ <% }) %> +
\ No newline at end of file diff --git a/app/views/profile.ejs b/app/views/profile.ejs index dba2ad1..4f4daec 100644 --- a/app/views/profile.ejs +++ b/app/views/profile.ejs @@ -63,15 +63,15 @@

<%= profile.name %>'s Wall

- <% if (posts.length == 0) { %> -
+
+ <% if (posts.length == 0) { %>
No posts yet
-
- <% } else { %> - <%- include('_posts', { posts }) %> - <% } %> + <% } else { %> + <%- include('_posts', { posts }) %> + <% } %> +