Letzter vollständiger SSR-Stand vor dem Rückbau auf reine SPA. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
84 lines
4.1 KiB
HTML
84 lines
4.1 KiB
HTML
{{/*
|
|
Ein Beitrag und die Blätternavigation -- als eigene Blöcke, damit Hauptfeed
|
|
und Nutzerfeed dieselbe Darstellung benutzen. Das Gegenstück zu renderEntry
|
|
in web/js/feed.js.
|
|
|
|
Jede Aktion ist ein echtes Formular mit return_to: ohne JavaScript ist eine
|
|
Interaktion immer ein Seitenwechsel, und der Anker #e{{.PID}} bringt den
|
|
Nutzer danach an genau den Beitrag zurück, den er bedient hat.
|
|
*/}}
|
|
|
|
{{define "entry"}}
|
|
<article class="card" id="e{{.PID}}">
|
|
{{if .Deleted}}
|
|
<div class="muted byline">
|
|
<span>[deleted] · <time datetime="{{timeAttr .CreatedAt}}">{{time .CreatedAt}}</time></span>
|
|
</div>
|
|
<div class="threadline-wrapper">
|
|
<div class="threadline"></div>
|
|
<div class="body"><div class="content">[deleted]</div></div>
|
|
</div>
|
|
{{else}}
|
|
<div class="muted byline">
|
|
<a href="{{profile .Username}}"><img class="avatar avatar-sm" src="{{avatar .Avatar}}" alt="" loading="lazy"></a>
|
|
<span><a href="{{profile .Username}}">{{.Username}}</a> ·
|
|
<time datetime="{{timeAttr .CreatedAt}}">{{time .CreatedAt}}</time></span>
|
|
<details class="report">
|
|
<summary>Melden</summary>
|
|
<form class="report-form" method="post" action="/entry/{{.PID}}/report">
|
|
<input type="hidden" name="return_to" value="{{.ReturnTo}}#e{{.PID}}">
|
|
<label for="reason-{{.PID}}">Grund <span class="muted">(optional)</span></label>
|
|
<input id="reason-{{.PID}}" name="reason" type="text" maxlength="500" autocomplete="off">
|
|
<button type="submit">Absenden</button>
|
|
</form>
|
|
</details>
|
|
</div>
|
|
<div class="threadline-wrapper">
|
|
<div class="threadline"></div>
|
|
<div class="body">
|
|
<div class="content">{{content .Content}}</div>
|
|
{{if .Filepath}}<img src="/{{.Filepath}}" alt="" loading="lazy">{{end}}
|
|
<div class="interactions">
|
|
<a class="button reply" href="/beitrag/{{.PID}}">Antworten ({{.ReplyCount}})</a>
|
|
{{if .EditURL}}<a class="button" href="{{.EditURL}}">Bearbeiten</a>{{end}}
|
|
{{if .DeleteURL}}<a class="button" href="{{.DeleteURL}}">Löschen</a>{{end}}
|
|
{{if .LoggedIn}}
|
|
<form class="row" method="post" action="/entry/{{.PID}}/vote">
|
|
<input type="hidden" name="return_to" value="{{.ReturnTo}}#e{{.PID}}">
|
|
<button class="ghost{{if eq .Selected "left"}} selected{{end}}"
|
|
name="mode" value="left">Links</button>
|
|
<span class="muted">{{.Left}} / {{.Right}}</span>
|
|
<button class="ghost{{if eq .Selected "right"}} selected{{end}}"
|
|
name="mode" value="right">Rechts</button>
|
|
</form>
|
|
{{/* Repost hebt den Beitrag im Feed wieder nach oben. Der Cooldown
|
|
sitzt am Beitrag (global) und wächst pro Repost; ist er aktiv,
|
|
ist der Knopf gesperrt und die Restzeit steht daneben. */}}
|
|
<form method="post" action="/entry/{{.PID}}/bump">
|
|
<input type="hidden" name="return_to" value="{{.ReturnTo}}#e{{.PID}}">
|
|
<button class="bump" type="submit"{{if .BumpLocked}} disabled{{end}}>Repost ({{.BumpCount}})</button>
|
|
{{if .BumpLocked}}<span class="muted"> · in {{.BumpWaitHours}}h</span>{{end}}
|
|
</form>
|
|
{{else}}
|
|
{{/* Ohne Anmeldung nur der Stand -- ein Formular hier würde
|
|
ausschließlich 401 liefern. */}}
|
|
<div class="row">
|
|
<span class="muted">{{.Left}} / {{.Right}} ·
|
|
<a href="/auth/login">anmelden zum Abstimmen</a></span>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
</article>
|
|
{{end}}
|
|
|
|
{{define "pager"}}
|
|
<nav class="pager">
|
|
{{if .PrevURL}}<a class="button" href="{{.PrevURL}}">← Neuere</a>{{end}}
|
|
<span class="muted">Seite {{.HumanPage}} von {{.Pages}}</span>
|
|
{{if .NextURL}}<a class="button" href="{{.NextURL}}">Ältere →</a>{{end}}
|
|
</nav>
|
|
{{end}}
|