From 39adc2e6068016cb4b007c8730d0280c96bd98fd Mon Sep 17 00:00:00 2001 From: Azareal Date: Thu, 30 Aug 2018 20:31:21 +1000 Subject: [PATCH] Per-topic views are now visible in the topic pages for the Nox Theme. The parent forum of a topic is now visible on the topic pages for the Cosora and Nox Themes. Added basic styling for polls to the Nox Theme. Improved the styling for topic title editing in the Nox Theme. --- common/pages.go | 1 + common/template_init.go | 14 ++++---- common/topic.go | 17 +++++---- common/topic_list.go | 4 +-- common/topic_store.go | 10 +++--- general_test.go | 2 +- routes/forum.go | 4 +-- routes/topic.go | 7 +++- templates/topic_alt.html | 7 ++-- themes/cosora/public/main.css | 15 ++++++++ themes/nox/public/main.css | 67 ++++++++++++++++++++++++++++++++++- 11 files changed, 122 insertions(+), 26 deletions(-) diff --git a/common/pages.go b/common/pages.go index cb4f4f0b..d3706d0e 100644 --- a/common/pages.go +++ b/common/pages.go @@ -94,6 +94,7 @@ type TopicPage struct { *Header ItemList []ReplyUser Topic TopicUser + Forum *Forum Poll Poll Page int LastPage int diff --git a/common/template_init.go b/common/template_init.go index 31de634c..e08ad184 100644 --- a/common/template_init.go +++ b/common/template_init.go @@ -189,7 +189,7 @@ func CompileTemplates() error { PollOption{1, "Something"}, }, VoteCount: 7} avatar, microAvatar := BuildAvatar(62, "") - topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, now, RelativeTime(now), now, RelativeTime(now), 0, "", "127.0.0.1", 0, 1, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", "", "", 58, false} + topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, now, RelativeTime(now), now, RelativeTime(now), 0, "", "127.0.0.1", 1, 0, 1, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", "", "", 58, false} var replyList []ReplyUser // TODO: Do we want the UID on this to be 0? avatar, microAvatar = BuildAvatar(0, "") @@ -197,7 +197,8 @@ func CompileTemplates() error { var varList = make(map[string]tmpl.VarItem) header.Title = "Topic Name" - tpage := TopicPage{header, replyList, topic, poll, 1, 1} + tpage := TopicPage{header, replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, 1, 1} + tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID) topicIDTmpl, err := c.Compile("topic.html", "templates/", "common.TopicPage", tpage, varList) if err != nil { return err @@ -234,7 +235,7 @@ func CompileTemplates() error { } var topicsList []*TopicsRow - topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, "Date", user3.ID, 1, "", "127.0.0.1", 0, 1, "classname", "", &user2, "", 0, &user3, "General", "/forum/general.2"}) + topicsList = append(topicsList, &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, "Date", user3.ID, 1, "", "127.0.0.1", 1, 0, 1, "classname", "", &user2, "", 0, &user3, "General", "/forum/general.2"}) header2.Title = "Topic List" topicListPage := TopicListPage{header, topicsList, forumList, Config.DefaultForum, Paginator{[]int{1}, 1, 1}} topicListTmpl, err := c.Compile("topics.html", "templates/", "common.TopicListPage", topicListPage, varList) @@ -365,7 +366,7 @@ func CompileJSTemplates() error { // TODO: Fix the import loop so we don't have to use this hack anymore c.SetBuildTags("!no_templategen,tmplgentopic") - var topicsRow = &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, "Date", user3.ID, 1, "", "127.0.0.1", 0, 1, "classname", "", &user2, "", 0, &user3, "General", "/forum/general.2"} + var topicsRow = &TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, "Date", user3.ID, 1, "", "127.0.0.1", 1, 0, 1, "classname", "", &user2, "", 0, &user3, "General", "/forum/general.2"} topicListItemTmpl, err := c.Compile("topics_topic.html", "templates/", "*common.TopicsRow", topicsRow, varList) if err != nil { return err @@ -376,7 +377,7 @@ func CompileJSTemplates() error { PollOption{1, "Something"}, }, VoteCount: 7} avatar, microAvatar := BuildAvatar(62, "") - topic := TopicUser{1, "blah", "Blah", "Hey there!", 62, false, false, now, RelativeTime(now), now, RelativeTime(now), 0, "", "127.0.0.1", 0, 1, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", "", "", 58, false} + topic := TopicUser{1, "blah", "Blah", "Hey there!", 62, false, false, now, RelativeTime(now), now, RelativeTime(now), 0, "", "127.0.0.1", 1, 0, 1, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", "", "", 58, false} var replyList []ReplyUser // TODO: Do we really want the UID here to be zero? avatar, microAvatar = BuildAvatar(0, "") @@ -384,7 +385,8 @@ func CompileJSTemplates() error { varList = make(map[string]tmpl.VarItem) header.Title = "Topic Name" - tpage := TopicPage{header, replyList, topic, poll, 1, 1} + tpage := TopicPage{header, replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, 1, 1} + tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID) topicIDTmpl, err := c.Compile("topic_posts.html", "templates/", "common.TopicPage", tpage, varList) if err != nil { return err diff --git a/common/topic.go b/common/topic.go index fb1af831..d4b74787 100644 --- a/common/topic.go +++ b/common/topic.go @@ -37,6 +37,7 @@ type Topic struct { ParentID int Status string // Deprecated. Marked for removal. IPAddress string + ViewCount int PostCount int LikeCount int ClassName string // CSS Class Name @@ -60,6 +61,7 @@ type TopicUser struct { ParentID int Status string // Deprecated. Marked for removal. IPAddress string + ViewCount int PostCount int LikeCount int ClassName string @@ -97,6 +99,7 @@ type TopicsRow struct { ParentID int Status string // Deprecated. Marked for removal. -Is there anything we could use it for? IPAddress string + ViewCount int PostCount int LikeCount int ClassName string @@ -123,6 +126,7 @@ type WsTopicsRow struct { RelativeLastReplyAt string LastReplyBy int ParentID int + ViewCount int PostCount int LikeCount int ClassName string @@ -133,7 +137,7 @@ type WsTopicsRow struct { } func (row *TopicsRow) WebSockets() *WsTopicsRow { - return &WsTopicsRow{row.ID, row.Link, row.Title, row.CreatedBy, row.IsClosed, row.Sticky, row.CreatedAt, row.LastReplyAt, row.RelativeLastReplyAt, row.LastReplyBy, row.ParentID, row.PostCount, row.LikeCount, row.ClassName, row.Creator.WebSockets(), row.LastUser.WebSockets(), row.ForumName, row.ForumLink} + return &WsTopicsRow{row.ID, row.Link, row.Title, row.CreatedBy, row.IsClosed, row.Sticky, row.CreatedAt, row.LastReplyAt, row.RelativeLastReplyAt, row.LastReplyBy, row.ParentID, row.ViewCount, row.PostCount, row.LikeCount, row.ClassName, row.Creator.WebSockets(), row.LastUser.WebSockets(), row.ForumName, row.ForumLink} } type TopicStmts struct { @@ -174,8 +178,8 @@ func init() { setPoll: acc.Update("topics").Set("content = '', parsed_content = '', poll = ?").Where("tid = ? AND poll = 0").Prepare(), createActionReply: acc.Insert("replies").Columns("tid, actionType, ipaddress, createdBy, createdAt, lastUpdated, content, parsed_content").Fields("?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),'',''").Prepare(), - getTopicUser: acc.SimpleLeftJoin("topics", "users", "topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, topics.poll, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level", "topics.createdBy = users.uid", "tid = ?", "", ""), - getByReplyID: acc.SimpleLeftJoin("replies", "topics", "topics.tid, topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, topics.poll, topics.data", "replies.tid = topics.tid", "rid = ?", "", ""), + getTopicUser: acc.SimpleLeftJoin("topics", "users", "topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.views, topics.postCount, topics.likeCount, topics.poll, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level", "topics.createdBy = users.uid", "tid = ?", "", ""), + getByReplyID: acc.SimpleLeftJoin("replies", "topics", "topics.tid, topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.views, topics.postCount, topics.likeCount, topics.poll, topics.data", "replies.tid = topics.tid", "rid = ?", "", ""), } return acc.FirstError() }) @@ -332,7 +336,7 @@ func (topic *Topic) Copy() Topic { // TODO: Load LastReplyAt? func TopicByReplyID(rid int) (*Topic, error) { topic := Topic{ID: 0} - err := topicStmts.getByReplyID.QueryRow(rid).Scan(&topic.ID, &topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Poll, &topic.Data) + err := topicStmts.getByReplyID.QueryRow(rid).Scan(&topic.ID, &topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.Poll, &topic.Data) topic.Link = BuildTopicURL(NameToSlug(topic.Title), topic.ID) return &topic, err } @@ -366,14 +370,14 @@ func GetTopicUser(tid int) (TopicUser, error) { } tu := TopicUser{ID: tid} - err := topicStmts.getTopicUser.QueryRow(tid).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.IsClosed, &tu.Sticky, &tu.ParentID, &tu.IPAddress, &tu.PostCount, &tu.LikeCount, &tu.Poll, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level) + err := topicStmts.getTopicUser.QueryRow(tid).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.IsClosed, &tu.Sticky, &tu.ParentID, &tu.IPAddress, &tu.ViewCount, &tu.PostCount, &tu.LikeCount, &tu.Poll, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level) tu.Avatar, tu.MicroAvatar = BuildAvatar(tu.CreatedBy, tu.Avatar) tu.Link = BuildTopicURL(NameToSlug(tu.Title), tu.ID) tu.UserLink = BuildProfileURL(NameToSlug(tu.CreatedByName), tu.CreatedBy) tu.Tag = Groups.DirtyGet(tu.Group).Tag if tcache != nil { - theTopic := Topic{ID: tu.ID, Link: tu.Link, Title: tu.Title, Content: tu.Content, CreatedBy: tu.CreatedBy, IsClosed: tu.IsClosed, Sticky: tu.Sticky, CreatedAt: tu.CreatedAt, LastReplyAt: tu.LastReplyAt, ParentID: tu.ParentID, IPAddress: tu.IPAddress, PostCount: tu.PostCount, LikeCount: tu.LikeCount, Poll: tu.Poll} + theTopic := Topic{ID: tu.ID, Link: tu.Link, Title: tu.Title, Content: tu.Content, CreatedBy: tu.CreatedBy, IsClosed: tu.IsClosed, Sticky: tu.Sticky, CreatedAt: tu.CreatedAt, LastReplyAt: tu.LastReplyAt, ParentID: tu.ParentID, IPAddress: tu.IPAddress, ViewCount: tu.ViewCount, PostCount: tu.PostCount, LikeCount: tu.LikeCount, Poll: tu.Poll} //log.Printf("theTopic: %+v\n", theTopic) _ = tcache.Add(&theTopic) } @@ -401,6 +405,7 @@ func copyTopicToTopicUser(topic *Topic, user *User) (tu TopicUser) { tu.LastReplyAt = topic.LastReplyAt tu.ParentID = topic.ParentID tu.IPAddress = topic.IPAddress + tu.ViewCount = topic.ViewCount tu.PostCount = topic.PostCount tu.LikeCount = topic.LikeCount tu.Poll = topic.Poll diff --git a/common/topic_list.go b/common/topic_list.go index 9dc13847..565fa765 100644 --- a/common/topic_list.go +++ b/common/topic_list.go @@ -216,7 +216,7 @@ func (tList *DefaultTopicList) getList(page int, argList []interface{}, qlist st } offset, page, lastPage := PageOffset(topicCount, page, Config.ItemsPerPage) - stmt, err := qgen.Builder.SimpleSelect("topics", "tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, postCount, likeCount", "parentID IN("+qlist+")", "sticky DESC, lastReplyAt DESC, createdBy DESC", "?,?") + stmt, err := qgen.Builder.SimpleSelect("topics", "tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, views, postCount, likeCount", "parentID IN("+qlist+")", "sticky DESC, lastReplyAt DESC, createdBy DESC", "?,?") if err != nil { return nil, Paginator{nil, 1, 1}, err } @@ -234,7 +234,7 @@ func (tList *DefaultTopicList) getList(page int, argList []interface{}, qlist st var reqUserList = make(map[int]bool) for rows.Next() { topicItem := TopicsRow{ID: 0} - err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.IsClosed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.LastReplyBy, &topicItem.ParentID, &topicItem.PostCount, &topicItem.LikeCount) + err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.IsClosed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.LastReplyBy, &topicItem.ParentID, &topicItem.ViewCount, &topicItem.PostCount, &topicItem.LikeCount) if err != nil { return nil, Paginator{nil, 1, 1}, err } diff --git a/common/topic_store.go b/common/topic_store.go index 69e03304..e089bce9 100644 --- a/common/topic_store.go +++ b/common/topic_store.go @@ -57,7 +57,7 @@ func NewDefaultTopicStore(cache TopicCache) (*DefaultTopicStore, error) { } return &DefaultTopicStore{ cache: cache, - get: acc.Select("topics").Columns("title, content, createdBy, createdAt, lastReplyAt, is_closed, sticky, parentID, ipaddress, postCount, likeCount, poll, data").Where("tid = ?").Prepare(), + get: acc.Select("topics").Columns("title, content, createdBy, createdAt, lastReplyAt, is_closed, sticky, parentID, ipaddress, views, postCount, likeCount, poll, data").Where("tid = ?").Prepare(), exists: acc.Select("topics").Columns("tid").Where("tid = ?").Prepare(), topicCount: acc.Count("topics").Prepare(), create: acc.Insert("topics").Columns("parentID, title, content, parsed_content, createdAt, lastReplyAt, lastReplyBy, ipaddress, words, createdBy").Fields("?,?,?,?,UTC_TIMESTAMP(),UTC_TIMESTAMP(),?,?,?,?").Prepare(), @@ -71,7 +71,7 @@ func (mts *DefaultTopicStore) DirtyGet(id int) *Topic { } topic = &Topic{ID: id} - err = mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Poll, &topic.Data) + err = mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.Poll, &topic.Data) if err == nil { topic.Link = BuildTopicURL(NameToSlug(topic.Title), id) _ = mts.cache.Add(topic) @@ -88,7 +88,7 @@ func (mts *DefaultTopicStore) Get(id int) (topic *Topic, err error) { } topic = &Topic{ID: id} - err = mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Poll, &topic.Data) + err = mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.Poll, &topic.Data) if err == nil { topic.Link = BuildTopicURL(NameToSlug(topic.Title), id) _ = mts.cache.Add(topic) @@ -99,14 +99,14 @@ func (mts *DefaultTopicStore) Get(id int) (topic *Topic, err error) { // BypassGet will always bypass the cache and pull the topic directly from the database func (mts *DefaultTopicStore) BypassGet(id int) (*Topic, error) { topic := &Topic{ID: id} - err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Poll, &topic.Data) + err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.Poll, &topic.Data) topic.Link = BuildTopicURL(NameToSlug(topic.Title), id) return topic, err } func (mts *DefaultTopicStore) Reload(id int) error { topic := &Topic{ID: id} - err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.PostCount, &topic.LikeCount, &topic.Poll, &topic.Data) + err := mts.get.QueryRow(id).Scan(&topic.Title, &topic.Content, &topic.CreatedBy, &topic.CreatedAt, &topic.LastReplyAt, &topic.IsClosed, &topic.Sticky, &topic.ParentID, &topic.IPAddress, &topic.ViewCount, &topic.PostCount, &topic.LikeCount, &topic.Poll, &topic.Data) if err == nil { topic.Link = BuildTopicURL(NameToSlug(topic.Title), id) _ = mts.cache.Set(topic) diff --git a/general_test.go b/general_test.go index a9dda025..e4751279 100644 --- a/general_test.go +++ b/general_test.go @@ -762,7 +762,7 @@ func BenchmarkQueryTopicParallel(b *testing.B) { b.RunParallel(func(pb *testing.PB) { var tu common.TopicUser for pb.Next() { - err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.IsClosed, &tu.Sticky, &tu.ParentID, &tu.IPAddress, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level) + err := db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, topics.ipaddress, topics.views, topics.postCount, topics.likeCount, users.name, users.avatar, users.group, users.url_prefix, users.url_name, users.level from topics left join users ON topics.createdBy = users.uid where tid = ?", 1).Scan(&tu.Title, &tu.Content, &tu.CreatedBy, &tu.CreatedAt, &tu.IsClosed, &tu.Sticky, &tu.ParentID, &tu.IPAddress, &tu.ViewCount, &tu.PostCount, &tu.LikeCount, &tu.CreatedByName, &tu.Avatar, &tu.Group, &tu.URLPrefix, &tu.URLName, &tu.Level) if err == ErrNoRows { log.Fatal("No rows found!") return diff --git a/routes/forum.go b/routes/forum.go index 7cc31d25..8e997530 100644 --- a/routes/forum.go +++ b/routes/forum.go @@ -21,7 +21,7 @@ var forumStmts ForumStmts func init() { common.DbInits.Add(func(acc *qgen.Accumulator) error { forumStmts = ForumStmts{ - getTopics: acc.Select("topics").Columns("tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, postCount, likeCount").Where("parentID = ?").Orderby("sticky DESC, lastReplyAt DESC, createdBy DESC").Limit("?,?").Prepare(), + getTopics: acc.Select("topics").Columns("tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, views, postCount, likeCount").Where("parentID = ?").Orderby("sticky DESC, lastReplyAt DESC, createdBy DESC").Limit("?,?").Prepare(), } return acc.FirstError() }) @@ -73,7 +73,7 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user common.User, sfid st var reqUserList = make(map[int]bool) for rows.Next() { var topicItem = common.TopicsRow{ID: 0} - err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.IsClosed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.LastReplyBy, &topicItem.ParentID, &topicItem.PostCount, &topicItem.LikeCount) + err := rows.Scan(&topicItem.ID, &topicItem.Title, &topicItem.Content, &topicItem.CreatedBy, &topicItem.IsClosed, &topicItem.Sticky, &topicItem.CreatedAt, &topicItem.LastReplyAt, &topicItem.LastReplyBy, &topicItem.ParentID, &topicItem.ViewCount, &topicItem.PostCount, &topicItem.LikeCount) if err != nil { return common.InternalError(err, w, r) } diff --git a/routes/topic.go b/routes/topic.go index f135c439..97f1a4a9 100644 --- a/routes/topic.go +++ b/routes/topic.go @@ -86,6 +86,11 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit } topic.RelativeCreatedAt = common.RelativeTime(topic.CreatedAt) + forum, err := common.Forums.Get(topic.ParentID) + if err != nil { + return common.InternalError(err, w, r) + } + var poll common.Poll if topic.Poll != 0 { pPoll, err := common.Polls.Get(topic.Poll) @@ -110,7 +115,7 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit // Calculate the offset offset, page, lastPage := common.PageOffset(topic.PostCount, page, common.Config.ItemsPerPage) - tpage := common.TopicPage{header, []common.ReplyUser{}, topic, poll, page, lastPage} + tpage := common.TopicPage{header, []common.ReplyUser{}, topic, forum, poll, page, lastPage} // Get the replies if we have any... if topic.PostCount > 0 { diff --git a/templates/topic_alt.html b/templates/topic_alt.html index 976faf24..37284469 100644 --- a/templates/topic_alt.html +++ b/templates/topic_alt.html @@ -12,8 +12,8 @@

