mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
pagination
This commit is contained in:
parent
fb2dc055d3
commit
7b91250e3a
11 changed files with 87 additions and 17 deletions
|
@ -92,6 +92,8 @@ def show_community(community: Community):
|
|||
if current_user.is_anonymous and request_etag_matches(current_etag):
|
||||
return return_304(current_etag)
|
||||
|
||||
page = request.args.get('page', 1, type=int)
|
||||
|
||||
mods = community.moderators()
|
||||
|
||||
is_moderator = current_user.is_authenticated and any(mod.user_id == current_user.id for mod in mods)
|
||||
|
@ -105,17 +107,23 @@ def show_community(community: Community):
|
|||
mod_list = User.query.filter(User.id.in_(mod_user_ids)).all()
|
||||
|
||||
if current_user.is_anonymous or current_user.ignore_bots:
|
||||
posts = community.posts.filter(Post.from_bot == False).order_by(desc(Post.last_active)).all()
|
||||
posts = community.posts.filter(Post.from_bot == False).order_by(desc(Post.last_active)).paginate(page=page, per_page=100, error_out=False)
|
||||
else:
|
||||
posts = community.posts.order_by(desc(Post.last_active)).all()
|
||||
posts = community.posts.order_by(desc(Post.last_active)).paginate(page=page, per_page=100, error_out=False)
|
||||
|
||||
description = shorten_string(community.description, 150) if community.description else None
|
||||
og_image = community.image.source_url if community.image_id else None
|
||||
|
||||
next_url = url_for('activitypub.community_profile', actor=community.ap_id if community.ap_id is not None else community.name,
|
||||
page=posts.next_num) if posts.has_next else None
|
||||
prev_url = url_for('activitypub.community_profile', actor=community.ap_id if community.ap_id is not None else community.name,
|
||||
page=posts.prev_num) if posts.has_prev and page != 1 else None
|
||||
|
||||
return render_template('community/community.html', community=community, title=community.title,
|
||||
is_moderator=is_moderator, is_owner=is_owner, mods=mod_list, posts=posts, description=description,
|
||||
og_image=og_image, POST_TYPE_IMAGE=POST_TYPE_IMAGE, POST_TYPE_LINK=POST_TYPE_LINK, SUBSCRIPTION_PENDING=SUBSCRIPTION_PENDING,
|
||||
SUBSCRIPTION_MEMBER=SUBSCRIPTION_MEMBER, etag=f"{community.id}_{hash(community.last_active)}",
|
||||
next_url=next_url, prev_url=prev_url,
|
||||
rss_feed=f"https://{current_app.config['SERVER_NAME']}/community/{community.link()}/feed", rss_feed_name=f"{community.title} posts on PieFed")
|
||||
|
||||
|
||||
|
|
|
@ -432,7 +432,7 @@ class Post(db.Model):
|
|||
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)
|
||||
score = db.Column(db.Integer, default=0, index=True) # used for 'top' ranking
|
||||
nsfw = db.Column(db.Boolean, default=False)
|
||||
nsfl = db.Column(db.Boolean, default=False)
|
||||
sticky = db.Column(db.Boolean, default=False)
|
||||
|
@ -445,7 +445,7 @@ class Post(db.Model):
|
|||
ip = db.Column(db.String(50))
|
||||
up_votes = db.Column(db.Integer, default=0)
|
||||
down_votes = db.Column(db.Integer, default=0)
|
||||
ranking = db.Column(db.Integer, default=0)
|
||||
ranking = db.Column(db.Integer, default=0) # used for 'hot' ranking
|
||||
language = db.Column(db.String(10))
|
||||
edited_at = db.Column(db.DateTime)
|
||||
|
||||
|
@ -507,7 +507,7 @@ class PostReply(db.Model):
|
|||
body = db.Column(db.Text)
|
||||
body_html = db.Column(db.Text)
|
||||
body_html_safe = db.Column(db.Boolean, default=False)
|
||||
score = db.Column(db.Integer, default=0, index=True)
|
||||
score = db.Column(db.Integer, default=0, index=True) # used for 'top' sorting
|
||||
nsfw = db.Column(db.Boolean, default=False)
|
||||
nsfl = db.Column(db.Boolean, default=False)
|
||||
notify_author = db.Column(db.Boolean, default=True)
|
||||
|
@ -517,7 +517,7 @@ class PostReply(db.Model):
|
|||
from_bot = db.Column(db.Boolean, default=False)
|
||||
up_votes = db.Column(db.Integer, default=0)
|
||||
down_votes = db.Column(db.Integer, default=0)
|
||||
ranking = db.Column(db.Integer, default=0, index=True)
|
||||
ranking = db.Column(db.Integer, default=0, index=True) # used for 'hot' sorting
|
||||
language = db.Column(db.String(10))
|
||||
edited_at = db.Column(db.DateTime)
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@ class NewReplyForm(FlaskForm):
|
|||
class ReportPostForm(FlaskForm):
|
||||
reason_choices = [('1', _l('Breaks community rules')), ('7', _l('Spam')), ('2', _l('Harassment')),
|
||||
('3', _l('Threatening violence')), ('4', _l('Hate / genocide')),
|
||||
('6', _l('Sharing personal information')),
|
||||
('15', _l('Misinformation / disinformation')),
|
||||
('16', _l('Racism, sexism, transphobia')),
|
||||
('6', _l('Sharing personal info - doxing')),
|
||||
('5', _l('Minor abuse or sexualization')),
|
||||
('8', _l('Non-consensual intimate media')),
|
||||
('9', _l('Prohibited transaction')), ('10', _l('Impersonation')),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from datetime import datetime
|
||||
|
||||
from flask import redirect, url_for, flash, current_app, abort
|
||||
from flask import redirect, url_for, flash, current_app, abort, request
|
||||
from flask_login import login_user, logout_user, current_user, login_required
|
||||
from flask_babel import _
|
||||
from sqlalchemy import or_, desc
|
||||
|
@ -449,6 +449,8 @@ def post_report(post_id: int):
|
|||
|
||||
flash(_('Post has been reported, thank you!'))
|
||||
return redirect(post.community.local_url())
|
||||
elif request.method == 'GET':
|
||||
form.report_remote.data = True
|
||||
|
||||
return render_template('post/post_report.html', title=_('Report post'), form=form, post=post)
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ def post_replies(post_id: int, sort_by: str, show_first: int = 0) -> List[PostRe
|
|||
elif sort_by == 'new':
|
||||
comments = comments.order_by(desc(PostReply.posted_at))
|
||||
|
||||
comments = comments.limit(2000) # paginating indented replies is too hard so just get the first 2000.
|
||||
|
||||
comments_dict = {comment.id: {'comment': comment, 'replies': []} for comment in comments.all()}
|
||||
|
||||
for comment in comments:
|
||||
|
|
|
@ -592,7 +592,7 @@ fieldset legend {
|
|||
list-style-type: none;
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
height: 135px;
|
||||
height: 230px;
|
||||
}
|
||||
|
||||
.table tr th {
|
||||
|
|
|
@ -330,7 +330,7 @@ nav, etc which are used site-wide */
|
|||
list-style-type: none;
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
height: 135px;
|
||||
height: 230px;
|
||||
}
|
||||
|
||||
.table {
|
||||
|
|
|
@ -42,6 +42,19 @@
|
|||
<p>{{ _('No posts in this community yet.') }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<nav aria-label="Pagination" class="mt-4">
|
||||
{% if prev_url %}
|
||||
<a href="{{ prev_url }}" class="btn btn-primary">
|
||||
<span aria-hidden="true">←</span> {{ _('Previous page') }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if next_url %}
|
||||
<a href="{{ next_url }}" class="btn btn-primary">
|
||||
{{ _('Next page') }} <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-4">
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
{% endif %}
|
||||
{% if post.user_id == current_user.id and not post.mea_culpa %}
|
||||
<li><a href="{{ url_for('post.post_mea_culpa', post_id=post.id) }}" class="no-underline"><span class="fe fe-mea-culpa"></span>
|
||||
{{ _("I changed my mind") }}</a></li>
|
||||
{{ _("I made a mistake with this post and have changed my mind about the topic") }}</a></li>
|
||||
{% endif %}
|
||||
{% if post.user_id != current_user.id %}
|
||||
<li><a href="{{ url_for('post.post_block_user', post_id=post.id) }}" class="no-underline"><span class="fe fe-block"></span>
|
||||
|
|
|
@ -38,22 +38,46 @@
|
|||
{{ user.about_html|safe }}
|
||||
{% endif %}
|
||||
|
||||
{% if len(posts) > 0 %}
|
||||
{% if posts %}
|
||||
<h2 class="mt-4">Posts</h2>
|
||||
<div class="post_list">
|
||||
{% for post in posts %}
|
||||
{% include 'post/_post_teaser.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<nav aria-label="Pagination" class="mt-4">
|
||||
{% if post_prev_url %}
|
||||
<a href="{{ post_prev_url }}" class="btn btn-primary">
|
||||
<span aria-hidden="true">←</span> {{ _('Previous page') }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if post_next_url %}
|
||||
<a href="{{ post_next_url }}" class="btn btn-primary">
|
||||
{{ _('Next page') }} <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
{% endif %}
|
||||
|
||||
{% if len(post_replies) > 0 %}
|
||||
<h2 class="mt-4">Comments</h2>
|
||||
{% if post_replies %}
|
||||
<h2 class="mt-4" id="comments">Comments</h2>
|
||||
<div class="post_list">
|
||||
{% for post_reply in post_replies %}
|
||||
{% include 'post/_post_reply_teaser.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<nav aria-label="Pagination" class="mt-4">
|
||||
{% if replies_prev_url %}
|
||||
<a href="{{ replies_prev_url }}#comments" class="btn btn-primary">
|
||||
<span aria-hidden="true">←</span> {{ _('Previous page') }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if replies_next_url %}
|
||||
<a href="{{ replies_next_url }}#comments" class="btn btn-primary">
|
||||
{{ _('Next page') }} <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -17,21 +17,40 @@ from sqlalchemy import desc, or_, text
|
|||
def show_profile(user):
|
||||
if user.deleted or user.banned and current_user.is_anonymous():
|
||||
abort(404)
|
||||
posts = Post.query.filter_by(user_id=user.id).order_by(desc(Post.posted_at)).limit(20).all()
|
||||
|
||||
post_page = request.args.get('post_page', 1, type=int)
|
||||
replies_page = request.args.get('replies_page', 1, type=int)
|
||||
|
||||
posts = Post.query.filter_by(user_id=user.id).order_by(desc(Post.posted_at)).paginate(page=post_page, per_page=50, error_out=False)
|
||||
moderates = Community.query.filter_by(banned=False).join(CommunityMember).filter(CommunityMember.user_id == user.id)\
|
||||
.filter(or_(CommunityMember.is_moderator, CommunityMember.is_owner))
|
||||
upvoted = Post.query.join(PostVote).filter(Post.id == PostVote.post_id, PostVote.effect > 0).order_by(desc(Post.posted_at)).limit(10).all()
|
||||
subscribed = Community.query.filter_by(banned=False).join(CommunityMember).filter(CommunityMember.user_id == user.id).all()
|
||||
if current_user.is_anonymous or user.id != current_user.id:
|
||||
moderates = moderates.filter(Community.private_mods == False)
|
||||
post_replies = PostReply.query.filter_by(user_id=user.id).order_by(desc(PostReply.posted_at)).limit(20).all()
|
||||
post_replies = PostReply.query.filter_by(user_id=user.id).order_by(desc(PostReply.posted_at)).paginate(page=replies_page, per_page=50, error_out=False)
|
||||
|
||||
# profile info
|
||||
canonical = user.ap_public_url if user.ap_public_url else None
|
||||
user.about_html = markdown_to_html(user.about)
|
||||
description = shorten_string(markdown_to_text(user.about), 150) if user.about else None
|
||||
|
||||
# pagination urls
|
||||
post_next_url = url_for('activitypub.user_profile', actor=user.ap_id if user.ap_id is not None else user.user_name,
|
||||
post_page=posts.next_num) if posts.has_next else None
|
||||
post_prev_url = url_for('activitypub.user_profile', actor=user.ap_id if user.ap_id is not None else user.user_name,
|
||||
post_page=posts.prev_num) if posts.has_prev and post_page != 1 else None
|
||||
replies_next_url = url_for('activitypub.user_profile', actor=user.ap_id if user.ap_id is not None else user.user_name,
|
||||
replies_page=post_replies.next_num) if post_replies.has_next else None
|
||||
replies_prev_url = url_for('activitypub.user_profile', actor=user.ap_id if user.ap_id is not None else user.user_name,
|
||||
replies_page=post_replies.prev_num) if post_replies.has_prev and replies_page != 1 else None
|
||||
|
||||
return render_template('user/show_profile.html', user=user, posts=posts, post_replies=post_replies,
|
||||
moderates=moderates.all(), canonical=canonical, title=_('Posts by %(user_name)s',
|
||||
user_name=user.user_name),
|
||||
description=description, subscribed=subscribed, upvoted=upvoted)
|
||||
description=description, subscribed=subscribed, upvoted=upvoted,
|
||||
post_next_url=post_next_url, post_prev_url=post_prev_url,
|
||||
replies_next_url=replies_next_url, replies_prev_url=replies_prev_url)
|
||||
|
||||
|
||||
@bp.route('/u/<actor>/profile', methods=['GET', 'POST'])
|
||||
|
|
Loading…
Add table
Reference in a new issue