Working post preview!

This commit is contained in:
Dominik Picheta 2018-05-12 16:43:52 +01:00
commit 4ff5df6be2
4 changed files with 94 additions and 13 deletions

View file

@ -14,7 +14,7 @@ import cgi except setCookie
import options
import redesign/threadlist except User
import redesign/[category, postlist, error, header]
import redesign/[category, postlist, error, header, post]
when not defined(windows):
import bcrypt # TODO
@ -1186,6 +1186,29 @@ routes:
let status = UserStatus(user: user)
resp $(%status), "application/json"
post "/karax/preview":
createTFD()
if not c.loggedIn():
let err = PostError(
errorFields: @[],
message: "Not logged in."
)
resp Http401, $(%err), "application/json"
let formData = request.formData
cond "msg" in formData
let msg = formData["msg"].body
try:
let rendered = msg.rstToHtml()
resp Http200, rendered
except EParseError:
let err = PostError(
errorFields: @[],
message: getCurrentExceptionMsg()
)
resp Http400, $(%err), "application/json"
get re"/karax/(.+)?":
resp readFile("redesign/karax.html")

View file

@ -56,7 +56,11 @@ proc anchorCB*(e: kdom.Event, n: VNode) = # TODO: Why does this need disamb?
type
FormData* = ref object
proc newFormData*(): FormData
{.importcpp: "new FormData()", constructor.}
proc newFormData*(form: dom.Element): FormData
{.importcpp: "new FormData(@)", constructor.}
proc get*(form: FormData, key: cstring): cstring
{.importcpp: "#.get(@)".}
{.importcpp: "#.get(@)".}
proc append*(form: FormData, key, val: cstring)
{.importcpp: "#.append(@)".}

View file

@ -1,7 +1,7 @@
import strformat
import threadlist
import karaxutils
type
PostInfo* = object
@ -20,5 +20,8 @@ type
## older versions of the post.
info*: PostInfo
proc renderPostUrl*(post: Post, thread: Thread): string =
makeUri(fmt"/t/{thread.id}#{post.id}")
when defined(js):
import karaxutils
proc renderPostUrl*(post: Post, thread: Thread): string =
makeUri(fmt"/t/{thread.id}#{post.id}")

View file

@ -1,20 +1,26 @@
when defined(js):
import strformat, options
import strformat, options, httpcore, json, sugar
from dom import getElementById, scrollIntoView, setTimeout
include karax/prelude
import karax / [vstyles, kajax, kdom]
import karaxutils, threadlist, post
import karaxutils, threadlist, post, error
type
ReplyBox* = ref object
shown: bool
text: kstring
preview: bool
loading: bool
error: Option[PostError]
rendering: Option[kstring]
proc newReplyBox*(): ReplyBox =
ReplyBox()
ReplyBox(
text: ""
)
proc performScroll() =
let replyBox = dom.document.getElementById("reply-box")
@ -31,6 +37,39 @@ when defined(js):
state.shown = true
proc onPreviewPost(httpStatus: int, response: kstring, state: ReplyBox) =
let status = httpStatus.HttpCode
if status == Http200:
kout(response)
state.rendering = some[kstring](response)
else:
# TODO: login has similar code, abstract this.
try:
let parsed = parseJson($response)
let error = to(parsed, PostError)
state.error = some(error)
except:
kout(getCurrentExceptionMsg().cstring)
state.error = some(PostError(
errorFields: @[],
message: "Unknown error occurred."
))
proc onPreviewClick(e: Event, n: VNode, state: ReplyBox) =
state.preview = true
let formData = newFormData()
formData.append("msg", state.text)
let uri = makeUri("/preview")
ajaxPost(uri, @[], cast[cstring](formData),
(s: int, r: kstring) => onPreviewPost(s, r, state))
proc onChange(e: Event, n: VNode, state: ReplyBox) =
# TODO: There should be a karax-way to do this. I guess I can just call
# `value` on the node? We need to document this better :)
state.text = cast[dom.TextAreaElement](n.dom).value
proc render*(state: ReplyBox, thread: Thread, post: Option[Post],
hasMore: bool): VNode =
if not state.shown:
@ -56,14 +95,26 @@ when defined(js):
tdiv(class="panel"):
tdiv(class="panel-nav"):
ul(class="tab tab-block"):
li(class=class({"active": not state.preview}, "tab-item")):
a(href="#"):
li(class=class({"active": not state.preview}, "tab-item"),
onClick=(e: Event, n: VNode) => (state.preview = false)):
a(class="c-hand"):
text "Message"
li(class=class({"active": state.preview}, "tab-item")):
a(href="#"):
li(class=class({"active": state.preview}, "tab-item"),
onClick=(e: Event, n: VNode) =>
onPreviewClick(e, n, state)):
a(class="c-hand"):
text "Preview"
tdiv(class="panel-body"):
textarea(class="form-input", rows="5")
if state.preview:
if state.loading:
tdiv(class="loading")
elif state.rendering.isSome():
verbatim(state.rendering.get())
else:
textarea(class="form-input", rows="5",
onChange=(e: Event, n: VNode) =>
onChange(e, n, state),
value=state.text)
tdiv(class="panel-footer"):
button(class="btn btn-primary float-right"):
text "Reply"