add thread view
This commit is contained in:
parent
e39ccd5939
commit
e5a140fa2e
@ -1,10 +1,12 @@
|
||||
from flask import (
|
||||
Blueprint, render_template, request, redirect, url_for
|
||||
)
|
||||
from .users import login_required, get_active_user
|
||||
from ..models import Threads, Topics
|
||||
from .users import login_required, mod_only, get_active_user, is_logged_in
|
||||
from ..db import db
|
||||
from ..models import Threads, Topics, Posts
|
||||
from .posts import create_post
|
||||
from slugify import slugify
|
||||
import math
|
||||
import time
|
||||
|
||||
bp = Blueprint("threads", __name__, url_prefix = "/threads/")
|
||||
@ -12,7 +14,43 @@ bp = Blueprint("threads", __name__, url_prefix = "/threads/")
|
||||
|
||||
@bp.get("/<slug>")
|
||||
def thread(slug):
|
||||
return slug
|
||||
POSTS_PER_PAGE = 10
|
||||
thread = Threads.find({"slug": slug})
|
||||
if not thread:
|
||||
return "no"
|
||||
|
||||
post_count = Posts.count({"thread_id": thread.id})
|
||||
page_count = max(math.ceil(post_count / POSTS_PER_PAGE), 1)
|
||||
|
||||
page = 1
|
||||
after = request.args.get("after", default=None)
|
||||
if after is not None:
|
||||
after_id = int(after)
|
||||
post_position = Posts.count([
|
||||
("thread_id", "=", thread.id),
|
||||
("id", "<=", after_id),
|
||||
])
|
||||
print(post_position)
|
||||
page = math.floor((post_position + 1) / POSTS_PER_PAGE) + 1
|
||||
else:
|
||||
page = max(1, min(page_count, int(request.args.get("page", default = 1))))
|
||||
|
||||
posts = thread.get_posts(POSTS_PER_PAGE, (page - 1) * POSTS_PER_PAGE)
|
||||
print(posts)
|
||||
topic = Topics.find({"id": thread.topic_id})
|
||||
other_topics = Topics.select()
|
||||
|
||||
#TODO: subscription last seen
|
||||
|
||||
return render_template(
|
||||
"threads/thread.html",
|
||||
thread = thread,
|
||||
current_page = page,
|
||||
page_count = page_count,
|
||||
posts = posts,
|
||||
topic = topic,
|
||||
topics = other_topics,
|
||||
)
|
||||
|
||||
|
||||
@bp.get("/create")
|
||||
@ -47,3 +85,23 @@ def create_form():
|
||||
})
|
||||
post = create_post(thread.id, user.id, post_content)
|
||||
return redirect(url_for(".thread", slug = thread.slug))
|
||||
|
||||
|
||||
@bp.post("/<slug>/lock")
|
||||
@login_required
|
||||
def lock(slug):
|
||||
pass
|
||||
|
||||
|
||||
@bp.post("/<slug>/sticky")
|
||||
@login_required
|
||||
@mod_only(".thread", slug = lambda slug: slug)
|
||||
def sticky(slug):
|
||||
pass
|
||||
|
||||
|
||||
@bp.post("/<slug>/move")
|
||||
@login_required
|
||||
@mod_only(".thread", slug = lambda slug: slug)
|
||||
def move(slug):
|
||||
pass
|
||||
|
@ -88,3 +88,86 @@
|
||||
</span>
|
||||
</form>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro full_post(post, render_sig = True, is_latest = False, editing = False, active_user = None) %}
|
||||
{% set postclass = "post" %}
|
||||
{% if editing %}
|
||||
{% set postclass = postclass + " editing" %}
|
||||
{% endif %}
|
||||
<div class=" {{ postclass }}" id="post-{{ post['id'] }}">
|
||||
<div class="usercard">
|
||||
<div class="usercard-inner">
|
||||
<a href="{{ url_for("users.page", username=post['username']) }}" style="display: contents;">
|
||||
<img src="{{ post['avatar_path'] }}" class="avatar">
|
||||
</a>
|
||||
<a href="{{ url_for("users.page", username=post['username']) }}" class="username-link">{{ post['username'] }}</a>
|
||||
{% if post['status'] %}
|
||||
<em class="user-status">{{ post['status'] }}</em>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="post-content-container" {{ "id=latest-post" if is_latest else "" }}>
|
||||
<div class="post-info">
|
||||
{% set post_permalink = url_for("threads.thread", slug = post['thread_slug'], after = post['id'], _anchor = ("post-" + (post['id'] | string))) %}
|
||||
<a href="{{ post_permalink }}" title="Permalink"><i>
|
||||
{% if (post['edited_at'] | int) > (post['created_at'] | int) %}
|
||||
Edited on {{ timestamp(post['edited_at']) }}
|
||||
{% else %}
|
||||
Posted on {{ timestamp(post['edited_at']) }}
|
||||
{% endif %}
|
||||
</i></a>
|
||||
<span>
|
||||
{% set show_edit = false %}
|
||||
{% if active_user %}
|
||||
{% set show_edit = (active_user.id | string) == (post['user_id'] | string) and (not post['thread_is_locked'] or active_user.is_mod()) and not no_reply %}
|
||||
{% endif %}
|
||||
{% if show_edit %}
|
||||
<a class="linkbutton" href="#TODO">Edit</a>
|
||||
{% endif %}
|
||||
|
||||
{% set show_reply = true %}
|
||||
|
||||
{% if active_user and post['thread_is_locked'] and not active_user.is_mod() %}
|
||||
{% set show_reply = false %}
|
||||
{% elif active_user and active_user.is_guest() %}
|
||||
{% set show_reply = false %}
|
||||
{% elif editing %}
|
||||
{% set show_reply = false %}
|
||||
{% elif no_reply %}
|
||||
{% set show_reply = false %}
|
||||
{% endif %}
|
||||
|
||||
{% if show_reply %}
|
||||
{% set qtext = "[url=%s]%s said:[/url]" | format(post_permalink, post['username']) %}
|
||||
{% set reply_text = "%s\n[quote]%s[/quote]\n" | format(qtext, post['original_markup']) %}
|
||||
<button value="{{ reply_text }}" class="reply-button">Quote</button>
|
||||
{% endif %}
|
||||
|
||||
{% set show_delete = false %}
|
||||
|
||||
{% if active_user %}
|
||||
{% set show_delete = (((post['user_id'] | string) == (active_user.id | string) and not post['thread_is_locked']) or active_user.is_mod()) and not no_reply %}
|
||||
{% endif %}
|
||||
|
||||
{% if show_delete %}
|
||||
<button class="critical post-delete-button" value="{{ post['id'] }}">Delete</button>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="post-content">
|
||||
{% if not editing %}
|
||||
<div class="post-inner">{{ post['content'] | safe }}</div>
|
||||
{% if render_sig and post['signature_rendered'] %}
|
||||
<div class="signature-container">
|
||||
<hr>
|
||||
{{ post['signature_rendered'] | safe }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ babycode_editor_form(cancel_url = post_permalink, prefill = post['original_markup'], ta_name = "new_content") }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
71
app/templates/threads/thread.html
Normal file
71
app/templates/threads/thread.html
Normal file
@ -0,0 +1,71 @@
|
||||
{% from 'common/macros.html' import pager, babycode_editor_form, full_post %}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ thread.title }}{% endblock %}
|
||||
{% block content %}
|
||||
{% set can_post = false %}
|
||||
{% set can_lock = false %}
|
||||
{% set can_subscribe = false %}
|
||||
{% if active_user %}
|
||||
{% set can_subscribe = true %}
|
||||
{% set can_post = (not thread.is_locked and not active_user.is_guest()) or active_user.is_mod() %}
|
||||
{% set can_lock = ((active_user.id | int) == (thread.user_id | int)) or active_user.is_mod() %}
|
||||
{% endif %}
|
||||
<main>
|
||||
<nav class="darkbg">
|
||||
<h1 class="thread-title">{{ thread.title }}</h1>
|
||||
<span>Posted in <a href="{{ url_for("topics.topic", slug=topic.slug) }}">{{ topic.name }}</a>
|
||||
{% if thread.is_stickied %}
|
||||
• <i>stickied, so it's probably important</i>
|
||||
{% endif %}
|
||||
</span>
|
||||
<div>
|
||||
{% if can_subscribe %}
|
||||
{% endif %}
|
||||
{% if can_lock %}
|
||||
<form class="modform" action="{{ url_for("threads.lock", slug=thread.slug) }}" method="post">
|
||||
<input type=hidden value="{{ (not thread.is_locked) | int }}">
|
||||
<input class="warn" type="submit" value="{{"Unlock thread" if thread.is_locked else "Lock thread"}}">
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if active_user.is_mod() %}
|
||||
<form class="modform" action="{{ url_for("threads.sticky", slug=thread.slug) }}" method="post">
|
||||
<input type=hidden value="{{ (not thread.is_stickied) | int }}">
|
||||
<input class="warn" type="submit" value="{{"Unsticky thread" if thread.is_stickied else "Sticky thread"}}">
|
||||
</form>
|
||||
<form class="modform" action="{{ url_for("threads.move", slug=thread.slug) }}" method="post">
|
||||
<label for="new_topic_id">Move to topic:</label>
|
||||
<select style="width:200px;" id="new_topic_id" name="new_topic_id" autocomplete="off">
|
||||
{% for topic in topics %}
|
||||
<option value="{{ topic['id'] }}" {{ "selected disabled" if (thread.topic_id | string) == (topic['id'] | string) else "" }}>{{ topic['name'] }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input class="warn" type="submit" value="Move thread">
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</nav>
|
||||
{% for post in posts %}
|
||||
{{ full_post(post = post, active_user = active_user, is_latest = loop.index0 == (posts | length)) }}
|
||||
{% endfor %}
|
||||
</main>
|
||||
|
||||
<nav id="bottomnav">
|
||||
{{ pager(current_page = current_page, page_count = page_count) }}
|
||||
</nav>
|
||||
|
||||
{% if can_post %}
|
||||
<h1>Respond to "{{ thread.title }}"</h1>
|
||||
{{ babycode_editor_form(ta_name = post_content)}}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
<dialog id="delete-dialog">
|
||||
<div class=delete-dialog-inner>
|
||||
Are you sure you want to delete the highlighted post?
|
||||
<span>
|
||||
<button id=post-delete-dialog-close>Cancel</button>
|
||||
<button class="critical" form=post-delete-form>Delete</button>
|
||||
<form id="post-delete-form" method="post"></form>
|
||||
</span>
|
||||
</div>
|
||||
</dialog>
|
||||
<script src="/static/js/thread.js?v=1"></script>
|
Loading…
Reference in New Issue
Block a user