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.
This commit is contained in:
parent
41c3a5bb4a
commit
39adc2e606
|
@ -94,6 +94,7 @@ type TopicPage struct {
|
|||
*Header
|
||||
ItemList []ReplyUser
|
||||
Topic TopicUser
|
||||
Forum *Forum
|
||||
Poll Poll
|
||||
Page int
|
||||
LastPage int
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
<form action='/topic/edit/submit/{{.Topic.ID}}?session={{.CurrentUser.Session}}' method="post">
|
||||
<div class="rowitem topic_item{{if .Topic.Sticky}} topic_sticky_head{{else if .Topic.IsClosed}} topic_closed_head{{end}}">
|
||||
<h1 class='topic_name hide_on_edit' title='{{.Topic.Title}}'>{{.Topic.Title}}</h1>
|
||||
{{/** TODO: Inline this CSS **/}}
|
||||
{{if .Topic.IsClosed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='{{lang "status.closed_tooltip"}}' aria-label='{{lang "topic.status_closed_aria"}}' style="font-weight:normal;float: right;position:relative;top:-5px;">🔒︎</span>{{end}}
|
||||
<span class="topic_name_forum_sep hide_on_edit"> / </span>
|
||||
<a href="{{.Forum.Link}}" class="topic_forum hide_on_edit">{{.Forum.Name}}</a>
|
||||
{{/** 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 @@
|
|||
<button name="topic-button" class="formbutton show_on_edit submit_edit">{{lang "topic.update_button"}}</button>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<span class="topic_view_count hide_on_edit">{{.Topic.ViewCount}}</span>
|
||||
{{/** TODO: Inline this CSS **/}}
|
||||
{{if .Topic.IsClosed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='{{lang "status.closed_tooltip"}}' aria-label='{{lang "topic.status_closed_aria"}}' style="font-weight:normal;float: right;position:relative;top:-5px;">🔒︎</span>{{end}}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"}}";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue