active sort with user default sort choice

This commit is contained in:
rimu 2024-01-15 18:26:22 +13:00
parent c3d83b1428
commit eee7c59b57
9 changed files with 67 additions and 12 deletions

View file

@ -101,7 +101,7 @@ def show_community(community: Community):
abort(404)
page = request.args.get('page', 1, type=int)
sort = request.args.get('sort', '')
sort = request.args.get('sort', '' if current_user.is_anonymous else current_user.default_sort)
# If nothing has changed since their last visit, return HTTP 304
current_etag = f"{community.id}{sort}_{hash(community.last_active)}"
@ -133,6 +133,8 @@ def show_community(community: Community):
posts = posts.filter(Post.posted_at > utcnow() - timedelta(days=7)).order_by(desc(Post.score))
elif sort == 'new':
posts = posts.order_by(desc(Post.posted_at))
elif sort == 'active':
posts = posts.order_by(desc(Post.last_active))
posts = posts.paginate(page=page, per_page=100, error_out=False)
description = shorten_string(community.description, 150) if community.description else None
@ -151,7 +153,7 @@ def show_community(community: Community):
next_url=next_url, prev_url=prev_url, low_bandwidth=request.cookies.get('low_bandwidth', '0') == '1',
rss_feed=f"https://{current_app.config['SERVER_NAME']}/community/{community.link()}/feed", rss_feed_name=f"{community.title} posts on PieFed",
content_filters=content_filters, moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()))
joined_communities=joined_communities(current_user.get_id()), sort=sort)
# RSS feed of the community

View file

@ -25,7 +25,7 @@ import pytesseract
@bp.route('/', methods=['HEAD', 'GET', 'POST'])
@bp.route('/home', methods=['GET', 'POST'])
@bp.route('/home/<sort>', methods=['GET', 'POST'])
def index(sort='hot'):
def index(sort=None):
if 'application/ld+json' in request.headers.get('Accept', '') or 'application/activity+json' in request.headers.get(
'Accept', ''):
return activitypub_application()
@ -35,21 +35,24 @@ def index(sort='hot'):
@bp.route('/popular', methods=['GET'])
@bp.route('/popular/<sort>', methods=['GET'])
def popular(sort='hot'):
def popular(sort=None):
return home_page('popular', sort)
@bp.route('/all', methods=['GET'])
@bp.route('/all/<sort>', methods=['GET'])
def all_posts(sort='hot'):
def all_posts(sort=None):
return home_page('all', sort)
def home_page(type, sort='hot'):
def home_page(type, sort):
verification_warning()
if sort is None:
sort = current_user.default_sort if current_user.is_authenticated else 'hot'
# If nothing has changed since their last visit, return HTTP 304
current_etag = f"{type}_{hash(str(g.site.last_active))}"
current_etag = f"{type}_{sort}_{hash(str(g.site.last_active))}"
if current_user.is_anonymous and request_etag_matches(current_etag):
return return_304(current_etag)
@ -92,6 +95,8 @@ def home_page(type, sort='hot'):
posts = posts.filter(Post.posted_at > utcnow() - timedelta(days=1)).order_by(desc(Post.score))
elif sort == 'new':
posts = posts.order_by(desc(Post.posted_at))
elif sort == 'active':
posts = posts.order_by(desc(Post.last_active))
# Pagination
posts = posts.paginate(page=page, per_page=100, error_out=False)
@ -111,7 +116,7 @@ def home_page(type, sort='hot'):
POST_TYPE_IMAGE=POST_TYPE_IMAGE, POST_TYPE_LINK=POST_TYPE_LINK,
low_bandwidth=request.cookies.get('low_bandwidth', '0') == '1',
SUBSCRIPTION_PENDING=SUBSCRIPTION_PENDING, SUBSCRIPTION_MEMBER=SUBSCRIPTION_MEMBER,
etag=f"{type}_{hash(str(g.site.last_active))}", next_url=next_url, prev_url=prev_url,
etag=f"{type}_{sort}_{hash(str(g.site.last_active))}", next_url=next_url, prev_url=prev_url,
rss_feed=f"https://{current_app.config['SERVER_NAME']}/feed",
rss_feed_name=f"Posts on " + g.site.name,
title=f"{g.site.name} - {g.site.description}",

View file

@ -343,6 +343,7 @@ class User(UserMixin, db.Model):
ip_address = db.Column(db.String(50))
instance_id = db.Column(db.Integer, db.ForeignKey('instance.id'), index=True)
reports = db.Column(db.Integer, default=0) # how many times this user has been reported.
default_sort = db.Column(db.String(25), default='hot')
avatar = db.relationship('File', lazy='joined', foreign_keys=[avatar_id], single_parent=True, cascade="all, delete-orphan")
cover = db.relationship('File', lazy='joined', foreign_keys=[cover_id], single_parent=True, cascade="all, delete-orphan")

