Relative times are now shown for all the topics on /topics/ and /forum/

You can now see which forum the topics are in on the topic list.
Relative times are now calculated in real-time rather than once at start-up. I'm not sure how it ended up like that.
Fixed an issue with the lastReplyAt field not being populated for topics.
We now have relative times for weeks and months.
This commit is contained in:
Azareal 2017-02-06 04:52:19 +00:00
parent dca8670eed
commit 0e5d0e649e
18 changed files with 152 additions and 45 deletions

View File

@ -98,8 +98,12 @@ We're looking for ways to clean-up the plugin system so that all of them (except
# Images
![Tempra Simple Theme](https://github.com/Azareal/Gosora/blob/master/images/tempra-simple.png)
![Tempra Simple Topic List](https://github.com/Azareal/Gosora/blob/master/images/topic-list.png)
![Tempra Conflux Theme](https://github.com/Azareal/Gosora/blob/master/images/tempra-conflux.png)
![Tempra Conflux Mobile](https://github.com/Azareal/Gosora/blob/master/images/tempra-conflux-mobile-320px.png)
![Cosmo Conflux Theme](https://github.com/Azareal/Gosora/blob/master/images/cosmo-conflux.png)
![Cosmo Theme](https://github.com/Azareal/Gosora/blob/master/images/cosmo.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

BIN
images/topic-list.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

10
main.go
View File

@ -51,7 +51,7 @@ func compile_templates() {
log.Print("Compiling the templates")
topic := TopicUser{1,"Blah",template.HTML("Hey there!"),0,false,false,"",0,"","127.0.0.1",0,"","",no_css_tmpl,0,"","","","",58}
topic := TopicUser{1,"Blah",template.HTML("Hey there!"),0,false,false,"Date","Date",0,"","127.0.0.1",0,"","",no_css_tmpl,0,"","","","",58}
var replyList []Reply
replyList = append(replyList, Reply{0,0,"",template.HTML("Yo!"),0,"","",0,0,"",no_css_tmpl,0,"","","","",0,"127.0.0.1"})
@ -74,11 +74,13 @@ func compile_templates() {
forums_page := ForumsPage{"Forum List",user,noticeList,forumList,0}
forums_tmpl := c.compile_template("forums.html","templates/","ForumsPage", forums_page, varList)
var topicList []TopicUser
topicList = append(topicList, TopicUser{1,"Topic Title","The topic content.",1,false,false,"",1,"","127.0.0.1",0,"Admin","","",0,"","","","",58})
topics_page := TopicsPage{"Topic List",user,noticeList,topicList,""}
var topicsList []TopicsRow
topicsList = append(topicsList, TopicsRow{1,"Topic Title","The topic content.",1,false,false,"Date","Date",1,"","127.0.0.1",0,"Admin","","",0,"","","","",58,"General"})
topics_page := TopicsPage{"Topic List",user,noticeList,topicsList,""}
topics_tmpl := c.compile_template("topics.html","templates/","TopicsPage", topics_page, varList)
var topicList []TopicUser
topicList = append(topicList, TopicUser{1,"Topic Title","The topic content.",1,false,false,"Date","Date",1,"","127.0.0.1",0,"Admin","","",0,"","","","",58})
forum_item := Forum{1,"General Forum",true,"all",0,"",0,"",0,""}
forum_page := ForumPage{"General Forum",user,noticeList,topicList,forum_item,1,1,nil}
forum_tmpl := c.compile_template("forum.html","templates/","ForumPage", forum_page, varList)

View File

@ -118,25 +118,25 @@ func init_database(err error) {
}
log.Print("Preparing get_forum_topics statement.")
get_forum_topics_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid where topics.parentID = ? order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy desc")
get_forum_topics_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid where topics.parentID = ? order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy desc")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing get_forum_topics_offset statement.")
get_forum_topics_offset_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid WHERE topics.parentID = ? order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC limit ?, " + strconv.Itoa(items_per_page))
get_forum_topics_offset_stmt, err = db.Prepare("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid WHERE topics.parentID = ? order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC limit ?, " + strconv.Itoa(items_per_page))
if err != nil {
log.Fatal(err)
}
log.Print("Preparing create_topic statement.")
create_topic_stmt, err = db.Prepare("insert into topics(parentID,title,content,parsed_content,createdAt,ipaddress,createdBy) VALUES(?,?,?,?,NOW(),?,?)")
create_topic_stmt, err = db.Prepare("insert into topics(parentID,title,content,parsed_content,createdAt,lastReplyAt,ipaddress,createdBy) VALUES(?,?,?,?,NOW(),NOW(),?,?)")
if err != nil {
log.Fatal(err)
}
log.Print("Preparing create_report statement.")
create_report_stmt, err = db.Prepare("INSERT INTO topics(title,content,parsed_content,createdAt,createdBy,data,parentID) VALUES(?,?,?,NOW(),?,?,1)")
create_report_stmt, err = db.Prepare("INSERT INTO topics(title,content,parsed_content,createdAt,lastReplyAt,createdBy,data,parentID) VALUES(?,?,?,NOW(),NOW(),?,?,1)")
if err != nil {
log.Fatal(err)
}
@ -148,7 +148,7 @@ func init_database(err error) {
}
log.Print("Preparing add_replies_to_topic statement.")
add_replies_to_topic_stmt, err = db.Prepare("UPDATE topics SET postCount = postCount + ? WHERE tid = ?")
add_replies_to_topic_stmt, err = db.Prepare("UPDATE topics SET postCount = postCount + ?, lastReplyAt = NOW() WHERE tid = ?")
if err != nil {
log.Fatal(err)
}
@ -525,7 +525,7 @@ func init_database(err error) {
fill_forum_id_gap(i, forum.ID)
}
if forum.LastTopicID != 0 {
/*if forum.LastTopicID != 0 {
forum.LastTopicTime, err = relative_time(forum.LastTopicTime)
if err != nil {
log.Fatal(err)
@ -533,7 +533,7 @@ func init_database(err error) {
} else {
forum.LastTopic = "None"
forum.LastTopicTime = ""
}
}*/
log.Print("Adding the " + forum.Name + " forum")
forums = append(forums,forum)

View File

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 182 KiB

View File

@ -28,7 +28,7 @@ type TopicsPage struct
Title string
CurrentUser User
NoticeList []string
ItemList []TopicUser
ItemList []TopicsRow
ExtData interface{}
}

View File

@ -100,17 +100,17 @@ func route_topics(w http.ResponseWriter, r *http.Request){
}
}
var topicList []TopicUser
rows, err := db.Query("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid where parentID in("+strings.Join(fidList,",")+") order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC")
var topicList []TopicsRow
rows, err := db.Query("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.lastReplyAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid where parentID in("+strings.Join(fidList,",")+") order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC")
//rows, err := get_topic_list_stmt.Query()
if err != nil {
InternalError(err,w,r)
return
}
topicItem := TopicUser{ID: 0,}
topicItem := TopicsRow{ID: 0,}
for rows.Next() {
err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.Is_Closed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.ParentID, &topicItem.CreatedByName, &topicItem.Avatar)
err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.Is_Closed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.ParentID, &topicItem.CreatedByName, &topicItem.Avatar)
if err != nil {
InternalError(err,w,r)
return
@ -124,8 +124,23 @@ func route_topics(w http.ResponseWriter, r *http.Request){
topicItem.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(topicItem.CreatedBy),1)
}
if topicItem.ParentID >= 0 {
topicItem.ForumName = forums[topicItem.ParentID].Name
} else {
topicItem.ForumName = ""
}
/*topicItem.CreatedAt, err = relative_time(topicItem.CreatedAt)
if err != nil {
InternalError(err,w,r)
}*/
topicItem.LastReplyAt, err = relative_time(topicItem.LastReplyAt)
if err != nil {
InternalError(err,w,r)
}
if hooks["trow_assign"] != nil {
topicItem = run_hook("trow_assign", topicItem).(TopicUser)
topicItem = run_hook("trow_assign", topicItem).(TopicsRow)
}
topicList = append(topicList, topicItem)
}
@ -185,7 +200,7 @@ func route_forum(w http.ResponseWriter, r *http.Request){
var topicList []TopicUser
topicItem := TopicUser{ID: 0}
for rows.Next() {
err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.Is_Closed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.ParentID, &topicItem.CreatedByName, &topicItem.Avatar)
err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.Is_Closed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.ParentID, &topicItem.CreatedByName, &topicItem.Avatar)
if err != nil {
InternalError(err,w,r)
return
@ -199,6 +214,11 @@ func route_forum(w http.ResponseWriter, r *http.Request){
topicItem.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(topicItem.CreatedBy),1)
}
topicItem.LastReplyAt, err = relative_time(topicItem.LastReplyAt)
if err != nil {
InternalError(err,w,r)
}
if hooks["trow_assign"] != nil {
topicItem = run_hook("trow_assign", topicItem).(TopicUser)
}
@ -229,12 +249,23 @@ func route_forums(w http.ResponseWriter, r *http.Request){
}
var forumList []Forum
var err error
group := groups[user.Group]
//fmt.Println(group.CanSee)
for _, fid := range group.CanSee {
//fmt.Println(forums[fid])
if forums[fid].Active && forums[fid].Name != "" {
forumList = append(forumList, forums[fid])
forum := forums[fid]
if forum.Active && forum.Name != "" {
if forum.LastTopicID != 0 {
forum.LastTopicTime, err = relative_time(forum.LastTopicTime)
if err != nil {
InternalError(err,w,r)
}
} else {
forum.LastTopic = "None"
forum.LastTopicTime = ""
}
forumList = append(forumList, forum)
}
}

View File

@ -95,16 +95,18 @@ if item.Is_Closed {
w.Write(forum_22)
}
w.Write(forum_23)
w.Write([]byte(item.LastReplyAt))
w.Write(forum_24)
}
} else {
w.Write(forum_24)
if tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
w.Write(forum_25)
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
if tmpl_forum_vars.CurrentUser.Perms.CreateTopic {
w.Write(forum_26)
}
w.Write([]byte(strconv.Itoa(tmpl_forum_vars.Forum.ID)))
w.Write(forum_27)
}
w.Write(forum_28)
}
w.Write(forum_29)
w.Write(footer_0)
}

View File

@ -405,12 +405,19 @@ var topics_6 []byte = []byte(`">
<a href="/topic/`)
var topics_7 []byte = []byte(`">`)
var topics_8 []byte = []byte(`</a> `)
var topics_9 []byte = []byte(`<span class="username topic_status_e topic_status_closed" style="float: right;position:relative;top:-5px;" title="Status: Closed">&#x1F512;&#xFE0E</span>`)
var topics_10 []byte = []byte(`
var topics_9 []byte = []byte(`<a href="/forum/`)
var topics_10 []byte = []byte(`" style="font-size:12px;">`)
var topics_11 []byte = []byte(`</a> `)
var topics_12 []byte = []byte(`<span class="username topic_status_e topic_status_closed" style="float: right;position:relative;top:-5px;margin-left:8px;" title="Status: Closed">&#x1F512;&#xFE0E</span>`)
var topics_13 []byte = []byte(`
<a style="float: right;font-size:12px;">`)
var topics_14 []byte = []byte(`</a>
</div>
`)
var topics_11 []byte = []byte(`<div class="rowitem passive">There aren't any topics yet.</div>`)
var topics_12 []byte = []byte(`
var topics_15 []byte = []byte(`<div class="rowitem passive">There aren't any topics yet.`)
var topics_16 []byte = []byte(` <a href="/topics/create/">Start one?</a>`)
var topics_17 []byte = []byte(`</div>`)
var topics_18 []byte = []byte(`
</div>
`)
var forum_0 []byte = []byte(`<div id="prevFloat" class="prev_button"><a class="prev_link" href="/forum/`)
@ -443,14 +450,16 @@ var forum_19 []byte = []byte(`">
<a href="/topic/`)
var forum_20 []byte = []byte(`">`)
var forum_21 []byte = []byte(`</a> `)
var forum_22 []byte = []byte(`<span class="username topic_status_e topic_status_closed" title="Status: Closed" style="float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>`)
var forum_22 []byte = []byte(`<span class="username topic_status_e topic_status_closed" title="Status: Closed" style="float: right;position:relative;top:-5px;margin-left:8px;">&#x1F512;&#xFE0E</span>`)
var forum_23 []byte = []byte(`
<a style="float: right;font-size:12px;">`)
var forum_24 []byte = []byte(`</a>
</div>
`)
var forum_24 []byte = []byte(`<div class="rowitem passive">There aren't any topics in this forum yet.`)
var forum_25 []byte = []byte(` <a href="/topics/create/`)
var forum_26 []byte = []byte(`">Start one?</a>`)
var forum_27 []byte = []byte(`</div>`)
var forum_28 []byte = []byte(`
var forum_25 []byte = []byte(`<div class="rowitem passive">There aren't any topics in this forum yet.`)
var forum_26 []byte = []byte(` <a href="/topics/create/`)
var forum_27 []byte = []byte(`">Start one?</a>`)
var forum_28 []byte = []byte(`</div>`)
var forum_29 []byte = []byte(`
</div>
`)

View File

@ -1,7 +1,7 @@
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main
import "io"
import "strconv"
import "io"
func init() {
template_profile_handle = template_profile

View File

@ -1,8 +1,8 @@
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
package main
import "html/template"
import "io"
import "strconv"
import "html/template"
func init() {
template_topic_alt_handle = template_topic_alt

View File

@ -61,14 +61,27 @@ w.Write([]byte(strconv.Itoa(item.ID)))
w.Write(topics_7)
w.Write([]byte(item.Title))
w.Write(topics_8)
if item.Is_Closed {
if item.ForumName != "" {
w.Write(topics_9)
}
w.Write([]byte(strconv.Itoa(item.ParentID)))
w.Write(topics_10)
}
} else {
w.Write([]byte(item.ForumName))
w.Write(topics_11)
}
if item.Is_Closed {
w.Write(topics_12)
}
w.Write(topics_13)
w.Write([]byte(item.LastReplyAt))
w.Write(topics_14)
}
} else {
w.Write(topics_15)
if tmpl_topics_vars.CurrentUser.Perms.CreateTopic {
w.Write(topics_16)
}
w.Write(topics_17)
}
w.Write(topics_18)
w.Write(footer_0)
}

View File

@ -8,7 +8,8 @@
</div>
<div class="rowblock">
{{range .ItemList}}<div class="rowitem passive" style="{{if .Avatar}}background-image: url({{.Avatar}});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;{{end}}{{if .Sticky}}background-color: #FFFFCC;{{else if .Is_Closed}}background-color: #eaeaea;{{end}}">
<a href="/topic/{{.ID}}">{{.Title}}</a> {{if .Is_Closed}}<span class="username topic_status_e topic_status_closed" title="Status: Closed" style="float: right;position:relative;top:-5px;">&#x1F512;&#xFE0E</span>{{end}}
<a href="/topic/{{.ID}}">{{.Title}}</a> {{if .Is_Closed}}<span class="username topic_status_e topic_status_closed" title="Status: Closed" style="float: right;position:relative;top:-5px;margin-left:8px;">&#x1F512;&#xFE0E</span>{{end}}
<a style="float: right;font-size:12px;">{{.LastReplyAt}}</a>
</div>
{{else}}<div class="rowitem passive">There aren't any topics in this forum yet.{{if .CurrentUser.Perms.CreateTopic}} <a href="/topics/create/{{.Forum.ID}}">Start one?</a>{{end}}</div>{{end}}
</div>

View File

@ -4,8 +4,10 @@
</div>
<div class="rowblock">
{{range .ItemList}}<div class="rowitem passive" style="{{if .Avatar}}background-image: url({{.Avatar}});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;{{end}}{{if .Sticky}}background-color: #FFFFCC;{{else if .Is_Closed}}background-color: #eaeaea;{{end}}">
<a href="/topic/{{.ID}}">{{.Title}}</a> {{if .Is_Closed}}<span class="username topic_status_e topic_status_closed" style="float: right;position:relative;top:-5px;" title="Status: Closed">&#x1F512;&#xFE0E</span>{{end}}
<a href="/topic/{{.ID}}">{{.Title}}</a> {{if .ForumName}}<a href="/forum/{{.ParentID}}" style="font-size:12px;">{{.ForumName}}</a> {{end}}
{{if .Is_Closed}}<span class="username topic_status_e topic_status_closed" style="float: right;position:relative;top:-5px;margin-left:8px;" title="Status: Closed">&#x1F512;&#xFE0E</span>{{end}}
<a style="float: right;font-size:12px;">{{.LastReplyAt}}</a>
</div>
{{else}}<div class="rowitem passive">There aren't any topics yet.</div>{{end}}
{{else}}<div class="rowitem passive">There aren't any topics yet.{{if .CurrentUser.Perms.CreateTopic}} <a href="/topics/create/">Start one?</a>{{end}}</div>{{end}}
</div>
{{template "footer.html" . }}

View File

@ -25,6 +25,7 @@ type TopicUser struct
Is_Closed bool
Sticky bool
CreatedAt string
LastReplyAt string
ParentID int
Status string // Deprecated. Marked for removal.
IpAddress string
@ -40,3 +41,31 @@ type TopicUser struct
URLName string
Level int
}
type TopicsRow struct
{
ID int
Title string
Content interface{}
CreatedBy int
Is_Closed bool
Sticky bool
CreatedAt string
LastReplyAt string
ParentID int
Status string // Deprecated. Marked for removal.
IpAddress string
PostCount int
CreatedByName string
Avatar string
Css template.CSS
ContentLines int
Tag string
URL string
URLPrefix string
URLName string
Level int
ForumName string //TopicsRow
}

View File

@ -21,6 +21,9 @@ func GenerateSafeString(length int) (string, error) {
}
func relative_time(in string) (string, error) {
if in == "" {
return "", nil
}
layout := "2006-01-02 15:04:05"
t, err := time.Parse(layout, in)
if err != nil {
@ -30,9 +33,20 @@ func relative_time(in string) (string, error) {
diff := time.Since(t)
hours := diff.Hours()
seconds := diff.Seconds()
weeks := int(hours / 24 / 7)
months := int(hours / 24 / 31)
switch {
case (hours / 24) > 7:
return t.Format("Mon Jan 2 2006"), err
case months > 11:
//return t.Format("Mon Jan 2 2006"), err
return t.Format("Jan 2 2006"), err
case months > 1:
return fmt.Sprintf("%d months ago", months), err
case months == 1:
return "a month ago", err
case weeks > 1:
return fmt.Sprintf("%d weeks ago", weeks), err
case int(hours / 24) == 7:
return "a week ago", err
case int(hours / 24) == 1:
return "1 day ago", err
case int(hours / 24) > 1: