return redirect(thread.getViewURL())
+
+
+class CommentForm(FlaskForm):
+ comment = TextAreaField("Comment", [InputRequired(), Length(10, 500)])
+ submit = SubmitField("Comment")
+
+
+
+@bp.route("/threads/<int:id>/edit/", methods=["GET", "POST"])
+@login_required
+def edit_reply(id):
+ thread = Thread.query.get(id)
+ if thread is None:
+ abort(404)
+
+ reply_id = request.args.get("reply")
+ if reply_id is None:
+ abort(404)
+
+ reply = ThreadReply.query.get(reply_id)
+ if reply is None or reply.thread != thread:
+ abort(404)
+
+ if not reply.checkPerm(current_user, Permission.EDIT_REPLY):
+ abort(403)
+
+ form = CommentForm(formdata=request.form, obj=reply)
+ if request.method == "POST" and form.validate():
+ comment = form.comment.data
+
+ msg = "Edited reply by {}".format(reply.author.display_name)
+ severity = AuditSeverity.NORMAL if current_user == reply.author else AuditSeverity.MODERATION
+ addNotification(reply.author, current_user, msg, thread.getViewURL(), thread.package)
+ addAuditLog(severity, current_user, msg, thread.getViewURL(), thread.package, reply.comment)
+
+ reply.comment = comment
+
+ db.session.commit()
+
+ return redirect(thread.getViewURL())
+
+ return render_template("threads/edit_reply.html", thread=thread, reply=reply, form=form)
+
+
@bp.route("/threads/<int:id>/", methods=["GET", "POST"])
def view(id):
thread = Thread.query.get(id)
<th>✓</th> <!-- admin -->
<th>✓</th>
</tr>
+ <tr>
+ <td>Edit Comments</td>
+ <th>✓</th> <!-- new -->
+ <th></th>
+ <th>✓</th> <!-- member -->
+ <th></th>
+ <th>✓</th> <!-- trusted member -->
+ <th></th>
+ <th>✓</th> <!-- editor -->
+ <th></th>
+ <th>✓</th> <!-- moderator -->
+ <th></th>
+ <th>✓</th> <!-- admin -->
+ <th>✓</th>
+ </tr>
<tr>
<td>Set Email</td>
<th>✓</th> <!-- new -->
COMMENT_THREAD = "COMMENT_THREAD"
LOCK_THREAD = "LOCK_THREAD"
DELETE_REPLY = "DELETE_REPLY"
+ EDIT_REPLY = "EDIT_REPLY"
UNAPPROVE_PACKAGE = "UNAPPROVE_PACKAGE"
TOPIC_DISCARD = "TOPIC_DISCARD"
CREATE_TOKEN = "CREATE_TOKEN"
elif type(perm) != Permission:
raise Exception("Unknown permission given to ThreadReply.checkPerm()")
- if perm == Permission.DELETE_REPLY:
+ if perm == Permission.EDIT_REPLY:
+ return (user == self.author and user.rank.atLeast(UserRank.MEMBER) and not self.thread.locked) or \
+ user.rank.atLeast(UserRank.ADMIN)
+
+ elif perm == Permission.DELETE_REPLY:
return user.rank.atLeast(UserRank.MODERATOR) and self.thread.replies[0] != self
else:
</div>
<div class="card-body">
+ {% if current_user == thread.author and thread.review and thread.replies[0] == r %}
+ <a class="float-right btn btn-primary btn-sm ml-2"
+ href="{{ thread.review.package.getReviewURL() }}">
+ <i class="fas fa-edit"></i>
+ </a>
+ {% elif r.checkPerm(current_user, "EDIT_REPLY") %}
+ <a class="float-right btn btn-primary btn-sm ml-2"
+ href="{{ url_for('threads.edit_reply', id=thread.id, reply=r.id) }}">
+ <i class="fas fa-edit"></i>
+ </a>
+ {% endif %}
+
{% if r.checkPerm(current_user, "DELETE_REPLY") %}
- <a class="float-right btn btn-secondary btn-sm"
+ <a class="float-right btn btn-secondary btn-sm ml-2"
href="{{ url_for('threads.delete_reply', id=thread.id, reply=r.id) }}">
<i class="fas fa-trash"></i>
</a>
--- /dev/null
+{% extends "base.html" %}
+
+{% block title %}
+ {{ _("Edit reply") }} - {{ thread.title }}
+{% endblock %}
+
+{% block content %}
+ <h1>{{ _("Edit reply") }}</h1>
+
+ {% from "macros/forms.html" import render_field, render_submit_field %}
+ <form method="POST" action="" enctype="multipart/form-data">
+ {{ form.hidden_tag() }}
+
+ {{ render_field(form.comment, label="", class_="m-0", fieldclass="form-control markdown") }} <br />
+ {{ render_submit_field(form.submit) }}
+ </form>
+{% endblock %}