Show who you're replying to and scroll to reply box.

This commit is contained in:
Dominik Picheta 2018-05-12 14:08:08 +01:00
commit 96e78a5b84
7 changed files with 75 additions and 38 deletions

View file

@ -81,7 +81,7 @@ when defined(js):
tdiv(class="navbar container grid-xl"):
section(class="navbar-section"):
a(href=makeUri("/")):
img(src="images/crown.png", id="img-logo") # TODO: Customisation.
img(src="/karax/images/crown.png", id="img-logo") # TODO: Customisation.
section(class="navbar-section"):
tdiv(class="input-group input-inline"):
input(class="search-input input-sm",

View file

@ -8,17 +8,15 @@
<title>The Nim programming language forum</title>
<base href="/karax/">
<link rel="stylesheet" href="nimforum.css">
<link rel="stylesheet" href="/karax/nimforum.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.12/css/all.css" integrity="sha384-G0fIWCsCzJIMAVNQPfjH08cyYaUtMwjJwqiRKxxE/rx96Uroj1BtIQ6MLJuheaO9" crossorigin="anonymous">
<link rel="icon" href="images/favicon.png">
<link rel="icon" href="/karax/images/favicon.png">
</head>
<body>
<div id="ROOT" />
<script type="text/javascript" src="nimcache/forum.js"></script>
<script type="text/javascript" src="/karax/nimcache/forum.js"></script>
</body>
</html>

View file

@ -13,7 +13,8 @@ proc class*(classes: varargs[tuple[name: string, present: bool]],
if class.present: result.add(class.name & " ")
proc makeUri*(relative: string, appName=appName, includeHash=false): string =
## Concatenates ``relative`` to the current URL in a way that is sane.
## Concatenates ``relative`` to the current URL in a way that is
## (possibly) sane.
var relative = relative
assert appName in $window.location.pathname
if relative[0] == '/': relative = relative[1..^1]

18
redesign/post.nim Normal file
View file

@ -0,0 +1,18 @@
import threadlist
type
PostInfo* = object
creation*: int64
content*: string
Post* = object
id*: int
author*: User
likes*: seq[User] ## Users that liked this post.
seen*: bool ## Determines whether the current user saw this post.
## I considered using a simple timestamp for each thread,
## but that wouldn't work when a user navigates to the last
## post in a thread for example.
history*: seq[PostInfo] ## If the post was edited this will contain the
## older versions of the post.
info*: PostInfo

View file

@ -1,23 +1,8 @@
import options, json, times, httpcore, strformat, sugar, math
import threadlist, category
import threadlist, category, post
type
PostInfo* = object
creation*: int64
content*: string
Post* = object
id*: int
author*: User
likes*: seq[User] ## Users that liked this post.
seen*: bool ## Determines whether the current user saw this post.
## I considered using a simple timestamp for each thread,
## but that wouldn't work when a user navigates to the last
## post in a thread for example.
history*: seq[PostInfo] ## If the post was edited this will contain the
## older versions of the post.
info*: PostInfo
PostList* = ref object
thread*: Thread
@ -38,7 +23,7 @@ when defined(js):
list: Option[PostList]
loading: bool
status: HttpCode
replyBoxShown: bool
replyingTo: Option[Post]
replyBox: ReplyBox
proc newState(): State =
@ -46,7 +31,7 @@ when defined(js):
list: none[PostList](),
loading: false,
status: Http200,
replyBoxShown: true,
replyingTo: none[Post](),
replyBox: newReplyBox()
)
@ -74,7 +59,12 @@ when defined(js):
proc renderPostUrl(post: Post, thread: Thread): string =
makeUri(fmt"/t/{thread.id}/p/{post.id}")
proc onReplyClick(e: Event, n: VNode, p: Option[Post]) =
state.replyingTo = p
state.replyBox.show()
proc genPost(post: Post, thread: Thread, isLoggedIn: bool): VNode =
let postCopy = post # TODO: Another workaround here, closure capture :(
result = buildHtml():
tdiv(class="post"):
tdiv(class="post-icon"):
@ -102,7 +92,8 @@ when defined(js):
button(class="btn"):
italic(class="far fa-flag")
tdiv(class="reply-button"):
button(class="btn"):
button(class="btn", onClick=(e: Event, n: VNode) =>
onReplyClick(e, n, some(postCopy))):
italic(class="fas fa-reply")
text " Reply"
@ -183,11 +174,9 @@ when defined(js):
genPost(post, list.thread, isLoggedIn)
prevPost = some(post)
if state.replyBoxShown and prevPost.isSome:
genTimePassed(prevPost.get(), none[Post]())
if list.moreCount > 0:
genLoadMore(list.posts.len)
elif prevPost.isSome:
genTimePassed(prevPost.get(), none[Post]())
if state.replyBoxShown:
render(state.replyBox, list.thread)
render(state.replyBox, list.thread, state.replyingTo)

View file

@ -1,28 +1,53 @@
when defined(js):
import strformat
import strformat, options
from dom import getElementById, scrollIntoView, setTimeout
include karax/prelude
import karax / [vstyles, kajax, kdom]
import karaxutils, threadlist
import karaxutils, threadlist, post
type
ReplyBox* = ref object
shown: bool
preview: bool
proc newReplyBox*(): ReplyBox =
ReplyBox()
proc render*(state: ReplyBox, thread: Thread): VNode =
proc performScroll() =
let replyBox = dom.document.getElementById("reply-box")
replyBox.scrollIntoView(false)
proc show*(state: ReplyBox) =
# Scroll to the reply box.
if not state.shown:
# TODO: It would be nice for Karax to give us an event when it renders
# things. That way we can remove this crappy hack.
discard dom.window.setTimeout(performScroll, 50)
else:
performScroll()
state.shown = true
proc render*(state: ReplyBox, thread: Thread, post: Option[Post]): VNode =
if not state.shown:
return buildHtml(tdiv(id="reply-box"))
result = buildHtml():
tdiv(class="information no-border"):
tdiv(class="information no-border", id="reply-box"):
tdiv(class="information-icon"):
italic(class="fas fa-reply")
tdiv(class="information-main", style=style(StyleAttr.width, "100%")):
tdiv(class="information-title"):
# text fmt("Replying to \"{thread.topic}\"")
# tdiv(class="information-content"):
tdiv(class="panel", id="reply-box"):
if post.isNone:
text fmt("Replying to \"{thread.topic}\"")
else:
text "Replying to "
renderUserMention(post.get().author)
tdiv(class="information-content"):
tdiv(class="panel"):
tdiv(class="panel-nav"):
ul(class="tab tab-block"):
li(class=class({"active": not state.preview}, "tab-item")):

View file

@ -70,6 +70,12 @@ when defined(js):
if user.isOnline:
italic(class="avatar-presense online")
proc renderUserMention*(user: User): VNode =
result = buildHtml():
# TODO: Add URL to profile.
span(class="user-mention"):
text "@" & user.name
proc genUserAvatars(users: seq[User]): VNode =
result = buildHtml(td):
for user in users: