Add communities, read-only for now
This commit is contained in:
parent
c376a4f065
commit
e33b8b9166
|
@ -294,7 +294,7 @@ router.get("/profile/:id(*)", async (req, res) => {
|
||||||
res.render("profile", { profile, posts, friends, friendshipStatus });
|
res.render("profile", { profile, posts, friends, friendshipStatus });
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post("/profile/:id/add_friend", async (req, res) => {
|
router.post("/profile/:id(*)/add_friend", async (req, res) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id;
|
||||||
if (id == req.context.profile.id) {
|
if (id == req.context.profile.id) {
|
||||||
throw "cannot befriend yourself";
|
throw "cannot befriend yourself";
|
||||||
|
@ -313,7 +313,7 @@ router.post("/profile/:id/add_friend", async (req, res) => {
|
||||||
res.redirect(profileUrl(id));
|
res.redirect(profileUrl(id));
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post("/profile/:id/reject_friend", async (req, res) => {
|
router.post("/profile/:id(*)/reject_friend", async (req, res) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id;
|
||||||
if (id == req.context.profile.id) {
|
if (id == req.context.profile.id) {
|
||||||
throw "cannot reject yourself";
|
throw "cannot reject yourself";
|
||||||
|
@ -362,7 +362,7 @@ router.post("/vanish", async (req, res) => {
|
||||||
res.send("ok");
|
res.send("ok");
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post("/profile/:id/publish", async (req, res) => {
|
router.post("/profile/:id(*)/publish", async (req, res) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id;
|
||||||
const visibility = req.body.visibility;
|
const visibility = req.body.visibility;
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ router.post("/pubs/add", async (req, res) => {
|
||||||
res.redirect("/");
|
res.redirect("/");
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/about", (_req, res) => {
|
router.get("/about", (req, res) => {
|
||||||
if (!req.context.profile) {
|
if (!req.context.profile) {
|
||||||
return res.render("index");
|
return res.render("index");
|
||||||
}
|
}
|
||||||
|
@ -448,19 +448,26 @@ router.post("/about", async (req, res) => {
|
||||||
res.redirect("/");
|
res.redirect("/");
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/debug", async (req, res) => {
|
router.get("/communities", async (req, res) => {
|
||||||
const query = req.query || {};
|
if (!req.context.profile) {
|
||||||
|
return res.render("index");
|
||||||
|
}
|
||||||
|
const communities = await queries.getCommunities(ssbServer);
|
||||||
|
|
||||||
const entries = await queries.getAllEntries(ssbServer, query);
|
res.render("communities", { communities });
|
||||||
|
|
||||||
res.render("debug", { entries, query });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/debug-error", (_req, res) => {
|
router.get("/communities/:name", async (req, res) => {
|
||||||
const object = {};
|
const name = req.params.name;
|
||||||
object.isUndefinedAFunction();
|
if (!req.context.profile) {
|
||||||
|
return res.render("index");
|
||||||
|
}
|
||||||
|
const [members, posts] = await Promise.all([
|
||||||
|
queries.getCommunityMembers(ssbServer, name),
|
||||||
|
queries.getCommunityPosts(ssbServer, name),
|
||||||
|
]);
|
||||||
|
|
||||||
res.send("should never reach here");
|
res.render("community", { community: { name, members, posts } });
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get("/search", async (req, res) => {
|
router.get("/search", async (req, res) => {
|
||||||
|
@ -484,6 +491,21 @@ router.get("/syncing", (req, res) => {
|
||||||
res.json({ syncing });
|
res.json({ syncing });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get("/debug", async (req, res) => {
|
||||||
|
const query = req.query || {};
|
||||||
|
|
||||||
|
const entries = await queries.getAllEntries(ssbServer, query);
|
||||||
|
|
||||||
|
res.render("debug", { entries, query });
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/debug-error", (_req, res) => {
|
||||||
|
const object = {};
|
||||||
|
object.isUndefinedAFunction();
|
||||||
|
|
||||||
|
res.send("should never reach here");
|
||||||
|
});
|
||||||
|
|
||||||
router.get("/metrics", (_req, res) => {
|
router.get("/metrics", (_req, res) => {
|
||||||
res.set("Content-Type", metrics.register.contentType);
|
res.set("Content-Type", metrics.register.contentType);
|
||||||
res.end(metrics.register.metrics());
|
res.end(metrics.register.metrics());
|
||||||
|
|
|
@ -5,7 +5,10 @@ const debugPosts = require("debug")("queries:posts"),
|
||||||
debugFriends = require("debug")("queries:friends"),
|
debugFriends = require("debug")("queries:friends"),
|
||||||
debugFriendshipStatus = require("debug")("queries:friendship_status"),
|
debugFriendshipStatus = require("debug")("queries:friendship_status"),
|
||||||
debugPeople = require("debug")("queries:people"),
|
debugPeople = require("debug")("queries:people"),
|
||||||
debugProfile = require("debug")("queries:profile");
|
debugProfile = require("debug")("queries:profile"),
|
||||||
|
debugCommunities = require("debug")("queries:communities"),
|
||||||
|
debugCommunityMembers = require("debug")("queries:communityMembers"),
|
||||||
|
debugCommunityPosts = require("debug")("queries:communityPosts");
|
||||||
const paramap = require("pull-paramap");
|
const paramap = require("pull-paramap");
|
||||||
const { promisePull, mapValues } = require("./utils");
|
const { promisePull, mapValues } = require("./utils");
|
||||||
|
|
||||||
|
@ -276,7 +279,7 @@ const getAllEntries = (ssbServer, query) => {
|
||||||
return promisePull(
|
return promisePull(
|
||||||
ssbServer.query.read({
|
ssbServer.query.read({
|
||||||
reverse: true,
|
reverse: true,
|
||||||
limit: 500,
|
limit: 1000,
|
||||||
...queryOpts,
|
...queryOpts,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -327,6 +330,96 @@ const autofollow = async (ssbServer, id) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getCommunities = async (ssbServer) => {
|
||||||
|
debugCommunities("Fetching");
|
||||||
|
|
||||||
|
const communitiesPosts = await promisePull(
|
||||||
|
ssbServer.query.read({
|
||||||
|
reverse: true,
|
||||||
|
query: [
|
||||||
|
{
|
||||||
|
$filter: {
|
||||||
|
value: {
|
||||||
|
private: { $not: true },
|
||||||
|
content: {
|
||||||
|
type: "post",
|
||||||
|
channel: { $truthy: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
limit: 1000,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const communities = Array.from(
|
||||||
|
new Set(communitiesPosts.map((p) => p.value.content.channel))
|
||||||
|
);
|
||||||
|
|
||||||
|
debugCommunities("Done");
|
||||||
|
|
||||||
|
return communities;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCommunityMembers = async (ssbServer, name) => {
|
||||||
|
debugCommunityMembers("Fetching");
|
||||||
|
|
||||||
|
const communityMembers = await promisePull(
|
||||||
|
ssbServer.query.read({
|
||||||
|
reverse: true,
|
||||||
|
query: [
|
||||||
|
{
|
||||||
|
$filter: {
|
||||||
|
value: {
|
||||||
|
content: {
|
||||||
|
type: "channel",
|
||||||
|
channel: name,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
limit: 100,
|
||||||
|
}),
|
||||||
|
paramap(mapProfiles(ssbServer))
|
||||||
|
);
|
||||||
|
|
||||||
|
debugCommunityMembers("Done");
|
||||||
|
|
||||||
|
return communityMembers.map((x) => x.value.authorProfile);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCommunityPosts = async (ssbServer, name) => {
|
||||||
|
debugCommunityPosts("Fetching");
|
||||||
|
|
||||||
|
const communityPosts = await promisePull(
|
||||||
|
ssbServer.query.read({
|
||||||
|
reverse: true,
|
||||||
|
query: [
|
||||||
|
{
|
||||||
|
$filter: {
|
||||||
|
value: {
|
||||||
|
content: {
|
||||||
|
type: "post",
|
||||||
|
channel: name,
|
||||||
|
reply: { $not: true },
|
||||||
|
root: { $not: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
limit: 100,
|
||||||
|
}),
|
||||||
|
paramap(mapProfiles(ssbServer))
|
||||||
|
);
|
||||||
|
|
||||||
|
debugCommunityPosts("Done");
|
||||||
|
|
||||||
|
return mapValues(communityPosts);
|
||||||
|
};
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
debugProfile("Clearing profile cache");
|
debugProfile("Clearing profile cache");
|
||||||
profileCache = {};
|
profileCache = {};
|
||||||
|
@ -342,6 +435,9 @@ module.exports = {
|
||||||
getVanishingMessages,
|
getVanishingMessages,
|
||||||
profileCache,
|
profileCache,
|
||||||
getFriendshipStatus,
|
getFriendshipStatus,
|
||||||
|
getCommunities,
|
||||||
|
getCommunityMembers,
|
||||||
|
getCommunityPosts,
|
||||||
progress,
|
progress,
|
||||||
autofollow,
|
autofollow,
|
||||||
};
|
};
|
||||||
|
|
|
@ -102,6 +102,11 @@ header .logo a:hover {
|
||||||
margin-left: 7px;
|
margin-left: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-link-style {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -277,7 +282,7 @@ button.notification-box:hover {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.friend-item {
|
.link-block {
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
@ -289,7 +294,7 @@ button.notification-box:hover {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.friend-item:hover {
|
.link-block:hover {
|
||||||
background: #f0f0f0;
|
background: #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<% friends.map(friend => { %>
|
<% friends.map(friend => { %>
|
||||||
<a class="friend-item" href="<%= profileUrl(friend.id) %>">
|
<a class="link-block" href="<%= profileUrl(friend.id) %>">
|
||||||
<img style="width: 32px; max-height: 100px; margin-right: 5px;" src="<%= profileImageUrl(friend) %>" />
|
<img style="width: 32px; max-height: 100px; margin-right: 5px;" src="<%= profileImageUrl(friend) %>" />
|
||||||
<div><%= friend.name %></div>
|
<div><%= friend.name %></div>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
<nav>
|
<nav>
|
||||||
<a href="/">Profile</a>
|
<a href="/">Profile</a>
|
||||||
<a href="/about">About me</a>
|
<a href="/about">About me</a>
|
||||||
|
<a href="/communities">Communities</a>
|
||||||
<% if (context.profile.admin) { %>
|
<% if (context.profile.admin) { %>
|
||||||
<a href="/pubs">Pubs</a>
|
<a href="/pubs">Pubs</a>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
<div style="padding-top: 15px;">
|
<div style="padding-top: 15px;">
|
||||||
<% posts.map(post => { %>
|
<% posts.map(post => { %>
|
||||||
|
<% if (!post.content.text) return %>
|
||||||
<div class="post">
|
<div class="post">
|
||||||
<div>
|
<div>
|
||||||
<img src="<%= profileImageUrl(post.authorProfile) %>" class="post-profile-pic" />
|
<a href="<%= profileUrl(post.author) %>">
|
||||||
|
<img src="<%= profileImageUrl(post.authorProfile) %>" class="post-profile-pic" />
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="post-content">
|
<div class="post-content">
|
||||||
<div class="content-header">
|
<div class="content-header">
|
||||||
<%= post.authorProfile.name %>
|
<a href="<%= profileUrl(post.author) %>" class="no-link-style">
|
||||||
|
<%= post.authorProfile.name %>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="content-body">
|
<div class="content-body">
|
||||||
<% let text = post.content.text.slice(0, 140) %>
|
<% let text = post.content.text.slice(0, 140) %>
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<%- include('_header') %>
|
||||||
|
|
||||||
|
<h1>Communities</h1>
|
||||||
|
|
||||||
|
<div style="padding-top: 20px">
|
||||||
|
<% communities.map(community => { %>
|
||||||
|
<a href="/communities/<%= community %>" class="link-block" style="display: inline-block">
|
||||||
|
#<%= community %>
|
||||||
|
</a>
|
||||||
|
<% }) %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%- include('_footer') %>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<%- include('_header') %>
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
max-width: none;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div style="background: #666; color: #FFF; padding: 50px 0">
|
||||||
|
<div style="max-width: 1200px; margin: 0 auto">
|
||||||
|
<h1 style="font-size: 60px">#<%= community.name %></h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="max-width: 1200px; margin: 0 auto">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="about">
|
||||||
|
<h2>Members</h2>
|
||||||
|
<%- include('_friends', { friends: community.members }) %>
|
||||||
|
</div>
|
||||||
|
<div class="wall">
|
||||||
|
<h2>Posts</h2>
|
||||||
|
<%- include('_posts', { posts: community.posts }) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%- include('_footer') %>
|
Loading…
Reference in New Issue