Create 'Summaries' page for new summary view

Problem: Until we have a way to change the view of each page, it seems
to me that each of the views that we're experimenting with should be on
their own page rather than modifying the existing pages to add more
functionality. I'm also noticing that I can't process all of the
information that's on the screen when the new horizontal layout is used,
and I think we would benefit from using the previous layout
consistently.

Solution: Move the summary view to its own page so that we can continue
to iterate on it without modifying the popular view, which is already
complex, and revert the style changes to maintain consistency with the
rest of the linear design (threads go downward, indentation denotes
sub-threads, etc).
This commit is contained in:
Christian Bundy 2020-02-17 12:08:03 -08:00
parent 5b37240067
commit 58b4d419f7
5 changed files with 98 additions and 42 deletions

View File

@ -331,7 +331,6 @@ section {
word-wrap: break-word;
background: var(--bg);
width: 100%;
max-width: var(--measure);
box-sizing: border-box;
}
@ -399,32 +398,6 @@ section > footer > form > button.liked {
color: var(--red);
}
.post-aside-wrapper {
display: flex;
flex-direction: column;
align-items: flex-start;
}
@media (min-width: 80rem) {
.post-aside-wrapper {
flex-direction: row;
}
}
.post-aside {
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-items: flex-start;
padding-left: var(--micro);
margin: var(--whole) 0;
}
.post-aside section {
max-width: var(--peta);
margin: 0 0 var(--micro) 0;
}
label {
display: block;
margin: 0;
@ -522,7 +495,8 @@ hr {
margin-bottom: var(--whole);
}
main {
width: 85vw;
width: 100%;
max-width: var(--measure);
}
body {
display: flex;
@ -538,3 +512,11 @@ hr {
.emoji {
font-family: initial;
}
/* This indent is used on the summaries page to create an indent of 1. It might
* be wise to nest these recursively on the thread view, which would make it so
* that we don't need any inline CSS anymore.
*/
.indent {
margin-left: 1rem;
}

View File

@ -63,7 +63,8 @@ const {
searchView,
setLanguage,
settingsView,
topicsView
topicsView,
summaryView
} = require("./views");
let sharp;
@ -147,6 +148,10 @@ router
const messages = await post.latestTopics();
ctx.body = await topicsView({ messages });
})
.get("/public/latest/summaries", async ctx => {
const messages = await post.latestSummaries();
ctx.body = await summaryView({ messages });
})
.get("/author/:feed", async ctx => {
const { feed } = ctx.params;
const author = async feedId => {

View File

@ -808,6 +808,55 @@ module.exports = ({ cooler, isPublic }) => {
return messages;
},
latestSummaries: async () => {
const ssb = await cooler.open();
const myFeedId = ssb.id;
const options = configure({
type: "post",
private: false
});
const source = ssb.messagesByType(options);
const extendedFilter = await socialFilter({
following: true
});
const messages = await new Promise((resolve, reject) => {
pull(
source,
pull.filter(
message =>
typeof message.value.content !== "string" &&
message.value.content.root == null
),
extendedFilter,
pull.take(maxMessages),
pullParallelMap(async (message, cb) => {
// Retrieve a preview of this post's comments / thread
const thread = await post.fromThread(message.key);
lodash.set(
message,
"value.meta.thread",
await transform(ssb, thread, myFeedId)
);
cb(null, message);
}),
pull.collect((err, collectedMessages) => {
if (err) {
reject(err);
} else {
resolve(transform(ssb, collectedMessages, myFeedId));
}
})
);
});
return messages;
},
popular: async ({ period }) => {
const ssb = await cooler.open();
@ -904,10 +953,6 @@ module.exports = ({ cooler, isPublic }) => {
pullParallelMap(async (key, cb) => {
try {
const msg = await post.get(key);
// Retrieve a preview of this post's comments / thread
const thread = await post.fromThread(key);
msg.thread = await transform(ssb, thread, myFeedId);
cb(null, msg);
} catch (e) {
cb(null, null);

View File

@ -24,6 +24,11 @@ module.exports = {
strong("Topics"),
" from people you follow, sorted by recency. Select the timestamp of any post to see the rest of the thread."
],
summaries: "Summaries",
summariesDescription: [
strong("Topics and some comments"),
" from people you follow, sorted by recency. Select the timestamp of any post to see the rest of the thread."
],
profile: "Profile",
manualMode: "Manual Mode",
mentions: "Mentions",

View File

@ -108,6 +108,11 @@ const template = (...elements) => {
emoji: "📖",
text: i18n.topics
}),
navLink({
href: "/public/latest/summaries",
emoji: "🗒️",
text: i18n.summaries
}),
navLink({ href: "/profile", emoji: "🐱", text: i18n.profile }),
navLink({ href: "/mentions", emoji: "💬", text: i18n.mentions }),
navLink({ href: "/inbox", emoji: "✉️", text: i18n.private }),
@ -282,7 +287,8 @@ const continueThreadComponent = (thread, isComment) => {
*
* @param {Object} post for which to display the aside
*/
const postAside = ({ key, value, thread }) => {
const postAside = ({ key, value }) => {
const thread = value.meta.thread;
if (thread == null) return null;
const isComment = value.meta.postType === "comment";
@ -306,10 +312,11 @@ const postAside = ({ key, value, thread }) => {
if (thread.length > THREAD_PREVIEW_LENGTH + 1) {
fragments.push(section(footer(continueThreadComponent(thread, isComment))));
}
return div({ class: "post-aside" }, fragments);
return div({ class: "indent" }, fragments);
};
const post = ({ msg }) => {
const post = ({ msg, aside = false }) => {
const encoded = {
key: encodeURIComponent(msg.key),
author: encodeURIComponent(msg.value.author),
@ -452,9 +459,11 @@ const post = ({ msg }) => {
)
);
const aside = postAside(msg);
const wrapper = div({ class: "post-aside-wrapper" }, fragment, aside);
return wrapper;
if (aside) {
return [fragment, postAside(msg)];
} else {
return fragment;
}
};
exports.authorView = ({
@ -834,14 +843,15 @@ exports.likesView = async ({ messages, feed, name }) => {
const messageListView = ({
messages,
prefix = null,
viewTitle = null,
viewDescription = null,
viewElements = null
viewElements = null,
// If `aside = true`, it will show a few comments in the thread.
aside = null
}) => {
return template(
section(h1(viewTitle), p(viewDescription), viewElements),
messages.map(msg => post({ msg }))
messages.map(msg => post({ msg, aside }))
);
};
@ -878,6 +888,15 @@ exports.topicsView = ({ messages }) => {
});
};
exports.summaryView = ({ messages }) => {
return messageListView({
messages,
viewTitle: i18n.summaries,
viewDescription: i18n.summariesDescription,
aside: true
});
};
exports.replyView = async ({ messages, myFeedId }) => {
const replyForm = `/reply/${encodeURIComponent(
messages[messages.length - 1].key