Redesigned front page.

Made font smalled for the thread list. Gravatars are now shown for each
user that posted in each thread listed. Time since last reply is now
calculated and shown beside each thread.
This commit is contained in:
Dominik Picheta 2014-11-09 18:28:21 +00:00
commit 114d322b50
4 changed files with 95 additions and 48 deletions

View file

@ -15,9 +15,9 @@
# count = 0 # count = 0
<div id="talk-heads"> <div id="talk-heads">
<div class="topic"><div>Topic</div></div> <div class="topic"><div>Topic</div></div>
<div class="reply"><div>Last</div></div> <div class="users"><div>Users</div></div>
<div class="detail"><div>Details</div></div> <div class="detail"><div>Details</div></div>
<div class="author"><div>Author</div></div> <div class="activity"><div>Activity</div></div>
</div> </div>
<div id="talk-threads"> <div id="talk-threads">
# for row in rows(db, query, $((c.pageNum-1) * ThreadsPerPage), $ThreadsPerPage): # for row in rows(db, query, $((c.pageNum-1) * ThreadsPerPage), $ThreadsPerPage):
@ -25,47 +25,44 @@
<div> <div>
<div class="topic"> <div class="topic">
<div> <div>
${UrlButton(c, xmlEncode(%name), c.genThreadUrl(threadid = %threadid))} <a href="${c.genThreadUrl(threadid = %threadid)}"
title="${xmlEncode(%name)}">${xmlEncode(%name)}</a>
${genPagenumLocalNav(c, (%threadid).parseInt)} ${genPagenumLocalNav(c, (%threadid).parseInt)}
</div> </div>
</div> </div>
#let users = getAllRows(db,
# sql("select distinct name, email from person where id in " &
# "(select author from post where thread = ?)"), %threadId)
<div class="users">
<div>
#for i in 0 .. min(6, users.len-1):
<img src="${getGravatarUrl(users[i][1], 20)}" title="${users[i][0]}">
#end for
</div>
</div>
#let latestReplyAuthor = getValue(db, sql("select name from person where id = " & #let latestReplyAuthor = getValue(db, sql("select name from person where id = " &
# "(select author from post where id = " & # "(select author from post where id = " &
# "(select max(id) from post where thread = ?))"), %threadId) # "(select max(id) from post where thread = ?))"), %threadId)
#let latestReplyDate = getValue(db, sql("SELECT strftime('%s', " &
# "(select creation from post where id = (select max(id) from post where thread = ?)))"), %threadId)
#let timeStr = formatTimestamp(latestReplyDate.parseInt())
#let replyProfileUrl = c.req.makeUri("profile/", false) & #let replyProfileUrl = c.req.makeUri("profile/", false) &
# xmlEncode(latestReplyAuthor) # xmlEncode(latestReplyAuthor)
<div class="reply">
<div>
<a href="$replyProfileUrl" title="$timeStr">$latestReplyAuthor</a>
</div>
</div>
# let posts = getValue(db, sql"select count(*) from post where thread = ?", %threadId) # let posts = getValue(db, sql"select count(*) from post where thread = ?", %threadId)
<div class="detail"> <div class="detail">
<div><div>${xmlEncode(%views)}</div></div> <div><div title="Views">${xmlEncode(%views)}</div></div>
<div><div>$posts</div></div> <div><div title="Posts">$posts</div></div>
</div> </div>
#let authorName = getValue(db, sql("select name from person where id = " & #let latestReplyDate = getValue(db, sql("SELECT strftime('%s', " &
# "(select author from post where id = " & # "(select creation from post where id = (select max(id) from post where thread = ?)))"), %threadId)
# "(select min(id) from post where thread = ?))"), %threadId) #let timeStr = formatTimestamp(latestReplyDate.parseInt())
#let profileUrl = c.req.makeUri("profile/", false) & xmlEncode(authorName) <div class="activity">
<div class="author"> <div>$timeStr</div>
<div><a href="$profileUrl">$authorName</a></div>
</div> </div>
</div> </div>
# end for # end for
<div>
<div class="topic"><div><a href="http://reign-studios.net/philipwitte/nim/forum-thread.htm">Cannot generate code for N (static[int]) in template</a></div></div>
<div class="reply"><div><a href="#" title="Mon, 29 Sep 2014 23:11 UTC">marcianx</a></div></div>
<div class="detail"><div><div>135</div></div><div><div>8</div></div></div>
<div class="author"><div><a href="#">marcianx</a></div></div>
</div>
</div> </div>
#end proc #end proc

View file

