diff --git a/app/activitypub/routes.py b/app/activitypub/routes.py index 0656f9f5..792c6c96 100644 --- a/app/activitypub/routes.py +++ b/app/activitypub/routes.py @@ -379,15 +379,18 @@ def shared_inbox(): if post_reply is not None: post = Post.query.get(post_id) - db.session.add(post_reply) - post.reply_count += 1 - community.post_reply_count += 1 - community.last_active = post.last_active = utcnow() - activity_log.result = 'success' - db.session.commit() - vote = PostReplyVote(user_id=user.id, author_id=post_reply.user_id, post_reply_id=post_reply.id, - effect=instance_weight(user.ap_domain)) - db.session.add(vote) + if post.comments_enabled: + db.session.add(post_reply) + post.reply_count += 1 + community.post_reply_count += 1 + community.last_active = post.last_active = utcnow() + activity_log.result = 'success' + db.session.commit() + vote = PostReplyVote(user_id=user.id, author_id=post_reply.user_id, post_reply_id=post_reply.id, + effect=instance_weight(user.ap_domain)) + db.session.add(vote) + else: + activity_log.exception_message = 'Comments disabled' else: activity_log.exception_message = 'Unacceptable type (kbin): ' + object_type @@ -472,9 +475,16 @@ def shared_inbox(): post_reply.body = html_to_markdown(post_reply.body_html) if post_reply is not None: - db.session.add(post_reply) - community.post_reply_count += 1 - db.session.commit() + post = Post.query.get(post_id) + if post.comments_enabled: + db.session.add(post_reply) + community.post_reply_count += 1 + community.last_active = utcnow() + post.last_active = utcnow() + activity_log.result = 'success' + db.session.commit() + else: + activity_log.exception_message = 'Comments disabled' else: activity_log.exception_message = 'Unacceptable type: ' + object_type diff --git a/app/models.py b/app/models.py index f13b559e..a8e2e275 100644 --- a/app/models.py +++ b/app/models.py @@ -429,6 +429,7 @@ class Post(db.Model): body_html = db.Column(db.Text) type = db.Column(db.Integer) comments_enabled = db.Column(db.Boolean, default=True) + mea_culpa = db.Column(db.Boolean, default=False) has_embed = db.Column(db.Boolean, default=False) reply_count = db.Column(db.Integer, default=0) score = db.Column(db.Integer, default=0, index=True) diff --git a/app/post/forms.py b/app/post/forms.py index 43668713..d488a3b2 100644 --- a/app/post/forms.py +++ b/app/post/forms.py @@ -12,7 +12,6 @@ class NewReplyForm(FlaskForm): submit = SubmitField(_l('Comment')) - class ReportPostForm(FlaskForm): reason_choices = [('1', _l('Breaks community rules')), ('7', _l('Spam')), ('2', _l('Harassment')), ('3', _l('Threatening violence')), ('4', _l('Hate / genocide')), @@ -35,3 +34,7 @@ class ReportPostForm(FlaskForm): if choice[0] == reason_id: result.append(str(choice[1])) return ', '.join(result) + + +class MeaCulpaForm(FlaskForm): + submit = SubmitField(_l('I changed my mind')) diff --git a/app/post/routes.py b/app/post/routes.py index 62f732a5..5b60ed04 100644 --- a/app/post/routes.py +++ b/app/post/routes.py @@ -9,7 +9,7 @@ from app import db, constants from app.activitypub.signature import HttpSignature from app.activitypub.util import default_context from app.community.util import save_post -from app.post.forms import NewReplyForm, ReportPostForm +from app.post.forms import NewReplyForm, ReportPostForm, MeaCulpaForm from app.community.forms import CreatePostForm from app.post.util import post_replies, get_comment_branch, post_reply_count from app.constants import SUBSCRIPTION_MEMBER, SUBSCRIPTION_OWNER, POST_TYPE_LINK, POST_TYPE_ARTICLE, POST_TYPE_IMAGE @@ -29,12 +29,20 @@ def show_post(post_id: int): if current_user.is_anonymous and request_etag_matches(current_etag): return return_304(current_etag) + if post.mea_culpa: + flash(_('%(name)s has indicated they made a mistake in this post.', name=post.author.user_name), 'warning') + mods = post.community.moderators() is_moderator = current_user.is_authenticated and any(mod.user_id == current_user.id for mod in mods) # handle top-level comments/replies form = NewReplyForm() if current_user.is_authenticated and current_user.verified and form.validate_on_submit(): + + if not post.comments_enabled: + flash('Comments have been disabled.', 'warning') + return redirect(url_for('activitypub.post_ap', post_id=post_id)) + reply = PostReply(user_id=current_user.id, post_id=post.id, community_id=post.community.id, body=form.body.data, body_html=markdown_to_html(form.body.data), body_html_safe=True, from_bot=current_user.bot, up_votes=1, nsfw=post.nsfw, nsfl=post.nsfl, @@ -247,6 +255,11 @@ def continue_discussion(post_id, comment_id): @login_required def add_reply(post_id: int, comment_id: int): post = Post.query.get_or_404(post_id) + + if not post.comments_enabled: + flash('The author of the post has changed their mind so comments have been disabled.', 'warning') + return redirect(url_for('activitypub.post_ap', post_id=post_id)) + in_reply_to = PostReply.query.get_or_404(comment_id) mods = post.community.moderators() is_moderator = current_user.is_authenticated and any(mod.user_id == current_user.id for mod in mods) @@ -477,3 +490,19 @@ def post_block_instance(post_id: int): db.session.commit() flash(_('Content from %(name)s will be hidden.', name=post.instance.domain)) return redirect(post.community.local_url()) + + +@login_required +@bp.route('/post//mea_culpa', methods=['GET', 'POST']) +def post_mea_culpa(post_id: int): + post = Post.query.get_or_404(post_id) + form = MeaCulpaForm() + if form.validate_on_submit(): + post.comments_enabled = False + post.mea_culpa = True + post.community.last_active = utcnow() + post.last_active = utcnow() + db.session.commit() + return redirect(url_for('activitypub.post_ap', post_id=post.id)) + + return render_template('post/post_mea_culpa.html', title=_('I changed my mind'), form=form, post=post) diff --git a/app/static/scss/_typography.scss b/app/static/scss/_typography.scss index 574c5783..c28d2f94 100644 --- a/app/static/scss/_typography.scss +++ b/app/static/scss/_typography.scss @@ -178,6 +178,10 @@ content: "\ea03"; } +.fe-mea-culpa::before { + content: "\e997"; +} + .fe-block::before { content: "\ea04"; } diff --git a/app/static/structure.css b/app/static/structure.css index c6cec898..cb7bcbf3 100644 --- a/app/static/structure.css +++ b/app/static/structure.css @@ -181,6 +181,10 @@ nav, etc which are used site-wide */ content: "\ea03"; } +.fe-mea-culpa::before { + content: "\e997"; +} + .fe-block::before { content: "\ea04"; } diff --git a/app/static/styles.css b/app/static/styles.css index 502af400..7df1746e 100644 --- a/app/static/styles.css +++ b/app/static/styles.css @@ -180,6 +180,10 @@ content: "\ea03"; } +.fe-mea-culpa::before { + content: "\e997"; +} + .fe-block::before { content: "\ea04"; } diff --git a/app/templates/post/continue_discussion.html b/app/templates/post/continue_discussion.html index e93d0b50..6ec78eb6 100644 --- a/app/templates/post/continue_discussion.html +++ b/app/templates/post/continue_discussion.html @@ -36,7 +36,9 @@
- reply + {% if post.comments_enabled %} + reply + {% endif %}
{% if comment['replies'] %}
diff --git a/app/templates/post/post.html b/app/templates/post/post.html index 3b2a8757..9e456dda 100644 --- a/app/templates/post/post.html +++ b/app/templates/post/post.html @@ -29,7 +29,7 @@

{{ _('Log in to comment') }}

{% endif %} {% else %} -

{{ _('Comments are disabled for this post.') }}

+

{{ _('Comments are disabled.') }}

{% endif %} {% if replies %}
@@ -72,7 +72,9 @@
{% if current_user.is_authenticated and current_user.verified %}
- reply + {% if post.comments_enabled %} + reply + {% endif %}
{% endif %} {% if comment['replies'] %} diff --git a/app/templates/post/post_mea_culpa.html b/app/templates/post/post_mea_culpa.html new file mode 100644 index 00000000..f70d73e7 --- /dev/null +++ b/app/templates/post/post_mea_culpa.html @@ -0,0 +1,20 @@ +{% extends "base.html" %} +{% from 'bootstrap/form.html' import render_form %} + +{% block app_content %} +
+ +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/post/post_options.html b/app/templates/post/post_options.html index 3b13255d..b3ca824e 100644 --- a/app/templates/post/post_options.html +++ b/app/templates/post/post_options.html @@ -8,22 +8,28 @@
{{ _('Options for "%(post_title)s"', post_title=post.title) }}