diff --git a/app/models.py b/app/models.py index b6f1226c..38561343 100644 --- a/app/models.py +++ b/app/models.py @@ -617,6 +617,8 @@ class User(UserMixin, db.Model): markdown_editor = db.Column(db.Boolean, default=False) interface_language = db.Column(db.String(10)) # a locale that the translation system understands e.g. 'en' or 'en-us'. If empty, use browser default language_id = db.Column(db.Integer, db.ForeignKey('language.id')) # the default choice in the language dropdown when composing posts & comments + reply_collapse_threshold = db.Column(db.Integer, default=-10) + reply_hide_threshold = db.Column(db.Integer, default=-20) 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") diff --git a/app/post/routes.py b/app/post/routes.py index e6cc1db8..2088016c 100644 --- a/app/post/routes.py +++ b/app/post/routes.py @@ -276,11 +276,13 @@ def show_post(post_id: int): recently_downvoted = recently_downvoted_posts(current_user.id) recently_upvoted_replies = recently_upvoted_post_replies(current_user.id) recently_downvoted_replies = recently_downvoted_post_replies(current_user.id) + reply_collapse_threshold = current_user.reply_collapse_threshold else: recently_upvoted = [] recently_downvoted = [] recently_upvoted_replies = [] recently_downvoted_replies = [] + reply_collapse_threshold = -10 # Polls poll_form = False @@ -316,6 +318,7 @@ def show_post(post_id: int): noindex=not post.author.indexable, preconnect=post.url if post.url else None, recently_upvoted=recently_upvoted, recently_downvoted=recently_downvoted, recently_upvoted_replies=recently_upvoted_replies, recently_downvoted_replies=recently_downvoted_replies, + reply_collapse_threshold=reply_collapse_threshold, etag=f"{post.id}{sort}_{hash(post.last_active)}", markdown_editor=current_user.is_authenticated and current_user.markdown_editor, low_bandwidth=request.cookies.get('low_bandwidth', '0') == '1', SUBSCRIPTION_MEMBER=SUBSCRIPTION_MEMBER, SUBSCRIPTION_OWNER=SUBSCRIPTION_OWNER, SUBSCRIPTION_MODERATOR=SUBSCRIPTION_MODERATOR, diff --git a/app/post/util.py b/app/post/util.py index 7aa3d9c5..8ab4ca9f 100644 --- a/app/post/util.py +++ b/app/post/util.py @@ -21,6 +21,11 @@ def post_replies(post_id: int, sort_by: str, show_first: int = 0) -> List[PostRe blocked_accounts = blocked_users(current_user.id) if blocked_accounts: comments = comments.filter(PostReply.user_id.not_in(blocked_accounts)) + if current_user.reply_hide_threshold: + comments = comments.filter(PostReply.score > current_user.reply_hide_threshold) + else: + comments.filter(PostReply.score > -20) + if sort_by == 'hot': comments = comments.order_by(desc(PostReply.ranking)) elif sort_by == 'top': diff --git a/app/static/styles.css b/app/static/styles.css index 67dc0161..79d44e32 100644 --- a/app/static/styles.css +++ b/app/static/styles.css @@ -621,6 +621,10 @@ div.navbar { margin-bottom: 3px; } +form h5 { + padding-top: 12px; +} + .coolfieldset, .coolfieldset.expanded { border: 1px solid #ddd; border-radius: 5px; diff --git a/app/static/styles.scss b/app/static/styles.scss index f12ce699..b0330edb 100644 --- a/app/static/styles.scss +++ b/app/static/styles.scss @@ -189,6 +189,12 @@ div.navbar { margin-bottom: 3px; } +form { + h5 { + padding-top: 12px; + } +} + .coolfieldset, .coolfieldset.expanded{ border:1px solid $light-grey; border-radius: 5px; diff --git a/app/templates/post/post.html b/app/templates/post/post.html index a79de916..ed0a4a4d 100644 --- a/app/templates/post/post.html +++ b/app/templates/post/post.html @@ -80,7 +80,7 @@ {% if comment['comment'].author.deleted -%} [deleted] {% else -%} - {% if comment['comment'].author.avatar_id and comment['comment'].score > -10 and not low_bandwidth -%} + {% if comment['comment'].author.avatar_id and comment['comment'].score > reply_collapse_threshold and not low_bandwidth -%} {% endif -%} @@ -122,7 +122,7 @@ {% endwith -%}
- {% if comment['comment'].score <= -10 -%} + {% if comment['comment'].score <= reply_collapse_threshold -%} {% else -%} @@ -148,7 +148,7 @@ {% endif -%} {% endif -%}
- {% if comment['comment'].score <= -10 -%} + {% if comment['comment'].score <= reply_collapse_threshold -%} diff --git a/app/templates/user/edit_settings.html b/app/templates/user/edit_settings.html index 5d142a6a..2ae7dad2 100644 --- a/app/templates/user/edit_settings.html +++ b/app/templates/user/edit_settings.html @@ -26,6 +26,10 @@ {{ render_field(form.email_unread) }}
Visibility
{{ render_field(form.ignore_bots) }} + {{ render_field(form.reply_collapse_threshold) }} + {{ _('Collapse replies with a score at or below this level - click to view.') }} + {{ render_field(form.reply_hide_threshold) }} + {{ _('Hide replies with a score at or below this level.') }} {{ render_field(form.nsfw) }} {{ render_field(form.nsfl) }} {{ render_field(form.searchable) }} diff --git a/app/user/forms.py b/app/user/forms.py index a44f3eb1..76df4941 100644 --- a/app/user/forms.py +++ b/app/user/forms.py @@ -38,6 +38,8 @@ class SettingsForm(FlaskForm): ignore_bots = BooleanField(_l('Hide posts by bots')) nsfw = BooleanField(_l('Show NSFW posts')) nsfl = BooleanField(_l('Show NSFL posts')) + reply_collapse_threshold = IntegerField(_l('Reply collapse threshold')) + reply_hide_threshold = IntegerField(_l('Reply hide threshold')) markdown_editor = BooleanField(_l('Use markdown editor GUI when writing')) searchable = BooleanField(_l('Show profile in user list')) indexable = BooleanField(_l('My posts appear in search results')) diff --git a/app/user/routes.py b/app/user/routes.py index 917f84fe..4eb92f6d 100644 --- a/app/user/routes.py +++ b/app/user/routes.py @@ -238,6 +238,8 @@ def change_settings(): current_user.email_unread = form.email_unread.data current_user.markdown_editor = form.markdown_editor.data current_user.interface_language = form.interface_language.data + current_user.reply_collapse_threshold = form.reply_collapse_threshold.data + current_user.reply_hide_threshold = form.reply_hide_threshold.data session['ui_language'] = form.interface_language.data import_file = request.files['import_file'] if propagate_indexable: @@ -277,6 +279,8 @@ def change_settings(): form.theme.data = current_user.theme form.markdown_editor.data = current_user.markdown_editor form.interface_language.data = current_user.interface_language + form.reply_collapse_threshold.data = current_user.reply_collapse_threshold + form.reply_hide_threshold.data = current_user.reply_hide_threshold return render_template('user/edit_settings.html', title=_('Edit profile'), form=form, user=current_user, moderating_communities=moderating_communities(current_user.get_id()), diff --git a/migrations/versions/363f2f07ff30_reply_thresholds.py b/migrations/versions/363f2f07ff30_reply_thresholds.py new file mode 100644 index 00000000..4532b9a9 --- /dev/null +++ b/migrations/versions/363f2f07ff30_reply_thresholds.py @@ -0,0 +1,36 @@ +"""reply thresholds + +Revision ID: 363f2f07ff30 +Revises: 745e3e985199 +Create Date: 2024-06-28 17:40:49.866284 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '363f2f07ff30' +down_revision = '745e3e985199' +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('reply_collapse_threshold', sa.Integer(), nullable=True)) + batch_op.add_column(sa.Column('reply_hide_threshold', sa.Integer(), nullable=True)) + + # ### end Alembic commands ### + + op.execute(sa.DDL('UPDATE "user" SET reply_collapse_threshold = -10, reply_hide_threshold = -20 WHERE ap_id is null')) + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('user', schema=None) as batch_op: + batch_op.drop_column('reply_hide_threshold') + batch_op.drop_column('reply_collapse_threshold') + + # ### end Alembic commands ###