351 lines
7.7 KiB
JavaScript
351 lines
7.7 KiB
JavaScript
"use strict";
|
|
|
|
const debug = require("debug")("oasis");
|
|
const ssbMarkdown = require("ssb-markdown");
|
|
const highlightJs = require("highlight.js");
|
|
|
|
const {
|
|
a,
|
|
article,
|
|
button,
|
|
code,
|
|
div,
|
|
footer,
|
|
form,
|
|
h1,
|
|
h2,
|
|
h3,
|
|
header,
|
|
img,
|
|
input,
|
|
label,
|
|
li,
|
|
option,
|
|
p,
|
|
pre,
|
|
progress,
|
|
section,
|
|
select,
|
|
span,
|
|
strong,
|
|
textarea,
|
|
ul
|
|
} = require("hyperaxe");
|
|
|
|
const template = require("./template");
|
|
const post = require("./post");
|
|
|
|
exports.authorView = ({
|
|
avatarUrl,
|
|
description,
|
|
feedId,
|
|
messages,
|
|
name,
|
|
relationship
|
|
}) => {
|
|
const mention = `[@${name}](${feedId})`;
|
|
const markdownMention = highlightJs.highlight("markdown", mention).value;
|
|
|
|
const areFollowing = relationship === "you are following";
|
|
|
|
const contactFormType = areFollowing ? "unfollow" : "follow";
|
|
|
|
// We're on our own profile!
|
|
const contactForm =
|
|
relationship !== null
|
|
? form(
|
|
{
|
|
action: `/${contactFormType}/${encodeURIComponent(feedId)}`,
|
|
method: "post"
|
|
},
|
|
button(
|
|
{
|
|
type: "submit"
|
|
},
|
|
contactFormType
|
|
)
|
|
)
|
|
: null;
|
|
|
|
const prefix = section(
|
|
{ class: "message" },
|
|
header(
|
|
{ class: "profile" },
|
|
img({ class: "avatar", src: avatarUrl }),
|
|
h1(name)
|
|
),
|
|
pre({
|
|
class: "md-mention",
|
|
innerHTML: markdownMention
|
|
}),
|
|
description !== "<p>null</p>\n"
|
|
? article({ innerHTML: description })
|
|
: null,
|
|
footer(
|
|
a({ href: `/likes/${encodeURIComponent(feedId)}` }, "view likes"),
|
|
span(relationship),
|
|
contactForm
|
|
)
|
|
);
|
|
|
|
return template(
|
|
prefix,
|
|
messages.map(msg => post({ msg }))
|
|
);
|
|
};
|
|
|
|
exports.commentView = async ({ messages, myFeedId, parentMessage }) => {
|
|
let markdownMention;
|
|
|
|
const messageElements = await Promise.all(
|
|
messages.reverse().map(message => {
|
|
debug("%O", message);
|
|
const authorName = message.value.meta.author.name;
|
|
const authorFeedId = message.value.author;
|
|
if (authorFeedId !== myFeedId) {
|
|
if (message.key === parentMessage.key) {
|
|
const x = `[@${authorName}](${authorFeedId})\n\n`;
|
|
markdownMention = x;
|
|
}
|
|
}
|
|
return post({ msg: message });
|
|
})
|
|
);
|
|
|
|
const action = `/comment/${encodeURIComponent(messages[0].key)}`;
|
|
const method = "post";
|
|
|
|
const isPrivate = parentMessage.value.meta.private;
|
|
|
|
const publicOrPrivate = isPrivate ? "private" : "public";
|
|
const maybeReplyText = isPrivate
|
|
? null
|
|
: [
|
|
" Messages cannot be edited or deleted. To respond to an individual message, select ",
|
|
strong("reply"),
|
|
" instead."
|
|
];
|
|
|
|
return template(
|
|
messageElements,
|
|
p(
|
|
"Write a ",
|
|
strong(`${publicOrPrivate} comment`),
|
|
" on this thread with ",
|
|
a({ href: "https://commonmark.org/help/" }, "Markdown"),
|
|
".",
|
|
maybeReplyText
|
|
),
|
|
form(
|
|
{ action, method },
|
|
textarea(
|
|
{
|
|
autofocus: true,
|
|
required: true,
|
|
name: "text"
|
|
},
|
|
markdownMention
|
|
),
|
|
button(
|
|
{
|
|
type: "submit"
|
|
},
|
|
"comment"
|
|
)
|
|
)
|
|
);
|
|
};
|
|
|
|
exports.listView = ({ messages }) =>
|
|
template(messages.map(msg => post({ msg })));
|
|
|
|
exports.markdownView = ({ text }) => {
|
|
const rawHtml = ssbMarkdown.block(text);
|
|
|
|
return template(section({ class: "message" }, { innerHTML: rawHtml }));
|
|
};
|
|
|
|
exports.metaView = ({ status, peers, theme, themeNames }) => {
|
|
const max = status.sync.since;
|
|
|
|
const progressElements = Object.entries(status.sync.plugins).map(e => {
|
|
const [key, val] = e;
|
|
const id = `progress-${key}`;
|
|
return div(label({ for: id }, key), progress({ id, value: val, max }, val));
|
|
});
|
|
|
|
const peerList = (peers || []).map(([, data]) =>
|
|
li(a({ href: `/author/${encodeURIComponent(data.key)}` }, code(data.key)))
|
|
);
|
|
|
|
const themeElements = themeNames.map(cur => {
|
|
const isCurrentTheme = cur === theme;
|
|
if (isCurrentTheme) {
|
|
return option({ value: cur, selected: true }, cur);
|
|
} else {
|
|
return option({ value: cur }, cur);
|
|
}
|
|
});
|
|
|
|
const base16 = [
|
|
// '00', removed because this is the background
|
|
"01",
|
|
"02",
|
|
"03",
|
|
"04",
|
|
"05",
|
|
"06",
|
|
"07",
|
|
"08",
|
|
"09",
|
|
"0A",
|
|
"0B",
|
|
"0C",
|
|
"0D",
|
|
"0E",
|
|
"0F"
|
|
];
|
|
|
|
const base16Elements = base16.map(base =>
|
|
div({
|
|
style: {
|
|
"background-color": `var(--base${base})`,
|
|
width: `${(1 / base16.length) * 100}%`,
|
|
height: "1em",
|
|
"margin-top": "1em",
|
|
display: "inline-block"
|
|
}
|
|
})
|
|
);
|
|
|
|
return template(
|
|
section(
|
|
{ class: "message" },
|
|
h1("Meta"),
|
|
p(
|
|
"Check out ",
|
|
a({ href: "/meta/readme" }, "the readme"),
|
|
", configure your theme, or view debugging information below."
|
|
),
|
|
h2("Theme"),
|
|
p(
|
|
"Choose from any theme you'd like. The default theme is Atelier-SulphurPool-Light."
|
|
),
|
|
form(
|
|
{ action: "/theme.css", method: "post" },
|
|
select({ name: "theme" }, ...themeElements),
|
|
button({ type: "submit" }, "set theme")
|
|
),
|
|
base16Elements,
|
|
h2("Status"),
|
|
h3("Indexes"),
|
|
progressElements,
|
|
peerList.length > 0 ? [h3("Peers"), ul(peerList)] : null
|
|
)
|
|
);
|
|
};
|
|
|
|
exports.publicView = ({ messages, prefix = null }) => {
|
|
const publishForm = "/publish/";
|
|
|
|
return template(
|
|
prefix,
|
|
section(
|
|
header(strong("🌐 Publish")),
|
|
form(
|
|
{ action: publishForm, method: "post" },
|
|
label(
|
|
{ for: "text" },
|
|
"Write a new message in ",
|
|
a(
|
|
{
|
|
href: "https://commonmark.org/help/",
|
|
target: "_blank"
|
|
},
|
|
"Markdown"
|
|
),
|
|
". Messages cannot be edited or deleted."
|
|
),
|
|
textarea({ required: true, name: "text" }),
|
|
button({ type: "submit" }, "submit")
|
|
)
|
|
),
|
|
messages.map(msg => post({ msg }))
|
|
);
|
|
};
|
|
|
|
exports.replyView = async ({ messages, myFeedId }) => {
|
|
const replyForm = `/reply/${encodeURIComponent(
|
|
messages[messages.length - 1].key
|
|
)}`;
|
|
|
|
let markdownMention;
|
|
|
|
const messageElements = await Promise.all(
|
|
messages.reverse().map(message => {
|
|
debug("%O", message);
|
|
const authorName = message.value.meta.author.name;
|
|
const authorFeedId = message.value.author;
|
|
if (authorFeedId !== myFeedId) {
|
|
if (message.key === messages[0].key) {
|
|
const x = `[@${authorName}](${authorFeedId})\n\n`;
|
|
markdownMention = x;
|
|
}
|
|
}
|
|
return post({ msg: message });
|
|
})
|
|
);
|
|
|
|
return template(
|
|
messageElements,
|
|
p(
|
|
"Write a ",
|
|
strong("public reply"),
|
|
" to this message with ",
|
|
a({ href: "https://commonmark.org/help/" }, "Markdown"),
|
|
". Messages cannot be edited or deleted. To respond to an entire thread, select ",
|
|
strong("comment"),
|
|
" instead."
|
|
),
|
|
form(
|
|
{ action: replyForm, method: "post" },
|
|
textarea(
|
|
{
|
|
autofocus: true,
|
|
required: true,
|
|
name: "text"
|
|
},
|
|
markdownMention
|
|
),
|
|
button(
|
|
{
|
|
type: "submit"
|
|
},
|
|
"reply"
|
|
)
|
|
)
|
|
);
|
|
};
|
|
|
|
exports.searchView = ({ messages, query }) =>
|
|
template(
|
|
section(
|
|
form(
|
|
{ action: "/search", method: "get" },
|
|
header(strong("Search")),
|
|
label(
|
|
{ for: "query" },
|
|
"Add word(s) to look for in downloaded messages."
|
|
),
|
|
input({ required: true, type: "search", name: "query", value: query }),
|
|
button(
|
|
{
|
|
type: "submit"
|
|
},
|
|
"submit"
|
|
)
|
|
)
|
|
),
|
|
messages.map(msg => post({ msg }))
|
|
);
|