add topic sorting & js to support it

This commit is contained in:
2026-05-28 04:19:42 +03:00
parent 303750a281
commit 6b7a0e7a17
8 changed files with 241 additions and 3 deletions

View File

@@ -2,6 +2,7 @@ from flask import Blueprint, abort, redirect, url_for, request, render_template,
from ..constants import InfoboxKind, PermissionLevel, MOTD_BANNED_TAGS
from ..auth import is_logged_in, get_active_user, csrf_verified
from ..models import Topics, Threads, Users, MOTD
from ..db import db
from ..lib.babycode import babycode_to_html, BABYCODE_VERSION
from slugify import slugify
from functools import wraps
@@ -26,7 +27,8 @@ def admin_only(view_func):
@bp.get('/')
def index():
motd = MOTD.get_all()[0] if MOTD.has_motd() else None
return render_template('mod/panel.html', MOTD_BANNED_TAGS=MOTD_BANNED_TAGS, motd=motd)
topics = Topics.get_list()
return render_template('mod/panel.html', MOTD_BANNED_TAGS=MOTD_BANNED_TAGS, motd=motd, topics=topics)
@bp.post('/motd/set/')
def set_motd():
@@ -143,6 +145,15 @@ def sticky_thread(thread_id):
thread.update({'is_stickied': request.form.get('sticky')})
return redirect(url_for('threads.thread_by_id', thread_id=thread.id))
@bp.post('/threads/sort/')
def sort_topics():
topics_list = request.form.getlist('topics[]')
with db.transaction():
for new_order, topic_id in enumerate(topics_list):
db.execute('UPDATE topics SET sort_order = ? WHERE id = ?', new_order, topic_id)
return redirect(url_for('.index', _anchor='sort-topics'))
@bp.post('/users/<int:user_id>/make-guest/')
@csrf_verified
def make_user_guest(user_id):

View File

@@ -23,5 +23,6 @@
{%- endwith -%}
{%- block content -%}{%- endblock -%}
{%- include 'common/footer.html' -%}
<script src="{{'/static/js/ui.js' | cachebust}}"></script>
</body>
</html>

View File

@@ -25,3 +25,7 @@
{%- macro icn_stickied(width=16) -%}
<img src="/static/icons/sticky.svg" title="Stickied" alt="paper held by pushpin" style="width: {{width}}px;">
{%- endmacro -%}
{%- macro icn_dragger(width=24) -%}
<img src="/static/icons/dragger.svg" style="width: {{width}}px;">
{%- endmacro -%}

View File

@@ -1,4 +1,8 @@
{%- from 'common/icons.html' import icn_info, icn_warn, icn_error, icn_bookmark, icn_megaphone -%}
{%- from 'common/icons.html' import icn_info, icn_warn, icn_error, icn_bookmark, icn_megaphone, icn_dragger -%}
{% macro dict_to_attr(attrs) -%}
{%- for key, value in attrs.items() if value is not none -%}{{' '}}{{key}}="{{value}}"{%- endfor -%}
{%- endmacro %}
{% macro timestamp(unix_ts) -%}
<time datetime="{{ unix_ts | iso8601 }}">{{ unix_ts | ts_datetime('%Y-%m-%d %H:%M')}} <abbr title="Server Time">ST</abbr></time>
@@ -253,3 +257,18 @@
</div>
{%- endif -%}
{%- endmacro %}
{% macro sortable_list(attr=none) -%}
<ol class="sortable-list plank even no-shadow minimal tertiary-bg" {% if attr %}{{ dict_to_attr(attr) }}{% endif %}>
{%- if caller -%}
{{ caller() }}
{%- endif -%}
</ol>
{%- endmacro %}
{% macro sortable_list_item(key, immovable=false, attr=none) -%}
<li class="sortable-item{{ ' immovable' if immovable else '' }} plank even no-shadow {{'tertiary-bg' if immovable else ''}}" data-sortable-list-key="{{key}}" {% if attr %}{{ dict_to_attr(attr) }}{% endif %}>
<span class="dragger plank minimal even no-shadow tertiary-bg" draggable="{{ 'true' if not immovable else 'false' }}">{{ icn_dragger() }}</span>
<div class="sortable-item-inner">{{ caller() }}</div>
</li>
{%- endmacro %}

View File

@@ -1,4 +1,4 @@
{%- from 'common/macros.html' import subheader, babycode_editor_component -%}
{%- from 'common/macros.html' import subheader, babycode_editor_component, sortable_list, sortable_list_item -%}
{%- extends 'base.html' -%}
{%- block title -%}settings{%- endblock -%}
{%- block content -%}
@@ -19,5 +19,18 @@
</fieldset>
<fieldset class="plank" id="sort-topics">
<legend>Sort topics</legend>
<p>Drag topics around to reorder them. Press "Save order" when done.</p>
<form method="POST" action="{{url_for('mod.sort_topics')}}">
<input type="submit" value="Save order">
{%- call() sortable_list() -%}
{%- for topic in topics -%}
{%- call() sortable_list_item(key="topics") -%}
<h2 class="info">{{ topic.name }}</h2>
<div>{{topic.description}}</div>
<input type="hidden" name="topics[]" value="{{ topic.id }}">
{%- endcall -%}
{%- endfor -%}
{%- endcall -%}
</form>
</fieldset>
{%- endblock -%}