Compare commits
7 Commits
0c2e920206
...
v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
cd507ac25f
|
|||
|
82659cedef
|
|||
|
7eafcde1d7
|
|||
|
a2ceaa0966
|
|||
|
f1931c76e6
|
|||
|
65ad672748
|
|||
|
b9c4ec3911
|
@@ -164,6 +164,7 @@ class Topics(Model):
|
|||||||
GROUP BY thread_id
|
GROUP BY thread_id
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
|
threads.id,
|
||||||
threads.title,
|
threads.title,
|
||||||
threads.slug,
|
threads.slug,
|
||||||
threads.created_at,
|
threads.created_at,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ def new_topic():
|
|||||||
@bp.post('/topics/new/')
|
@bp.post('/topics/new/')
|
||||||
def new_topic_post():
|
def new_topic_post():
|
||||||
topic = Topics.new(request.form.get('name'), request.form.get('description'))
|
topic = Topics.new(request.form.get('name'), request.form.get('description'))
|
||||||
return redirect(url_for('topics.topic', slug=topic.slug))
|
return redirect(url_for('topics.topic_by_id', topic_id=topic.id))
|
||||||
|
|
||||||
@bp.get('/topics/sort/')
|
@bp.get('/topics/sort/')
|
||||||
def sort_topics():
|
def sort_topics():
|
||||||
@@ -43,7 +43,7 @@ def edit_topic_post(topic_id):
|
|||||||
'name': request.form.get('name').strip(),
|
'name': request.form.get('name').strip(),
|
||||||
'description': request.form.get('description').strip(),
|
'description': request.form.get('description').strip(),
|
||||||
})
|
})
|
||||||
return redirect(url_for('topics.topic', slug=topic.slug))
|
return redirect(url_for('topics.topic_by_id', topic_id=topic.id))
|
||||||
|
|
||||||
@bp.post('/topics/<int:topic_id>/lock/')
|
@bp.post('/topics/<int:topic_id>/lock/')
|
||||||
def lock_topic(topic_id):
|
def lock_topic(topic_id):
|
||||||
@@ -51,7 +51,7 @@ def lock_topic(topic_id):
|
|||||||
if not topic:
|
if not topic:
|
||||||
abort(404)
|
abort(404)
|
||||||
topic.update({'is_locked': request.form.get('lock', default=0)})
|
topic.update({'is_locked': request.form.get('lock', default=0)})
|
||||||
return redirect(url_for('topics.topic', slug=topic.slug))
|
return redirect(url_for('topics.topic_by_id', topic_id=topic.id))
|
||||||
|
|
||||||
@bp.post('/threads/<int:thread_id>/move/')
|
@bp.post('/threads/<int:thread_id>/move/')
|
||||||
def move_thread(thread_id):
|
def move_thread(thread_id):
|
||||||
@@ -62,7 +62,7 @@ def move_thread(thread_id):
|
|||||||
if not target_topic:
|
if not target_topic:
|
||||||
abort(404)
|
abort(404)
|
||||||
thread.update({'topic_id': target_topic.id})
|
thread.update({'topic_id': target_topic.id})
|
||||||
return redirect(url_for('threads.thread', slug=thread.slug))
|
return redirect(url_for('threads.thread_by_id', thread_id=thread.id))
|
||||||
|
|
||||||
@bp.post('/threads/<int:thread_id>/lock/')
|
@bp.post('/threads/<int:thread_id>/lock/')
|
||||||
def lock_thread(thread_id):
|
def lock_thread(thread_id):
|
||||||
@@ -70,7 +70,7 @@ def lock_thread(thread_id):
|
|||||||
if not thread:
|
if not thread:
|
||||||
abort(404)
|
abort(404)
|
||||||
thread.update({'is_locked': request.form.get('lock')})
|
thread.update({'is_locked': request.form.get('lock')})
|
||||||
return redirect(url_for('threads.thread', slug=thread.slug))
|
return redirect(url_for('threads.thread_by_id', thread_id=thread.id))
|
||||||
|
|
||||||
@bp.post('/threads/<int:thread_id>/sticky/')
|
@bp.post('/threads/<int:thread_id>/sticky/')
|
||||||
def sticky_thread(thread_id):
|
def sticky_thread(thread_id):
|
||||||
@@ -78,7 +78,7 @@ def sticky_thread(thread_id):
|
|||||||
if not thread:
|
if not thread:
|
||||||
abort(404)
|
abort(404)
|
||||||
thread.update({'is_stickied': request.form.get('sticky')})
|
thread.update({'is_stickied': request.form.get('sticky')})
|
||||||
return redirect(url_for('threads.thread', slug=thread.slug))
|
return redirect(url_for('threads.thread_by_id', thread_id=thread.id))
|
||||||
|
|
||||||
@bp.post('/users/<int:user_id>/make-guest/')
|
@bp.post('/users/<int:user_id>/make-guest/')
|
||||||
@csrf_verified
|
@csrf_verified
|
||||||
|
|||||||
@@ -1,7 +1,44 @@
|
|||||||
from flask import Blueprint
|
from flask import Blueprint, abort
|
||||||
|
from functools import wraps
|
||||||
|
from ..auth import login_required, get_active_user
|
||||||
|
from ..models import Posts
|
||||||
|
|
||||||
bp = Blueprint('posts', __name__, url_prefix='/posts/')
|
bp = Blueprint('posts', __name__, url_prefix='/posts/')
|
||||||
|
|
||||||
|
def ownership_required(view_func):
|
||||||
|
@wraps(view_func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
post = Posts.find({'id': kwargs.get('post_id', None)})
|
||||||
|
if not post:
|
||||||
|
abort(404)
|
||||||
|
|
||||||
|
if post.user_id != get_active_user().id:
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
return view_func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
def ownership_or_mod_required(view_func):
|
||||||
|
@wraps(view_func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
post = Posts.find({'id': kwargs.get('post_id', None)})
|
||||||
|
if not post:
|
||||||
|
abort(404)
|
||||||
|
|
||||||
|
if post.user_id != get_active_user().id and not get_active_user().is_mod():
|
||||||
|
abort(403)
|
||||||
|
|
||||||
|
return view_func(*args, **kwargs)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
@bp.get('/<int:post_id>/edit/')
|
@bp.get('/<int:post_id>/edit/')
|
||||||
|
@login_required
|
||||||
|
@ownership_required
|
||||||
def edit(post_id):
|
def edit(post_id):
|
||||||
return 'stub'
|
return 'stub'
|
||||||
|
|
||||||
|
@bp.get('/<int:post_id>/delete/')
|
||||||
|
@login_required
|
||||||
|
@ownership_or_mod_required
|
||||||
|
def delete(post_id):
|
||||||
|
return 'stub'
|
||||||
|
|||||||
@@ -5,11 +5,21 @@ import math
|
|||||||
|
|
||||||
bp = Blueprint('threads', __name__, url_prefix='/threads/')
|
bp = Blueprint('threads', __name__, url_prefix='/threads/')
|
||||||
|
|
||||||
@bp.get('/<slug>/')
|
@bp.get('/<int:thread_id>/')
|
||||||
def thread(slug):
|
def thread_by_id(thread_id):
|
||||||
thread = Threads.find({'slug': slug})
|
thread = Threads.find({'id': thread_id})
|
||||||
if not thread:
|
if not thread:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
return redirect(url_for('.thread', thread_id=thread_id, slug=thread.slug, **request.args))
|
||||||
|
|
||||||
|
@bp.get('/<int:thread_id>/<slug>/')
|
||||||
|
def thread(thread_id, slug):
|
||||||
|
thread = Threads.find({'id': thread_id})
|
||||||
|
if not thread:
|
||||||
|
abort(404)
|
||||||
|
if thread.slug != slug:
|
||||||
|
return redirect(url_for('.thread', thread_id=thread_id, slug=thread.slug, **request.kwargs))
|
||||||
|
|
||||||
topic = Topics.find({'id': thread.topic_id})
|
topic = Topics.find({'id': thread.topic_id})
|
||||||
started_by = Users.find({'id': thread.user_id})
|
started_by = Users.find({'id': thread.user_id})
|
||||||
PER_PAGE = 10
|
PER_PAGE = 10
|
||||||
@@ -34,21 +44,21 @@ def thread(slug):
|
|||||||
abort(404)
|
abort(404)
|
||||||
return render_template('threads/thread.html', thread=thread, posts=thread.get_posts(PER_PAGE, page), page=page, page_count=page_count, topic=topic, started_by=started_by, topics=Topics.get_list(), Reactions=Reactions)
|
return render_template('threads/thread.html', thread=thread, posts=thread.get_posts(PER_PAGE, page), page=page, page_count=page_count, topic=topic, started_by=started_by, topics=Topics.get_list(), Reactions=Reactions)
|
||||||
|
|
||||||
@bp.post('/<slug>/reply/')
|
@bp.post('/<int:thread_id>/reply/')
|
||||||
@login_required
|
@login_required
|
||||||
def reply(slug):
|
def reply(thread_id):
|
||||||
user = get_active_user()
|
user = get_active_user()
|
||||||
thread = Threads.find({'slug': slug})
|
thread = Threads.find({'id': thread_id})
|
||||||
if not thread:
|
if not thread:
|
||||||
abort(404)
|
abort(404)
|
||||||
if thread.locked() and not user.is_mod():
|
if thread.locked() and not user.is_mod():
|
||||||
# TODO: flash
|
# TODO: flash
|
||||||
return redirect(url_for('.thread', slug=slug))
|
return redirect(url_for('.thread_by_id', thread_id=thread_id))
|
||||||
post = Posts.new(user.id, thread.id, request.form.get('babycode_content'))
|
post = Posts.new(user.id, thread.id, request.form.get('babycode_content'))
|
||||||
return redirect(url_for('.thread', slug=slug, after=post.id, _anchor=f'post-{post.id}'))
|
return redirect(url_for('.thread_by_id', thread_id=thread_id, after=post.id, _anchor=f'post-{post.id}'))
|
||||||
|
|
||||||
@bp.get('/<slug>/feed.atom/')
|
@bp.get('/<int:thread_id>/feed.atom/')
|
||||||
def feed(slug):
|
def feed(thread_id):
|
||||||
return 'stub'
|
return 'stub'
|
||||||
|
|
||||||
@bp.get('/new/')
|
@bp.get('/new/')
|
||||||
|
|||||||
@@ -10,13 +10,23 @@ def all_topics():
|
|||||||
topic_list = Topics.get_list()
|
topic_list = Topics.get_list()
|
||||||
return render_template('topics/topics.html', topics=topic_list)
|
return render_template('topics/topics.html', topics=topic_list)
|
||||||
|
|
||||||
@bp.get('/<slug>/')
|
@bp.get('/<int:topic_id>/')
|
||||||
def topic(slug):
|
def topic_by_id(topic_id):
|
||||||
topic = Topics.find({'slug': slug})
|
topic = Topics.find({'id': topic_id})
|
||||||
if not topic:
|
if not topic:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
return redirect(url_for('.topic', topic_id=topic_id, slug=topic.slug, **request.args))
|
||||||
|
|
||||||
|
@bp.get('/<int:topic_id>/<slug>/')
|
||||||
|
def topic(topic_id, slug):
|
||||||
|
topic = Topics.find({'id': topic_id})
|
||||||
|
if not topic:
|
||||||
|
abort(404)
|
||||||
|
if topic.slug != slug:
|
||||||
|
return redirect(url_for('.topic', topic_id=topic_id, slug=topic.slug, **request.args))
|
||||||
|
|
||||||
sort_by = request.args.get('sort_by', default=session.get('sort_by', default='activity'))
|
sort_by = request.args.get('sort_by', default=session.get('sort_by', default='activity'))
|
||||||
PER_PAGE = 3
|
PER_PAGE = 10
|
||||||
threads_count = Threads.count({'topic_id': topic.id})
|
threads_count = Threads.count({'topic_id': topic.id})
|
||||||
page_count = max(1, math.ceil(threads_count / PER_PAGE))
|
page_count = max(1, math.ceil(threads_count / PER_PAGE))
|
||||||
try:
|
try:
|
||||||
@@ -25,6 +35,6 @@ def topic(slug):
|
|||||||
abort(404)
|
abort(404)
|
||||||
return render_template('topics/topic.html', topic=topic, threads=topic.get_threads(PER_PAGE, page, sort_by), sort_by=sort_by, page=page, page_count=page_count)
|
return render_template('topics/topic.html', topic=topic, threads=topic.get_threads(PER_PAGE, page, sort_by), sort_by=sort_by, page=page, page_count=page_count)
|
||||||
|
|
||||||
@bp.get('/<slug>/feed.atom')
|
@bp.get('/<int:topic_id>/feed.atom/')
|
||||||
def feed(slug):
|
def feed(topic_id):
|
||||||
return 'stub'
|
return 'stub'
|
||||||
|
|||||||
@@ -147,18 +147,18 @@
|
|||||||
<a class="linkbutton" href="{{url_for('posts.edit', post_id=post.id)}}">Edit</a>
|
<a class="linkbutton" href="{{url_for('posts.edit', post_id=post.id)}}">Edit</a>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- if can_reply -%}
|
{%- if can_reply -%}
|
||||||
<button>Quote</button>
|
<button disabled title="This feature requires JavaScript to be enabled.">Quote</button>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- if can_delete -%}
|
{%- if can_delete -%}
|
||||||
<button class="critical">Delete</button>
|
<a class="linkbutton critical" href="{{url_for('posts.delete', post_id=post.id)}}">Delete</a>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
<button>Bookmark…</button>
|
<button disabled title="This feature requires JavaScript to be enabled.">Bookmark…</button>
|
||||||
</span>
|
</span>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
<div class="plank even no-shadow post-content-inner minimal">{{post.content | safe}}
|
<div class="plank even no-shadow post-content-inner minimal">{{post.content | safe}}
|
||||||
{%- if render_sig and post.signature_rendered -%}
|
{%- if render_sig and post.signature_rendered -%}
|
||||||
<div class="post-signature">{{post.signature_rendered | safe}}</div>
|
<aside class="post-signature">{{post.signature_rendered | safe}}</aside>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
{%- if show_reactions -%}
|
{%- if show_reactions -%}
|
||||||
@@ -172,10 +172,10 @@
|
|||||||
{% set reactors_str = reactors_str + '\n...and many others' %}
|
{% set reactors_str = reactors_str + '\n...and many others' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% set has_reacted = get_active_user() is not none and get_active_user().username in reactors %}
|
{% set has_reacted = get_active_user() is not none and get_active_user().username in reactors %}
|
||||||
<button {{'disabled' if not is_logged_in() else ''}} title="{{reactors_str}}" class="minimal {{'alt' if has_reacted else ''}}"><img src="/static/emoji/{{reaction.reaction_text}}.png">{{reaction.c}}</button>
|
<button disabled title="{{reactors_str}}" class="minimal {{'alt' if has_reacted else ''}}"><img src="/static/emoji/{{reaction.reaction_text}}.png">{{reaction.c}}</button>
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
</span>
|
</span>
|
||||||
{%- if is_logged_in() -%}<button>Add reaction</button>{%- endif -%}
|
{%- if is_logged_in() -%}<button disabled title="This feature requires JavaScript to be enabled.">Add reaction</button>{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
{%- block content -%}
|
{%- block content -%}
|
||||||
{%- set td -%}
|
{%- set td -%}
|
||||||
<ul class="horizontal">
|
<ul class="horizontal">
|
||||||
<li>Started by <a href="{{url_for('users.user_page', username=started_by.username)}}">{{started_by.get_readable_name()}}</a> in topic <a href="{{url_for('topics.topic', slug=topic.slug)}}">{{topic.name}}</a></li>
|
<li>Started by <a href="{{url_for('users.user_page', username=started_by.username)}}">{{started_by.get_readable_name()}}</a> in topic <a href="{{url_for('topics.topic_by_id', topic_id=topic.id)}}">{{topic.name}}</a></li>
|
||||||
{%- if thread.locked() or thread.stickied() -%}
|
{%- if thread.locked() or thread.stickied() -%}
|
||||||
{%- if thread.locked() -%}
|
{%- if thread.locked() -%}
|
||||||
<li class="visible">Locked</li>
|
<li class="visible">Locked</li>
|
||||||
@@ -21,9 +21,9 @@
|
|||||||
<legend>Actions</legend>
|
<legend>Actions</legend>
|
||||||
{%- if is_logged_in() -%}
|
{%- if is_logged_in() -%}
|
||||||
<button>Subscribe</button>
|
<button>Subscribe</button>
|
||||||
<button>Bookmark…</button>
|
<button disabled title="This feature requires JavaScript to be enabled.">Bookmark…</button>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
<a href="{{url_for('threads.feed', slug=thread.slug)}}" class="linkbutton rss">Subscribe via RSS</a>
|
<a href="{{url_for('threads.feed', thread_id=thread.id)}}" class="linkbutton rss">Subscribe via RSS</a>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{%- if is_mod() -%}
|
{%- if is_mod() -%}
|
||||||
<fieldset class="plank even no-shadow minimal thread-actions">
|
<fieldset class="plank even no-shadow minimal thread-actions">
|
||||||
@@ -35,9 +35,10 @@
|
|||||||
<input type="submit" class="warn" value="{{'Unsticky' if thread.stickied() else 'Sticky'}}" formaction="{{url_for('mod.sticky_thread', thread_id=thread.id)}}">
|
<input type="submit" class="warn" value="{{'Unsticky' if thread.stickied() else 'Sticky'}}" formaction="{{url_for('mod.sticky_thread', thread_id=thread.id)}}">
|
||||||
</form>
|
</form>
|
||||||
<form class="horizontal wrap" method="POST" action="{{url_for('mod.move_thread', thread_id=thread.id)}}">
|
<form class="horizontal wrap" method="POST" action="{{url_for('mod.move_thread', thread_id=thread.id)}}">
|
||||||
<select name="new_topic_id" id="new-topic-id">
|
<select name="new_topic_id" id="new-topic-id" autocomplete="off" required>
|
||||||
|
<option selected disabled value="">Move to topic:</option>
|
||||||
{%- for t in topics -%}
|
{%- for t in topics -%}
|
||||||
<option value="{{t.id}}" {{'selected disabled' if t.id == topic.id else ''}} autocomplete="off">{{t.name}}</option>
|
<option value="{{t.id}}" {{'disabled' if t.id==topic.id else ''}}>{{t.name}}</option>
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
</select>
|
</select>
|
||||||
<input type="submit" value="Move" class="warn">
|
<input type="submit" value="Move" class="warn">
|
||||||
@@ -63,7 +64,7 @@
|
|||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
{%- if is_logged_in() -%}
|
{%- if is_logged_in() -%}
|
||||||
<form action="{{url_for('threads.reply', slug=thread.slug)}}" method="POST" class="plank post-edit-form">
|
<form action="{{url_for('threads.reply', thread_id=thread.id)}}" method="POST" class="plank post-edit-form">
|
||||||
<h2 class="info">Reply to "{{thread.title}}"</h2>
|
<h2 class="info">Reply to "{{thread.title}}"</h2>
|
||||||
{{- babycode_editor_component() -}}
|
{{- babycode_editor_component() -}}
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
{%- if is_logged_in() and get_active_user().can_post_to_topic(topic) -%}
|
{%- if is_logged_in() and get_active_user().can_post_to_topic(topic) -%}
|
||||||
<a href="{{url_for('threads.new', topic_id=topic.id)}}" class="linkbutton">New thread</a>
|
<a href="{{url_for('threads.new', topic_id=topic.id)}}" class="linkbutton">New thread</a>
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
<a href="{{url_for('topics.feed', slug=topic.slug)}}" class="linkbutton rss">Subscribe via RSS</a>
|
<a href="{{url_for('topics.feed', topic_id=topic.id)}}" class="linkbutton rss">Subscribe via RSS</a>
|
||||||
<form method="GET">
|
<form method="GET">
|
||||||
<select name="sort_by">
|
<select name="sort_by">
|
||||||
<option value="activity"{% if sort_by == 'activity' %}selected{% endif %}>Sorted by activity</option>
|
<option value="activity"{% if sort_by == 'activity' %}selected{% endif %}>Sorted by activity</option>
|
||||||
@@ -48,10 +48,10 @@
|
|||||||
{%- for thread in threads -%}
|
{%- for thread in threads -%}
|
||||||
<div class="topic-info plank">
|
<div class="topic-info plank">
|
||||||
<div class="title-container">
|
<div class="title-container">
|
||||||
<span class="info thread-title-counter"><a href="{{url_for('threads.thread', slug=thread.slug)}}">{{thread.title}}</a></span>
|
<span class="info thread-title-counter"><a href="{{url_for('threads.thread_by_id', thread_id=thread.id)}}">{{thread.title}}</a></span>
|
||||||
<ul class="horizontal"></ul>
|
<ul class="horizontal"></ul>
|
||||||
{%- if thread.posts_count / 10 > 1 -%}
|
{%- if thread.posts_count / 10 > 1 -%}
|
||||||
{{pager(0, (((thread.posts_count / 10) | round(0, 'ceil') )| int), 'flex-last', url=url_for('threads.thread', slug=thread.slug))}}
|
{{pager(0, (((thread.posts_count / 10) | round(0, 'ceil') )| int), 'flex-last', url=url_for('threads.thread_by_id', thread_id=thread.id))}}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
<span>Started by <a href="{{url_for('users.user_page', username=thread.started_by)}}">{{thread.started_by_display_name if thread.started_by_display_name else thread.started_by}}</a> on {{timestamp(thread.created_at)}}</span>
|
<span>Started by <a href="{{url_for('users.user_page', username=thread.started_by)}}">{{thread.started_by_display_name if thread.started_by_display_name else thread.started_by}}</a> on {{timestamp(thread.created_at)}}</span>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
{%- for topic in topics -%}
|
{%- for topic in topics -%}
|
||||||
<div class="topic-info plank">
|
<div class="topic-info plank">
|
||||||
<div class="title-container">
|
<div class="title-container">
|
||||||
<a class="info" href="{{url_for('topics.topic', slug=topic.slug)}}">{{topic.name}}</a>
|
<a class="info" href="{{url_for('topics.topic_by_id', topic_id=topic.id)}}">{{topic.name}}</a>
|
||||||
</div>
|
</div>
|
||||||
<div>{{topic.description}}</div>
|
<div>{{topic.description}}</div>
|
||||||
<ul class="horizontal">
|
<ul class="horizontal">
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ def get_post_url(post_id, _anchor=False, external=False):
|
|||||||
|
|
||||||
anchor = None if not _anchor else f'post-{post_id}'
|
anchor = None if not _anchor else f'post-{post_id}'
|
||||||
|
|
||||||
return url_for('threads.thread', slug=thread.slug, after=post_id, _external=external, _anchor=anchor)
|
return url_for('threads.thread_by_id', thread_id=thread.id, after=post_id, _external=external, _anchor=anchor)
|
||||||
|
|
||||||
def dict_to_query_string(d) -> str:
|
def dict_to_query_string(d) -> str:
|
||||||
return '?' + '&'.join([f'{key}={str(value)}' for key, value in d.items()])
|
return '?' + '&'.join([f'{key}={str(value)}' for key, value in d.items()])
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ button, .linkbutton, input[type="submit"] {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
display: inline flex;
|
display: inline flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -322,6 +324,20 @@ fieldset {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
legend {
|
||||||
|
padding: var(--small-padding);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
border: 2px groove var(--border-color);
|
||||||
|
margin-top: var(--small-padding);
|
||||||
|
|
||||||
|
.plank:not(.secondary-bg) > & {
|
||||||
|
background-color: var(--bg-color-secondary);
|
||||||
|
}
|
||||||
|
.plank.secondary-bg > & {
|
||||||
|
background-color: var(--bg-color-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ul.horizontal, ol.horizontal {
|
ul.horizontal, ol.horizontal {
|
||||||
display: inline flex;
|
display: inline flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user