long topics should render properly again

try to simplify TopicsRow
This commit is contained in:
Azareal 2020-08-15 12:37:56 +10:00
parent 40783f00da
commit 7d3085ce90
3 changed files with 81 additions and 71 deletions

View File

@ -227,7 +227,8 @@ func compileCommons(c *tmpl.CTemplateSet, head, head2 *Header, forumList []Forum
}*/
var topicsList []TopicsRowMut
topicsList = append(topicsList, TopicsRowMut{&TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "::1", 1, 0, 1, 1, 0, "classname", 0, "", user2, "", 0, user3, "General", "/forum/general.2", nil}, false})
topic := Topic{1, "/topic/topic-title.1","Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "::1", 1, 0, 1, 1, "classname",0,"",nil}
topicsList = append(topicsList, TopicsRowMut{&TopicsRow{topic,1, user2, "", 0, user3, "General", "/forum/general.2"}, false})
topicListPage := TopicListPage{htitle("Topic List"), topicsList, forumList, Config.DefaultForum, TopicListSort{"lastupdated", false}, QuickTools{false, false, false}, Paginator{[]int{1}, 1, 1}}
o.Add("topics", "c.TopicListPage", topicListPage)
o.Add("topics_mini", "c.TopicListPage", topicListPage)
@ -243,14 +244,14 @@ func compileCommons(c *tmpl.CTemplateSet, head, head2 *Header, forumList []Forum
}, VoteCount: 7}
avatar, microAvatar := BuildAvatar(62, "")
miniAttach := []*MiniAttachment{&MiniAttachment{Path: "/"}}
topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, now, now, 1, 1, 0, "", "127.0.0.1", 1, 0, 1, 0, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", 58, false, miniAttach, nil, false}
tu := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, now, now, 1, 1, 0, "", "127.0.0.1", 1, 0, 1, 0, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", 58, false, miniAttach, nil, false}
var replyList []*ReplyUser
reply := Reply{1, 1, "Yo!", 1 /*, Config.DefaultGroup*/, now, 0, 0, 1, "::1", true, 1, 1, ""}
ru := &ReplyUser{ClassName: "", Reply: reply, CreatedByName: "Alice", Avatar: avatar, Group: Config.DefaultGroup, Level: 0, Attachments: miniAttach}
ru.Init(user2)
replyList = append(replyList, ru)
tpage := TopicPage{htitle("Topic Name"), replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, &poll, Paginator{[]int{1}, 1, 1}}
tpage := TopicPage{htitle("Topic Name"), replyList, tu, &Forum{ID: 1, Name: "Hahaha"}, &poll, Paginator{[]int{1}, 1, 1}}
tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID)
o.Add("topic", "c.TopicPage", tpage)
o.Add("topic_mini", "c.TopicPage", tpage)
@ -310,7 +311,8 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
t.Add("profile", "c.ProfilePage", ppage)
var topicsList []TopicsRowMut
topicsList = append(topicsList, TopicsRowMut{&TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "127.0.0.1", 1, 0, 1, 1, 0, "classname", 0, "", user2, "", 0, user3, "General", "/forum/general.2", nil}, false})
topic := Topic{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "::1", 1, 0, 1, 1, "classname",0,"",nil}
topicsList = append(topicsList, TopicsRowMut{&TopicsRow{topic,0, user2, "", 0, user3, "General", "/forum/general.2"}, false})
topicListPage := TopicListPage{htitle("Topic List"), topicsList, forumList, Config.DefaultForum, TopicListSort{"lastupdated", false}, QuickTools{false, false, false}, Paginator{[]int{1}, 1, 1}}
forumItem := BlankForum(1, "general-forum.1", "General Forum", "Where the general stuff happens", true, "all", 0, "", 0)
@ -349,7 +351,7 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
}
t.AddStd("login", "c.Page", Page{htitle("Login Page"), tList, nil})
t.AddStd("register", "c.RegisterPage", RegisterPage{htitle("Registration Page"), false, ""})
t.AddStd("register", "c.RegisterPage", RegisterPage{htitle("Registration Page"), false, "",[]RegisterVerify{RegisterVerify{true,&RegisterVerifyImageGrid{"What?",[]RegisterVerifyImageGridImage{RegisterVerifyImageGridImage{"something.png"}}}}}})
t.AddStd("error", "c.ErrorPage", ErrorPage{htitle("Error"), "A problem has occurred in the system."})
ipSearchPage := IPSearchPage{htitle("IP Search"), map[int]*User{1: user2}, "::1"}
@ -538,7 +540,8 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
t := TItemHold(make(map[string]TItem))
topicsRow := TopicsRowMut{&TopicsRow{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "::1", 1, 0, 1, 0, 1, "classname", 0, "", user2, "", 0, user3, "General", "/forum/general.2", nil}, false}
topic := Topic{1, "topic-title", "Topic Title", "The topic content.", 1, false, false, now, now, user3.ID, 1, 1, "", "::1", 1, 0, 1, 0, "classname",1,"",nil}
topicsRow := TopicsRowMut{&TopicsRow{topic, 0, user2, "", 0, user3, "General", "/forum/general.2"}, false}
t.AddStd("topics_topic", "c.TopicsRowMut", topicsRow)
poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{
@ -547,7 +550,7 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
}, VoteCount: 7}
avatar, microAvatar := BuildAvatar(62, "")
miniAttach := []*MiniAttachment{&MiniAttachment{Path: "/"}}
topic := TopicUser{1, "blah", "Blah", "Hey there!", 62, false, false, now, now, 1, 1, 0, "", "::1", 1, 0, 1, 0, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", 58, false, miniAttach, nil, false}
tu := TopicUser{1, "blah", "Blah", "Hey there!", 62, false, false, now, now, 1, 1, 0, "", "::1", 1, 0, 1, 0, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", 58, false, miniAttach, nil, false}
var replyList []*ReplyUser
// TODO: Do we really want the UID here to be zero?
avatar, microAvatar = BuildAvatar(0, "")
@ -558,7 +561,7 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
varList = make(map[string]tmpl.VarItem)
header.Title = "Topic Name"
tpage := TopicPage{header, replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, &poll, Paginator{[]int{1}, 1, 1}}
tpage := TopicPage{header, replyList, tu, &Forum{ID: 1, Name: "Hahaha"}, &poll, Paginator{[]int{1}, 1, 1}}
tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID)
t.AddStd("topic_posts", "c.TopicPage", tpage)
t.AddStd("topic_alt_posts", "c.TopicPage", tpage)

View File

@ -39,7 +39,7 @@ type Topic struct {
LastReplyBy int
LastReplyID int
ParentID int
Status string // Deprecated. Marked for removal.
Status string // Deprecated. Marked for removal. -Is there anything we could use it for?
IP string
ViewCount int64
PostCount int
@ -101,28 +101,8 @@ type TopicsRowMut struct {
// TODO: Embed TopicUser to simplify this structure and it's related logic?
type TopicsRow struct {
ID int
Link string
Title string
Content string
CreatedBy int
IsClosed bool
Sticky bool
CreatedAt time.Time
LastReplyAt time.Time
LastReplyBy int
LastReplyID int
ParentID int
Status string // Deprecated. Marked for removal. -Is there anything we could use it for?
IP string
ViewCount int64
PostCount int
LikeCount int
AttachCount int
LastPage int
ClassName string
Poll int
Data string // Used for report metadata
Topic
LastPage int
Creator *User
CSS template.CSS
@ -131,7 +111,6 @@ type TopicsRow struct {
ForumName string //TopicsRow
ForumLink string
Rids []int
}
type WsTopicsRow struct {
@ -179,13 +158,15 @@ func (t *Topic) TopicsRow() *TopicsRow {
forumName := ""
forumLink := ""
return &TopicsRow{t.ID, t.Link, t.Title, t.Content, t.CreatedBy, t.IsClosed, t.Sticky, t.CreatedAt, t.LastReplyAt, t.LastReplyBy, t.LastReplyID, t.ParentID, t.Status, t.IP, t.ViewCount, t.PostCount, t.LikeCount, t.AttachCount, lastPage, t.ClassName, t.Poll, t.Data, creator, "", contentLines, lastUser, forumName, forumLink, t.Rids}
//return &TopicsRow{t.ID, t.Link, t.Title, t.Content, t.CreatedBy, t.IsClosed, t.Sticky, t.CreatedAt, t.LastReplyAt, t.LastReplyBy, t.LastReplyID, t.ParentID, t.Status, t.IP, t.ViewCount, t.PostCount, t.LikeCount, t.AttachCount, lastPage, t.ClassName, t.Poll, t.Data, creator, "", contentLines, lastUser, forumName, forumLink, t.Rids}
return &TopicsRow{*t, lastPage, creator, "", contentLines, lastUser, forumName, forumLink}
}
// ! Some data may be lost in the conversion
func (t *TopicsRow) Topic() *Topic {
return &Topic{t.ID, t.Link, t.Title, t.Content, t.CreatedBy, t.IsClosed, t.Sticky, t.CreatedAt, t.LastReplyAt, t.LastReplyBy, t.LastReplyID, t.ParentID, t.Status, t.IP, t.ViewCount, t.PostCount, t.LikeCount, t.AttachCount, t.ClassName, t.Poll, t.Data, t.Rids}
}
/*func (t *TopicsRow) Topic() *Topic {
//return &Topic{t.ID, t.Link, t.Title, t.Content, t.CreatedBy, t.IsClosed, t.Sticky, t.CreatedAt, t.LastReplyAt, t.LastReplyBy, t.LastReplyID, t.ParentID, t.Status, t.IP, t.ViewCount, t.PostCount, t.LikeCount, t.AttachCount, t.ClassName, t.Poll, t.Data, t.Rids}
return &t.Topic
}*/
// ! Not quite safe as Topic doesn't contain all the data needed to constructs a WsTopicsRow
/*func (t *Topic) WsTopicsRows() *WsTopicsRow {
@ -864,6 +845,12 @@ func (t *TopicUser) Replies(offset int /*pFrag int, */, user *User) (rlist []*Re
//log.Printf("r: %d-%d", r.ID, len(rlist)-1)
} else {
//log.Print("reply query serve")
ap1 := func(r *ReplyUser) {
H_topic_reply_row_assign_hook(hTbl, r)
// TODO: Use a pointer instead to make it easier to abstract this loop? What impact would this have on escape analysis?
rlist = append(rlist, r)
//log.Printf("r: %d-%d", r.ID, len(rlist)-1)
}
rf2 := func(r *ReplyUser) {
if r.LikeCount > 0 && user.Liked > 0 {
if likedMap == nil {
@ -883,31 +870,27 @@ func (t *TopicUser) Replies(offset int /*pFrag int, */, user *User) (rlist []*Re
attachQueryList = append(attachQueryList, r.ID)
}
}
H_topic_reply_row_assign_hook(hTbl, r)
// TODO: Use a pointer instead to make it easier to abstract this loop? What impact would this have on escape analysis?
rlist = append(rlist, r)
//log.Printf("r: %d-%d", r.ID, len(rlist)-1)
}
if !user.Perms.ViewIPs && ruser != nil {
rows, err := topicStmts.getReplies3.Query(t.ID, offset, Config.ItemsPerPage)
rows, e := topicStmts.getReplies3.Query(t.ID, offset, Config.ItemsPerPage)
if err != nil {
return nil, externalHead, err
return nil, externalHead, e
}
defer rows.Close()
for rows.Next() {
r := &ReplyUser{Avatar: ruser.Avatar, MicroAvatar: ruser.MicroAvatar, UserLink: ruser.Link, CreatedByName: ruser.Name, Group: ruser.Group, Level: ruser.Level}
err := rows.Scan(&r.ID, &r.Content, &r.CreatedBy, &r.CreatedAt, &r.LastEdit, &r.LastEditBy, &r.LikeCount, &r.AttachCount, &r.ActionType)
if err != nil {
return nil, externalHead, err
e := rows.Scan(&r.ID, &r.Content, &r.CreatedBy, &r.CreatedAt, &r.LastEdit, &r.LastEditBy, &r.LikeCount, &r.AttachCount, &r.ActionType)
if e != nil {
return nil, externalHead, e
}
if err = rf3(r); err != nil {
return nil, externalHead, err
if e = rf3(r); e != nil {
return nil, externalHead, e
}
rf2(r)
ap1(r)
}
if err = rows.Err(); err != nil {
return nil, externalHead, err
if e = rows.Err(); e != nil {
return nil, externalHead, e
}
} else if user.Perms.ViewIPs {
rows, err := topicStmts.getReplies.Query(t.ID, offset, Config.ItemsPerPage)
@ -925,11 +908,13 @@ func (t *TopicUser) Replies(offset int /*pFrag int, */, user *User) (rlist []*Re
return nil, externalHead, err
}
rf2(r)
ap1(r)
}
if err = rows.Err(); err != nil {
return nil, externalHead, err
}
} else if t.PostCount >= 20 {
//log.Print("t.PostCount >= 20")
rows, err := topicStmts.getReplies3.Query(t.ID, offset, Config.ItemsPerPage)
if err != nil {
return nil, externalHead, err
@ -945,12 +930,14 @@ func (t *TopicUser) Replies(offset int /*pFrag int, */, user *User) (rlist []*Re
if r.CreatedBy != t.CreatedBy && r.CreatedBy != user.ID {
reqUserList[r.CreatedBy] = true
}
ap1(r)
}
if err = rows.Err(); err != nil {
return nil, externalHead, err
}
if len(reqUserList) == 1 {
//log.Print("len(reqUserList) == 1: ", len(reqUserList) == 1)
var uitem *User
for uid, _ := range reqUserList {
uitem, err = Users.Get(uid)
@ -984,8 +971,10 @@ func (t *TopicUser) Replies(offset int /*pFrag int, */, user *User) (rlist []*Re
rf2(r)
}
} else {
//log.Print("len(reqUserList) != 1: ", len(reqUserList) != 1)
var userList map[int]*User
if len(reqUserList) > 0 {
//log.Print("len(reqUserList) > 0: ", len(reqUserList) > 0)
// Convert the user ID map to a slice, then bulk load the users
idSlice := make([]int, len(reqUserList))
var i int
@ -1026,6 +1015,7 @@ func (t *TopicUser) Replies(offset int /*pFrag int, */, user *User) (rlist []*Re
}
}
} else {
//log.Print("reply fallback")
rows, err := topicStmts.getReplies2.Query(t.ID, offset, Config.ItemsPerPage)
if err != nil {
return nil, externalHead, err
@ -1041,6 +1031,7 @@ func (t *TopicUser) Replies(offset int /*pFrag int, */, user *User) (rlist []*Re
return nil, externalHead, err
}
rf2(r)
ap1(r)
}
if err = rows.Err(); err != nil {
return nil, externalHead, err

View File

@ -309,7 +309,7 @@ func (tList *DefaultTopicList) GetListByForum(f *Forum, page, orderby int) (topi
// TODO: Use something other than TopicsRow as we don't need to store the forum name and link on each and every topic item?
reqUserList := make(map[int]bool)
for rows.Next() {
t := TopicsRow{ID: 0}
t := TopicsRow{Topic:Topic{ID: 0}}
err := rows.Scan(&t.ID, &t.Title, &t.Content, &t.CreatedBy, &t.IsClosed, &t.Sticky, &t.CreatedAt, &t.LastReplyAt, &t.LastReplyBy, &t.LastReplyID, &t.ViewCount, &t.PostCount, &t.LikeCount)
if err != nil {
return nil, Paginator{nil, 1, 1}, err
@ -391,7 +391,7 @@ func (tList *DefaultTopicList) GetListByCanSee(canSee []int, page, orderby int,
f := Forums.DirtyGet(fid)
if f.Name != "" && f.Active && (f.ParentType == "" || f.ParentType == "forum") && f.TopicCount != 0 {
fcopy := f.Copy()
// TODO: Add a hook here for plugin_guilds
// TODO: Add a hook here for plugin_guilds !!
forumList = append(forumList, fcopy)
}
}
@ -592,8 +592,9 @@ func (tList *DefaultTopicList) getList(page, orderby, topicCount int, argList []
}
if tc != nil {
if _, err := tc.Get(t.ID); err == sql.ErrNoRows {
_ = tc.Set(t.Topic())
if _, e := tc.Get(t.ID); e == sql.ErrNoRows {
//_ = tc.Set(t.Topic())
_ = tc.Set(&t.Topic)
}
}
}
@ -601,25 +602,40 @@ func (tList *DefaultTopicList) getList(page, orderby, topicCount int, argList []
return nil, Paginator{nil, 1, 1}, err
}
// Convert the user ID map to a slice, then bulk load the users
idSlice := make([]int, len(reqUserList))
var i int
for userID := range reqUserList {
idSlice[i] = userID
i++
}
// TODO: specialcase for when reqUserList only has one or two items to avoid map alloc
if len(reqUserList) == 1 {
var u *User
for uid, _ := range reqUserList {
u, err = Users.Get(uid)
if err != nil {
return nil, Paginator{nil, 1, 1}, err
}
}
for _, t := range topicList {
t.Creator = u
t.LastUser = u
}
} else if len(reqUserList) > 0 {
// Convert the user ID map to a slice, then bulk load the users
idSlice := make([]int, len(reqUserList))
var i int
for userID := range reqUserList {
idSlice[i] = userID
i++
}
// TODO: What if a user is deleted via the Control Panel?
userList, err := Users.BulkGetMap(idSlice)
if err != nil {
return nil, Paginator{nil, 1, 1}, err
}
// TODO: What if a user is deleted via the Control Panel?
userList, err := Users.BulkGetMap(idSlice)
if err != nil {
return nil, Paginator{nil, 1, 1}, err
}
// Second pass to the add the user data
// TODO: Use a pointer to TopicsRow instead of TopicsRow itself?
for _, t := range topicList {
t.Creator = userList[t.CreatedBy]
t.LastUser = userList[t.LastReplyBy]
// Second pass to the add the user data
// TODO: Use a pointer to TopicsRow instead of TopicsRow itself?
for _, t := range topicList {
t.Creator = userList[t.CreatedBy]
t.LastUser = userList[t.LastReplyBy]
}
}
pageList := Paginate(page, lastPage, 5)