Code architected by Disco DeDisco <discodedisco@outlook.com> Git commit message Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
101 lines
5.5 KiB
HTML
101 lines
5.5 KiB
HTML
{% extends "core/base.html" %}
|
|
{% load lyric_extras %}
|
|
|
|
{% block title_text %}Billpost{% endblock title_text %}
|
|
{% block header_text %}<span>Bill</span><span>post</span>{% endblock header_text %}
|
|
|
|
|
|
{% block content %}
|
|
{# Hidden owner span — preserves the existing FT contract that reads the #}
|
|
{# post owner via #id_post_owner. Visible owner attribution moved into the #}
|
|
{# self line ("just me, …" / "& me, …") below. #}
|
|
<span id="id_post_owner" hidden>{{ post.owner|display_name }}</span>
|
|
|
|
<div class="post-page">
|
|
<header class="post-header">
|
|
<h3 class="post-title">{{ post.title }}</h3>
|
|
{% if viewer_is_owner %}
|
|
{# Owner viewing — owner-centric prose. "shared between" lists #}
|
|
{# every recipient; the self line is the owner's own handle. #}
|
|
{% if other_recipients %}
|
|
<p class="post-shared-recipients">shared between {% for r in other_recipients %}<span class="post-recipient post-attribution" data-user-id="{{ r.id }}">{{ r|at_handle }}</span>{% if not forloop.last %}, {% endif %}{% endfor %}</p>
|
|
<p class="post-shared-self">& me, <span class="post-attribution">{{ post.owner|at_handle }} the {{ post.owner.active_title_display }}</span></p>
|
|
{% else %}
|
|
<p class="post-shared-self">just me, <span class="post-attribution">{{ post.owner|at_handle }} the {{ post.owner.active_title_display }}</span></p>
|
|
{% endif %}
|
|
{% else %}
|
|
{# Invitee viewing — "shared with" prose centred on the viewer #}
|
|
{# (request.user). Sole invitee collapses to a single line; the #}
|
|
{# "created by …" line attributes the post to its founder. #}
|
|
{% if other_recipients %}
|
|
<p class="post-shared-recipients">shared with {% for r in other_recipients %}<span class="post-recipient post-attribution" data-user-id="{{ r.id }}">{{ r|at_handle }}</span>{% if not forloop.last %}, {% endif %}{% endfor %}</p>
|
|
<p class="post-shared-self">& me, <span class="post-attribution">{{ request.user|at_handle }} the {{ request.user.active_title_display }}</span></p>
|
|
{% else %}
|
|
<p class="post-shared-self">shared with me, <span class="post-attribution">{{ request.user|at_handle }} the {{ request.user.active_title_display }}</span></p>
|
|
{% endif %}
|
|
<p class="post-created-by">created by <span class="post-attribution">{{ post.owner|at_handle }} the {{ post.owner.active_title_display }}</span></p>
|
|
{% endif %}
|
|
</header>
|
|
|
|
<ul id="id_post_table" class="post-lines">
|
|
{% for line in post.lines.all %}
|
|
<li class="post-line {% if line.author.username == 'adman' %}post-line--system{% endif %}">
|
|
<span class="post-line-author">{{ line.author|at_handle }}</span>
|
|
<span class="post-line-text">{# adman-authored Lines (note unlock + share invite system prose) carry an `<a class="note-ref">` anchor that needs to render as HTML. User-typed Lines stay escaped. #}{% if line.author.username == 'adman' %}{{ line.text|safe }}{% else %}{{ line.text }}{% endif %}</span>
|
|
<time class="post-line-time" datetime="{{ line.created_at|date:'c' }}">{{ line.created_at|relative_ts }}</time>
|
|
</li>
|
|
{% endfor %}
|
|
<li class="post-line-buffer" aria-hidden="true"></li>
|
|
</ul>
|
|
|
|
{# Admin-Post (note-unlock thread) input is read-only: the user can't #}
|
|
{# respond, and the placeholder calls that out. View_post hard-rejects #}
|
|
{# POSTs to NOTE_UNLOCK posts; the post_save Line signal is the safety #}
|
|
{# net for ORM-level / API writes that bypass the view. #}
|
|
{% if post.kind == 'note_unlock' %}
|
|
<form id="id_post_line_form" class="post-line-form">
|
|
<input
|
|
id="id_post_line_text"
|
|
name="text"
|
|
class="form-control"
|
|
placeholder="No response needed at this time"
|
|
readonly
|
|
/>
|
|
</form>
|
|
{% else %}
|
|
<form id="id_post_line_form" method="POST" action="{% url 'billboard:view_post' post.id %}" class="post-line-form">
|
|
{% csrf_token %}
|
|
<input
|
|
id="id_post_line_text"
|
|
name="text"
|
|
class="form-control{% if form.errors.text %} is-invalid{% endif %}"
|
|
placeholder="Enter a post line"
|
|
value="{{ form.text.value|default:'' }}"
|
|
aria-describedby="id_post_line_feedback"
|
|
required
|
|
/>
|
|
{% if form.errors %}
|
|
<div id="id_post_line_feedback" class="invalid-feedback">
|
|
{{ form.errors.text.0 }}
|
|
</div>
|
|
{% endif %}
|
|
</form>
|
|
{% endif %}
|
|
|
|
{# Bud btn (bottom-left) + slide-out recipient field — async share. #}
|
|
{# Suppressed on admin Posts (note unlock thread) since friend-invites #}
|
|
{# don't apply to system-authored threads. #}
|
|
{% if post.kind != 'note_unlock' %}
|
|
{% include "apps/billboard/_partials/_bud_panel.html" %}
|
|
{% endif %}
|
|
|
|
{# Gear btn (bottom-right) + menu — NVM always; DEL (owner) / BYE #}
|
|
{# (invitee) gated to user-Posts. #}
|
|
{% include "apps/billboard/_partials/_post_gear.html" %}
|
|
</div>
|
|
{% endblock content %}
|
|
|
|
{% block scripts %}
|
|
{% include "apps/dashboard/_partials/_scripts.html" %}
|
|
{% endblock scripts %}
|