Merge pull request #127 from christianbundy/view-markdown

Move Markdown handling from model module to view
This commit is contained in:
Cinnamon 2020-01-31 20:39:11 -08:00 committed by GitHub
commit 173e0ee4b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 152 additions and 173 deletions

View File

@ -11,8 +11,6 @@ const pullSort = require("pull-sort");
// HACK: https://github.com/ssbc/ssb-thread-schema/issues/4
const isNestedReply = require("ssb-thread-schema/post/nested-reply/validator");
const markdown = require("./markdown");
const nullImage = `&${"0".repeat(43)}=.sha256`;
const defaultOptions = {
@ -57,7 +55,7 @@ module.exports = cooler => {
key: "description",
dest: feedId
});
return markdown(raw);
return raw;
},
all: async feedId => {
const ssb = await cooler.connect();
@ -315,10 +313,6 @@ module.exports = cooler => {
return null;
}
lodash.set(msg, "value.meta.md.block", () =>
markdown(msg.value.content.text, msg.value.content.mentions)
);
const filterQuery = {
$filter: {
dest: msg.key

View File

@ -9,6 +9,7 @@ const {
article,
button,
code,
details,
div,
footer,
form,
@ -28,12 +29,160 @@ const {
select,
span,
strong,
summary,
textarea,
ul
} = require("hyperaxe");
const template = require("./template");
const post = require("./post");
const markdown = require("./markdown");
const lodash = require("lodash");
const post = ({ msg }) => {
const encoded = {
key: encodeURIComponent(msg.key),
author: encodeURIComponent(msg.value.author),
parent: encodeURIComponent(msg.value.content.root)
};
const url = {
author: `/author/${encoded.author}`,
likeForm: `/like/${encoded.key}`,
link: `/thread/${encoded.key}#${encoded.key}`,
parent: `/thread/${encoded.parent}#${encoded.parent}`,
avatar: msg.value.meta.author.avatar.url,
json: `/json/${encoded.key}`,
reply: `/reply/${encoded.key}`,
comment: `/comment/${encoded.key}`
};
const isPrivate = Boolean(msg.value.meta.private);
const isRoot = msg.value.content.root == null;
const isThreadTarget = Boolean(
lodash.get(msg, "value.meta.thread.target", false)
);
// TODO: I think this is actually true for both replies and comments.
const isReply = Boolean(lodash.get(msg, "value.meta.thread.reply", false));
const { name } = msg.value.meta.author;
const timeAgo = msg.value.meta.timestamp.received.since.replace("~", "");
const depth = lodash.get(msg, "value.meta.thread.depth", 0);
const markdownContent = markdown(
msg.value.content.text,
msg.value.content.mentions
);
const hasContentWarning =
typeof msg.value.content.contentWarning === "string";
const likeButton = msg.value.meta.voted
? { value: 0, class: "liked" }
: { value: 1, class: null };
const likeCount = msg.value.meta.votes.length;
const messageClasses = [];
if (isPrivate) {
messageClasses.push("private");
}
if (isThreadTarget) {
messageClasses.push("thread-target");
}
if (isReply) {
// True for comments too, I think
messageClasses.push("reply");
}
const isFork = msg.value.meta.postType === "reply";
const postOptions = {
post: null,
comment: ["commented on ", a({ href: url.parent }, " thread")],
reply: ["replied to ", a({ href: url.parent }, " message")],
mystery: "posted a mysterious message"
};
const emptyContent = "<p>undefined</p>\n";
const articleElement =
markdownContent === emptyContent
? article(
{ class: "content" },
pre({
innerHTML: highlightJs.highlight(
"json",
JSON.stringify(msg, null, 2)
).value
})
)
: article({ class: "content", innerHTML: markdownContent });
const articleContent = hasContentWarning
? details(summary(msg.value.content.contentWarning), articleElement)
: articleElement;
const fragment = section(
{
id: msg.key,
class: messageClasses.join(" "),
style: `margin-left: ${depth}rem;`
},
header(
span(
{ class: "author" },
a(
{ href: url.author },
img({ class: "avatar", src: url.avatar, alt: "" }),
name
),
postOptions[msg.value.meta.postType]
),
span(
{ class: "time" },
isPrivate ? "🔒" : null,
a({ href: url.link }, timeAgo)
)
),
articleContent,
// HACK: centered-footer
//
// Here we create an empty div with an anchor tag that can be linked to.
// In our CSS we ensure that this gets centered on the screen when we
// link to this anchor tag.
//
// This is used for redirecting users after they like a post, when we
// want the like button that they just clicked to remain close-ish to
// where it was before they clicked the button.
div({ id: `centered-footer-${encoded.key}`, class: "centered-footer" }),
footer(
form(
{ action: url.likeForm, method: "post" },
button(
{
name: "voteValue",
type: "submit",
value: likeButton.value,
class: likeButton.class
},
`${likeCount}`
)
),
a({ href: url.comment }, "Comment"),
isPrivate || isRoot || isFork ? null : a({ href: url.reply }, "Reply"),
a({ href: url.json }, "JSON")
)
);
return fragment;
};
exports.authorView = ({
avatarUrl,
@ -78,9 +227,7 @@ exports.authorView = ({
class: "md-mention",
innerHTML: markdownMention
}),
description !== "<p>null</p>\n"
? article({ innerHTML: description })
: null,
description !== "" ? article({ innerHTML: markdown(description) }) : null,
footer(
a({ href: `/likes/${encodeURIComponent(feedId)}` }, "View likes"),
span(relationship),

View File

@ -1,162 +0,0 @@
"use strict";
const {
a,
article,
button,
details,
div,
footer,
form,
header,
img,
section,
span,
summary,
pre
} = require("hyperaxe");
const highlightJs = require("highlight.js");
const lodash = require("lodash");
module.exports = ({ msg }) => {
const encoded = {
key: encodeURIComponent(msg.key),
author: encodeURIComponent(msg.value.author),
parent: encodeURIComponent(msg.value.content.root)
};
const url = {
author: `/author/${encoded.author}`,
likeForm: `/like/${encoded.key}`,
link: `/thread/${encoded.key}#${encoded.key}`,
parent: `/thread/${encoded.parent}#${encoded.parent}`,
avatar: msg.value.meta.author.avatar.url,
json: `/json/${encoded.key}`,
reply: `/reply/${encoded.key}`,
comment: `/comment/${encoded.key}`
};
const isPrivate = Boolean(msg.value.meta.private);
const isRoot = msg.value.content.root == null;
const isThreadTarget = Boolean(
lodash.get(msg, "value.meta.thread.target", false)
);
// TODO: I think this is actually true for both replies and comments.
const isReply = Boolean(lodash.get(msg, "value.meta.thread.reply", false));
const { name } = msg.value.meta.author;
const timeAgo = msg.value.meta.timestamp.received.since.replace("~", "");
const depth = lodash.get(msg, "value.meta.thread.depth", 0);
const markdownContent = msg.value.meta.md.block();
const hasContentWarning =
typeof msg.value.content.contentWarning === "string";
const likeButton = msg.value.meta.voted
? { value: 0, class: "liked" }
: { value: 1, class: null };
const likeCount = msg.value.meta.votes.length;
const messageClasses = [];
if (isPrivate) {
messageClasses.push("private");
}
if (isThreadTarget) {
messageClasses.push("thread-target");
}
if (isReply) {
// True for comments too, I think
messageClasses.push("reply");
}
const isFork = msg.value.meta.postType === "reply";
const postOptions = {
post: null,
comment: ["commented on ", a({ href: url.parent }, " thread")],
reply: ["replied to ", a({ href: url.parent }, " message")],
mystery: "posted a mysterious message"
};
const emptyContent = "<p>undefined</p>\n";
const articleElement =
markdownContent === emptyContent
? article(
{ class: "content" },
pre({
innerHTML: highlightJs.highlight(
"json",
JSON.stringify(msg, null, 2)
).value
})
)
: article({ class: "content", innerHTML: markdownContent });
const articleContent = hasContentWarning
? details(summary(msg.value.content.contentWarning), articleElement)
: articleElement;
const fragment = section(
{
id: msg.key,
class: messageClasses.join(" "),
style: `margin-left: ${depth}rem;`
},
header(
span(
{ class: "author" },
a(
{ href: url.author },
img({ class: "avatar", src: url.avatar, alt: "" }),
name
),
postOptions[msg.value.meta.postType]
),
span(
{ class: "time" },
isPrivate ? "🔒" : null,
a({ href: url.link }, timeAgo)
)
),
articleContent,
// HACK: centered-footer
//
// Here we create an empty div with an anchor tag that can be linked to.
// In our CSS we ensure that this gets centered on the screen when we
// link to this anchor tag.
//
// This is used for redirecting users after they like a post, when we
// want the like button that they just clicked to remain close-ish to
// where it was before they clicked the button.
div({ id: `centered-footer-${encoded.key}`, class: "centered-footer" }),
footer(
form(
{ action: url.likeForm, method: "post" },
button(
{
name: "voteValue",
type: "submit",
value: likeButton.value,
class: likeButton.class
},
`${likeCount}`
)
),
a({ href: url.comment }, "Comment"),
isPrivate || isRoot || isFork ? null : a({ href: url.reply }, "Reply"),
a({ href: url.json }, "JSON")
)
);
return fragment;
};