posting to topics and auto-join communities as needed fixes #30

This commit is contained in:
rimu 2024-02-08 18:34:58 +13:00
parent 9159764176
commit 95cd37e6b3
8 changed files with 129 additions and 2 deletions

View file

@ -352,6 +352,36 @@ def unsubscribe(actor):
abort(404) abort(404)
@bp.route('/<actor>/join_then_add', methods=['GET', 'POST'])
@login_required
@validation_required
def join_then_add(actor):
community = actor_to_community(actor)
if not current_user.subscribed(community.id):
if not community.is_local():
# send ActivityPub message to remote community, asking to follow. Accept message will be sent to our shared inbox
join_request = CommunityJoinRequest(user_id=current_user.id, community_id=community.id)
db.session.add(join_request)
db.session.commit()
follow = {
"actor": f"https://{current_app.config['SERVER_NAME']}/u/{current_user.user_name}",
"to": [community.ap_profile_id],
"object": community.ap_profile_id,
"type": "Follow",
"id": f"https://{current_app.config['SERVER_NAME']}/activities/follow/{join_request.id}"
}
success = post_request(community.ap_inbox_url, follow, current_user.private_key,
current_user.profile_id() + '#main-key')
member = CommunityMember(user_id=current_user.id, community_id=community.id)
db.session.add(member)
db.session.commit()
flash('You joined ' + community.title)
if not community.user_is_banned(current_user):
return redirect(url_for('community.add_post', actor=community.link()))
else:
abort(401)
@bp.route('/<actor>/submit', methods=['GET', 'POST']) @bp.route('/<actor>/submit', methods=['GET', 'POST'])
@login_required @login_required
@validation_required @validation_required

View file

@ -9,6 +9,7 @@ document.addEventListener("DOMContentLoaded", function () {
setupMobileNav(); setupMobileNav();
setupLightDark(); setupLightDark();
setupKeyboardShortcuts(); setupKeyboardShortcuts();
setupTopicChooser();
}); });
@ -487,6 +488,26 @@ function setupKeyboardShortcuts() {
}); });
} }
function setupTopicChooser() {
// at /topic/news/submit, clicking on an anchor element needs to save the clicked community id to a hidden field and then submit the form
var chooseTopicLinks = document.querySelectorAll('a.choose_topic_for_post');
chooseTopicLinks.forEach(function(link) {
link.addEventListener('click', function(event) {
event.preventDefault();
var communityIdInput = document.getElementById('community_id');
var communityForm = document.getElementById('choose_community');
// Set the value of the hidden input field
if (communityIdInput) {
communityIdInput.value = this.getAttribute('data-id');
}
if (communityForm) {
communityForm.submit();
}
});
});
}
function formatTime(seconds) { function formatTime(seconds) {
const hours = Math.floor(seconds / 3600); const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60); const minutes = Math.floor((seconds % 3600) / 60);

View file

@ -1164,4 +1164,12 @@ fieldset legend {
top: 0; top: 0;
} }
#choose_community table th {
white-space: nowrap;
overflow: hidden;
}
#choose_community table th img {
vertical-align: middle;
}
/*# sourceMappingURL=structure.css.map */ /*# sourceMappingURL=structure.css.map */

View file

@ -849,3 +849,13 @@ fieldset {
.skip-link:focus { .skip-link:focus {
top: 0; top: 0;
} }
#choose_community {
table th {
white-space: nowrap;
overflow: hidden;
img {
vertical-align: middle;
}
}
}

View file

@ -105,7 +105,7 @@
<div class="card-body"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-6"> <div class="col-6">
<a class="w-100 btn btn-primary" href="/community/{{ community.link() }}/submit">{{ _('Create a post') }}</a> <a class="w-100 btn btn-primary" href="/community/{{ community.link() }}/submit" rel="nofollow">{{ _('Create post') }}</a>
</div> </div>
<div class="col-6"> <div class="col-6">
{% if current_user.is_authenticated and community_membership(current_user, community) in [SUBSCRIPTION_MEMBER, SUBSCRIPTION_MODERATOR, SUBSCRIPTION_OWNER] %} {% if current_user.is_authenticated and community_membership(current_user, community) in [SUBSCRIPTION_MEMBER, SUBSCRIPTION_MODERATOR, SUBSCRIPTION_OWNER] %}

View file

@ -52,6 +52,18 @@
</div> </div>
<aside id="side_pane" class="col-12 col-md-4 side_pane" role="complementary"> <aside id="side_pane" class="col-12 col-md-4 side_pane" role="complementary">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-6">
<a class="w-100 btn btn-primary" href="{{ url_for('topic.topic_create_post', topic_name=topic.machine_name) }}" rel="nofollow">{{ _('Create post') }}</a>
</div>
<div class="col-6">
</div>
</div>
</div>
</div>
{% if topic_communities %} {% if topic_communities %}
<div class="card mt-3"> <div class="card mt-3">
<div class="card-header"> <div class="card-header">

View file

@ -0,0 +1,30 @@
{% extends 'base.html' %}
{% from 'bootstrap/form.html' import render_form %}
{% block app_content %}
<div class="row">
<div class="col col-login mx-auto">
<div class="card mt-5">
<div class="card-body p-6" id="choose_topics_card">
<div class="card-title text-center">{{ _('Which community within %(topic)s to post in?', topic=topic.name) }}</div>
<form method="post" id="choose_community">
<input type="hidden" name="community_id" id="community_id" />
<table class="communities_table table table-hover w-100">
<tbody>
{% for community in communities %}
{% if not community.user_is_banned(current_user) %}
<tr>
<th class="pl-2"><a class="choose_topic_for_post" data-id="{{ community.id }}" href="/community/{{ community.link() }}/submit" rel="nofollow" aria-label="{{ _('Post in %(name)s', name=community.display_name()) }}"><img src="{{ community.icon_image('tiny') }}" class="community_icon rounded-circle" loading="lazy" alt="" />
{{ community.display_name() }}</a></th>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -14,7 +14,7 @@ from app.topic import bp
from app import db, celery, cache from app import db, celery, cache
from app.topic.forms import ChooseTopicsForm from app.topic.forms import ChooseTopicsForm
from app.utils import render_template, user_filters_posts, moderating_communities, joined_communities, \ from app.utils import render_template, user_filters_posts, moderating_communities, joined_communities, \
community_membership, blocked_domains community_membership, blocked_domains, validation_required
@bp.route('/topic/<topic_name>', methods=['GET']) @bp.route('/topic/<topic_name>', methods=['GET'])
@ -109,6 +109,22 @@ def choose_topics():
) )
@bp.route('/topic/<topic_name>/submit', methods=['GET', 'POST'])
@login_required
@validation_required
def topic_create_post(topic_name):
topic = Topic.query.filter(Topic.machine_name == topic_name.strip().lower()).first()
if not topic:
abort(404)
communities = Community.query.filter_by(topic_id=topic.id, banned=False).order_by(Community.title).all()
if request.form.get('community_id', '') != '':
community = Community.query.get_or_404(int(request.form.get('community_id')))
return redirect(url_for('community.join_then_add', actor=community.link()))
return render_template('topic/topic_create_post.html', communities=communities, topic=topic,
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()))
def topics_for_form(): def topics_for_form():
topics = Topic.query.order_by(Topic.name).all() topics = Topic.query.order_by(Topic.name).all()
result = [] result = []