mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
reply to a reply
This commit is contained in:
parent
4cd94ecf4c
commit
ef275f4fbf
12 changed files with 301 additions and 36 deletions
|
@ -71,5 +71,5 @@ class CreatePost(FlaskForm):
|
||||||
|
|
||||||
|
|
||||||
class NewReplyForm(FlaskForm):
|
class NewReplyForm(FlaskForm):
|
||||||
body = TextAreaField(_l('Body'), render_kw={'placeholder': 'What are your thoughts?'})
|
body = TextAreaField(_l('Body'), render_kw={'placeholder': 'What are your thoughts?', 'rows': 3})
|
||||||
submit = SubmitField(_l('Comment'))
|
submit = SubmitField(_l('Comment'))
|
||||||
|
|
|
@ -29,7 +29,8 @@ def add_local():
|
||||||
private_key, public_key = RsaKeys.generate_keypair()
|
private_key, public_key = RsaKeys.generate_keypair()
|
||||||
community = Community(title=form.community_name.data, name=form.url.data, description=form.description.data,
|
community = Community(title=form.community_name.data, name=form.url.data, description=form.description.data,
|
||||||
rules=form.rules.data, nsfw=form.nsfw.data, private_key=private_key,
|
rules=form.rules.data, nsfw=form.nsfw.data, private_key=private_key,
|
||||||
public_key=public_key, ap_profile_id=current_app.config['SERVER_NAME'] + '/c/' + form.url.data,
|
public_key=public_key,
|
||||||
|
ap_profile_id=current_app.config['SERVER_NAME'] + '/c/' + form.url.data,
|
||||||
subscriptions_count=1)
|
subscriptions_count=1)
|
||||||
db.session.add(community)
|
db.session.add(community)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
@ -71,7 +72,8 @@ def show_community(community: Community):
|
||||||
mods = community.moderators()
|
mods = community.moderators()
|
||||||
|
|
||||||
is_moderator = current_user.is_authenticated and any(mod.user_id == current_user.id for mod in mods)
|
is_moderator = current_user.is_authenticated and any(mod.user_id == current_user.id for mod in mods)
|
||||||
is_owner = current_user.is_authenticated and any(mod.user_id == current_user.id and mod.is_owner == True for mod in mods)
|
is_owner = current_user.is_authenticated and any(
|
||||||
|
mod.user_id == current_user.id and mod.is_owner == True for mod in mods)
|
||||||
|
|
||||||
if community.private_mods:
|
if community.private_mods:
|
||||||
mod_list = []
|
mod_list = []
|
||||||
|
@ -125,7 +127,7 @@ def subscribe(actor):
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
flash('Failed to send request to subscribe: ' + str(ex), 'error')
|
flash('Failed to send request to subscribe: ' + str(ex), 'error')
|
||||||
current_app.logger.error("Exception while trying to subscribe" + str(ex))
|
current_app.logger.error("Exception while trying to subscribe" + str(ex))
|
||||||
else: # for local communities, joining is instant
|
else: # for local communities, joining is instant
|
||||||
banned = CommunityBan.query.filter_by(user_id=current_user.id, community_id=community.id).first()
|
banned = CommunityBan.query.filter_by(user_id=current_user.id, community_id=community.id).first()
|
||||||
if banned:
|
if banned:
|
||||||
flash('You cannot join this community')
|
flash('You cannot join this community')
|
||||||
|
@ -237,7 +239,8 @@ def show_post(post_id: int):
|
||||||
flash('Your comment has been added.')
|
flash('Your comment has been added.')
|
||||||
# todo: flush cache
|
# todo: flush cache
|
||||||
# todo: federation
|
# todo: federation
|
||||||
return redirect(url_for('community.show_post', post_id=post_id)) # redirect to current page to avoid refresh resubmitting the form
|
return redirect(url_for('community.show_post',
|
||||||
|
post_id=post_id)) # redirect to current page to avoid refresh resubmitting the form
|
||||||
else:
|
else:
|
||||||
replies = post_replies(post.id, 'top')
|
replies = post_replies(post.id, 'top')
|
||||||
return render_template('community/post.html', title=post.title, post=post, is_moderator=is_moderator,
|
return render_template('community/post.html', title=post.title, post=post, is_moderator=is_moderator,
|
||||||
|
@ -250,25 +253,25 @@ def comment_vote(comment_id, vote_direction):
|
||||||
comment = PostReply.query.get_or_404(comment_id)
|
comment = PostReply.query.get_or_404(comment_id)
|
||||||
existing_vote = PostReplyVote.query.filter_by(user_id=current_user.id, post_reply_id=comment.id).first()
|
existing_vote = PostReplyVote.query.filter_by(user_id=current_user.id, post_reply_id=comment.id).first()
|
||||||
if existing_vote:
|
if existing_vote:
|
||||||
if existing_vote.effect > 0: # previous vote was up
|
if existing_vote.effect > 0: # previous vote was up
|
||||||
if vote_direction == 'upvote': # new vote is also up, so remove it
|
if vote_direction == 'upvote': # new vote is also up, so remove it
|
||||||
db.session.delete(existing_vote)
|
db.session.delete(existing_vote)
|
||||||
comment.up_votes -= 1
|
comment.up_votes -= 1
|
||||||
comment.score -= 1
|
comment.score -= 1
|
||||||
else: # new vote is down while previous vote was up, so reverse their previous vote
|
else: # new vote is down while previous vote was up, so reverse their previous vote
|
||||||
existing_vote.effect = -1
|
existing_vote.effect = -1
|
||||||
comment.up_votes -= 1
|
comment.up_votes -= 1
|
||||||
comment.down_votes += 1
|
comment.down_votes += 1
|
||||||
comment.score -= 2
|
comment.score -= 2
|
||||||
downvoted_class = 'voted_down'
|
downvoted_class = 'voted_down'
|
||||||
else: # previous vote was down
|
else: # previous vote was down
|
||||||
if vote_direction == 'upvote': # new vote is upvote
|
if vote_direction == 'upvote': # new vote is upvote
|
||||||
existing_vote.effect = 1
|
existing_vote.effect = 1
|
||||||
comment.up_votes += 1
|
comment.up_votes += 1
|
||||||
comment.down_votes -= 1
|
comment.down_votes -= 1
|
||||||
comment.score += 1
|
comment.score += 1
|
||||||
upvoted_class = 'voted_up'
|
upvoted_class = 'voted_up'
|
||||||
else: # reverse a previous downvote
|
else: # reverse a previous downvote
|
||||||
db.session.delete(existing_vote)
|
db.session.delete(existing_vote)
|
||||||
comment.down_votes -= 1
|
comment.down_votes -= 1
|
||||||
comment.score += 2
|
comment.score += 2
|
||||||
|
@ -289,3 +292,36 @@ def comment_vote(comment_id, vote_direction):
|
||||||
return render_template('community/_voting_buttons.html', comment=comment,
|
return render_template('community/_voting_buttons.html', comment=comment,
|
||||||
upvoted_class=upvoted_class,
|
upvoted_class=upvoted_class,
|
||||||
downvoted_class=downvoted_class)
|
downvoted_class=downvoted_class)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/post/<int:post_id>/comment/<int:comment_id>')
|
||||||
|
def show_comment(post_id, comment_id):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/post/<int:post_id>/comment/<int:comment_id>/reply', methods=['GET', 'POST'])
|
||||||
|
def add_reply(post_id: int, comment_id: int):
|
||||||
|
post = Post.query.get_or_404(post_id)
|
||||||
|
comment = 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)
|
||||||
|
form = NewReplyForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
reply = PostReply(user_id=current_user.id, post_id=post.id, parent_id=comment.id, depth=comment.depth + 1,
|
||||||
|
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)
|
||||||
|
db.session.add(reply)
|
||||||
|
db.session.commit()
|
||||||
|
reply_vote = PostReplyVote(user_id=current_user.id, author_id=current_user.id, post_reply_id=reply.id,
|
||||||
|
effect=1.0)
|
||||||
|
db.session.add(reply_vote)
|
||||||
|
db.session.commit()
|
||||||
|
form.body.data = ''
|
||||||
|
flash('Your comment has been added.')
|
||||||
|
# todo: flush cache
|
||||||
|
# todo: federation
|
||||||
|
return redirect(url_for('community.show_post', post_id=post_id, _anchor=f'comment_{reply.id}'))
|
||||||
|
else:
|
||||||
|
return render_template('community/add_reply.html', title=_('Discussing %(title)s', title=post.title), post=post,
|
||||||
|
is_moderator=is_moderator, form=form, comment=comment)
|
||||||
|
|
BIN
app/static/images/collapsed.gif
Normal file
BIN
app/static/images/collapsed.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 176 B |
BIN
app/static/images/expanded.gif
Normal file
BIN
app/static/images/expanded.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 183 B |
85
app/static/js/coolfieldset.js
Normal file
85
app/static/js/coolfieldset.js
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
(function () {
|
||||||
|
function hideFieldsetContent(fieldset, options) {
|
||||||
|
const content = fieldset.querySelectorAll('*:not(legend)');
|
||||||
|
if (options.animation) {
|
||||||
|
content.forEach((element) => {
|
||||||
|
element.style.display = 'none';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
content.forEach((element) => {
|
||||||
|
element.style.display = 'none';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
fieldset.classList.remove('expanded');
|
||||||
|
fieldset.classList.add('collapsed');
|
||||||
|
content.forEach((element) => {
|
||||||
|
element.setAttribute('aria-expanded', 'false');
|
||||||
|
});
|
||||||
|
if (!options.animation) {
|
||||||
|
fieldset.dispatchEvent(new Event('update'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showFieldsetContent(fieldset, options) {
|
||||||
|
const content = fieldset.querySelectorAll('*:not(legend)');
|
||||||
|
if (options.animation) {
|
||||||
|
content.forEach((element) => {
|
||||||
|
element.style.display = '';
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
content.forEach((element) => {
|
||||||
|
element.style.display = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
fieldset.classList.remove('collapsed');
|
||||||
|
fieldset.classList.add('expanded');
|
||||||
|
content.forEach((element) => {
|
||||||
|
element.setAttribute('aria-expanded', 'true');
|
||||||
|
});
|
||||||
|
if (!options.animation) {
|
||||||
|
fieldset.dispatchEvent(new Event('update'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function doToggle(fieldset, setting) {
|
||||||
|
if (fieldset.classList.contains('collapsed')) {
|
||||||
|
showFieldsetContent(fieldset, setting);
|
||||||
|
} else if (fieldset.classList.contains('expanded')) {
|
||||||
|
hideFieldsetContent(fieldset, setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function coolfieldset(selector, options) {
|
||||||
|
const fieldsets = document.querySelectorAll(selector);
|
||||||
|
const setting = { collapsed: false, animation: true, speed: 'medium', ...options };
|
||||||
|
|
||||||
|
fieldsets.forEach((fieldset) => {
|
||||||
|
const legend = fieldset.querySelector('legend');
|
||||||
|
const content = fieldset.querySelectorAll('*:not(legend)');
|
||||||
|
|
||||||
|
content.forEach((element) => {
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
wrapper.classList.add('wrapper');
|
||||||
|
element.parentNode.insertBefore(wrapper, element);
|
||||||
|
wrapper.appendChild(element);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (setting.collapsed) {
|
||||||
|
hideFieldsetContent(fieldset, { animation: false });
|
||||||
|
} else {
|
||||||
|
fieldset.classList.add('expanded');
|
||||||
|
}
|
||||||
|
|
||||||
|
legend.addEventListener('click', () => doToggle(fieldset, setting));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.coolfieldset = coolfieldset;
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Usage:
|
||||||
|
// coolfieldset('.coolfieldset', { collapsed: true, animation: true, speed: 'slow' });
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
coolfieldset('.coolfieldset', { collapsed: true, animation: true, speed: 'slow' });
|
||||||
|
});
|
|
@ -15,7 +15,7 @@ function setupShowMoreLinks() {
|
||||||
const comments = document.querySelectorAll('.comment');
|
const comments = document.querySelectorAll('.comment');
|
||||||
|
|
||||||
comments.forEach(comment => {
|
comments.forEach(comment => {
|
||||||
const content = comment.querySelector('.comment_body');
|
const content = comment.querySelector('.limit_height');
|
||||||
if (content && content.clientHeight > 400) {
|
if (content && content.clientHeight > 400) {
|
||||||
content.style.overflow = 'hidden';
|
content.style.overflow = 'hidden';
|
||||||
content.style.maxHeight = '400px';
|
content.style.maxHeight = '400px';
|
||||||
|
@ -33,6 +33,7 @@ function setupShowMoreLinks() {
|
||||||
showMoreLink.innerHTML = '<i class="fe fe-angles-up" title="Collapse"></i>';
|
showMoreLink.innerHTML = '<i class="fe fe-angles-up" title="Collapse"></i>';
|
||||||
} else {
|
} else {
|
||||||
content.style.overflow = 'hidden';
|
content.style.overflow = 'hidden';
|
||||||
|
content.style.maxHeight = '400px';
|
||||||
showMoreLink.innerHTML = '<i class="fe fe-angles-down" title="Read more"></i>';
|
showMoreLink.innerHTML = '<i class="fe fe-angles-down" title="Read more"></i>';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -95,6 +96,11 @@ function setupHideButtons() {
|
||||||
hidable.style.display = isHidden ? 'block' : 'none';
|
hidable.style.display = isHidden ? 'block' : 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const moreHidables = parentElement.parentElement.querySelectorAll('.hidable');
|
||||||
|
moreHidables.forEach(hidable => {
|
||||||
|
hidable.style.display = isHidden ? 'block' : 'none';
|
||||||
|
});
|
||||||
|
|
||||||
// Toggle the content of hideEl
|
// Toggle the content of hideEl
|
||||||
if (isHidden) {
|
if (isHidden) {
|
||||||
hideEl.innerHTML = "<a href='#'>[-] hide</a>";
|
hideEl.innerHTML = "<a href='#'>[-] hide</a>";
|
||||||
|
|
|
@ -366,14 +366,13 @@ fieldset legend {
|
||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
.comment .comment_body {
|
.comment .limit_height {
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.comment .comment_body.expanded {
|
.comment .limit_height.expanded {
|
||||||
max-height: none;
|
max-height: none;
|
||||||
}
|
}
|
||||||
.comment .comment_body.expanded .show-more {
|
.comment .limit_height.expanded .show-more {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.comment .show-more {
|
.comment .show-more {
|
||||||
|
@ -441,4 +440,8 @@ fieldset legend {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.add_reply .form-control-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/*# sourceMappingURL=structure.css.map */
|
/*# sourceMappingURL=structure.css.map */
|
||||||
|
|
|
@ -140,8 +140,7 @@ nav, etc which are used site-wide */
|
||||||
clear: both;
|
clear: both;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|
||||||
.comment_body {
|
.limit_height {
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&.expanded {
|
&.expanded {
|
||||||
|
@ -233,3 +232,9 @@ nav, etc which are used site-wide */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.add_reply {
|
||||||
|
.form-control-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
|
@ -324,4 +324,34 @@ nav.navbar {
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.coolfieldset, .coolfieldset.expanded {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolfieldset.collapsed {
|
||||||
|
border: 0;
|
||||||
|
border-top: 1px solid #bbb;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolfieldset legend {
|
||||||
|
padding-left: 13px;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: white;
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
top: -11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolfieldset legend, .coolfieldset.expanded legend {
|
||||||
|
background: whitesmoke url(/static/images/expanded.gif) no-repeat center left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolfieldset.collapsed legend {
|
||||||
|
background: whitesmoke url(/static/images/collapsed.gif) no-repeat center left;
|
||||||
|
}
|
||||||
|
|
||||||
/*# sourceMappingURL=styles.css.map */
|
/*# sourceMappingURL=styles.css.map */
|
||||||
|
|
|
@ -91,3 +91,33 @@ nav.navbar {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
margin-bottom: 3px;
|
margin-bottom: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.coolfieldset, .coolfieldset.expanded{
|
||||||
|
border:1px solid $light-grey;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolfieldset.collapsed{
|
||||||
|
border:0;
|
||||||
|
border-top:1px solid $grey;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolfieldset legend{
|
||||||
|
padding-left:13px;
|
||||||
|
font-weight:bold;
|
||||||
|
cursor:pointer;
|
||||||
|
background-color: white;
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
top: -11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolfieldset legend, .coolfieldset.expanded legend{
|
||||||
|
background: whitesmoke url(/static/images/expanded.gif) no-repeat center left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coolfieldset.collapsed legend{
|
||||||
|
background: whitesmoke url(/static/images/collapsed.gif) no-repeat center left;
|
||||||
|
}
|
68
app/templates/community/add_reply.html
Normal file
68
app/templates/community/add_reply.html
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% from 'bootstrap/form.html' import render_form %}
|
||||||
|
|
||||||
|
{% block app_content %}
|
||||||
|
<script src="/static/js/coolfieldset.js"></script>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12 col-md-8 position-relative add_reply">
|
||||||
|
<fieldset class="coolfieldset mt-4"><legend class="w-auto">Original post</legend>
|
||||||
|
<h3>{{ post.title }}</h3>
|
||||||
|
{{ post.body_html | safe }}
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="coolfieldset mt-4"><legend class="w-auto">Comment you are replying to</legend>
|
||||||
|
{{ comment.body_html | safe}}
|
||||||
|
</fieldset>
|
||||||
|
{{ render_form(form) }}
|
||||||
|
</div>
|
||||||
|
<div class="col-12 col-md-4">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6">
|
||||||
|
{% if current_user.is_authenticated and current_user.subscribed(post.community) %}
|
||||||
|
<a class="w-100 btn btn-primary" href="/community/{{ post.community.link() }}/unsubscribe">{{ _('Unsubscribe') }}</a>
|
||||||
|
{% else %}
|
||||||
|
<a class="w-100 btn btn-primary" href="/community/{{ post.community.link() }}/subscribe">{{ _('Subscribe') }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<a class="w-100 btn btn-primary" href="/community/{{ post.community.link() }}/submit">{{ _('Create post') }}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form method="get">
|
||||||
|
<input type="search" name="search" class="form-control mt-2" placeholder="{{ _('Search this community') }}" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card mt-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2>{{ _('About community') }}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p>{{ post.community.description|safe }}</p>
|
||||||
|
<p>{{ post.community.rules|safe }}</p>
|
||||||
|
{% if len(mods) > 0 and not post.community.private_mods %}
|
||||||
|
<h3>Moderators</h3>
|
||||||
|
<ol>
|
||||||
|
{% for mod in mods %}
|
||||||
|
<li><a href="/u/{{ mod.user_name }}">{{ mod.user_name }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ol>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if is_moderator %}
|
||||||
|
<div class="card mt-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<h2>{{ _('Community Settings') }}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p><a href="#" class="btn btn-primary">{{ _('Moderate') }}</a></p>
|
||||||
|
<p><a href="#" class="btn btn-primary">{{ _('Settings') }}</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -82,28 +82,30 @@
|
||||||
<div class="row post_replies">
|
<div class="row post_replies">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
{% macro render_comment(comment) %}
|
{% macro render_comment(comment) %}
|
||||||
<div class="comment" style="margin-left: {{ comment['comment'].depth * 20 }}px;">
|
<div id="comment_{{ comment['comment'].id }}" class="comment" style="margin-left: {{ comment['comment'].depth * 20 }}px;">
|
||||||
<div class="voting_buttons">
|
<div class="limit_height">
|
||||||
{% with comment=comment['comment'] %}
|
<div class="voting_buttons">
|
||||||
{% include "community/_voting_buttons.html" %}
|
{% with comment=comment['comment'] %}
|
||||||
{% endwith %}
|
{% include "community/_voting_buttons.html" %}
|
||||||
</div>
|
{% endwith %}
|
||||||
<div class="hide_button"><a href='#'>[-] hide</a></div>
|
</div>
|
||||||
<div class="comment_author">
|
<div class="hide_button"><a href='#'>[-] hide</a></div>
|
||||||
{% if comment['comment'].author.avatar_id %}
|
<div class="comment_author">
|
||||||
<a href="/u/{{ comment['comment'].author.link() }}" title="{{ comment['comment'].author.ap_id }}">
|
{% if comment['comment'].author.avatar_id %}
|
||||||
<img src="{{ comment['comment'].author.avatar_image() }}" alt="Avatar" /></a>
|
<a href="/u/{{ comment['comment'].author.link() }}" title="{{ comment['comment'].author.ap_id }}">
|
||||||
{% endif %}
|
<img src="{{ comment['comment'].author.avatar_image() }}" alt="Avatar" /></a>
|
||||||
<a href="/u/{{ comment['comment'].author.link() }}" title="{{ comment['comment'].author.link() }}">
|
{% endif %}
|
||||||
<strong>{{ comment['comment'].author.user_name}}</strong></a>
|
<a href="/u/{{ comment['comment'].author.link() }}" title="{{ comment['comment'].author.link() }}">
|
||||||
{% if comment['comment'].author.id == post.author.id%}<span title="Submitter of original post" aria-label="submitter">[S]</span>{% endif %}
|
<strong>{{ comment['comment'].author.user_name}}</strong></a>
|
||||||
<span class="text-muted small">{{ moment(comment['comment'].posted_at).fromNow(refresh=True) }}</span>
|
{% if comment['comment'].author.id == post.author.id%}<span title="Submitter of original post" aria-label="submitter">[S]</span>{% endif %}
|
||||||
</div>
|
<span class="text-muted small">{{ moment(comment['comment'].posted_at).fromNow(refresh=True) }}</span>
|
||||||
<div class="comment_body hidable">
|
</div>
|
||||||
{{ comment['comment'].body_html | safe }}
|
<div class="comment_body hidable">
|
||||||
|
{{ comment['comment'].body_html | safe }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="comment_actions hidable">
|
<div class="comment_actions hidable">
|
||||||
<a href="#"><span class="fe fe-reply"></span> reply</a>
|
<a href="{{ url_for('community.add_reply', post_id=post.id, comment_id=comment['comment'].id) }}" rel="nofollow"><span class="fe fe-reply"></span> reply</a>
|
||||||
</div>
|
</div>
|
||||||
{% if comment['replies'] %}
|
{% if comment['replies'] %}
|
||||||
<div class="replies hidable">
|
<div class="replies hidable">
|
||||||
|
|
Loading…
Add table
Reference in a new issue