View file

@ -8,4 +8,7 @@
<a href="/{{ type }}/new" class="btn {{ 'btn-primary' if sort == 'new' else 'btn-outline-secondary' }}" rel="nofollow">
{{ _('New') }}
</a>
<a href="/{{ type }}/active" class="btn {{ 'btn-primary' if sort == 'active' else 'btn-outline-secondary' }}" rel="nofollow">
{{ _('Active') }}
</a>
</div>

View file

@ -2,13 +2,16 @@
<a class="btn btn-primary" href="/community/{{ community.link() }}/submit">{{ _('Create post') }}</a>
</div>
<div class="btn-group mt-1 mb-2">
<a href="?sort=hot" class="btn {{ 'btn-primary' if request.args.get('sort', '') == '' or request.args.get('sort', '') == 'hot' else 'btn-outline-secondary' }}" rel="nofollow">
<a href="?sort=hot" class="btn {{ 'btn-primary' if sort == '' or sort == 'hot' else 'btn-outline-secondary' }}" rel="nofollow">
{{ _('Hot') }}
</a>
<a href="?sort=top" class="btn {{ 'btn-primary' if request.args.get('sort', '') == 'top' else 'btn-outline-secondary' }}" rel="nofollow">
<a href="?sort=top" class="btn {{ 'btn-primary' if sort == 'top' else 'btn-outline-secondary' }}" rel="nofollow">
{{ _('Top') }}
</a>
<a href="?sort=new" class="btn {{ 'btn-primary' if request.args.get('sort', '') == 'new' else 'btn-outline-secondary' }}" rel="nofollow">
<a href="?sort=new" class="btn {{ 'btn-primary' if sort == 'new' else 'btn-outline-secondary' }}" rel="nofollow">
{{ _('New') }}
</a>
<a href="?sort=active" class="btn {{ 'btn-primary' if sort == 'active' else 'btn-outline-secondary' }}" rel="nofollow">
{{ _('Active') }}
</a>
</div>

View file

@ -20,6 +20,7 @@
{{ render_field(form.nsfl) }}
{{ render_field(form.searchable) }}
{{ render_field(form.indexable) }}
{{ render_field(form.default_sort) }}
{{ render_field(form.import_file) }}
{{ render_field(form.submit) }}
&nbsp;&nbsp;<a href="{{ url_for('user.user_settings_filters') }}">{{ _('Manage content filters') }}</a>

View file

@ -2,7 +2,7 @@ from flask import session
from flask_login import current_user
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, PasswordField, BooleanField, EmailField, TextAreaField, FileField, \
RadioField, DateField
RadioField, DateField, SelectField
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo, Length, Optional
from flask_babel import _, lazy_gettext as _l
@ -35,6 +35,12 @@ class SettingsForm(FlaskForm):
indexable = BooleanField(_l('Allow search engines to index this profile'))
manually_approves_followers = BooleanField(_l('Manually approve followers'))
import_file = FileField(_('Import community subscriptions and user blocks from Lemmy'))
sorts = [('hot', _l('Hot')),
('top', _l('Top')),
('new', _l('New')),
('active', _l('Active')),
]
default_sort = SelectField(_l('By default, sort posts by'), choices=sorts, validators=[DataRequired()], coerce=str)
submit = SubmitField(_l('Save settings'))

View file

@ -158,6 +158,7 @@ def change_settings():
current_user.show_nsfl = form.nsfl.data
current_user.searchable = form.searchable.data
current_user.indexable = form.indexable.data
current_user.default_sort = form.default_sort.data
import_file = request.files['import_file']
if import_file and import_file.filename != '':
file_ext = os.path.splitext(import_file.filename)[1]
@ -187,6 +188,7 @@ def change_settings():
form.nsfl.data = current_user.show_nsfl
form.searchable.data = current_user.searchable
form.indexable.data = current_user.indexable
form.default_sort.data = current_user.default_sort
return render_template('user/edit_settings.html', title=_('Edit profile'), form=form, user=current_user,
moderating_communities=moderating_communities(current_user.get_id()),

View file

@ -0,0 +1,32 @@
"""default sort
Revision ID: b86c49cbd9a0
Revises: 8885aafd5291
Create Date: 2024-01-15 17:37:17.886232
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'b86c49cbd9a0'
down_revision = '8885aafd5291'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('user', schema=None) as batch_op:
batch_op.add_column(sa.Column('default_sort', sa.String(length=25), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('user', schema=None) as batch_op:
batch_op.drop_column('default_sort')
# ### end Alembic commands ###