{{.Topic.Title}}

- {{/** TODO: Inline this CSS **/}} - {{if .Topic.IsClosed}}🔒︎{{end}} + / + {{.Forum.Name}} {{/** TODO: Does this need to be guarded by a permission? It's only visible in edit mode anyway, which can't be triggered, if they don't have the permission **/}} {{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}} {{if .CurrentUser.Perms.EditTopic}} @@ -21,6 +21,9 @@ {{end}} {{end}} + {{.Topic.ViewCount}} + {{/** TODO: Inline this CSS **/}} + {{if .Topic.IsClosed}}🔒︎{{end}}
diff --git a/themes/cosora/public/main.css b/themes/cosora/public/main.css index 7c4c2083..ae759fc7 100644 --- a/themes/cosora/public/main.css +++ b/themes/cosora/public/main.css @@ -946,6 +946,21 @@ textarea { margin-top: 0px; } +.topic_block { + padding-bottom: 10px; +} +.topic_name_forum_sep { + margin-left: 6px; + margin-right: 6px; + line-height: 26px; + font-size: 18px; +} +.topic_forum { + line-height: 23px; +} +.topic_view_count { + display: none; +} .postImage { width: 100%; max-width: 240px; diff --git a/themes/nox/public/main.css b/themes/nox/public/main.css index 44826254..82e48207 100644 --- a/themes/nox/public/main.css +++ b/themes/nox/public/main.css @@ -516,10 +516,37 @@ button, .formbutton, .panel_right_button { width: 36px; } -.colstack { +.colstack, .topic_item { display: flex; } +.topic_item .topic_name_forum_sep { + font-size: 20px; + line-height: 30px; + margin-left: 7px; + margin-right: 7px; +} +.topic_item .topic_forum { + font-size: 19px; + line-height: 31px; + color: #dddddd; +} +.topic_view_count { + font-size: 17px; + margin-left: auto; + margin-right: 20px; + margin-top: 6px; +} +.topic_view_count:after { + content: " views"; +} +.topic_name_input { + width: 100%; + margin-right: 12px; +} +.topic_item .submit_edit { + margin-right: 16px; +} .postImage { width: 100%; max-width: 320px; @@ -610,6 +637,44 @@ button, .formbutton, .panel_right_button { margin-right: auto; } +input[type=checkbox] { + display: none; +} +input[type=checkbox] + label { + display: inline-flex; + width: 18px; + height: 18px; + margin-bottom: -2px; + margin-right: 8px; + border: 1px solid rgb(120,120,120); + background-color: rgb(90,90,90); + padding-top: 1px; + border-radius: 2px; +} +input[type=checkbox]:checked + label .sel { + width: 8px; + height: 8px; + background: rgb(160,160,160); + margin-left: auto; + margin-right: auto; + margin-top: auto; + margin-bottom: auto; + border-radius: 2px; +} +.poll_option { + display: flex; + margin-bottom: 10px; +} +.poll_option_text { + line-height: 14px; +} +.poll_buttons { + padding-top: 4px; +} +.poll_buttons button { + margin-right: 8px; +} + .add_like:before, .remove_like:before { content: "{{index .Phrases "topic.plus_one"}}"; }