@ -143,15 +143,50 @@ proc genButtons(c: var TForumData, btns: seq[TStyledButton]): string =
result.add(("""<a class="$3active button" href="$1$4">$2</a>""") % [ result.add(("""<a class="$3active button" href="$1$4">$2</a>""") % [
btns[i].link, btns[i].text, class, anchor]) btns[i].link, btns[i].text, class, anchor])
proc toInterval(diff: int64): TimeInterval =
var remaining = diff
let years = remaining div 31536000
remaining -= years * 31536000
let months = remaining div 2592000
remaining -= months * 2592000
let days = remaining div 86400
remaining -= days * 86400
let hours = remaining div 3600
remaining -= hours * 3600
let minutes = remaining div 60
remaining -= minutes * 60
#assert false
result = initInterval(0, remaining.int, minutes.int, hours.int, days.int,
months.int, years.int)
proc formatTimestamp(t: int): string = proc formatTimestamp(t: int): string =
let t2 = getGMTime(TTime(t)) let t2 = TTime(t)
return t2.format("ddd',' d MMM yyyy HH':'mm 'UTC'") let now = getTime()
let diff = (now - t2).toInterval()
if diff.years > 0:
return getGMTime(t2).format("MMMM d',' yyyy")
elif diff.months > 0:
return $diff.months & (if diff.months > 1: " months ago" else: " month ago")
elif diff.days > 0:
return $diff.days & (if diff.days > 1: " days ago" else: " day ago")
elif diff.hours > 0:
return $diff.hours & (if diff.hours > 1: " hours ago" else: " hour ago")
elif diff.minutes > 0:
return $diff.minutes &
(if diff.minutes > 1: " minutes ago" else: " minute ago")
elif diff.seconds > 0:
return $diff.seconds &
(if diff.seconds > 1: " seconds ago" else: " second ago")
else:
return "less than a second ago"
proc getGravatarUrl(email: string, size = 80): string =
let emailMD5 = email.toLower.toMD5
return ("http://www.gravatar.com/avatar/" & $emailMD5 & "?s=" & $size &
"&d=identicon")
proc genGravatar(email: string, size: int = 80): string = proc genGravatar(email: string, size: int = 80): string =
let emailMD5 = email.toLower.toMD5 result = "<img src=\"$1\" />" % getGravatarUrl(email, size)
result = "<img src=\"$1\" />" %
("http://www.gravatar.com/avatar/" & $emailMD5 & "?s=" & $size &
"&d=identicon")
proc randomSalt(): string = proc randomSalt(): string =
result = "" result = ""
@ -535,8 +570,8 @@ proc genPagenumNav(c: var TForumData, stats: TForumStats): string =
else: else:
lastTag = htmlgen.a(href=lastUrl, ">>") lastTag = htmlgen.a(href=lastUrl, ">>")
nextTag = htmlgen.a(href=nextUrl, "••>") nextTag = htmlgen.a(href=nextUrl, "••>")
result.add(lastTag)
result.add(nextTag) result.add(nextTag)
result.add(lastTag)
proc gatherTotalPostsByID(c: var TForumData, thrid: int): int = proc gatherTotalPostsByID(c: var TForumData, thrid: int): int =
## Gets the total post count of a thread. ## Gets the total post count of a thread.

View file

@ -110,7 +110,8 @@
#if c.errorMsg != "": #if c.errorMsg != "":
<span class="error">$c.errorMsg</span> <span class="error">$c.errorMsg</span>
#end if #end if
<a href="#" class="button" style="float: left;">Register</a> <a href="${frontQuery}register" class="button"
style="float: left;">Register</a>
<a href="#" onclick="document.forms['login'].submit()" <a href="#" onclick="document.forms['login'].submit()"
class="button">Login</a> class="button">Login</a>
</div> </div>

View file

