Highlight the currently active zone in the menu for Nox.

Replaced the Level Progress widget in the Account Dashboard with a similar progressbar to the one in the level progress page.
This commit is contained in:
Azareal 2018-10-14 15:08:44 +10:00
parent c451358156
commit aabfbe3622
13 changed files with 112 additions and 94 deletions

View File

@ -7,6 +7,7 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"strconv" "strconv"
"strings"
"../query_gen/lib" "../query_gen/lib"
) )
@ -19,9 +20,15 @@ type MenuListHolder struct {
Variations map[int]menuTmpl // 0 = Guest Menu, 1 = Member Menu, 2 = Super Mod Menu, 3 = Admin Menu Variations map[int]menuTmpl // 0 = Guest Menu, 1 = Member Menu, 2 = Super Mod Menu, 3 = Admin Menu
} }
type menuPath struct {
Path string
Index int
}
type menuTmpl struct { type menuTmpl struct {
RenderBuffer [][]byte RenderBuffer [][]byte
VariableIndices []int VariableIndices []int
PathMappings []menuPath
} }
type MenuItem struct { type MenuItem struct {
@ -135,11 +142,8 @@ func (hold *MenuListHolder) Preparse() error {
} }
var addVariation = func(index int, callback func(mitem MenuItem) bool) { var addVariation = func(index int, callback func(mitem MenuItem) bool) {
renderBuffer, variableIndices := hold.Scan(tmpls, callback) renderBuffer, variableIndices, pathList := hold.Scan(tmpls, callback)
hold.Variations[index] = menuTmpl{renderBuffer, variableIndices} hold.Variations[index] = menuTmpl{renderBuffer, variableIndices, pathList}
//fmt.Print("renderBuffer: ")
//menuDumpSlice(renderBuffer)
//fmt.Printf("\nvariableIndices: %+v\n", variableIndices)
} }
// Guest Menu // Guest Menu
@ -202,15 +206,11 @@ func skipUntilCharsExist(tmplData []byte, i int, expects []byte) (newI int, hasI
func skipAllUntilCharsExist(tmplData []byte, i int, expects []byte) (newI int, hasIt bool) { func skipAllUntilCharsExist(tmplData []byte, i int, expects []byte) (newI int, hasIt bool) {
j := i j := i
expectIndex := 0 expectIndex := 0
//fmt.Printf("tmplData: %+v\n", string(tmplData))
for ; j < len(tmplData) && expectIndex < len(expects); j++ { for ; j < len(tmplData) && expectIndex < len(expects); j++ {
//fmt.Println("j: ", j)
//fmt.Println("tmplData[j]: ", string(tmplData[j])+" ")
if tmplData[j] == expects[expectIndex] { if tmplData[j] == expects[expectIndex] {
//fmt.Printf("expects[expectIndex]: %+v - %d\n", string(expects[expectIndex]), expectIndex) //fmt.Printf("expects[expectIndex]: %+v - %d\n", string(expects[expectIndex]), expectIndex)
expectIndex++ expectIndex++
if len(expects) <= expectIndex { if len(expects) <= expectIndex {
//fmt.Println("breaking")
break break
} }
} else { } else {
@ -226,8 +226,6 @@ func skipAllUntilCharsExist(tmplData []byte, i int, expects []byte) (newI int, h
expectIndex = 0 expectIndex = 0
} }
} }
//fmt.Println("len(expects): ", len(expects))
//fmt.Println("expectIndex: ", expectIndex)
return j, len(expects) == expectIndex return j, len(expects) == expectIndex
} }
@ -254,19 +252,16 @@ func menuDumpSlice(outerSlice [][]byte) {
} }
func (hold *MenuListHolder) Parse(name string, tmplData []byte) (menuTmpl MenuTmpl) { func (hold *MenuListHolder) Parse(name string, tmplData []byte) (menuTmpl MenuTmpl) {
//fmt.Println("tmplData: ", string(tmplData))
var textBuffer, variableBuffer [][]byte var textBuffer, variableBuffer [][]byte
var renderList []menuRenderItem var renderList []menuRenderItem
var subBuffer []byte var subBuffer []byte
// ? We only support simple properties on MenuItem right now // ? We only support simple properties on MenuItem right now
var addVariable = func(name []byte) { var addVariable = func(name []byte) {
//fmt.Println("appending subBuffer: ", string(subBuffer))
// TODO: Check if the subBuffer has any items or is empty // TODO: Check if the subBuffer has any items or is empty
textBuffer = append(textBuffer, subBuffer) textBuffer = append(textBuffer, subBuffer)
subBuffer = nil subBuffer = nil
//fmt.Println("adding variable: ", string(name))
variableBuffer = append(variableBuffer, name) variableBuffer = append(variableBuffer, name)
renderList = append(renderList, menuRenderItem{0, len(textBuffer) - 1}) renderList = append(renderList, menuRenderItem{0, len(textBuffer) - 1})
renderList = append(renderList, menuRenderItem{1, len(variableBuffer) - 1}) renderList = append(renderList, menuRenderItem{1, len(variableBuffer) - 1})
@ -277,10 +272,8 @@ func (hold *MenuListHolder) Parse(name string, tmplData []byte) (menuTmpl MenuTm
for i := 0; i < len(tmplData); i++ { for i := 0; i < len(tmplData); i++ {
char := tmplData[i] char := tmplData[i]
if char == '{' { if char == '{' {
//fmt.Println("found open fence")
dotIndex, hasDot := skipUntilIfExists(tmplData, i, '.') dotIndex, hasDot := skipUntilIfExists(tmplData, i, '.')
if !hasDot { if !hasDot {
//fmt.Println("no dot, assumed template function style")
// Template function style // Template function style
langIndex, hasChars := skipUntilCharsExist(tmplData, i+1, []byte("lang")) langIndex, hasChars := skipUntilCharsExist(tmplData, i+1, []byte("lang"))
if hasChars { if hasChars {
@ -302,7 +295,6 @@ func (hold *MenuListHolder) Parse(name string, tmplData []byte) (menuTmpl MenuTm
} }
fenceIndex, hasFence := skipUntilIfExists(tmplData, dotIndex, '}') fenceIndex, hasFence := skipUntilIfExists(tmplData, dotIndex, '}')
if !hasFence { if !hasFence {
//fmt.Println("no end fence")
break break
} }
addVariable(tmplData[dotIndex:fenceIndex]) addVariable(tmplData[dotIndex:fenceIndex])
@ -317,25 +309,21 @@ func (hold *MenuListHolder) Parse(name string, tmplData []byte) (menuTmpl MenuTm
renderList = append(renderList, menuRenderItem{0, len(textBuffer) - 1}) renderList = append(renderList, menuRenderItem{0, len(textBuffer) - 1})
} }
//fmt.Println("name: ", name)
//fmt.Print("textBuffer: ")
//menuDumpSlice(textBuffer)
//fmt.Print("\nvariableBuffer: ")
//menuDumpSlice(variableBuffer)
//fmt.Printf("\nrenderList: %+v\n", renderList)
return MenuTmpl{name, textBuffer, variableBuffer, renderList} return MenuTmpl{name, textBuffer, variableBuffer, renderList}
} }
func (hold *MenuListHolder) Scan(menuTmpls map[string]MenuTmpl, showItem func(mitem MenuItem) bool) (renderBuffer [][]byte, variableIndices []int) { func (hold *MenuListHolder) Scan(menuTmpls map[string]MenuTmpl, showItem func(mitem MenuItem) bool) (renderBuffer [][]byte, variableIndices []int, pathList []menuPath) {
for _, mitem := range hold.List { for _, mitem := range hold.List {
// Do we want this item in this variation of the menu? // Do we want this item in this variation of the menu?
if !showItem(mitem) { if !showItem(mitem) {
continue continue
} }
renderBuffer, variableIndices = hold.ScanItem(menuTmpls, mitem, renderBuffer, variableIndices) renderBuffer, variableIndices = hold.ScanItem(menuTmpls, mitem, renderBuffer, variableIndices)
pathList = append(pathList, menuPath{mitem.Path, len(renderBuffer) - 1})
} }
// TODO: Need more coalescing in the renderBuffer // TODO: Need more coalescing in the renderBuffer
return renderBuffer, variableIndices return renderBuffer, variableIndices, pathList
} }
// Note: This doesn't do a visibility check like hold.Scan() does // Note: This doesn't do a visibility check like hold.Scan() does
@ -345,7 +333,6 @@ func (hold *MenuListHolder) ScanItem(menuTmpls map[string]MenuTmpl, mitem MenuIt
menuTmpl = menuTmpls["menu_item"] menuTmpl = menuTmpls["menu_item"]
} }
//fmt.Println("menuTmpl: ", menuTmpl)
for _, renderItem := range menuTmpl.RenderList { for _, renderItem := range menuTmpl.RenderList {
if renderItem.Type == 0 { if renderItem.Type == 0 {
renderBuffer = append(renderBuffer, menuTmpl.TextBuffer[renderItem.Index]) renderBuffer = append(renderBuffer, menuTmpl.TextBuffer[renderItem.Index])
@ -353,72 +340,70 @@ func (hold *MenuListHolder) ScanItem(menuTmpls map[string]MenuTmpl, mitem MenuIt
} }
variable := menuTmpl.VariableBuffer[renderItem.Index] variable := menuTmpl.VariableBuffer[renderItem.Index]
//fmt.Println("initial variable: ", string(variable))
dotAt, hasDot := skipUntilIfExists(variable, 0, '.') dotAt, hasDot := skipUntilIfExists(variable, 0, '.')
if !hasDot { if !hasDot {
//fmt.Println("no dot")
continue continue
} }
if bytes.Equal(variable[:dotAt], []byte("lang")) { if bytes.Equal(variable[:dotAt], []byte("lang")) {
//fmt.Println("lang: ", string(bytes.TrimPrefix(variable[dotAt:], []byte("."))))
renderBuffer = append(renderBuffer, []byte(GetTmplPhrase(string(bytes.TrimPrefix(variable[dotAt:], []byte(".")))))) renderBuffer = append(renderBuffer, []byte(GetTmplPhrase(string(bytes.TrimPrefix(variable[dotAt:], []byte("."))))))
} else { continue
var renderItem []byte }
switch string(variable) {
case ".ID":
renderItem = []byte(strconv.Itoa(mitem.ID))
case ".Name":
renderItem = []byte(mitem.Name)
case ".HTMLID":
renderItem = []byte(mitem.HTMLID)
case ".CSSClass":
renderItem = []byte(mitem.CSSClass)
case ".Position":
renderItem = []byte(mitem.Position)
case ".Path":
renderItem = []byte(mitem.Path)
case ".Aria":
renderItem = []byte(mitem.Aria)
case ".Tooltip":
renderItem = []byte(mitem.Tooltip)
}
_, hasInnerVar := skipUntilIfExists(renderItem, 0, '{') var renderItem []byte
if hasInnerVar { switch string(variable) {
//fmt.Println("inner var: ", string(renderItem)) case ".ID":
dotAt, hasDot := skipUntilIfExists(renderItem, 0, '.') renderItem = []byte(strconv.Itoa(mitem.ID))
endFence, hasEndFence := skipUntilIfExists(renderItem, dotAt, '}') case ".Name":
if !hasDot || !hasEndFence || (endFence-dotAt) <= 1 { renderItem = []byte(mitem.Name)
renderBuffer = append(renderBuffer, renderItem) case ".HTMLID":
variableIndices = append(variableIndices, len(renderBuffer)-1) renderItem = []byte(mitem.HTMLID)
continue case ".CSSClass":
} renderItem = []byte(mitem.CSSClass)
case ".Position":
renderItem = []byte(mitem.Position)
case ".Path":
renderItem = []byte(mitem.Path)
case ".Aria":
renderItem = []byte(mitem.Aria)
case ".Tooltip":
renderItem = []byte(mitem.Tooltip)
case ".CSSActive":
renderItem = []byte("{dyn.active}")
}
if bytes.Equal(renderItem[1:dotAt], []byte("lang")) { _, hasInnerVar := skipUntilIfExists(renderItem, 0, '{')
//fmt.Println("lang var: ", string(renderItem[dotAt+1:endFence])) if hasInnerVar {
renderBuffer = append(renderBuffer, []byte(GetTmplPhrase(string(renderItem[dotAt+1:endFence])))) fmt.Println("inner var: ", string(renderItem))
} else { dotAt, hasDot := skipUntilIfExists(renderItem, 0, '.')
//fmt.Println("other var: ", string(variable[:dotAt])) endFence, hasEndFence := skipUntilIfExists(renderItem, dotAt, '}')
if len(renderItem) > 0 { if !hasDot || !hasEndFence || (endFence-dotAt) <= 1 {
renderBuffer = append(renderBuffer, renderItem) renderBuffer = append(renderBuffer, renderItem)
variableIndices = append(variableIndices, len(renderBuffer)-1) variableIndices = append(variableIndices, len(renderBuffer)-1)
}
}
continue continue
} }
//fmt.Println("normal var: ", string(variable[:dotAt])) if bytes.Equal(renderItem[1:dotAt], []byte("lang")) {
if len(renderItem) > 0 { //fmt.Println("lang var: ", string(renderItem[dotAt+1:endFence]))
renderBuffer = append(renderBuffer, renderItem) renderBuffer = append(renderBuffer, []byte(GetTmplPhrase(string(renderItem[dotAt+1:endFence]))))
} else {
fmt.Println("other var: ", string(variable[:dotAt]))
if len(renderItem) > 0 {
renderBuffer = append(renderBuffer, renderItem)
variableIndices = append(variableIndices, len(renderBuffer)-1)
}
} }
continue
}
if len(renderItem) > 0 {
renderBuffer = append(renderBuffer, renderItem)
} }
} }
return renderBuffer, variableIndices return renderBuffer, variableIndices
} }
// TODO: Pre-render the lang stuff // TODO: Pre-render the lang stuff
func (hold *MenuListHolder) Build(w io.Writer, user *User) error { func (hold *MenuListHolder) Build(w io.Writer, user *User, pathPrefix string) error {
var mTmpl menuTmpl var mTmpl menuTmpl
if !user.Loggedin { if !user.Loggedin {
mTmpl = hold.Variations[0] mTmpl = hold.Variations[0]
@ -429,11 +414,12 @@ func (hold *MenuListHolder) Build(w io.Writer, user *User) error {
} else { } else {
mTmpl = hold.Variations[1] mTmpl = hold.Variations[1]
} }
if pathPrefix == "" {
pathPrefix = Config.DefaultPath
}
if len(mTmpl.VariableIndices) == 0 { if len(mTmpl.VariableIndices) == 0 {
//fmt.Println("no variable indices")
for _, renderItem := range mTmpl.RenderBuffer { for _, renderItem := range mTmpl.RenderBuffer {
//fmt.Printf("renderItem: %+v\n", renderItem)
w.Write(renderItem) w.Write(renderItem)
} }
return nil return nil
@ -442,17 +428,15 @@ func (hold *MenuListHolder) Build(w io.Writer, user *User) error {
var nearIndex = 0 var nearIndex = 0
for index, renderItem := range mTmpl.RenderBuffer { for index, renderItem := range mTmpl.RenderBuffer {
if index != mTmpl.VariableIndices[nearIndex] { if index != mTmpl.VariableIndices[nearIndex] {
//fmt.Println("wrote text: ", string(renderItem))
w.Write(renderItem) w.Write(renderItem)
continue continue
} }
//fmt.Println("variable: ", string(renderItem))
variable := renderItem variable := renderItem
// ? - I can probably remove this check now that I've kicked it upstream, or we could keep it here for safety's sake? // ? - I can probably remove this check now that I've kicked it upstream, or we could keep it here for safety's sake?
if len(variable) == 0 { if len(variable) == 0 {
continue continue
} }
prevIndex := 0 prevIndex := 0
for i := 0; i < len(renderItem); i++ { for i := 0; i < len(renderItem); i++ {
fenceStart, hasFence := skipUntilIfExists(variable, i, '{') fenceStart, hasFence := skipUntilIfExists(variable, i, '{')
@ -469,9 +453,9 @@ func (hold *MenuListHolder) Build(w io.Writer, user *User) error {
if !hasDot { if !hasDot {
continue continue
} }
//fmt.Println("checking me: ", string(variable[fenceStart+1:dotAt]))
if bytes.Equal(variable[fenceStart+1:dotAt], []byte("me")) { switch string(variable[fenceStart+1 : dotAt]) {
//fmt.Println("maybe me variable") case "me":
w.Write(variable[prevIndex:fenceStart]) w.Write(variable[prevIndex:fenceStart])
switch string(variable[dotAt+1 : fenceEnd]) { switch string(variable[dotAt+1 : fenceEnd]) {
case "Link": case "Link":
@ -479,11 +463,32 @@ func (hold *MenuListHolder) Build(w io.Writer, user *User) error {
case "Session": case "Session":
w.Write([]byte(user.Session)) w.Write([]byte(user.Session))
} }
prevIndex = fenceEnd
// TODO: Optimise this
case "dyn":
w.Write(variable[prevIndex:fenceStart])
var pmi int
for ii, pathItem := range mTmpl.PathMappings {
pmi = ii
if pathItem.Index > index {
break
}
}
if len(mTmpl.PathMappings) != 0 {
path := mTmpl.PathMappings[pmi].Path
if path == "" || path == "/" {
path = Config.DefaultPath
}
if strings.HasPrefix(path, pathPrefix) {
w.Write([]byte(" menu_active"))
}
}
prevIndex = fenceEnd prevIndex = fenceEnd
} }
} }
//fmt.Println("prevIndex: ", prevIndex)
//fmt.Println("len(variable)-1: ", len(variable)-1)
w.Write(variable[prevIndex : len(variable)-1]) w.Write(variable[prevIndex : len(variable)-1])
if len(mTmpl.VariableIndices) > (nearIndex + 1) { if len(mTmpl.VariableIndices) > (nearIndex + 1) {
nearIndex++ nearIndex++

View File

@ -24,6 +24,7 @@ type Header struct {
//TemplateName string // TODO: Use this to move template calls to the router rather than duplicating them over and over and over? //TemplateName string // TODO: Use this to move template calls to the router rather than duplicating them over and over and over?
CurrentUser User // TODO: Deprecate CurrentUser on the page structs and use a pointer here CurrentUser User // TODO: Deprecate CurrentUser on the page structs and use a pointer here
Zone string Zone string
Path string
MetaDesc string MetaDesc string
Writer http.ResponseWriter Writer http.ResponseWriter
ExtData ExtData ExtData ExtData
@ -158,6 +159,7 @@ type AccountDashPage struct {
CurrentScore int CurrentScore int
NextScore int NextScore int
NextLevel int NextLevel int
Percentage int
} }
type LevelListItem struct { type LevelListItem struct {

View File

@ -239,6 +239,14 @@ func GetTitlePhrase(name string) string {
return res return res
} }
func GetTitlePhrasef(name string, params ...interface{}) string {
res, ok := currentLangPack.Load().(*LanguagePack).PageTitles[name]
if !ok {
return getPhrasePlaceholder("title", name)
}
return fmt.Sprintf(res, params...)
}
func GetTmplPhrase(name string) string { func GetTmplPhrase(name string) string {
res, ok := currentLangPack.Load().(*LanguagePack).TmplPhrases[name] res, ok := currentLangPack.Load().(*LanguagePack).TmplPhrases[name]
if !ok { if !ok {

View File

@ -136,7 +136,7 @@ func BuildWidget(dock string, header *Header) (sbody string) {
// 1 = id for the default menu // 1 = id for the default menu
mhold, err := Menus.Get(1) mhold, err := Menus.Get(1)
if err == nil { if err == nil {
err := mhold.Build(header.Writer, &header.CurrentUser) err := mhold.Build(header.Writer, &header.CurrentUser, header.Path)
if err != nil { if err != nil {
LogError(err) LogError(err)
} }

View File

@ -93,7 +93,7 @@ func afterDBInit() (err error) {
} }
fmt.Printf("menuHold: %+v\n", menuHold) fmt.Printf("menuHold: %+v\n", menuHold)
var b bytes.Buffer var b bytes.Buffer
menuHold.Build(&b, &common.GuestUser) menuHold.Build(&b, &common.GuestUser, "/")
fmt.Println("menuHold output: ", string(b.Bytes())) fmt.Println("menuHold output: ", string(b.Bytes()))
log.Print("Initialising the authentication system") log.Print("Initialising the authentication system")

View File

@ -362,6 +362,7 @@ func accountEditHead(titlePhrase string, w http.ResponseWriter, r *http.Request,
return nil, ferr return nil, ferr
} }
header.Title = common.GetTitlePhrase(titlePhrase) header.Title = common.GetTitlePhrase(titlePhrase)
header.Path = "/user/edit/"
header.AddSheet(header.Theme.Name + "/account.css") header.AddSheet(header.Theme.Name + "/account.css")
header.AddScript("account.js") header.AddScript("account.js")
return header, nil return header, nil
@ -394,8 +395,9 @@ func AccountEdit(w http.ResponseWriter, r *http.Request, user common.User) commo
prevScore := common.GetLevelScore(user.Level) prevScore := common.GetLevelScore(user.Level)
currentScore := user.Score - prevScore currentScore := user.Score - prevScore
nextScore := common.GetLevelScore(user.Level+1) - prevScore nextScore := common.GetLevelScore(user.Level+1) - prevScore
perc := int(math.Ceil((float64(nextScore) / float64(currentScore)) * 100))
pi := common.AccountDashPage{header, mfaSetup, currentScore, nextScore, user.Level + 1} pi := common.AccountDashPage{header, mfaSetup, currentScore, nextScore, user.Level + 1, perc * 2}
if common.RunPreRenderHook("pre_render_account_own_edit", w, r, &user, &pi) { if common.RunPreRenderHook("pre_render_account_own_edit", w, r, &user, &pi) {
return nil return nil
} }

View File

@ -14,6 +14,7 @@ func ForumList(w http.ResponseWriter, r *http.Request, user common.User) common.
} }
header.Title = common.GetTitlePhrase("forums") header.Title = common.GetTitlePhrase("forums")
header.Zone = "forums" header.Zone = "forums"
header.Path = "/forums/"
header.MetaDesc = header.Settings["meta_desc"].(string) header.MetaDesc = header.Settings["meta_desc"].(string)
var err error var err error

View File

@ -27,6 +27,7 @@ func init() {
}) })
} }
// TODO: Remove the View part of the name?
func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
header, ferr := common.UserCheck(w, r, &user) header, ferr := common.UserCheck(w, r, &user)
if ferr != nil { if ferr != nil {
@ -68,6 +69,7 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User) commo
} }
// TODO: Add a phrase for this title // TODO: Add a phrase for this title
header.Title = puser.Name + "'s Profile" header.Title = puser.Name + "'s Profile"
header.Path = common.BuildProfileURL(common.NameToSlug(puser.Name), puser.ID)
// Get the replies.. // Get the replies..
rows, err := profileStmts.getReplies.Query(puser.ID) rows, err := profileStmts.getReplies.Query(puser.ID)

View File

@ -59,18 +59,17 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user common.User, urlBit
return common.InternalError(err, w, r) return common.InternalError(err, w, r)
} }
topic.ClassName = "" topic.ClassName = ""
//log.Printf("topic: %+v\n", topic)
header, ferr := common.ForumUserCheck(w, r, &user, topic.ParentID) header, ferr := common.ForumUserCheck(w, r, &user, topic.ParentID)
if ferr != nil { if ferr != nil {
return ferr return ferr
} }
if !user.Perms.ViewTopic { if !user.Perms.ViewTopic {
//log.Printf("user.Perms: %+v\n", user.Perms)
return common.NoPermissions(w, r, user) return common.NoPermissions(w, r, user)
} }
header.Title = topic.Title header.Title = topic.Title
header.Zone = "view_topic" header.Zone = "view_topic"
header.Path = common.BuildTopicURL(common.NameToSlug(topic.Title), topic.ID)
topic.ContentHTML = common.ParseMessage(topic.Content, topic.ParentID, "forums") topic.ContentHTML = common.ParseMessage(topic.Content, topic.ParentID, "forums")
topic.ContentLines = strings.Count(topic.Content, "\n") topic.ContentLines = strings.Count(topic.Content, "\n")

View File

@ -15,6 +15,7 @@ func TopicList(w http.ResponseWriter, r *http.Request, user common.User) common.
} }
header.Title = common.GetTitlePhrase("topics") header.Title = common.GetTitlePhrase("topics")
header.Zone = "topics" header.Zone = "topics"
header.Path = "/topics/"
header.MetaDesc = header.Settings["meta_desc"].(string) header.MetaDesc = header.Settings["meta_desc"].(string)
group, err := common.Groups.Get(user.Group) group, err := common.Groups.Get(user.Group)
@ -62,6 +63,7 @@ func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user common.Use
} }
header.Title = common.GetTitlePhrase("topics") header.Title = common.GetTitlePhrase("topics")
header.Zone = "topics" header.Zone = "topics"
header.Path = "/topics/"
header.MetaDesc = header.Settings["meta_desc"].(string) header.MetaDesc = header.Settings["meta_desc"].(string)
group, err := common.Groups.Get(user.Group) group, err := common.Groups.Get(user.Group)

View File

@ -21,14 +21,11 @@
</div> </div>
<div id="dash_right" class="coldyn_item"> <div id="dash_right" class="coldyn_item">
<div class="rowitem">{{if not .MFASetup}}<a href="/user/edit/mfa/setup/">{{lang "account_dash_2fa_setup"}}</a>{{else}}<a href="/user/edit/mfa/">{{lang "account_dash_2fa_manage"}}</a>{{end}} <span class="dash_security">{{lang "account_dash_security_notice"}}</span></div> <div class="rowitem">{{if not .MFASetup}}<a href="/user/edit/mfa/setup/">{{lang "account_dash_2fa_setup"}}</a>{{else}}<a href="/user/edit/mfa/">{{lang "account_dash_2fa_manage"}}</a>{{end}} <span class="dash_security">{{lang "account_dash_security_notice"}}</span></div>
<!--<div class="rowitem">
<a href="/user/levels/">{{level .CurrentUser.Level}}: [{{.CurrentScore}} / {{.NextScore}}]</a> <span class="account_soon">{{lang "account_coming_soon"}}</span>
</div>-->
<div class="rowitem level_inprogress"> <div class="rowitem level_inprogress">
<div class="levelBit"> <div class="levelBit">
<a href="/user/levels/">{{level .CurrentUser.Level}}</a> <a href="/user/levels/">{{level .CurrentUser.Level}}</a>
</div> </div>
<div class="progressWrap" style="width: 180%;"> <div class="progressWrap" style="width: {{.Percentage}}%;">
<div>{{.CurrentScore}} / {{.NextScore}}</div> <div>{{.CurrentScore}} / {{.NextScore}}</div>
</div> </div>
</div> </div>

View File

@ -29,7 +29,7 @@
<nav class="nav"> <nav class="nav">
<div class="move_left"> <div class="move_left">
<div class="move_right"> <div class="move_right">
<ul>{{/** TODO: Have the theme control whether the long or short form of the name is used **/}} <ul class="zone_{{.Header.Zone}}">{{/** TODO: Have the theme control whether the long or short form of the name is used **/}}
<li id="menu_overview" class="menu_left"><a href="/" rel="home">{{if eq .Header.Theme.Name "nox"}}{{.Header.Site.Name}}{{else}}{{.Header.Site.ShortName}}{{end}}</a></li> <li id="menu_overview" class="menu_left"><a href="/" rel="home">{{if eq .Header.Theme.Name "nox"}}{{.Header.Site.Name}}{{else}}{{.Header.Site.ShortName}}{{end}}</a></li>
{{dock "topMenu" .Header }} {{dock "topMenu" .Header }}
<li class="menu_left menu_hamburger" title="{{lang "menu_hamburger_tooltip"}}"><a></a></li> <li class="menu_left menu_hamburger" title="{{lang "menu_hamburger_tooltip"}}"><a></a></li>

View File

@ -1 +1 @@
<li id="{{.HTMLID}}" class="menu_{{.Position}} {{.CSSClass}}"><a href="{{.Path}}" aria-label="{{.Aria}}" title="{{.Tooltip}}">{{.Name}}</a></li> <li id="{{.HTMLID}}" class="menu_{{.Position}} {{.CSSClass}}{{.CSSActive}}"><a href="{{.Path}}" aria-label="{{.Aria}}" title="{{.Tooltip}}">{{.Name}}</a></li>