Implements posts and threads list in profile page.
This commit is contained in:
parent
2dd9dd52a2
commit
30721d53d6
4 changed files with 119 additions and 28 deletions
77
forum.nim
77
forum.nim
|
|
@ -1214,14 +1214,33 @@ routes:
|
|||
var
|
||||
username = @"username"
|
||||
|
||||
# Have to do this because SQLITE doesn't support `in` queries with
|
||||
# multiple columns :/
|
||||
# TODO: Figure out a better way. This is horrible.
|
||||
let creatorSubquery = """
|
||||
(select $1 from post p
|
||||
where p.thread = t.id
|
||||
order by p.id asc limit 1)
|
||||
"""
|
||||
|
||||
let threadsFrom = """
|
||||
from thread t, post p
|
||||
where ? in $1 and p.id in $2
|
||||
""" % [creatorSubquery % "author", creatorSubquery % "id"]
|
||||
|
||||
let postsFrom = """
|
||||
from post p, person u, thread t
|
||||
where u.id = p.author and p.thread = t.id and u.name = ?
|
||||
"""
|
||||
|
||||
let postsQuery = sql("""
|
||||
select p.id, p.content, strftime('%s', p.creation), p.author,
|
||||
select p.id, strftime('%s', p.creation),
|
||||
u.name, u.email, strftime('%s', u.lastOnline), u.status,
|
||||
strftime('%s', u.creation)
|
||||
from post p, person u
|
||||
where u.id = p.author and u.name = ?
|
||||
order by p.id desc;
|
||||
""")
|
||||
strftime('%s', u.creation), u.id,
|
||||
t.name, t.id
|
||||
$1
|
||||
order by p.id desc limit 10;
|
||||
""" % postsFrom)
|
||||
|
||||
var profile = Profile(
|
||||
threads: @[],
|
||||
|
|
@ -1229,29 +1248,43 @@ routes:
|
|||
)
|
||||
|
||||
let rows = db.getAllRows(postsQuery, username)
|
||||
let userID = rows[0][7]
|
||||
profile.user = selectUser(@[
|
||||
rows[0][4], rows[0][5], rows[0][6], rows[0][7]
|
||||
rows[0][2], rows[0][3], rows[0][4], rows[0][5]
|
||||
], avatarSize=200)
|
||||
profile.joinTime = rows[0][8].parseInt()
|
||||
profile.joinTime = rows[0][7].parseInt()
|
||||
profile.postCount =
|
||||
getValue(db, sql("select count(*) " & postsFrom), username).parseInt()
|
||||
profile.threadCount =
|
||||
getValue(db, sql("select count(*) " & threadsFrom), userID).parseInt()
|
||||
|
||||
if c.rank >= Admin:
|
||||
profile.email = some(rows[0][5])
|
||||
profile.email = some(rows[0][3])
|
||||
|
||||
for row in rows:
|
||||
let firstPostForThread = getRow(db,
|
||||
sql"""select t.id, t.name, t.views, t.modified, p.id
|
||||
from thread t, post p
|
||||
where p.thread = t.id
|
||||
order by p.id limit 1""", row[0])
|
||||
|
||||
# Check if the thread that contains this post was created by the user.
|
||||
if firstPostForThread[4] == row[0]:
|
||||
profile.threads.add(
|
||||
selectThread(firstPostForThread)
|
||||
)
|
||||
|
||||
profile.posts.add(
|
||||
selectPost(row, @[])
|
||||
PostLink(
|
||||
creation: row[1].parseInt(),
|
||||
topic: row[8],
|
||||
threadId: row[9].parseInt(),
|
||||
postId: row[0].parseInt()
|
||||
)
|
||||
)
|
||||
|
||||
let threadsQuery = sql("""
|
||||
select t.id, t.name, strftime('%s', p.creation), p.id
|
||||
$1
|
||||
order by t.id desc
|
||||
limit 10;
|
||||
""" % threadsFrom)
|
||||
for row in db.getAllRows(threadsQuery, userID):
|
||||
profile.threads.add(
|
||||
PostLink(
|
||||
creation: row[2].parseInt(),
|
||||
topic: row[1],
|
||||
threadId: row[0].parseInt(),
|
||||
postId: row[3].parseInt()
|
||||
)
|
||||
)
|
||||
|
||||
resp $(%profile), "application/json"
|
||||
|
|
|
|||
|
|
@ -499,4 +499,16 @@ hr {
|
|||
dd {
|
||||
margin-right: $control-padding-x-lg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.profile-post {
|
||||
@extend .post;
|
||||
|
||||
.profile-post-main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.profile-post-time {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,19 @@ type
|
|||
info*: PostInfo
|
||||
moreBefore*: seq[int]
|
||||
|
||||
PostLink* = object ## Used by profile
|
||||
creation*: int64
|
||||
topic*: string
|
||||
threadId*: int
|
||||
postId*: int
|
||||
|
||||
when defined(js):
|
||||
import karaxutils
|
||||
proc renderPostUrl*(threadId, postId: int): string =
|
||||
makeUri(fmt"/t/{threadId}#{postId}")
|
||||
|
||||
proc renderPostUrl*(post: Post, thread: Thread): string =
|
||||
makeUri(fmt"/t/{thread.id}#{post.id}")
|
||||
renderPostUrl(thread.id, post.id)
|
||||
|
||||
proc renderPostUrl*(link: PostLink): string =
|
||||
renderPostUrl(link.threadId, link.postId)
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
import options, httpcore, json, sugar
|
||||
import options, httpcore, json, sugar, times
|
||||
|
||||
import threadlist, post, category, error
|
||||
type
|
||||
Profile* = object
|
||||
user*: User
|
||||
joinTime*: int64
|
||||
threads*: seq[Thread]
|
||||
posts*: seq[Post]
|
||||
threads*: seq[PostLink]
|
||||
posts*: seq[PostLink]
|
||||
postCount*: int
|
||||
threadCount*: int
|
||||
# Information that only admins should see.
|
||||
email*: Option[string]
|
||||
|
||||
|
|
@ -38,6 +40,20 @@ when defined(js):
|
|||
|
||||
state.profile = some(profile)
|
||||
|
||||
proc genPostLink(link: PostLink): VNode =
|
||||
let url = renderPostUrl(link)
|
||||
result = buildHtml():
|
||||
tdiv(class="profile-post"):
|
||||
tdiv(class="profile-post-main"):
|
||||
tdiv(class="profile-post-title"):
|
||||
a(href=url):
|
||||
text link.topic
|
||||
tdiv(class="profile-post-time"):
|
||||
let title = link.creation.fromUnix().local.
|
||||
format("MMM d, yyyy HH:mm")
|
||||
p(title=title):
|
||||
text renderActivity(link.creation)
|
||||
|
||||
proc render*(state: ProfileState, username: string): VNode =
|
||||
if state.status != Http200:
|
||||
return renderError("Couldn't retrieve profile.")
|
||||
|
|
@ -63,16 +79,34 @@ when defined(js):
|
|||
dt(text "Joined")
|
||||
dd(text threadlist.renderActivity(profile.joinTime))
|
||||
dt(text "Last Post")
|
||||
dd(text renderActivity(profile.posts[0].info.creation))
|
||||
dd(text renderActivity(profile.posts[0].creation))
|
||||
dt(text "Last Online")
|
||||
dd(text renderActivity(profile.user.lastOnline))
|
||||
dt(text "Posts")
|
||||
dd():
|
||||
if profile.postCount > 999:
|
||||
text $(profile.postCount / 1000) & "k"
|
||||
else:
|
||||
text $profile.postCount
|
||||
dt(text "Threads")
|
||||
dd():
|
||||
if profile.threadCount > 999:
|
||||
text $(profile.threadCount / 1000) & "k"
|
||||
else:
|
||||
text $profile.threadCount
|
||||
dt(text "Rank")
|
||||
dd(text $profile.user.rank)
|
||||
|
||||
tdiv(class="columns"):
|
||||
tdiv(class="column col-6"):
|
||||
h4(text "Latest Posts")
|
||||
tdiv(class="posts"):
|
||||
for post in profile.posts:
|
||||
genPostLink(post)
|
||||
tdiv(class="column col-6"):
|
||||
h4(text "Latest Threads")
|
||||
tdiv(class="posts"):
|
||||
for thread in profile.threads:
|
||||
genPostLink(thread)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue