diff --git a/app/routes/mod.py b/app/routes/mod.py index 3c6609a..a98ccfb 100644 --- a/app/routes/mod.py +++ b/app/routes/mod.py @@ -1,7 +1,8 @@ from flask import Blueprint, abort, redirect, url_for, request, render_template, flash -from ..constants import InfoboxKind, PermissionLevel +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 +from ..models import Topics, Threads, Users, MOTD +from ..lib.babycode import babycode_to_html, BABYCODE_VERSION from slugify import slugify from functools import wraps import time @@ -24,7 +25,49 @@ def admin_only(view_func): @bp.get('/') def index(): - return 'stub' + 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) + +@bp.post('/motd/set/') +def set_motd(): + title = request.form.get('motd_title', '') + if not title: + flash('MOTD must have a title.', InfoboxKind.ERROR) + return redirect(url_for('.index')) + orig_body = request.form.get('babycode_content', '') + if not orig_body: + flash('MOTD must have a body.', InfoboxKind.ERROR) + return redirect(url_for('.index')) + user = get_active_user() + data = { + 'title': title.strip(), + 'body_original_markup': orig_body, + 'body_rendered': babycode_to_html(orig_body, banned_tags=MOTD_BANNED_TAGS).result, + 'format_version': BABYCODE_VERSION, + 'edited_at': int(time.time()), + 'user_id': user.id, + } + if MOTD.has_motd(): + motd = MOTD.get_all()[0] + motd.update(data) + message = 'MOTD updated.' + else: + data['created_at'] = int(time.time()) + motd = MOTD.create(data) + message = 'MOTD created.' + + flash(message, InfoboxKind.INFO) + return redirect(url_for('.index')) + +@bp.post('/motd/clear/') +def clear_motd(): + if not MOTD.has_motd(): + return redirect(url_for('.index')) + + current = MOTD.get_all()[0] + current.delete() + flash('MOTD cleared.', InfoboxKind.INFO) + return redirect(url_for('.index')) @bp.get('/topics/new/') def new_topic(): @@ -35,10 +78,6 @@ def new_topic_post(): topic = Topics.new(request.form.get('name'), request.form.get('description')) return redirect(url_for('topics.topic_by_id', topic_id=topic.id)) -@bp.get('/topics/sort/') -def sort_topics(): - return 'stub' - @bp.get('/topics//edit/') def edit_topic(topic_id): topic = Topics.find({'id': topic_id}) diff --git a/app/templates/common/icons.html b/app/templates/common/icons.html index 699c3d9..fd17191 100644 --- a/app/templates/common/icons.html +++ b/app/templates/common/icons.html @@ -10,6 +10,10 @@ error {%- endmacro -%} +{%- macro icn_megaphone(width=48) -%} +megaphone +{%- endmacro -%} + {%- macro icn_bookmark(width=16) -%} bookmark {%- endmacro -%} diff --git a/app/templates/common/macros.html b/app/templates/common/macros.html index d19635a..7d51fe0 100644 --- a/app/templates/common/macros.html +++ b/app/templates/common/macros.html @@ -1,4 +1,4 @@ -{%- from 'common/icons.html' import icn_info, icn_warn, icn_error, icn_bookmark -%} +{%- from 'common/icons.html' import icn_info, icn_warn, icn_error, icn_bookmark, icn_megaphone -%} {% macro timestamp(unix_ts) -%} @@ -238,3 +238,18 @@ {%- endif -%} {%- endmacro %} + +{% macro motd(motd_objs) -%} +{%- if motd_objs -%} +
+
+ {{ icn_megaphone(64) }} + MOTD +
+
+

{{ motd_objs[0].title }}

+
{{ motd_objs[0].body_rendered | safe }}
+
+
+{%- endif -%} +{%- endmacro %} diff --git a/app/templates/mod/panel.html b/app/templates/mod/panel.html new file mode 100644 index 0000000..fb69f10 --- /dev/null +++ b/app/templates/mod/panel.html @@ -0,0 +1,23 @@ +{%- from 'common/macros.html' import subheader, babycode_editor_component -%} +{%- extends 'base.html' -%} +{%- block title -%}settings{%- endblock -%} +{%- block content -%} +{{- subheader('Moderation panel') -}} +
+ Message of the Day +

The Message of the Day is shown on the front page and on each topic's thread list.

+
+ + + + {{ babycode_editor_component(placeholder='MOTD content', prefill=motd.body_original_markup, id='motd-content', banned_tags=MOTD_BANNED_TAGS) }} +
+ +
+ +
+
+
+ Sort topics +
+{%- endblock -%} diff --git a/app/templates/topics/topic.html b/app/templates/topics/topic.html index 5a13d21..99bb559 100644 --- a/app/templates/topics/topic.html +++ b/app/templates/topics/topic.html @@ -1,4 +1,4 @@ -{% from 'common/macros.html' import timestamp, subheader, pager %} +{% from 'common/macros.html' import timestamp, subheader, pager, motd %} {% from 'common/icons.html' import icn_locked, icn_stickied %} {%- extends 'base.html' -%} {%- block title -%}browsing topic {{topic.name}}{%- endblock -%} @@ -46,6 +46,7 @@ {%- if threads | length == 0 -%}

There are no threads in this topic yet.{%- if is_logged_in() and get_active_user().can_post_to_thread_or_topic(topic) %} Be the first to start a discussion!{%- endif -%}

{%- endif -%} +{{ motd(get_motds()) }} {%- for thread in threads -%}
diff --git a/app/templates/topics/topics.html b/app/templates/topics/topics.html index 59389db..71acc80 100644 --- a/app/templates/topics/topics.html +++ b/app/templates/topics/topics.html @@ -1,4 +1,4 @@ -{% from 'common/macros.html' import timestamp, subheader %} +{% from 'common/macros.html' import timestamp, subheader, motd %} {% from 'common/icons.html' import icn_locked %} {%- extends 'base.html' -%} {%- block content -%} @@ -7,10 +7,11 @@
Moderation actions New topic - Sort topics + Sort topics
{%- endif -%} {%- endcall -%} +{{ motd(get_motds()) }} {%- for topic in topics -%}
diff --git a/data/static/css/style.css b/data/static/css/style.css index c591cad..a0ece7f 100644 --- a/data/static/css/style.css +++ b/data/static/css/style.css @@ -389,7 +389,7 @@ ul.horizontal, ol.horizontal { .motd { display: flex; - gap: var(--base-padding); + gap: var(--big-padding); } .contain-svg { diff --git a/data/static/icons/megaphone.svg b/data/static/icons/megaphone.svg new file mode 100644 index 0000000..27adcfc --- /dev/null +++ b/data/static/icons/megaphone.svg @@ -0,0 +1 @@ + \ No newline at end of file