Compare commits
4 Commits
abcc10654b
...
f08c60de75
Author | SHA1 | Date | |
---|---|---|---|
f08c60de75
|
|||
2e8fd9a22e
|
|||
6e86832211
|
|||
c7f29c1cd4
|
@ -103,6 +103,7 @@ def create_app():
|
|||||||
"InfoboxIcons": InfoboxIcons,
|
"InfoboxIcons": InfoboxIcons,
|
||||||
"InfoboxHTMLClass": InfoboxHTMLClass,
|
"InfoboxHTMLClass": InfoboxHTMLClass,
|
||||||
"InfoboxKind": InfoboxKind,
|
"InfoboxKind": InfoboxKind,
|
||||||
|
"PermissionLevel": PermissionLevel,
|
||||||
"__commit": commit,
|
"__commit": commit,
|
||||||
"__emoji": EMOJI,
|
"__emoji": EMOJI,
|
||||||
}
|
}
|
||||||
@ -116,11 +117,11 @@ def create_app():
|
|||||||
return datetime.utcfromtimestamp(ts or int(time.time())).strftime(format)
|
return datetime.utcfromtimestamp(ts or int(time.time())).strftime(format)
|
||||||
|
|
||||||
@app.template_filter("pluralize")
|
@app.template_filter("pluralize")
|
||||||
def pluralize(number, singular = "", plural = "s"):
|
def pluralize(subject, num=1, singular = "", plural = "s"):
|
||||||
if number == 1:
|
if int(num) == 1:
|
||||||
return singular
|
return subject + singular
|
||||||
|
|
||||||
return plural
|
return subject + plural
|
||||||
|
|
||||||
@app.template_filter("permission_string")
|
@app.template_filter("permission_string")
|
||||||
def permission_string(term):
|
def permission_string(term):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
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, mod_only
|
from .users import login_required, mod_only, get_active_user
|
||||||
from ..models import Users
|
from ..models import Users
|
||||||
from ..db import db, DB
|
from ..db import db, DB
|
||||||
bp = Blueprint("mod", __name__, url_prefix = "/mod/")
|
bp = Blueprint("mod", __name__, url_prefix = "/mod/")
|
||||||
|
@ -171,3 +171,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro accordion(hidden=false, style="", disabled=false) %}
|
||||||
|
{% if disabled %}
|
||||||
|
{% set hidden = true %}
|
||||||
|
{% endif %}
|
||||||
|
<div class="accordion {{ "hidden" if hidden else ""}}" style="{{style}}">
|
||||||
|
<div class="accordion-header">
|
||||||
|
<button type="button" class="accordion-toggle" {{"disabled" if disabled else ""}}>{{ "+" if hidden else "-" }}</button>
|
||||||
|
{{ caller('header') }}
|
||||||
|
</div>
|
||||||
|
<div class="accordion-content {{ "hidden" if hidden else "" }}">
|
||||||
|
{{ caller('content') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
@ -1,10 +1,59 @@
|
|||||||
|
{% from "common/macros.html" import timestamp, accordion %}
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="darkbg settings-container">
|
<div class="darkbg inbox-container">
|
||||||
<ul>
|
{% set guests = (users | selectattr('permission', 'eq', PermissionLevel.GUEST.value) | list) %}
|
||||||
{% for user in users %}
|
{% set not_guests = (users | selectattr('permission', 'gt', PermissionLevel.GUEST.value) | list) %}
|
||||||
<li><a href="{{url_for("users.page", username=user['username'])}}">{{user['username']}}</a>
|
{% call(section) accordion(disabled=(guests | count==0)) %}
|
||||||
{% endfor %}
|
{% if section == "header" %}
|
||||||
</ul>
|
<span>Unconfirmed guests</span>
|
||||||
|
{% elif section == "content" %}
|
||||||
|
<table class="colorful-table">
|
||||||
|
<thead>
|
||||||
|
<th>Username</th>
|
||||||
|
<th class="small">Signed up on</th>
|
||||||
|
</thead>
|
||||||
|
{% for user in guests %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{url_for("users.page", username=user['username'])}}">{{user['username']}}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ timestamp(user.created_at) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
{% endcall %}
|
||||||
|
|
||||||
|
{% call(section) accordion() %}
|
||||||
|
{% if section == "header" %}
|
||||||
|
<span>Other users</span>
|
||||||
|
{% elif section == "content" %}
|
||||||
|
<table class="colorful-table">
|
||||||
|
<thead>
|
||||||
|
<th>Username</th>
|
||||||
|
<th class="small">Permission</th>
|
||||||
|
<th class="small">Signed up on</th>
|
||||||
|
</thead>
|
||||||
|
{% for user in not_guests %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="{{url_for("users.page", username=user['username'])}}">{{user['username']}}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ user.permission | permission_string }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ timestamp(user.created_at) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
{% endcall %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -1,51 +1,65 @@
|
|||||||
{% from "common/macros.html" import timestamp, full_post %}
|
{% from "common/macros.html" import timestamp, full_post, accordion %}
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block title %}inbox{% endblock %}
|
{% block title %}inbox{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="inbox-container">
|
<div class="darkbg inbox-container">
|
||||||
{% if all_subscriptions is none %}
|
{% set has_subscriptions = all_subscriptions is not none %}
|
||||||
You have no subscriptions.<br>
|
{% call(section) accordion(disabled=not has_subscriptions) %}
|
||||||
{% else %}
|
{% if section == "header" %}
|
||||||
Your subscriptions:
|
{% if not has_subscriptions %}
|
||||||
<ul>
|
(You have no subscriptions)
|
||||||
{% for sub in all_subscriptions %}
|
{% else %}
|
||||||
<li>
|
Your subscriptions
|
||||||
<a href=" {{ url_for("threads.thread", slug=sub.thread_slug) }} ">{{ sub.thread_title }}</a>
|
{% endif %}
|
||||||
<form class="modform" method="post" action="{{ url_for("threads.subscribe", slug = sub.thread_slug) }}">
|
{% elif section == "content" and has_subscriptions %}
|
||||||
<input type="hidden" name="subscribe" value="unsubscribe">
|
<table class="colorful-table">
|
||||||
<input class="warn" type="submit" value="Unsubscribe">
|
<thead>
|
||||||
</form>
|
<th>Thread</th>
|
||||||
</li>
|
<th class="small">Unsubscribe</th>
|
||||||
|
</thead>
|
||||||
|
{% for sub in all_subscriptions %}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href=" {{ url_for("threads.thread", slug=sub.thread_slug) }} ">{{ sub.thread_title }}</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<form class="modform" method="post" action="{{ url_for("threads.subscribe", slug = sub.thread_slug) }}">
|
||||||
|
<input type="hidden" name="subscribe" value="unsubscribe">
|
||||||
|
<input class="warn" type="submit" value="Unsubscribe">
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
{% endcall %}
|
||||||
|
{% if has_subscriptions %}
|
||||||
|
{% if not new_posts %}
|
||||||
|
You have no unread posts.
|
||||||
|
{% else %}
|
||||||
|
You have {{ total_unreads_count }} total unread {{("post" | pluralize(num=total_unreads_count))}}:
|
||||||
|
{% for thread in new_posts %}
|
||||||
|
{% call(section) accordion() %}
|
||||||
|
{% if section == "header" %}
|
||||||
|
{% set latest_post_id = thread.posts[-1].id %}
|
||||||
|
{% set unread_posts_text = " (" + (thread.unread_count | string) + (" unread post" | pluralize(num=thread.unread_count)) %}
|
||||||
|
<a class="accordion-title" href="{{ url_for("threads.thread", slug=latest_post_slug, after=latest_post_id, _anchor="post-" + (latest_post_id | string)) }}" title="Jump to latest post">{{thread.thread_title + unread_posts_text}}, latest at {{ timestamp(thread.newest_post_time) }})</a>
|
||||||
|
<form class="modform" method="post" action="{{ url_for("threads.subscribe", slug = thread.thread_slug) }}">
|
||||||
|
<input type="hidden" name="subscribe" value="read">
|
||||||
|
<input type="submit" value="Mark thread as Read">
|
||||||
|
</form>
|
||||||
|
<form class="modform" method="post" action="{{ url_for("threads.subscribe", slug = thread.thread_slug) }}">
|
||||||
|
<input type="hidden" name="subscribe" value="unsubscribe">
|
||||||
|
<input class="warn" type="submit" value="Unsubscribe">
|
||||||
|
</form>
|
||||||
|
{% elif section == "content" %}
|
||||||
|
{% for post in thread.posts %}
|
||||||
|
{{ full_post(post, no_reply = true) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endcall %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
{% if not new_posts %}
|
|
||||||
You have no unread posts.
|
|
||||||
{% else %}
|
|
||||||
You have {{ total_unreads_count }} unread post{{(total_unreads_count | int) | pluralize }}:
|
|
||||||
{% for thread in new_posts %}
|
|
||||||
<div class="accordion">
|
|
||||||
<div class="accordion-header">
|
|
||||||
<button type="button" class="accordion-toggle">▼</button>
|
|
||||||
{% set latest_post_id = thread.posts[-1].id %}
|
|
||||||
{% set unread_posts_text = " (" + (thread.unread_count | string) + (" unread post" | pluralize) %}
|
|
||||||
<a class="accordion-title" href="{{ url_for("threads.thread", slug=latest_post_slug, after=latest_post_id, _anchor="post-" + (latest_post_id | string)) }}" title="Jump to latest post">{{thread.thread_title + unread_posts_text}}, latest at {{ timestamp(thread.newest_post_time) }})</a>
|
|
||||||
<form class="modform" method="post" action="{{ url_for("threads.subscribe", slug = thread.thread_slug) }}">
|
|
||||||
<input type="hidden" name="subscribe" value="read">
|
|
||||||
<input type="submit" value="Mark thread as Read">
|
|
||||||
</form>
|
|
||||||
<form class="modform" method="post" action="{{ url_for("threads.subscribe", slug = thread.thread_slug) }}">
|
|
||||||
<input type="hidden" name="subscribe" value="unsubscribe">
|
|
||||||
<input class="warn" type="submit" value="Unsubscribe">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="accordion-content">
|
|
||||||
{% for post in thread.posts %}
|
|
||||||
{{ full_post(post, no_reply = true) }}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -120,7 +120,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
accordion.classList.toggle("hidden");
|
accordion.classList.toggle("hidden");
|
||||||
content.classList.toggle("hidden");
|
content.classList.toggle("hidden");
|
||||||
toggleButton.textContent = content.classList.contains("hidden") ? "►" : "▼"
|
toggleButton.textContent = content.classList.contains("hidden") ? "+" : "-"
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleButton.addEventListener("click", toggle);
|
toggleButton.addEventListener("click", toggle);
|
||||||
|
@ -570,6 +570,28 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.colorful-table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorful-table tr th {
|
||||||
|
background-color: #beb1ce;
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorful-table tr td {
|
||||||
|
background-color: rgb(177, 206, 204.5);
|
||||||
|
padding: 5px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorful-table .small {
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
.topic {
|
.topic {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1.5fr 96px;
|
grid-template-columns: 1.5fr 96px;
|
||||||
@ -771,3 +793,7 @@ ul, ol {
|
|||||||
background-color: rgba(0, 0, 0, 0.5019607843);
|
background-color: rgba(0, 0, 0, 0.5019607843);
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
border-top: 1px solid black;
|
||||||
|
}
|
||||||
|
@ -567,6 +567,28 @@ input[type="text"], input[type="password"], textarea, select {
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.colorful-table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorful-table tr th {
|
||||||
|
background-color: $button_color2;
|
||||||
|
padding: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorful-table tr td {
|
||||||
|
background-color: $button_color;
|
||||||
|
padding: 5px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.colorful-table .small {
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
.topic {
|
.topic {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1.5fr 96px;
|
grid-template-columns: 1.5fr 96px;
|
||||||
@ -761,3 +783,7 @@ ul, ol {
|
|||||||
background-color: #00000080;
|
background-color: #00000080;
|
||||||
padding: 5px 10px;
|
padding: 5px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
border-top: 1px solid black;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user