Moderated posts are now shown to correct people in correct circumstances.
This commit is contained in:
parent
c6b42c5979
commit
60694d9fbd
5 changed files with 46 additions and 26 deletions
10
forum.nim
10
forum.nim
|
|
@ -1205,19 +1205,13 @@ routes:
|
||||||
let threadRow = getRow(db, threadsQuery, id)
|
let threadRow = getRow(db, threadsQuery, id)
|
||||||
let thread = selectThread(threadRow)
|
let thread = selectThread(threadRow)
|
||||||
|
|
||||||
let modClause =
|
|
||||||
if c.rank >= Moderator:
|
|
||||||
"(1 or u.id = ?)"
|
|
||||||
else:
|
|
||||||
"(u.status <> 'Moderated' or p.author = ?)"
|
|
||||||
let postsQuery =
|
let postsQuery =
|
||||||
sql(
|
sql(
|
||||||
"""select p.id, p.content, strftime('%s', p.creation), p.author,
|
"""select p.id, p.content, strftime('%s', p.creation), p.author,
|
||||||
u.name, u.email, strftime('%s', u.lastOnline), u.status
|
u.name, u.email, strftime('%s', u.lastOnline), u.status
|
||||||
from post p, person u
|
from post p, person u
|
||||||
where u.id = p.author and p.thread = ? and $#
|
where u.id = p.author and p.thread = ?
|
||||||
and (u.status <> 'Spammer' or p.author = ?)
|
order by p.id"""
|
||||||
order by p.id""" % modClause
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var list = PostList(
|
var list = PostList(
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ proc render(): VNode =
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
r("/", (params: Params) => renderThreadList())
|
r("/", (params: Params) => renderThreadList(getLoggedInUser()))
|
||||||
])
|
])
|
||||||
|
|
||||||
window.onPopState = onPopState
|
window.onPopState = onPopState
|
||||||
|
|
|
||||||
|
|
@ -68,9 +68,11 @@ when defined(js):
|
||||||
let uri = makeUri("status.json", [("logout", $logout)])
|
let uri = makeUri("status.json", [("logout", $logout)])
|
||||||
ajaxGet(uri, @[], onStatus)
|
ajaxGet(uri, @[], onStatus)
|
||||||
|
|
||||||
|
proc getLoggedInUser*(): Option[User] =
|
||||||
|
state.data.map(x => x.user).flatten
|
||||||
|
|
||||||
proc isLoggedIn*(): bool =
|
proc isLoggedIn*(): bool =
|
||||||
let user = state.data.map(x => x.user).flatten
|
not getLoggedInUser().isNone
|
||||||
not user.isNone
|
|
||||||
|
|
||||||
proc renderHeader*(): VNode =
|
proc renderHeader*(): VNode =
|
||||||
if state.data.isNone:
|
if state.data.isNone:
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,18 @@ when defined(js):
|
||||||
section(class="container grid-xl"):
|
section(class="container grid-xl"):
|
||||||
tdiv(class="title"):
|
tdiv(class="title"):
|
||||||
p(): text list.thread.topic
|
p(): text list.thread.topic
|
||||||
|
if list.thread.isLocked:
|
||||||
|
italic(class="fas fa-lock fa-xs",
|
||||||
|
title="Thread cannot be replied to")
|
||||||
|
text "Locked"
|
||||||
|
if list.thread.isModerated:
|
||||||
|
italic(class="fas fa-eye-slash fa-xs",
|
||||||
|
title="Thread is moderated")
|
||||||
|
text "Moderated"
|
||||||
|
if list.thread.isSolved:
|
||||||
|
italic(class="fas fa-check-square fa-xs",
|
||||||
|
title="Thread has a solution")
|
||||||
|
text "Solved"
|
||||||
render(list.thread.category)
|
render(list.thread.category)
|
||||||
tdiv(class="posts"):
|
tdiv(class="posts"):
|
||||||
var prevPost: Option[Post] = none[Post]()
|
var prevPost: Option[Post] = none[Post]()
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ type
|
||||||
lastVisit*: int64 ## Unix timestamp
|
lastVisit*: int64 ## Unix timestamp
|
||||||
moreCount*: int ## How many more threads are left
|
moreCount*: int ## How many more threads are left
|
||||||
|
|
||||||
proc isInvisible*(thread: Thread): bool =
|
proc isModerated*(thread: Thread): bool =
|
||||||
## Determines whether the specified thread is under moderation.
|
## Determines whether the specified thread is under moderation.
|
||||||
thread.author.rank <= Moderated
|
thread.author.rank <= Moderated
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ when defined(js):
|
||||||
include karax/prelude
|
include karax/prelude
|
||||||
import karax / [vstyles, kajax, kdom]
|
import karax / [vstyles, kajax, kdom]
|
||||||
|
|
||||||
import karaxutils, error
|
import karaxutils, error, user
|
||||||
|
|
||||||
type
|
type
|
||||||
State = ref object
|
State = ref object
|
||||||
|
|
@ -38,7 +38,6 @@ when defined(js):
|
||||||
loading: bool
|
loading: bool
|
||||||
status: HttpCode
|
status: HttpCode
|
||||||
|
|
||||||
proc onNewThread(threadId, postId: int)
|
|
||||||
proc newState(): State =
|
proc newState(): State =
|
||||||
State(
|
State(
|
||||||
list: none[ThreadList](),
|
list: none[ThreadList](),
|
||||||
|
|
@ -49,10 +48,20 @@ when defined(js):
|
||||||
var
|
var
|
||||||
state = newState()
|
state = newState()
|
||||||
|
|
||||||
proc onNewThread(threadId, postId: int) =
|
proc visibleTo(thread: Thread, user: Option[User]): bool =
|
||||||
discard
|
## Determines whether the specified thread should be shown to the user.
|
||||||
|
##
|
||||||
|
## The rules for this are determined by the rank of the user, their
|
||||||
|
## settings (TODO), and whether the thread's creator is moderated or not.
|
||||||
|
if user.isNone(): return not thread.isModerated
|
||||||
|
|
||||||
proc genTopButtons(): VNode =
|
let rank = user.get().rank
|
||||||
|
if rank < Moderator and thread.isModerated:
|
||||||
|
return thread.author == user.get()
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
proc genTopButtons(currentUser: Option[User]): VNode =
|
||||||
result = buildHtml():
|
result = buildHtml():
|
||||||
section(class="navbar container grid-xl", id="main-buttons"):
|
section(class="navbar container grid-xl", id="main-buttons"):
|
||||||
section(class="navbar-section"):
|
section(class="navbar-section"):
|
||||||
|
|
@ -67,6 +76,7 @@ when defined(js):
|
||||||
button(class="btn btn-link"): text "Most Active"
|
button(class="btn btn-link"): text "Most Active"
|
||||||
button(class="btn btn-link"): text "Categories"
|
button(class="btn btn-link"): text "Categories"
|
||||||
section(class="navbar-section"):
|
section(class="navbar-section"):
|
||||||
|
if currentUser.isSome():
|
||||||
a(href=makeUri("/newthread"), onClick=anchorCB):
|
a(href=makeUri("/newthread"), onClick=anchorCB):
|
||||||
button(class="btn btn-secondary"):
|
button(class="btn btn-secondary"):
|
||||||
italic(class="fas fa-plus")
|
italic(class="fas fa-plus")
|
||||||
|
|
@ -102,7 +112,7 @@ when defined(js):
|
||||||
if thread.isLocked:
|
if thread.isLocked:
|
||||||
italic(class="fas fa-lock fa-xs",
|
italic(class="fas fa-lock fa-xs",
|
||||||
title="Thread cannot be replied to")
|
title="Thread cannot be replied to")
|
||||||
if thread.isInvisible:
|
if thread.isModerated:
|
||||||
italic(class="fas fa-eye-slash fa-xs",
|
italic(class="fas fa-eye-slash fa-xs",
|
||||||
title="Thread is moderated")
|
title="Thread is moderated")
|
||||||
if thread.isSolved:
|
if thread.isSolved:
|
||||||
|
|
@ -147,7 +157,7 @@ when defined(js):
|
||||||
let start = state.list.get().threads.len
|
let start = state.list.get().threads.len
|
||||||
ajaxGet(makeUri("threads.json?start=" & $start), @[], onThreadList)
|
ajaxGet(makeUri("threads.json?start=" & $start), @[], onThreadList)
|
||||||
|
|
||||||
proc genThreadList(): VNode =
|
proc genThreadList(currentUser: Option[User]): VNode =
|
||||||
if state.status != Http200:
|
if state.status != Http200:
|
||||||
return renderError("Couldn't retrieve threads.")
|
return renderError("Couldn't retrieve threads.")
|
||||||
|
|
||||||
|
|
@ -171,6 +181,8 @@ when defined(js):
|
||||||
tbody():
|
tbody():
|
||||||
for i in 0 ..< list.threads.len:
|
for i in 0 ..< list.threads.len:
|
||||||
let thread = list.threads[i]
|
let thread = list.threads[i]
|
||||||
|
if not visibleTo(thread, currentUser): continue
|
||||||
|
|
||||||
let isLastVisit =
|
let isLastVisit =
|
||||||
i+1 < list.threads.len and
|
i+1 < list.threads.len and
|
||||||
list.threads[i].activity < list.lastVisit
|
list.threads[i].activity < list.lastVisit
|
||||||
|
|
@ -191,7 +203,7 @@ when defined(js):
|
||||||
td(colspan="6", onClick=onLoadMore):
|
td(colspan="6", onClick=onLoadMore):
|
||||||
span(text "load more threads")
|
span(text "load more threads")
|
||||||
|
|
||||||
proc renderThreadList*(): VNode =
|
proc renderThreadList*(currentUser: Option[User]): VNode =
|
||||||
result = buildHtml(tdiv):
|
result = buildHtml(tdiv):
|
||||||
genTopButtons()
|
genTopButtons(currentUser)
|
||||||
genThreadList()
|
genThreadList(currentUser)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue