Editors can now lock threads

This commit is contained in:
Eduard Urbach 2018-04-25 18:59:23 +02:00
parent 7d70f3b0b5
commit 3ebd4b0856
11 changed files with 75 additions and 36 deletions

View File

@ -70,7 +70,7 @@ import (
"github.com/animenotifier/notify.moe/pages/statistics" "github.com/animenotifier/notify.moe/pages/statistics"
"github.com/animenotifier/notify.moe/pages/support" "github.com/animenotifier/notify.moe/pages/support"
"github.com/animenotifier/notify.moe/pages/terms" "github.com/animenotifier/notify.moe/pages/terms"
"github.com/animenotifier/notify.moe/pages/threads" "github.com/animenotifier/notify.moe/pages/thread"
"github.com/animenotifier/notify.moe/pages/upload" "github.com/animenotifier/notify.moe/pages/upload"
"github.com/animenotifier/notify.moe/pages/user" "github.com/animenotifier/notify.moe/pages/user"
"github.com/animenotifier/notify.moe/pages/users" "github.com/animenotifier/notify.moe/pages/users"
@ -101,7 +101,7 @@ func Configure(app *aero.Application) {
// Forum // Forum
l.Page("/forum", forum.Get) l.Page("/forum", forum.Get)
l.Page("/forum/:tag", forum.Get) l.Page("/forum/:tag", forum.Get)
l.Page("/thread/:id", threads.Get) l.Page("/thread/:id", thread.Get)
l.Page("/post/:id", posts.Get) l.Page("/post/:id", posts.Get)
l.Page("/new/thread", newthread.Get) l.Page("/new/thread", newthread.Get)

View File

@ -1,4 +1,4 @@
package threads package thread
import ( import (
"net/http" "net/http"

37
pages/thread/thread.pixy Normal file
View File

@ -0,0 +1,37 @@
component Thread(thread *arn.Thread, posts []*arn.Post, user *arn.User)
h1.thread-title= thread.Title
#thread.thread(data-id=thread.ID)
.posts
Postable(thread.ToPostable(), user, thread.Creator().ID)
each post in posts
Postable(post.ToPostable(), user, thread.Creator().ID)
//- Reply
if user != nil
if thread.Locked
footer.footer.mountable
p.text-center This topic is locked.
else
NewPostArea(user, "Reply")
.buttons
if !thread.Locked
button.mountable.action(data-action="forumReply", data-trigger="click")
Icon("mail-reply")
span Reply
if user.Role == "admin" || user.Role == "editor"
if thread.Locked
button.mountable.action(data-action="unlockThread", data-trigger="click", data-api="/api/thread/" + thread.ID)
Icon("unlock")
span Unlock
else
button.mountable.action(data-action="lockThread", data-trigger="click", data-api="/api/thread/" + thread.ID)
Icon("lock")
span Lock
button.mountable.action(data-action="deleteObject", data-trigger="click", data-return-path="/forum", data-confirm-type="thread", data-api="/api/thread/" + thread.ID)
Icon("trash")
span Delete

View File

@ -1,23 +0,0 @@
component Thread(thread *arn.Thread, posts []*arn.Post, user *arn.User)
h1.thread-title= thread.Title
#thread.thread(data-id=thread.ID)
.posts
Postable(thread.ToPostable(), user, thread.Creator().ID)
each post in posts
Postable(post.ToPostable(), user, thread.Creator().ID)
// Reply
if user != nil
NewPostArea(user, "Reply")
.buttons
button.action(data-action="forumReply", data-trigger="click")
Icon("mail-reply")
span Reply
if user.Role == "admin" || user.Role == "editor"
button.action(data-action="deleteObject", data-trigger="click", data-return-path="/forum", data-confirm-type="thread", data-api="/api/thread/" + thread.ID)
Icon("trash")
span Delete

View File

@ -8,7 +8,7 @@ export async function addAnimeToCollection(arn: AnimeNotifier, button: HTMLButto
let apiEndpoint = arn.findAPIEndpoint(button) let apiEndpoint = arn.findAPIEndpoint(button)
try { try {
await arn.post(apiEndpoint + "/add/" + animeId, "") await arn.post(apiEndpoint + "/add/" + animeId)
arn.reloadContent() arn.reloadContent()
// Show status message // Show status message
@ -31,7 +31,7 @@ export function removeAnimeFromCollection(arn: AnimeNotifier, button: HTMLElemen
let {animeId, nick} = button.dataset let {animeId, nick} = button.dataset
let apiEndpoint = arn.findAPIEndpoint(button) let apiEndpoint = arn.findAPIEndpoint(button)
arn.post(apiEndpoint + "/remove/" + animeId, "") arn.post(apiEndpoint + "/remove/" + animeId)
.then(() => arn.app.load(`/+${nick}/animelist/` + (document.getElementById("Status") as HTMLSelectElement).value)) .then(() => arn.app.load(`/+${nick}/animelist/` + (document.getElementById("Status") as HTMLSelectElement).value))
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
} }

View File

@ -2,7 +2,7 @@ import AnimeNotifier from "../AnimeNotifier"
// Follow user // Follow user
export function followUser(arn: AnimeNotifier, elem: HTMLElement) { export function followUser(arn: AnimeNotifier, elem: HTMLElement) {
return arn.post(elem.dataset.api, "") return arn.post(elem.dataset.api)
.then(() => arn.reloadContent()) .then(() => arn.reloadContent())
.then(() => arn.statusMessage.showInfo("You are now following " + document.getElementById("nick").innerText + ".")) .then(() => arn.statusMessage.showInfo("You are now following " + document.getElementById("nick").innerText + "."))
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
@ -10,7 +10,7 @@ export function followUser(arn: AnimeNotifier, elem: HTMLElement) {
// Unfollow user // Unfollow user
export function unfollowUser(arn: AnimeNotifier, elem: HTMLElement) { export function unfollowUser(arn: AnimeNotifier, elem: HTMLElement) {
return arn.post(elem.dataset.api, "") return arn.post(elem.dataset.api)
.then(() => arn.reloadContent()) .then(() => arn.reloadContent())
.then(() => arn.statusMessage.showInfo("You stopped following " + document.getElementById("nick").innerText + ".")) .then(() => arn.statusMessage.showInfo("You stopped following " + document.getElementById("nick").innerText + "."))
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))

View File

@ -51,7 +51,7 @@ export function deletePost(arn: AnimeNotifier, element: HTMLElement) {
let endpoint = arn.findAPIEndpoint(element) let endpoint = arn.findAPIEndpoint(element)
arn.post(endpoint + "/delete", "") arn.post(endpoint + "/delete")
.then(() => arn.reloadContent()) .then(() => arn.reloadContent())
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
} }
@ -94,3 +94,28 @@ export function createThread(arn: AnimeNotifier) {
.then(() => arn.app.load("/forum/" + thread.tags[0])) .then(() => arn.app.load("/forum/" + thread.tags[0]))
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
} }
// Lock thread
export function lockThread(arn: AnimeNotifier, element: HTMLButtonElement) {
setThreadLock(arn, element, true)
}
// Unlock thread
export function unlockThread(arn: AnimeNotifier, element: HTMLButtonElement) {
setThreadLock(arn, element, false)
}
// Set thread locked state
function setThreadLock(arn: AnimeNotifier, element: HTMLButtonElement, state: boolean) {
let verb = state ? "lock" : "unlock"
if(!confirm(`Are you sure you want to ${verb} this Thread?`)) {
return
}
let endpoint = arn.findAPIEndpoint(element)
arn.post(`${endpoint}/${verb}`)
.then(() => arn.reloadContent())
.catch(err => arn.statusMessage.showError(err))
}

View File

@ -4,7 +4,7 @@ import AnimeNotifier from "../AnimeNotifier"
export function newObject(arn: AnimeNotifier, button: HTMLButtonElement) { export function newObject(arn: AnimeNotifier, button: HTMLButtonElement) {
let dataType = button.dataset.type let dataType = button.dataset.type
arn.post(`/api/new/${dataType}`, "") arn.post(`/api/new/${dataType}`)
.then(response => response.json()) .then(response => response.json())
.then(obj => arn.app.load(`/${dataType}/${obj.id}/edit`)) .then(obj => arn.app.load(`/${dataType}/${obj.id}/edit`))
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
@ -28,7 +28,7 @@ export function deleteObject(arn: AnimeNotifier, button: HTMLButtonElement) {
let endpoint = arn.findAPIEndpoint(button) let endpoint = arn.findAPIEndpoint(button)
arn.post(endpoint + "/delete", "") arn.post(endpoint + "/delete")
.then(() => arn.app.load(returnPath)) .then(() => arn.app.load(returnPath))
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
} }

View File

@ -4,7 +4,7 @@ import AnimeNotifier from "../AnimeNotifier"
export function publish(arn: AnimeNotifier, button: HTMLButtonElement) { export function publish(arn: AnimeNotifier, button: HTMLButtonElement) {
let endpoint = arn.findAPIEndpoint(button) let endpoint = arn.findAPIEndpoint(button)
arn.post(endpoint + "/publish", "") arn.post(endpoint + "/publish")
.then(() => arn.app.load(arn.app.currentPath.replace("/edit", ""))) .then(() => arn.app.load(arn.app.currentPath.replace("/edit", "")))
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
} }
@ -13,7 +13,7 @@ export function publish(arn: AnimeNotifier, button: HTMLButtonElement) {
export function unpublish(arn: AnimeNotifier, button: HTMLButtonElement) { export function unpublish(arn: AnimeNotifier, button: HTMLButtonElement) {
let endpoint = arn.findAPIEndpoint(button) let endpoint = arn.findAPIEndpoint(button)
arn.post(endpoint + "/unpublish", "") arn.post(endpoint + "/unpublish")
.then(() => arn.reloadContent()) .then(() => arn.reloadContent())
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
} }

View File

@ -122,7 +122,7 @@ export function arrayRemove(arn: AnimeNotifier, element: HTMLElement) {
let index = element.dataset.index let index = element.dataset.index
let apiEndpoint = arn.findAPIEndpoint(element) let apiEndpoint = arn.findAPIEndpoint(element)
arn.post(apiEndpoint + "/field/" + field + "/remove/" + index, "") arn.post(apiEndpoint + "/field/" + field + "/remove/" + index)
.then(() => arn.reloadContent()) .then(() => arn.reloadContent())
.catch(err => arn.statusMessage.showError(err)) .catch(err => arn.statusMessage.showError(err))
} }