Implements newthread logic on backend and marries it all together.
This commit is contained in:
parent
76c7f43079
commit
702967f624
3 changed files with 84 additions and 14 deletions
68
forum.nim
68
forum.nim
|
|
@ -77,6 +77,7 @@ type
|
|||
lastIp: string
|
||||
|
||||
ForumError = object of Exception
|
||||
data: PostError
|
||||
|
||||
var
|
||||
db: DbConn
|
||||
|
|
@ -85,6 +86,16 @@ var
|
|||
useCaptcha: bool
|
||||
captcha: ReCaptcha
|
||||
|
||||
proc newForumError(message: string,
|
||||
fields: seq[string] = @[]): ref ForumError =
|
||||
new(result)
|
||||
result.msg = message
|
||||
result.data =
|
||||
PostError(
|
||||
errorFields: fields,
|
||||
message: message
|
||||
)
|
||||
|
||||
proc init(c: TForumData) =
|
||||
c.userPass = ""
|
||||
c.userName = ""
|
||||
|
|
@ -1076,9 +1087,10 @@ proc executeReply(c: TForumData, threadId: int, content: string,
|
|||
|
||||
let subject = "" # TODO: Remove this redundant field.
|
||||
if rateLimitCheck(c):
|
||||
raise newException(ForumError, "You're posting too fast!")
|
||||
raise newForumError("You're posting too fast!")
|
||||
|
||||
# TODO: Replying to.
|
||||
# Verify that content can be parsed as RST.
|
||||
let retID = insertID(
|
||||
db,
|
||||
crud(crCreate, "post", "author", "ip", "header", "content", "thread"),
|
||||
|
|
@ -1095,6 +1107,35 @@ proc executeReply(c: TForumData, threadId: int, content: string,
|
|||
|
||||
return retID
|
||||
|
||||
proc executeNewThread(c: TForumData, subject, msg: string): (int64, int64) =
|
||||
const
|
||||
query = sql"""
|
||||
insert into thread(name, views, modified) values (?, 0, DATETIME('now'))
|
||||
"""
|
||||
|
||||
assert c.loggedIn()
|
||||
|
||||
if subject.len <= 2:
|
||||
raise newForumError("Subject is too short", @["subject"])
|
||||
if subject.len > 100:
|
||||
raise newForumError("Subject is too long", @["subject"])
|
||||
|
||||
if not validateRst(c, msg):
|
||||
raise newForumError("Message needs to be valid RST", @["msg"])
|
||||
|
||||
if rateLimitCheck(c):
|
||||
raise newForumError("You're posting too fast!")
|
||||
|
||||
result[0] = tryInsertID(db, query, subject).int
|
||||
if result[0] < 0:
|
||||
raise newForumError("Subject already exists", @["subject"])
|
||||
|
||||
discard tryExec(db, crud(crCreate, "thread_fts", "id", "name"),
|
||||
c.threadID, subject)
|
||||
result[1] = executeReply(c, result[0].int, msg, -1)
|
||||
discard tryExec(db, sql"insert into post_fts(post_fts) values('optimize')")
|
||||
discard tryExec(db, sql"insert into post_fts(thread_fts) values('optimize')")
|
||||
|
||||
initialise()
|
||||
|
||||
routes:
|
||||
|
|
@ -1370,12 +1411,31 @@ routes:
|
|||
try:
|
||||
let id = executeReply(c, threadId, msg, replyingTo)
|
||||
resp Http200, $(%id), "application/json"
|
||||
except ForumError:
|
||||
except ForumError as exc:
|
||||
resp Http400, $(%exc.data), "application/json"
|
||||
|
||||
post "/karax/newthread":
|
||||
createTFD()
|
||||
if not c.loggedIn():
|
||||
let err = PostError(
|
||||
errorFields: @[],
|
||||
message: getCurrentExceptionMsg()
|
||||
message: "Not logged in."
|
||||
)
|
||||
resp Http400, $(%err), "application/json"
|
||||
resp Http401, $(%err), "application/json"
|
||||
|
||||
let formData = request.formData
|
||||
cond "msg" in formData
|
||||
cond "subject" in formData
|
||||
|
||||
let msg = formData["msg"].body
|
||||
let subject = formData["subject"].body
|
||||
# TODO: category
|
||||
|
||||
try:
|
||||
let res = executeNewThread(c, subject, msg)
|
||||
resp Http200, $(%[res[0], res[1]]), "application/json"
|
||||
except ForumError as exc:
|
||||
resp Http400, $(%exc.data), "application/json"
|
||||
|
||||
get re"/karax/(.+)?":
|
||||
resp readFile("redesign/karax.html")
|
||||
|
|
|
|||
|
|
@ -13,28 +13,35 @@ when defined(js):
|
|||
loading: bool
|
||||
error: Option[PostError]
|
||||
replyBox: ReplyBox
|
||||
subject: kstring
|
||||
|
||||
proc newNewThread*(): NewThread =
|
||||
NewThread(
|
||||
replyBox: newReplyBox(nil),
|
||||
subject: ""
|
||||
)
|
||||
|
||||
proc onSubjectChange(e: Event, n: VNode, state: NewThread) =
|
||||
state.subject = n.value
|
||||
|
||||
proc onCreatePost(httpStatus: int, response: kstring, state: NewThread) =
|
||||
postFinished:
|
||||
# TODO
|
||||
discard
|
||||
let j = parseJson($response)
|
||||
let response = to(j, array[2, int])
|
||||
navigateTo(renderPostUrl(response[0], response[1]))
|
||||
|
||||
proc onCreateClick(ev: Event, n: VNode, state: NewThread) =
|
||||
state.loading = true
|
||||
state.error = none[PostError]()
|
||||
|
||||
let uri = makeUri("login")
|
||||
let uri = makeUri("newthread")
|
||||
# TODO: This is a hack, karax should support this.
|
||||
let formData = newFormData()
|
||||
#formData.append("" TODO
|
||||
formData.append("subject", state.subject)
|
||||
formData.append("msg", state.replyBox.getText())
|
||||
ajaxPost(uri, @[], cast[cstring](formData),
|
||||
(s: int, r: kstring) => onCreatePost(s, r, state))
|
||||
|
||||
proc newNewThread*(): NewThread =
|
||||
NewThread(
|
||||
replyBox: newReplyBox(nil)
|
||||
)
|
||||
|
||||
proc render*(state: NewThread): VNode =
|
||||
result = buildHtml():
|
||||
section(class="container grid-xl"):
|
||||
|
|
@ -43,7 +50,8 @@ when defined(js):
|
|||
p(): text "New Thread"
|
||||
tdiv(class="content"):
|
||||
input(class="form-input", `type`="text", name="username",
|
||||
placeholder="Type the title here")
|
||||
placeholder="Type the title here",
|
||||
onChange=(e: Event, n: VNode) => onSubjectChange(e, n, state))
|
||||
renderContent(state.replyBox, none[Thread](), none[Post]())
|
||||
tdiv(class="footer"):
|
||||
button(class=class(
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ when defined(js):
|
|||
|
||||
state.shown = true
|
||||
|
||||
proc getText*(state: ReplyBox): kstring = state.text
|
||||
|
||||
proc onPreviewPost(httpStatus: int, response: kstring, state: ReplyBox) =
|
||||
postFinished:
|
||||
kout(response)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue