2022-08-29 04:01:11 +00:00
{{define "title"}}{{.Thread.Title}} - {{.Forum.Title}}{{end}}
2022-08-24 05:55:19 +00:00
{{define "content"}}
< div class = "block" >
< section class = "hero is-light is-success" >
< div class = "hero-body" >
< div class = "container" >
< h1 class = "title" >
2024-04-02 00:53:19 +00:00
< span class = "icon mr-4" > < i class = "fa fa-comments" > < / i > < / span >
< span > {{.Forum.Title}}< / span >
2022-08-24 05:55:19 +00:00
< / h1 >
< / div >
< / div >
< / section >
< / div >
{{$Root := .}}
< div class = "block px-4" >
< div class = "columns" >
< div class = "column" >
< nav class = "breadcrumb" aria-label = "breadcrumbs" >
< ul >
< li > < a href = "/forum" > Forums< / a > < / li >
< li > < a href = "/f/{{.Forum.Fragment}}" > {{.Forum.Title}}< / a > < / Li >
< li class = "is-active" >
< a href = "{{.Request.URL.Path}}" aria-current = "page" > {{or .Thread.Title "Untitled Thread"}}< / a >
< / li >
< / ul >
< / nav >
< / div >
< div class = "column is-narrow" >
2022-08-25 04:17:34 +00:00
{{if not .Thread.NoReply}}
2022-08-24 05:55:19 +00:00
< a href = "/forum/post?to={{.Forum.Fragment}}&thread={{.Thread.ID}}" class = "button is-link" >
< span class = "icon" > < i class = "fa fa-reply" > < / i > < / span >
< span > Add Reply< / span >
< / a >
2022-08-25 04:17:34 +00:00
{{end}}
2022-08-24 05:55:19 +00:00
< / div >
< / div >
< / div >
2022-08-25 04:17:34 +00:00
< h1 class = "title px-4" >
{{if .Thread.Pinned}}< sup class = "fa fa-thumbtack has-text-success mr-2 is-size-5" title = "Pinned" > < / sup > {{end}}
{{or .Thread.Title "Untitled Thread"}}
< / h1 >
< div class = "px-4" >
{{if .Thread.Pinned}}
< span class = "tag is-success is-light mr-2" >
< span class = "icon" > < i class = "fa fa-thumbtack" > < / i > < / span >
< span > Pinned< / span >
< / span >
{{end}}
{{if .Thread.Explicit}}
< span class = "tag is-danger is-light mr-2" >
< span class = "icon" > < i class = "fa fa-fire" > < / i > < / span >
< span > NSFW< / span >
< / span >
{{end}}
{{if .Thread.NoReply}}
< span class = "tag is-warning is-light mr-2" title = "This thread can not be replied to." >
< span class = "icon" > < i class = "fa fa-ban" > < / i > < / span >
< span > No Reply< / span >
< / span >
{{end}}
2024-03-30 21:09:16 +00:00
< span class = "tag is-grey is-light has-text-dark mr-2" title = "This thread can not be replied to." >
2022-08-31 05:13:57 +00:00
< span class = "icon" > < i class = "fa fa-eye" > < / i > < / span >
< span > {{.Thread.Views}} View{{PluralizeU64 .Thread.Views}}< / span >
< / span >
< em title = "{{.Thread.UpdatedAt.Format " 2006-01-02 15:04:05 " } } " >
Updated {{SincePrettyCoarse .Thread.UpdatedAt}} ago
< / em >
2022-08-25 04:17:34 +00:00
< / div >
2022-08-24 05:55:19 +00:00
2022-08-27 18:42:48 +00:00
< p class = "block p-4 mb-0" >
2022-08-24 05:55:19 +00:00
Found < strong > {{.Pager.Total}}< / strong > post{{Pluralize64 .Pager.Total}} on this thread
(page {{.Pager.Page}} of {{.Pager.Pages}}).
< / p >
2022-08-27 18:42:48 +00:00
< p class = "block px-4 mb-4" >
< a href = "/comments/subscription?table_name=threads&table_id={{.Thread.ID}}&next={{UrlEncode .Request.URL.String}}&subscribe={{if not .IsSubscribed}}true{{else}}false{{end}}" >
< span class = "icon" > < i class = "fa fa-bell{{if not .IsSubscribed}}-slash{{end}}" > < / i > < / span >
< span >
{{if .IsSubscribed}}
Disable notifications about this thread
{{else}}
Enable notifications about this thread
{{end}}
< / span >
< / a >
< / p >
2022-08-24 05:55:19 +00:00
< div class = "block p-2" >
2023-06-22 03:46:27 +00:00
{{SimplePager .Pager}}
2022-08-24 05:55:19 +00:00
< / div >
{{$Root := .}}
< div class = "block p-2" >
2022-12-15 06:57:06 +00:00
{{range $i, $c := .Comments}}
2024-04-05 05:24:35 +00:00
< div class = "box has-text-dark" id = "p{{.ID}}" >
2022-08-24 05:55:19 +00:00
< div class = "columns" >
< div class = "column is-2 has-text-centered" >
< div >
2022-12-15 06:57:06 +00:00
< a href = "/u/{{$c.User.Username}}" >
{{template "avatar-96x96" $c.User}}
2022-08-24 05:55:19 +00:00
< / a >
< / div >
2023-12-21 23:09:23 +00:00
< a href = "/u/{{$c.User.Username}}" > {{$c.User.NameOrUsername}}< / a >
2022-12-15 06:57:06 +00:00
{{if $c.User.IsAdmin}}
2022-08-24 05:55:19 +00:00
< div class = "is-size-7 mt-1" >
2022-08-31 05:13:57 +00:00
< span class = "tag is-danger is-light" >
2023-08-30 07:08:20 +00:00
< span class = "icon" > < i class = "fa fa-peace" > < / i > < / span >
2022-08-24 05:55:19 +00:00
< span > Admin< / span >
< / span >
< / div >
{{end}}
< / div >
< div class = "column content" >
2022-12-15 06:57:06 +00:00
{{ToMarkdown $c.Message}}
2022-08-24 05:55:19 +00:00
2022-12-15 06:57:06 +00:00
{{if $c.IsEdited}}
2022-08-27 02:50:33 +00:00
< div class = "mt-4" >
2022-12-15 06:57:06 +00:00
< em title = "{{$c.UpdatedAt.Format " 2006-01-02 15:04:05 " } } " >
< small > Edited {{SincePrettyCoarse $c.UpdatedAt}} ago< / small >
2022-08-27 02:50:33 +00:00
< / em >
< / div >
{{end}}
2022-12-15 06:57:06 +00:00
<!-- Poll attachment? -->
2023-11-24 20:26:17 +00:00
{{if and (eq $Root.Pager.Page 1) (eq $i 0) $Root.Thread.PollID}}
2022-12-15 06:57:06 +00:00
< h2 > Poll< / h2 >
2022-12-21 03:15:45 +00:00
<!-- Get the results -->
{{$Poll := $Root.Thread.Poll}}
{{$PollResult := $Poll.Result $Root.CurrentUser}}
2022-12-15 06:57:06 +00:00
< form name = "ballot" action = "/poll/vote" method = "POST" >
{{InputCSRF}}
< input type = "hidden" name = "poll_id" value = "{{$Root.Thread.PollID}}" >
< input type = "hidden" name = "from_thread_id" value = "{{$Root.Thread.ID}}" >
2022-12-21 03:15:45 +00:00
<!-- Poll is open? -->
{{if $PollResult.AcceptingVotes}}
{{range $Poll.Options}}
< div class = "control" >
< label class = "{{$Poll.InputType}} box nonshy-fullwidth p-3 mb-3" >
< input type = "{{$Poll.InputType}}"
name="answer"
value="{{.}}">
{{.}}
< / label >
< / div >
{{end}}
{{if $Poll.MultipleChoice}}
< div class = "mt-2 mb-4" >
< strong > Multiple choice:< / strong > select all the answers you want before casting your vote!
< / div >
{{end}}
< div class = "mb-4" >
{{if and ($Poll.Expires) (not $Poll.IsExpired)}}
Poll expires in about < span title = "{{$Poll.ExpiresAt.Format " 2006-01-02 15:04:05 " } } " > {{SincePrettyCoarse $Root.Thread.Poll.ExpiresAt}}< / span > .
Vote or wait to see the responses.
{{else}}
Poll doesn't expire. Vote to see the responses.
{{end}}
< / div >
< button type = "submit"
class="button is-primary is-outline">
Submit response
< / button >
{{else}}
{{range $Poll.Options}}
< div class = "columns mb-0" >
< div class = "column is-one-quarter" >
{{.}}
< / div >
< div class = "column" >
< progress class = "{{$PollResult.GetClass .}}" value = "{{$PollResult.GetPercent .}}" max = "100" > {{$PollResult.GetPercent .}}%< / progress >
< / div >
< div class = "column is-1" >
{{$PollResult.GetPercent .}}%
< / div >
< / div >
{{end}}
< em >
{{$PollResult.TotalVotes}} vote{{Pluralize $PollResult.TotalVotes}}.
{{if $Poll.IsExpired}}
Poll ended < span title = "{{$Poll.ExpiresAt.Format " 2006-01-02 15:04:05 " } } " > {{SincePrettyCoarse $Root.Thread.Poll.ExpiresAt}} ago< / span > .
{{end}}
< / em >
2022-12-15 06:57:06 +00:00
{{end}}
2022-12-21 03:15:45 +00:00
2022-12-15 06:57:06 +00:00
< / form >
{{end}}
2022-10-21 04:02:30 +00:00
<!-- Photo attachments? -->
2022-12-15 06:57:06 +00:00
{{$Photos := $Root.PhotoMap.Get $c.ID}}
2022-10-21 04:02:30 +00:00
{{if $Photos}}
{{range $Photos}}
{{if not .ExpiredAt.IsZero}}
< div class = "mt-4" >
< span class = "tag is-dark" > photo expired on {{.ExpiredAt.Format "2006-01-02"}}< / span >
< / div >
{{else}}
2023-06-26 05:55:07 +00:00
<!-- GIF video? -->
{{if HasSuffix .Filename ".mp4"}}
2024-01-27 22:44:30 +00:00
< video autoplay loop controls controlsList = "nodownload" >
2023-06-26 05:55:07 +00:00
< source src = "{{PhotoURL .Filename}}" type = "video/mp4" >
< / video >
{{else}}
2023-09-20 01:24:57 +00:00
< div class = "mt-4 is-clipped" >
2023-12-21 22:37:16 +00:00
< img src = "{{PhotoURL .Filename}}" loading = "lazy" { { if and ( or $ Root . Forum . Explicit $ Root . Thread . Explicit ) ( eq ( $ Root . CurrentUser . GetProfileField " blur_explicit " ) " true " ) } } class = "blurred-explicit" { { end } } >
2022-10-21 04:02:30 +00:00
< / div >
2023-06-26 05:55:07 +00:00
{{end}}
2022-10-21 04:02:30 +00:00
{{end}}
{{end}}
{{end}}
2022-08-24 05:55:19 +00:00
< hr class = "has-background-grey mb-2" >
2022-08-25 04:17:34 +00:00
< div class = "columns is-mobile is-multiline is-size-7 mb-0" >
2022-08-24 05:55:19 +00:00
< div class = "column is-narrow" >
< span title = "{{.CreatedAt.Format " 2006-01-02 15:04:05 " } } " >
{{SincePrettyCoarse .CreatedAt}} ago
< / span >
< / div >
2022-08-25 04:17:34 +00:00
2022-08-30 03:00:15 +00:00
< div class = "column is-narrow" >
{{$Like := $Root.LikeMap.Get .ID}}
< a href = "#" class = "has-text-dark nonshy-like-button"
data-table-name="comments" data-table-id="{{.ID}}"
title="Like">
< span class = "icon{{if $Like.UserLikes}} has-text-danger{{end}}" > < i class = "fa fa-heart" > < / i > < / span >
< span class = "nonshy-likes" >
Like
{{if gt $Like.Count 0}}
({{$Like.Count}})
{{end}}
< / span >
< / a >
< / div >
2023-09-14 04:28:38 +00:00
< div class = "column is-narrow" >
<!-- Button to inspect the likes -->
< a href = "#" class = "has-text-dark"
onclick="ShowLikeModal('comments', {{.ID}}); return false">
< span class = "icon" > < i class = "fa fa-eye" > < / i > < / span >
< span > Likes< / span >
< / a >
< / div >
2022-08-24 05:55:19 +00:00
< div class = "column is-narrow" >
< a href = "/contact?intent=report&subject=report.comment&id={{.ID}}" class = "has-text-dark" >
< span class = "icon" > < i class = "fa fa-flag" > < / i > < / span >
< span > Report< / span >
< / a >
< / div >
2022-08-25 04:17:34 +00:00
{{if not $Root.Thread.NoReply}}
2022-08-24 05:55:19 +00:00
< div class = "column is-narrow" >
2022-09-10 19:09:46 +00:00
< a href = "/forum/post?to={{$Root.Forum.Fragment}}&thread={{$Root.Thread.ID}}"e={{.ID}}"
class="has-text-dark nonshy-quote-button" data-quote-body="{{.Message}}">
2022-08-24 05:55:19 +00:00
< span class = "icon" > < i class = "fa fa-quote-right" > < / i > < / span >
< span > Quote< / span >
< / a >
< / div >
< div class = "column is-narrow" >
2022-09-10 19:09:46 +00:00
< a href = "/forum/post?to={{$Root.Forum.Fragment}}&thread={{$Root.Thread.ID}}"
class="has-text-dark nonshy-reply-button" data-reply-to="{{.User.Username}}">
2022-08-24 05:55:19 +00:00
< span class = "icon" > < i class = "fa fa-reply" > < / i > < / span >
< span > Reply< / span >
< / a >
< / div >
2022-08-25 04:17:34 +00:00
{{end}}
2022-08-24 05:55:19 +00:00
{{if or $Root.CurrentUser.IsAdmin (eq $Root.CurrentUser.ID .User.ID)}}
< div class = "column is-narrow" >
< a href = "/forum/post?to={{$Root.Forum.Fragment}}&thread={{$Root.Thread.ID}}&edit={{.ID}}" class = "has-text-dark" >
< span class = "icon" > < i class = "fa fa-edit" > < / i > < / span >
< span > Edit< / span >
< / a >
< / div >
< div class = "column is-narrow" >
< a href = "/forum/post?to={{$Root.Forum.Fragment}}&thread={{$Root.Thread.ID}}&edit={{.ID}}&delete=true" onclick = "return confirm('Are you sure you want to delete this comment?')" class = "has-text-dark" >
< span class = "icon" > < i class = "fa fa-trash" > < / i > < / span >
< span > Delete< / span >
< / a >
< / div >
{{end}}
2024-01-06 06:14:42 +00:00
<!-- Copy link to clipboard -->
< div class = "column is-narrow" >
< a href = "/go/comment?id={{.ID}}" onclick = "navigator.clipboard.writeText(this.href); window.location='#p{{.ID}}'; return false"
class="has-text-dark"
title="Copy link to clipboard">
< span class = "icon" > < i class = "fa fa-paragraph" > < / i > < / span >
2024-01-06 06:25:05 +00:00
< span > Link< / span >
2024-01-06 06:14:42 +00:00
< / a >
< / div >
2024-04-05 05:24:35 +00:00
<!-- Admin: history -->
{{if $Root.CurrentUser.IsAdmin}}
< div class = "column is-narrow" >
< a href = "/admin/changelog?table_name=comments&table_id={{.ID}}" class = "has-text-warning" >
< span class = "icon" > < i class = "fa fa-clipboard-list" > < / i > < / span >
< span > Change log< / span >
< / a >
< / div >
{{end}}
2022-08-24 05:55:19 +00:00
< / div >
2022-08-25 04:17:34 +00:00
{{if $Root.CurrentUser.IsAdmin}}
< div >
< span class = "tag is-primary is-light" >
< span class = "icon" > < i class = "fa fa-database" > < / i > < / span >
< span > ID: {{.ID}}< / span >
< / span >
< / div >
{{end}}
2022-08-24 05:55:19 +00:00
< / div >
< / div >
< / div >
{{end}}
< / div >
2023-07-23 23:37:11 +00:00
< div class = "block p-2" >
{{SimplePager .Pager}}
< / div >
2022-08-25 04:17:34 +00:00
{{if .Thread.NoReply}}
< div class = "block notification is-warning is-light" >
< i class = "fa fa-ban pr-2" > < / i >
This thread is not accepting any new replies.
< / div >
{{else}}
2022-09-10 19:09:46 +00:00
< div class = "block p-2" id = "reply" >
< div class = "card" >
< header class = "card-header has-background-link" >
< p class = "card-header-title has-text-light" >
< i class = "fa fa-comment mr-2" > < / i >
Reply to Thread
< / p >
< / header >
< div class = "card-content" >
2022-10-21 04:02:30 +00:00
< form action = "/forum/post?to={{.Forum.Fragment}}&thread={{.Thread.ID}}" method = "POST" enctype = "multipart/form-data" >
2022-09-10 19:09:46 +00:00
{{InputCSRF}}
< div class = "field block" >
< label for = "message" class = "label" > Message< / label >
< textarea class = "textarea" cols = "80" rows = "6"
name="message"
id="message"
2022-10-21 04:02:30 +00:00
{{if not .Forum.PermitPhotos}}required{{end}}
2022-09-10 19:09:46 +00:00
placeholder="Message">< / textarea >
< p class = "help" >
2023-02-06 04:26:36 +00:00
< a href = "/markdown" target = "_blank" > Markdown formatting< / a > supported.
2022-09-10 19:09:46 +00:00
< / p >
< / div >
2022-10-21 04:02:30 +00:00
<!-- Photo board that allows attachments? -->
{{if .Forum.PermitPhotos}}
< div class = "field block mb-4" >
< input type = "hidden" name = "photo_intent" id = "photoIntent" >
<!-- Drag/Drop Modal -->
< div class = "modal" id = "drop-modal" >
< div class = "modal-background" > < / div >
< div class = "modal-content" >
< div class = "box content has-text-centered" >
< h1 > < i class = "fa fa-upload mr-2" > < / i > Drop image to select it for upload< / h1 >
< / div >
< / div >
< / div >
< label class = "label" > Photo Attachment< / label >
< div class = "file has-name is-fullwidth" >
< label class = "file-label" >
< input class = "file-input" type = "file"
name="file"
id="file"
accept=".jpg,.jpeg,.jpe,.png">
< span class = "file-cta" >
< span class = "file-icon" >
< i class = "fas fa-upload" > < / i >
< / span >
< span class = "file-label" >
Choose a file…
< / span >
< / span >
< span class = "file-name" id = "fileName" >
Select a file
< / span >
< / label >
< / div >
< / div >
{{end}}
2022-09-10 19:09:46 +00:00
< div class = "field has-text-centered" >
< button type = "submit"
name="intent"
value="preview"
class="button is-link">
Preview
< / button >
< button type = "submit"
name="intent"
value="submit"
class="button is-success">
Post Message
< / button >
< / div >
< / form >
< / div >
< / div >
2022-08-25 04:17:34 +00:00
< / div >
{{end}}
2022-08-24 05:55:19 +00:00
2022-09-10 19:09:46 +00:00
< script type = "text/javascript" >
document.addEventListener('DOMContentLoaded', function() {
const $message = document.querySelector("#message");
// Enhance the in-post Quote and Reply buttons to activate the reply field
// at the page footer instead of going to the dedicated comment page.
(document.querySelectorAll(".nonshy-quote-button") || []).forEach(node => {
const message = node.dataset.quoteBody;
node.addEventListener("click", (e) => {
e.preventDefault();
// Prepare the quoted message.
var lines = [];
for (let line of message.split("\n")) {
lines.push("> " + line);
}
$message.value += lines.join("\n") + "\n\n";
$message.scrollIntoView();
$message.focus();
});
});
(document.querySelectorAll(".nonshy-reply-button") || []).forEach(node => {
const replyTo = node.dataset.replyTo;
node.addEventListener("click", (e) => {
e.preventDefault();
$message.value += "@" + replyTo + "\n\n";
$message.scrollIntoView();
$message.focus();
});
});
});
< / script >
2022-10-21 04:02:30 +00:00
<!-- Script for photo upload on photo boards -->
{{if .Forum.PermitPhotos}}
< script type = "text/javascript" >
window.addEventListener("DOMContentLoaded", (event) => {
let $file = document.querySelector("#file"),
$fileName = document.querySelector("#fileName"),
$dropArea = document.querySelector("#drop-modal"),
$photoIntent = document.querySelector("#photoIntent"),
$body = document.querySelector("body");
// Common handler for file selection (file input or drag/drop)
let onFile = (file) => {
$photoIntent.value = "upload";
$fileName.innerHTML = file.name;
};
// Set up drag/drop file upload events.
$body.addEventListener("dragenter", function(e) {
e.preventDefault();
e.stopPropagation();
$dropArea.classList.add("is-active");
});
$body.addEventListener("dragover", function(e) {
e.preventDefault();
e.stopPropagation();
$dropArea.classList.add("is-active");
});
$body.addEventListener("dragleave", function(e) {
e.preventDefault();
e.stopPropagation();
$dropArea.classList.remove("is-active");
});
$body.addEventListener("drop", function(e) {
e.preventDefault();
e.stopPropagation();
$dropArea.classList.remove("is-active");
// Grab the file.
let dt = e.dataTransfer;
let file = dt.files[0];
// Set the file on the input field too.
$file.files = dt.files;
onFile(file);
});
// File input handler.
$file.addEventListener("change", function() {
let file = this.files[0];
onFile(file);
});
});
< / script >
{{end}}<!-- .Forum.PermitPhotos -->
2023-06-22 03:46:27 +00:00
{{end}}