Add button to join/leave communities
This commit is contained in:
parent
bf7f2e7aeb
commit
5282ba0648
|
@ -501,9 +501,13 @@ router.get(
|
||||||
|
|
||||||
const communityData = (req) => {
|
const communityData = (req) => {
|
||||||
const name = req.params.name;
|
const name = req.params.name;
|
||||||
return queries.getCommunityMembers(name).then((members) => ({
|
return Promise.all([
|
||||||
|
queries.getCommunityMembers(name),
|
||||||
|
queries.isMember(req.context.profile.id, name),
|
||||||
|
]).then(([members, isMember]) => ({
|
||||||
name,
|
name,
|
||||||
members,
|
members,
|
||||||
|
isMember,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -558,6 +562,38 @@ router.post("/communities/:name/new", async (req, res) => {
|
||||||
res.redirect(`/communities/${name}/${topic.key.replace("%", "")}`);
|
res.redirect(`/communities/${name}/${topic.key.replace("%", "")}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.post("/communities/:name/join", async (req, res) => {
|
||||||
|
const name = req.params.name;
|
||||||
|
|
||||||
|
await ssb.client().identities.publishAs({
|
||||||
|
id: req.context.profile.id,
|
||||||
|
private: false,
|
||||||
|
content: {
|
||||||
|
type: "channel",
|
||||||
|
channel: name,
|
||||||
|
subscribed: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
res.redirect(`/communities/${name}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post("/communities/:name/leave", async (req, res) => {
|
||||||
|
const name = req.params.name;
|
||||||
|
|
||||||
|
await ssb.client().identities.publishAs({
|
||||||
|
id: req.context.profile.id,
|
||||||
|
private: false,
|
||||||
|
content: {
|
||||||
|
type: "channel",
|
||||||
|
channel: name,
|
||||||
|
subscribed: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
res.redirect(`/communities/${name}`);
|
||||||
|
});
|
||||||
|
|
||||||
router.post("/communities/:name/:key(*)/publish", async (req, res) => {
|
router.post("/communities/:name/:key(*)/publish", async (req, res) => {
|
||||||
const name = req.params.name;
|
const name = req.params.name;
|
||||||
const key = req.params.key;
|
const key = req.params.key;
|
||||||
|
|
|
@ -94,13 +94,14 @@ module.exports.setupRoutes = (router) => {
|
||||||
async (req, res) => {
|
async (req, res) => {
|
||||||
const name = req.params.name;
|
const name = req.params.name;
|
||||||
|
|
||||||
const [posts, members] = await Promise.all([
|
const [posts, members, isMember] = await Promise.all([
|
||||||
queries.getCommunityPosts(name),
|
queries.getCommunityPosts(name),
|
||||||
queries.getCommunityMembers(name),
|
queries.getCommunityMembers(name),
|
||||||
|
queries.isMember(req.context.profile.id, name),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
res.render("mobile/communities/community", {
|
res.render("mobile/communities/community", {
|
||||||
community: { name, members },
|
community: { name, members, isMember },
|
||||||
posts,
|
posts,
|
||||||
layout: "mobile/_layout",
|
layout: "mobile/_layout",
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,7 +8,8 @@ const debugPosts = require("debug")("queries:posts"),
|
||||||
debugProfile = require("debug")("queries:profile"),
|
debugProfile = require("debug")("queries:profile"),
|
||||||
debugCommunities = require("debug")("queries:communities"),
|
debugCommunities = require("debug")("queries:communities"),
|
||||||
debugCommunityMembers = require("debug")("queries:communityMembers"),
|
debugCommunityMembers = require("debug")("queries:communityMembers"),
|
||||||
debugCommunityPosts = require("debug")("queries:communityPosts");
|
debugCommunityPosts = require("debug")("queries:communityPosts"),
|
||||||
|
debugCommunityIsMember = require("debug")("queries:communityIsMember");
|
||||||
const paramap = require("pull-paramap");
|
const paramap = require("pull-paramap");
|
||||||
const { promisePull, mapValues } = require("./utils");
|
const { promisePull, mapValues } = require("./utils");
|
||||||
const ssb = require("./ssb-client");
|
const ssb = require("./ssb-client");
|
||||||
|
@ -450,6 +451,32 @@ const getCommunities = async () => {
|
||||||
return communities;
|
return communities;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isMember = async (id, channel) => {
|
||||||
|
debugCommunityIsMember("Fetching");
|
||||||
|
const [lastSubscription] = await promisePull(
|
||||||
|
ssb.client().query.read({
|
||||||
|
reverse: true,
|
||||||
|
limit: 1,
|
||||||
|
query: [
|
||||||
|
{
|
||||||
|
$filter: {
|
||||||
|
value: {
|
||||||
|
author: id,
|
||||||
|
content: {
|
||||||
|
type: "channel",
|
||||||
|
channel: channel,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
debugCommunityIsMember("Done");
|
||||||
|
|
||||||
|
return lastSubscription && lastSubscription.value.content.subscribed;
|
||||||
|
};
|
||||||
|
|
||||||
const getCommunityMembers = async (name) => {
|
const getCommunityMembers = async (name) => {
|
||||||
debugCommunityMembers("Fetching");
|
debugCommunityMembers("Fetching");
|
||||||
|
|
||||||
|
@ -472,10 +499,22 @@ const getCommunityMembers = async (name) => {
|
||||||
}),
|
}),
|
||||||
paramap(mapProfiles)
|
paramap(mapProfiles)
|
||||||
);
|
);
|
||||||
|
const dedupMembers = {};
|
||||||
|
for (const member of communityMembers) {
|
||||||
|
const author = member.value.author;
|
||||||
|
if (dedupMembers[author]) continue;
|
||||||
|
dedupMembers[author] = member;
|
||||||
|
}
|
||||||
|
const onlySubscribedMembers = Object.values(dedupMembers).filter(
|
||||||
|
(x) => x.value.content.subscribed
|
||||||
|
);
|
||||||
|
const memberProfiles = onlySubscribedMembers.map(
|
||||||
|
(x) => x.value.authorProfile
|
||||||
|
);
|
||||||
|
|
||||||
debugCommunityMembers("Done");
|
debugCommunityMembers("Done");
|
||||||
|
|
||||||
return communityMembers.map((x) => x.value.authorProfile);
|
return memberProfiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPostWithReplies = async (channel, key) => {
|
const getPostWithReplies = async (channel, key) => {
|
||||||
|
@ -611,4 +650,5 @@ module.exports = {
|
||||||
getPostWithReplies,
|
getPostWithReplies,
|
||||||
progress,
|
progress,
|
||||||
autofollow,
|
autofollow,
|
||||||
|
isMember,
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div style="background: #9b5f5f; padding: 50px; border-radius: 5px 5px 0 0">
|
<div style="background: #9b5f5f; padding: 14px; border-radius: 5px 5px 0 0">
|
||||||
<div style="max-width: 1200px; margin: 0 auto">
|
<div style="max-width: 1200px; margin: 0 auto; padding: 36px;">
|
||||||
<h1 style="font-size: 60px">
|
<h1 style="font-size: 60px">
|
||||||
<a href="/communities/<%= community.name %>" style="color: #FFF; text-decoration: none;">
|
<a href="/communities/<%= community.name %>" style="color: #FFF; text-decoration: none;">
|
||||||
#<%= community.name %>
|
#<%= community.name %>
|
||||||
|
@ -19,7 +19,12 @@
|
||||||
<div style="max-width: 1200px; margin: 0 auto; border-radius: 0 0 5px 5px">
|
<div style="max-width: 1200px; margin: 0 auto; border-radius: 0 0 5px 5px">
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="friends-communities" style="border-radius: 0">
|
<div class="friends-communities" style="border-radius: 0">
|
||||||
<h2>Members</h2>
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||||
|
<h2 style="margin: 0;">Members</h2>
|
||||||
|
<div>
|
||||||
|
<%- include('../shared/_join_button') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<%- include('../_friends', { friends: community.members }) %>
|
<%- include('../_friends', { friends: community.members }) %>
|
||||||
</div>
|
</div>
|
||||||
<div class="wall">
|
<div class="wall">
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
<div class="pink-background" style="flex-grow: 0;">
|
<div class="pink-background" style="flex-grow: 0;">
|
||||||
|
<div style="display: flex; justify-content: space-between;">
|
||||||
<h1>
|
<h1>
|
||||||
<a href="/communities/<%= community.name %>" style="color: #600; text-decoration: none;">
|
<a href="/communities/<%= community.name %>" style="color: #600; text-decoration: none;">
|
||||||
#<%= community.name %>
|
#<%= community.name %>
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
|
<%- include('../../shared/_join_button') %>
|
||||||
|
</div>
|
||||||
<a href="/mobile/communities/<%= community.name %>/new" class="compose-new-button" style="background: #fbb">
|
<a href="/mobile/communities/<%= community.name %>/new" class="compose-new-button" style="background: #fbb">
|
||||||
<div style="font-size: 40px; color: #FFF">+</div>
|
<div style="font-size: 40px; color: #FFF">+</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -19,7 +22,7 @@
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div class="tab-item js-tab-item">
|
<div class="tab-item js-tab-item">
|
||||||
<% posts.map(post => { %>
|
<% posts.map(post => { %>
|
||||||
<a href="/communities/<%= community.name %>/<%= post.key.replace("%", "") %>" class="columns community-topic-link">
|
<a href="/mobile/communities/<%= community.name %>/<%= post.key.replace("%", "") %>" class="columns community-topic-link">
|
||||||
<div class="community-topic-name">
|
<div class="community-topic-name">
|
||||||
<%- topicTitle(post.value) %>
|
<%- topicTitle(post.value) %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<% if (community.isMember) { %>
|
||||||
|
<form action="/communities/<%= community.name %>/leave" method="POST">
|
||||||
|
<input type="submit" value="Leave" />
|
||||||
|
</form>
|
||||||
|
<% } else { %>
|
||||||
|
<form action="/communities/<%= community.name %>/join" method="POST">
|
||||||
|
<input type="submit" value="Join" />
|
||||||
|
</form>
|
||||||
|
<% } %>
|
Loading…
Reference in New Issue