Finished the Most Viewed Page for Nox.

Added three phrases for topic_list.
Moved the topic_middle_inside suffix phrases from the CSS files into the template proper.
Removed a newline in topic_middle_inside and used flex instead.
The link_select drop-down is now only visible when someone clicks on the link.
Tweaked the .topic_forum line height for Cosora.
Tweaked the .topic_view_count font size for Cosora.
This commit is contained in:
Azareal 2018-09-26 17:46:30 +10:00
parent efbb59f085
commit 859ed2c730
13 changed files with 446 additions and 377 deletions

View File

@ -17,9 +17,9 @@ type TopicListHolder struct {
}
type TopicListInt interface {
GetListByCanSee(canSee []int, page int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
GetListByGroup(group *Group, page int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
GetList(page int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
GetListByCanSee(canSee []int, page int, orderby string) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
GetListByGroup(group *Group, page int, orderby string) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
GetList(page int, orderby string) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
RebuildPermTree() error
}
@ -72,7 +72,7 @@ func (tList *DefaultTopicList) Tick() error {
var canSeeHolders = make(map[string]*TopicListHolder)
for name, canSee := range tList.permTree.Load().(map[string][]int) {
topicList, forumList, paginator, err := tList.GetListByCanSee(canSee, 1)
topicList, forumList, paginator, err := tList.GetListByCanSee(canSee, 1, "")
if err != nil {
return err
}
@ -128,12 +128,12 @@ func (tList *DefaultTopicList) RebuildPermTree() error {
return nil
}
func (tList *DefaultTopicList) GetListByGroup(group *Group, page int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) {
func (tList *DefaultTopicList) GetListByGroup(group *Group, page int, orderby string) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) {
if page == 0 {
page = 1
}
// TODO: Cache the first three pages not just the first along with all the topics on this beaten track
if page == 1 {
if page == 1 && orderby == "" {
var holder *TopicListHolder
var ok bool
if group.ID%2 == 0 {
@ -152,10 +152,10 @@ func (tList *DefaultTopicList) GetListByGroup(group *Group, page int) (topicList
// TODO: Make CanSee a method on *Group with a canSee field? Have a CanSee method on *User to cover the case of superadmins?
//log.Printf("deoptimising for %d on page %d\n", group.ID, page)
return tList.GetListByCanSee(group.CanSee, page)
return tList.GetListByCanSee(group.CanSee, page, orderby)
}
func (tList *DefaultTopicList) GetListByCanSee(canSee []int, page int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) {
func (tList *DefaultTopicList) GetListByCanSee(canSee []int, page int, orderby string) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) {
// We need a list of the visible forums for Quick Topic
// ? - Would it be useful, if we could post in social groups from /topics/?
for _, fid := range canSee {
@ -174,12 +174,12 @@ func (tList *DefaultTopicList) GetListByCanSee(canSee []int, page int) (topicLis
return topicList, forumList, Paginator{[]int{}, 1, 1}, nil
}
topicList, paginator, err = tList.getList(page, argList, qlist)
topicList, paginator, err = tList.getList(page, orderby, argList, qlist)
return topicList, forumList, paginator, err
}
// TODO: Reduce the number of returns
func (tList *DefaultTopicList) GetList(page int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) {
func (tList *DefaultTopicList) GetList(page int, orderby string) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) {
// TODO: Make CanSee a method on *Group with a canSee field? Have a CanSee method on *User to cover the case of superadmins?
canSee, err := Forums.GetAllVisibleIDs()
if err != nil {
@ -204,20 +204,27 @@ func (tList *DefaultTopicList) GetList(page int) (topicList []*TopicsRow, forumL
return topicList, forumList, Paginator{[]int{}, 1, 1}, err
}
topicList, paginator, err = tList.getList(page, argList, qlist)
topicList, paginator, err = tList.getList(page, orderby, argList, qlist)
return topicList, forumList, paginator, err
}
// TODO: Rename this to TopicListStore and pass back a TopicList instance holding the pagination data and topic list rather than passing them back one argument at a time
func (tList *DefaultTopicList) getList(page int, argList []interface{}, qlist string) (topicList []*TopicsRow, paginator Paginator, err error) {
func (tList *DefaultTopicList) getList(page int, orderby string, argList []interface{}, qlist string) (topicList []*TopicsRow, paginator Paginator, err error) {
topicCount, err := ArgQToTopicCount(argList, qlist)
if err != nil {
return nil, Paginator{nil, 1, 1}, err
}
offset, page, lastPage := PageOffset(topicCount, page, Config.ItemsPerPage)
var orderq string
if orderby == "most-viewed" {
orderq = "views DESC, lastReplyAt DESC, createdBy DESC"
} else {
orderq = "sticky DESC, lastReplyAt DESC, createdBy DESC"
}
// TODO: Prepare common qlist lengths to speed this up in common cases, prepared statements are prepared lazily anyway, so it probably doesn't matter if we do ten or so
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", "?,?")
stmt, err := qgen.Builder.SimpleSelect("topics", "tid, title, content, createdBy, is_closed, sticky, createdAt, lastReplyAt, lastReplyBy, parentID, views, postCount, likeCount", "parentID IN("+qlist+")", orderq, "?,?")
if err != nil {
return nil, Paginator{nil, 1, 1}, err
}

View File

@ -49,7 +49,7 @@ func (hub *WsHubImpl) Start() {
func (hub *WsHubImpl) Tick() error {
// Don't waste CPU time if nothing has happened
// TODO: Get a topic list method which strips stickies?
tList, _, _, err := TopicList.GetList(1)
tList, _, _, err := TopicList.GetList(1, "")
if err != nil {
hub.lastTick = time.Now()
return err // TODO: Do we get ErrNoRows here?
@ -117,7 +117,7 @@ func (hub *WsHubImpl) Tick() error {
var canSeeRenders = make(map[string][]byte)
for name, canSee := range canSeeMap {
topicList, forumList, _, err := TopicList.GetListByCanSee(canSee, 1)
topicList, forumList, _, err := TopicList.GetListByCanSee(canSee, 1, "")
if err != nil {
return err // TODO: Do we get ErrNoRows here?
}

File diff suppressed because it is too large Load Diff

View File

@ -441,6 +441,9 @@
"topic_list.move_head":"Move these topics to?",
"topic_list.move_button":"Move Topics",
"topic_list.changed_topics":"Click to see %d new or changed topics",
"topic_list.replies_suffix":"replies",
"topic_list.likes_suffix":"likes",
"topic_list.views_suffix":"views",
"status.closed_tooltip":"Status: Closed",
"status.pinned_tooltip":"Status: Pinned",

View File

@ -358,6 +358,12 @@ function mainInit(){
});
});
$(".link_label").click(function(event) {
event.preventDefault();
let forSelect = $(this).attr("data-for");
$('#'+forSelect).addClass("link_opened");
});
$(".open_edit").click((event) => {
event.preventDefault();
$('.hide_on_edit').addClass("edit_opened");

View File

@ -27,6 +27,7 @@ func routes() {
topicGroup := newRouteGroup("/topics/",
View("routes.TopicList", "/topics/"),
View("routes.TopicListMostViewed", "/topics/most-viewed/"),
MemberView("routes.CreateTopic", "/topics/create/", "extraData"),
)
addRouteGroup(topicGroup)

View File

@ -31,9 +31,9 @@ func TopicList(w http.ResponseWriter, r *http.Request, user common.User) common.
var forumList []common.Forum
var paginator common.Paginator
if user.IsSuperAdmin {
topicList, forumList, paginator, err = common.TopicList.GetList(page)
topicList, forumList, paginator, err = common.TopicList.GetList(page, "")
} else {
topicList, forumList, paginator, err = common.TopicList.GetListByGroup(group, page)
topicList, forumList, paginator, err = common.TopicList.GetListByGroup(group, page, "")
}
if err != nil {
return common.InternalError(err, w, r)
@ -54,3 +54,50 @@ func TopicList(w http.ResponseWriter, r *http.Request, user common.User) common.
}
return nil
}
func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user)
if ferr != nil {
return ferr
}
header.Title = common.GetTitlePhrase("topics")
header.Zone = "topics"
header.MetaDesc = header.Settings["meta_desc"].(string)
group, err := common.Groups.Get(user.Group)
if err != nil {
log.Printf("Group #%d doesn't exist despite being used by common.User #%d", user.Group, user.ID)
return common.LocalError("Something weird happened", w, r, user)
}
// Get the current page
page, _ := strconv.Atoi(r.FormValue("page"))
// TODO: Pass a struct back rather than passing back so many variables
var topicList []*common.TopicsRow
var forumList []common.Forum
var paginator common.Paginator
if user.IsSuperAdmin {
topicList, forumList, paginator, err = common.TopicList.GetList(page, "most-viewed")
} else {
topicList, forumList, paginator, err = common.TopicList.GetListByGroup(group, page, "most-viewed")
}
if err != nil {
return common.InternalError(err, w, r)
}
// ! Need an inline error not a page level error
if len(topicList) == 0 {
return common.NotFound(w, r, header)
}
pi := common.TopicListPage{header, topicList, forumList, common.Config.DefaultForum, common.TopicListSort{"mostviewed", false}, paginator}
if common.RunPreRenderHook("pre_render_topic_list", w, r, &user, &pi) {
return nil
}
err = common.RunThemeTemplate(header.Theme.Name, "topics", pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
}

View File

@ -7,8 +7,8 @@
<div class="optbox">
{{if .ForumList}}
<div class="opt filter_opt">
<a href="#" class="filter_opt_label"> / Most Recent <span class="filter_opt_pointy"></span></a>
<div class="link_select">
<a href="#" class="filter_opt_label link_label" data-for="topic_list_filter_select"> / Most Recent <span class="filter_opt_pointy"></span></a>
<div id="topic_list_filter_select" class="link_select">
<div class="link_option link_selected">
<a href="/topics/">Most Recent</a>
</div>
@ -115,7 +115,7 @@
<div class="rowblock more_topic_block more_topic_block_initial">
<div class="rowitem rowmsg"><a href="" class="more_topics"></a></div>
</div>
<div id="topic_list" class="rowblock topic_list" aria-label="{{lang "topics_list_aria"}}">
<div id="topic_list" class="rowblock topic_list topic_list_{{.Sort.SortBy}}" aria-label="{{lang "topics_list_aria"}}">
{{range .TopicList}}{{template "topics_topic.html" . }}{{else}}<div class="rowitem passive rowmsg">{{lang "topics_no_topics"}}{{if .CurrentUser.Perms.CreateTopic}} <a href="/topics/create/">{{lang "topics_start_one"}}</a>{{end}}</div>{{end}}
</div>

View File

@ -17,8 +17,9 @@
</div>
<div class="topic_middle">
<div class="topic_middle_inside rowsmall">
<span class="replyCount">{{.PostCount}}</span><br />
<span class="likeCount">{{.LikeCount}}</span>
<span class="replyCount">{{.PostCount}}&nbsp;{{lang "topic_list.replies_suffix"}}</span>
<span class="likeCount">{{.LikeCount}}&nbsp;{{lang "topic_list.likes_suffix"}}</span>
<span class="viewCount">{{.ViewCount}}&nbsp;{{lang "topic_list.views_suffix"}}</span>
</div>
</div>
<div class="rowitem topic_right passive datarow">

View File

@ -534,7 +534,7 @@ input[type=checkbox]:checked + label .sel {
.pollinput:not(:only-child):not(:first-child) {
margin-bottom: 5px;
}
.auto_hide, .show_on_edit:not(.edit_opened), .hide_on_edit.edit_opened {
.auto_hide, .show_on_edit:not(.edit_opened), .hide_on_edit.edit_opened, .link_select:not(.link_opened) {
display: none;
}
@ -963,11 +963,11 @@ textarea {
font-size: 18px;
}
.topic_forum {
line-height: 23px;
line-height: 24px;
}
.topic_view_count {
margin-left: 6px;
font-size: 13px;
font-size: 14px;
margin-top: 4px;
}
.topic_view_count:before {

View File

@ -318,7 +318,7 @@ h2 {
.more_topic_block_active {
display: block;
}
.hide_ajax_topic, .auto_hide, .show_on_edit:not(.edit_opened), .hide_on_edit.edit_opened {
.hide_ajax_topic, .auto_hide, .show_on_edit:not(.edit_opened), .hide_on_edit.edit_opened, .link_select:not(.link_opened) {
display: none !important;
}
@ -458,15 +458,13 @@ h2 {
.topic_inner_left br, .topic_right_inside br, .topic_inner_right {
display: none;
}
.topic_middle .replyCount:after {
content: "replies";
margin-left: 3px;
}
.topic_middle .likeCount:after {
content: "likes";
margin-left: 3px;
.topic_list:not(.topic_list_mostviewed) .topic_middle .viewCount,
.topic_list_mostviewed .topic_middle .likeCount {
display: none;
}
.topic_middle_inside {
display: flex;
flex-direction: column;
margin-left: auto;
margin-right: auto;
margin-top: -3px;

View File

@ -208,7 +208,7 @@ a {
float: left;
width: calc(70% - 24px);
}
.colstack_left:empty, .colstack_right:empty, .show_on_edit:not(.edit_opened), .hide_on_edit.edit_opened {
.colstack_left:empty, .colstack_right:empty, .show_on_edit:not(.edit_opened), .hide_on_edit.edit_opened, .link_select:not(.link_opened) {
display: none;
}

View File

@ -739,7 +739,7 @@ button.username {
.mention {
font-weight: bold;
}
.show_on_edit:not(.edit_opened), .hide_on_edit.edit_opened, .auto_hide, .hide_on_big, .show_on_mobile {
.show_on_edit:not(.edit_opened), .hide_on_edit.edit_opened, .auto_hide, .hide_on_big, .show_on_mobile, .link_select:not(.link_opened) {
display: none;
}