add thread view
This commit is contained in:
parent
e39ccd5939
commit
e5a140fa2e
@ -1,10 +1,12 @@
|
|||||||
from flask import (
|
from flask import (
|
||||||
Blueprint, render_template, request, redirect, url_for
|
Blueprint, render_template, request, redirect, url_for
|
||||||
)
|
)
|
||||||
from .users import login_required, get_active_user
|
from .users import login_required, mod_only, get_active_user, is_logged_in
|
||||||
from ..models import Threads, Topics
|
from ..db import db
|
||||||
|
from ..models import Threads, Topics, Posts
|
||||||
from .posts import create_post
|
from .posts import create_post
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
|
import math
|
||||||
import time
|
import time
|
||||||
|
|
||||||
bp = Blueprint("threads", __name__, url_prefix = "/threads/")
|
bp = Blueprint("threads", __name__, url_prefix = "/threads/")
|
||||||
@ -12,7 +14,43 @@ bp = Blueprint("threads", __name__, url_prefix = "/threads/")
|
|||||||
|
|
||||||
@bp.get("/<slug>")
|
@bp.get("/<slug>")
|
||||||
def thread(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")
|
@bp.get("/create")
|
||||||
@ -47,3 +85,23 @@ def create_form():
|
|||||||
})
|
})
|
||||||
post = create_post(thread.id, user.id, post_content)
|
post = create_post(thread.id, user.id, post_content)
|
||||||
return redirect(url_for(".thread", slug = thread.slug))
|
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>
|
</span>
|
||||||
</form>
|
</form>
|
||||||
{% endmacro %}
|
{% 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