@ -26,7 +26,7 @@ pre .end { background:url("/images/tabEnd.png") no-repeat left bottom; }
.page-layout { margin:0 auto; width:1000px; } .page-layout { margin:0 auto; width:1000px; }
.docs-layout { margin:0 40px; } .docs-layout { margin:0 40px; }
.talk-layout { margin:0 40px; } .talk-layout { margin:0 40px; min-height: 700px; }
.wide-layout { margin:0 auto; } .wide-layout { margin:0 auto; }
#head { height:100px; background:url("/images/head.png") repeat-x bottom; } #head { height:100px; background:url("/images/head.png") repeat-x bottom; }
@ -167,11 +167,11 @@ pre .end { background:url("/images/tabEnd.png") no-repeat left bottom; }
#talk-heads > div { float:left; font-size:120%; font-weight:bold; } #talk-heads > div { float:left; font-size:120%; font-weight:bold; }
#talk-heads > .topic { width:55%; } #talk-heads > .topic { width:55%; }
#talk-heads > .detail { width:15%; } #talk-heads > .detail { width:15%; }
#talk-heads > .author { width:15%; } #talk-heads > .activity { width:15%; }
#talk-heads > .reply { width:15%; } #talk-heads > .users { width:15%; }
#talk-heads > div > div { margin:0 10px 10px 10px; padding:0 10px 10px 10px; border-bottom:1px dashed rgba(0,0,0,0.4); } #talk-heads > div > div { margin:0 10px 10px 10px; padding:0 10px 10px 10px; border-bottom:1px dashed rgba(0,0,0,0.4); }
#talk-heads > .topic > div { margin-left:0; } #talk-heads > .topic > div { margin-left:0; }
#talk-heads > .author > div { margin-right:0; } #talk-heads > .activity > div { margin-right:0; }
#talk-thread > div, #talk-thread > div,
#talk-threads > div { #talk-threads > div {
@ -186,21 +186,35 @@ pre .end { background:url("/images/tabEnd.png") no-repeat left bottom; }
#talk-thread > div:nth-child(odd) { background:rgba(255,255,255,0.1); } #talk-thread > div:nth-child(odd) { background:rgba(255,255,255,0.1); }
#talk-threads > div:nth-child(odd) { background:rgba(0,0,0,0.2); } #talk-threads > div:nth-child(odd) { background:rgba(0,0,0,0.2); }
#talk-thread > div > div, #talk-thread > div > div,
#talk-threads > div > div { float:left; } #talk-threads > div > div
{
float:left;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
font-size: 10pt;
}
#talk-thread > div > div > div, #talk-thread > div > div > div,
#talk-threads > div > div > div { margin:10px 20px; } #talk-threads > div > div > div { margin: 5px 20px; }
#talk-threads > div > .topic { width:55%; } #talk-threads > div > .topic { width:55%; }
#talk-threads > div > .reply { width:15%; overflow:hidden; } #talk-threads > div > .users { width:15%; overflow:hidden; }
#talk-threads > div > .users > div > img
{
margin-bottom: -4pt;
cursor: help;
}
#talk-threads > div > .detail { width:15%; overflow:hidden; } #talk-threads > div > .detail { width:15%; overflow:hidden; }
#talk-thread > div > .author, #talk-thread > div > .activity,
#talk-threads > div > .author { #talk-threads > div > .activity {
position:absolute; position:absolute;
right:0; right:0;
top:0; top:0;
bottom:0; bottom:0;
width:15%; width:15%;
overflow:hidden; overflow:hidden;
background:rgba(0,0,0,0.8); } background:rgba(0,0,0,0.8);
color: white;
}
#talk-thread > div > .author a, #talk-thread > div > .author a,
#talk-threads > div > .author a { color:#1cb3ec !important; } #talk-threads > div > .author a { color:#1cb3ec !important; }
#talk-thread > div > .author a:hover, #talk-thread > div > .author a:hover,
@ -208,10 +222,10 @@ pre .end { background:url("/images/tabEnd.png") no-repeat left bottom; }
#talk-threads > div > .topic .pages { float:right; } #talk-threads > div > .topic .pages { float:right; }
#talk-threads > div > .topic > div > a { font-weight:bold; } #talk-threads > div > .topic > div > a { font-weight:bold; }
#talk-threads > div > .detail > div { float:left; margin:0; } #talk-threads > div > .detail > div { float:left; margin:0; }
#talk-threads > div > .detail > div > div { margin-left:20px; padding:10px 10px 10px 22px; } #talk-threads > div > .detail > div > div { margin-left:20px; padding: 5px 5px 5px 22px; }
#talk-threads > div > .detail > div { width:50%; } #talk-threads > div > .detail > div { width:50%; }
#talk-threads > div > .detail > div:first-child > div { background:url("/images/forum-views.png") no-repeat left; } #talk-threads > div > .detail > div:first-child > div { background:url("/images/forum-views.png") no-repeat left; cursor: help; }
#talk-threads > div > .detail > div:last-child > div { background:url("/images/forum-posts.png") no-repeat left; } #talk-threads > div > .detail > div:last-child > div { background:url("/images/forum-posts.png") no-repeat left; cursor: help; }
#talk-thread > div { margin:20px 0; min-height:150px; box-shadow:1px 3px 12px rgba(0,0,0,.4) } #talk-thread > div { margin:20px 0; min-height:150px; box-shadow:1px 3px 12px rgba(0,0,0,.4) }
#talk-thread > div > .author > div > .avatar { margin-top:20px; } #talk-thread > div > .author > div > .avatar { margin-top:20px; }