Added the level list page.
Levels can now be localised individually. Added the level template function. Fixed the padding on alerts without avatars. The level data is now in it's own block in the profiles. Removed three level phrases and replaced them with the new Level API.
This commit is contained in:
parent
de78268b20
commit
05ab585d41
|
@ -160,6 +160,18 @@ type AccountDashPage struct {
|
||||||
NextLevel int
|
NextLevel int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LevelListItem struct {
|
||||||
|
Level int
|
||||||
|
Score int
|
||||||
|
Status string
|
||||||
|
Percentage int // 0 to 200 to fit with the CSS logic
|
||||||
|
}
|
||||||
|
|
||||||
|
type LevelListPage struct {
|
||||||
|
*Header
|
||||||
|
Levels []LevelListItem
|
||||||
|
}
|
||||||
|
|
||||||
type PanelStats struct {
|
type PanelStats struct {
|
||||||
Users int
|
Users int
|
||||||
Groups int
|
Groups int
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -141,6 +142,14 @@ func SaveLangPack(langPack *LanguagePack) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetLevelPhrase(level int) string {
|
||||||
|
levelPhrases := currentLangPack.Load().(*LanguagePack).Levels
|
||||||
|
if len(levelPhrases.Levels) > 0 && level < len(levelPhrases.Levels) {
|
||||||
|
return strings.Replace(levelPhrases.Levels[level], "{0}", strconv.Itoa(level), -1)
|
||||||
|
}
|
||||||
|
return strings.Replace(levelPhrases.Level, "{0}", strconv.Itoa(level), -1)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Merge these two maps?
|
// TODO: Merge these two maps?
|
||||||
func GetGlobalPermPhrase(name string) string {
|
func GetGlobalPermPhrase(name string) string {
|
||||||
res, ok := currentLangPack.Load().(*LanguagePack).GlobalPerms[name]
|
res, ok := currentLangPack.Load().(*LanguagePack).GlobalPerms[name]
|
||||||
|
|
|
@ -511,6 +511,14 @@ func InitTemplates() error {
|
||||||
return GetTmplPhrase(phraseName)
|
return GetTmplPhrase(phraseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmap["level"] = func(levelInt interface{}) interface{} {
|
||||||
|
level, ok := levelInt.(int)
|
||||||
|
if !ok {
|
||||||
|
panic("levelInt is not an integer")
|
||||||
|
}
|
||||||
|
return GetLevelPhrase(level)
|
||||||
|
}
|
||||||
|
|
||||||
fmap["scope"] = func(name interface{}) interface{} {
|
fmap["scope"] = func(name interface{}) interface{} {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,7 @@ func NewCTemplateSet() *CTemplateSet {
|
||||||
"divide": true,
|
"divide": true,
|
||||||
"dock": true,
|
"dock": true,
|
||||||
"lang": true,
|
"lang": true,
|
||||||
|
"level": true,
|
||||||
"scope": true,
|
"scope": true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -715,6 +716,19 @@ ArgLoop:
|
||||||
out = "w.Write(phrases[" + strconv.Itoa(len(c.langIndexToName)-1) + "])\n"
|
out = "w.Write(phrases[" + strconv.Itoa(len(c.langIndexToName)-1) + "])\n"
|
||||||
literal = true
|
literal = true
|
||||||
break ArgLoop
|
break ArgLoop
|
||||||
|
case "level":
|
||||||
|
var leftParam string
|
||||||
|
// TODO: Implement level literals
|
||||||
|
leftOperand := node.Args[pos+1].String()
|
||||||
|
if len(leftOperand) == 0 {
|
||||||
|
panic("The leftoperand for function level cannot be left blank")
|
||||||
|
}
|
||||||
|
|
||||||
|
leftParam, _ = c.compileIfVarsub(leftOperand, varholder, templateName, holdreflect)
|
||||||
|
// TODO: Refactor this
|
||||||
|
out = "w.Write([]byte(common.GetLevelPhrase(" + leftParam + ")))\n"
|
||||||
|
literal = true
|
||||||
|
break ArgLoop
|
||||||
case "scope":
|
case "scope":
|
||||||
literal = true
|
literal = true
|
||||||
break ArgLoop
|
break ArgLoop
|
||||||
|
|
234
gen_router.go
234
gen_router.go
|
@ -113,6 +113,7 @@ var RouteMap = map[string]interface{}{
|
||||||
"routes.AccountEditMFADisableSubmit": routes.AccountEditMFADisableSubmit,
|
"routes.AccountEditMFADisableSubmit": routes.AccountEditMFADisableSubmit,
|
||||||
"routes.AccountEditEmail": routes.AccountEditEmail,
|
"routes.AccountEditEmail": routes.AccountEditEmail,
|
||||||
"routes.AccountEditEmailTokenSubmit": routes.AccountEditEmailTokenSubmit,
|
"routes.AccountEditEmailTokenSubmit": routes.AccountEditEmailTokenSubmit,
|
||||||
|
"routes.LevelList": routes.LevelList,
|
||||||
"routes.ViewProfile": routes.ViewProfile,
|
"routes.ViewProfile": routes.ViewProfile,
|
||||||
"routes.BanUserSubmit": routes.BanUserSubmit,
|
"routes.BanUserSubmit": routes.BanUserSubmit,
|
||||||
"routes.UnbanUser": routes.UnbanUser,
|
"routes.UnbanUser": routes.UnbanUser,
|
||||||
|
@ -244,43 +245,44 @@ var routeMapEnum = map[string]int{
|
||||||
"routes.AccountEditMFADisableSubmit": 87,
|
"routes.AccountEditMFADisableSubmit": 87,
|
||||||
"routes.AccountEditEmail": 88,
|
"routes.AccountEditEmail": 88,
|
||||||
"routes.AccountEditEmailTokenSubmit": 89,
|
"routes.AccountEditEmailTokenSubmit": 89,
|
||||||
"routes.ViewProfile": 90,
|
"routes.LevelList": 90,
|
||||||
"routes.BanUserSubmit": 91,
|
"routes.ViewProfile": 91,
|
||||||
"routes.UnbanUser": 92,
|
"routes.BanUserSubmit": 92,
|
||||||
"routes.ActivateUser": 93,
|
"routes.UnbanUser": 93,
|
||||||
"routes.IPSearch": 94,
|
"routes.ActivateUser": 94,
|
||||||
"routes.CreateTopicSubmit": 95,
|
"routes.IPSearch": 95,
|
||||||
"routes.EditTopicSubmit": 96,
|
"routes.CreateTopicSubmit": 96,
|
||||||
"routes.DeleteTopicSubmit": 97,
|
"routes.EditTopicSubmit": 97,
|
||||||
"routes.StickTopicSubmit": 98,
|
"routes.DeleteTopicSubmit": 98,
|
||||||
"routes.UnstickTopicSubmit": 99,
|
"routes.StickTopicSubmit": 99,
|
||||||
"routes.LockTopicSubmit": 100,
|
"routes.UnstickTopicSubmit": 100,
|
||||||
"routes.UnlockTopicSubmit": 101,
|
"routes.LockTopicSubmit": 101,
|
||||||
"routes.MoveTopicSubmit": 102,
|
"routes.UnlockTopicSubmit": 102,
|
||||||
"routes.LikeTopicSubmit": 103,
|
"routes.MoveTopicSubmit": 103,
|
||||||
"routes.ViewTopic": 104,
|
"routes.LikeTopicSubmit": 104,
|
||||||
"routes.CreateReplySubmit": 105,
|
"routes.ViewTopic": 105,
|
||||||
"routes.ReplyEditSubmit": 106,
|
"routes.CreateReplySubmit": 106,
|
||||||
"routes.ReplyDeleteSubmit": 107,
|
"routes.ReplyEditSubmit": 107,
|
||||||
"routes.ReplyLikeSubmit": 108,
|
"routes.ReplyDeleteSubmit": 108,
|
||||||
"routes.ProfileReplyCreateSubmit": 109,
|
"routes.ReplyLikeSubmit": 109,
|
||||||
"routes.ProfileReplyEditSubmit": 110,
|
"routes.ProfileReplyCreateSubmit": 110,
|
||||||
"routes.ProfileReplyDeleteSubmit": 111,
|
"routes.ProfileReplyEditSubmit": 111,
|
||||||
"routes.PollVote": 112,
|
"routes.ProfileReplyDeleteSubmit": 112,
|
||||||
"routes.PollResults": 113,
|
"routes.PollVote": 113,
|
||||||
"routes.AccountLogin": 114,
|
"routes.PollResults": 114,
|
||||||
"routes.AccountRegister": 115,
|
"routes.AccountLogin": 115,
|
||||||
"routes.AccountLogout": 116,
|
"routes.AccountRegister": 116,
|
||||||
"routes.AccountLoginSubmit": 117,
|
"routes.AccountLogout": 117,
|
||||||
"routes.AccountLoginMFAVerify": 118,
|
"routes.AccountLoginSubmit": 118,
|
||||||
"routes.AccountLoginMFAVerifySubmit": 119,
|
"routes.AccountLoginMFAVerify": 119,
|
||||||
"routes.AccountRegisterSubmit": 120,
|
"routes.AccountLoginMFAVerifySubmit": 120,
|
||||||
"routes.DynamicRoute": 121,
|
"routes.AccountRegisterSubmit": 121,
|
||||||
"routes.UploadedFile": 122,
|
"routes.DynamicRoute": 122,
|
||||||
"routes.StaticFile": 123,
|
"routes.UploadedFile": 123,
|
||||||
"routes.RobotsTxt": 124,
|
"routes.StaticFile": 124,
|
||||||
"routes.SitemapXml": 125,
|
"routes.RobotsTxt": 125,
|
||||||
"routes.BadRoute": 126,
|
"routes.SitemapXml": 126,
|
||||||
|
"routes.BadRoute": 127,
|
||||||
}
|
}
|
||||||
var reverseRouteMapEnum = map[int]string{
|
var reverseRouteMapEnum = map[int]string{
|
||||||
0: "routes.Overview",
|
0: "routes.Overview",
|
||||||
|
@ -373,43 +375,44 @@ var reverseRouteMapEnum = map[int]string{
|
||||||
87: "routes.AccountEditMFADisableSubmit",
|
87: "routes.AccountEditMFADisableSubmit",
|
||||||
88: "routes.AccountEditEmail",
|
88: "routes.AccountEditEmail",
|
||||||
89: "routes.AccountEditEmailTokenSubmit",
|
89: "routes.AccountEditEmailTokenSubmit",
|
||||||
90: "routes.ViewProfile",
|
90: "routes.LevelList",
|
||||||
91: "routes.BanUserSubmit",
|
91: "routes.ViewProfile",
|
||||||
92: "routes.UnbanUser",
|
92: "routes.BanUserSubmit",
|
||||||
93: "routes.ActivateUser",
|
93: "routes.UnbanUser",
|
||||||
94: "routes.IPSearch",
|
94: "routes.ActivateUser",
|
||||||
95: "routes.CreateTopicSubmit",
|
95: "routes.IPSearch",
|
||||||
96: "routes.EditTopicSubmit",
|
96: "routes.CreateTopicSubmit",
|
||||||
97: "routes.DeleteTopicSubmit",
|
97: "routes.EditTopicSubmit",
|
||||||
98: "routes.StickTopicSubmit",
|
98: "routes.DeleteTopicSubmit",
|
||||||
99: "routes.UnstickTopicSubmit",
|
99: "routes.StickTopicSubmit",
|
||||||
100: "routes.LockTopicSubmit",
|
100: "routes.UnstickTopicSubmit",
|
||||||
101: "routes.UnlockTopicSubmit",
|
101: "routes.LockTopicSubmit",
|
||||||
102: "routes.MoveTopicSubmit",
|
102: "routes.UnlockTopicSubmit",
|
||||||
103: "routes.LikeTopicSubmit",
|
103: "routes.MoveTopicSubmit",
|
||||||
104: "routes.ViewTopic",
|
104: "routes.LikeTopicSubmit",
|
||||||
105: "routes.CreateReplySubmit",
|
105: "routes.ViewTopic",
|
||||||
106: "routes.ReplyEditSubmit",
|
106: "routes.CreateReplySubmit",
|
||||||
107: "routes.ReplyDeleteSubmit",
|
107: "routes.ReplyEditSubmit",
|
||||||
108: "routes.ReplyLikeSubmit",
|
108: "routes.ReplyDeleteSubmit",
|
||||||
109: "routes.ProfileReplyCreateSubmit",
|
109: "routes.ReplyLikeSubmit",
|
||||||
110: "routes.ProfileReplyEditSubmit",
|
110: "routes.ProfileReplyCreateSubmit",
|
||||||
111: "routes.ProfileReplyDeleteSubmit",
|
111: "routes.ProfileReplyEditSubmit",
|
||||||
112: "routes.PollVote",
|
112: "routes.ProfileReplyDeleteSubmit",
|
||||||
113: "routes.PollResults",
|
113: "routes.PollVote",
|
||||||
114: "routes.AccountLogin",
|
114: "routes.PollResults",
|
||||||
115: "routes.AccountRegister",
|
115: "routes.AccountLogin",
|
||||||
116: "routes.AccountLogout",
|
116: "routes.AccountRegister",
|
||||||
117: "routes.AccountLoginSubmit",
|
117: "routes.AccountLogout",
|
||||||
118: "routes.AccountLoginMFAVerify",
|
118: "routes.AccountLoginSubmit",
|
||||||
119: "routes.AccountLoginMFAVerifySubmit",
|
119: "routes.AccountLoginMFAVerify",
|
||||||
120: "routes.AccountRegisterSubmit",
|
120: "routes.AccountLoginMFAVerifySubmit",
|
||||||
121: "routes.DynamicRoute",
|
121: "routes.AccountRegisterSubmit",
|
||||||
122: "routes.UploadedFile",
|
122: "routes.DynamicRoute",
|
||||||
123: "routes.StaticFile",
|
123: "routes.UploadedFile",
|
||||||
124: "routes.RobotsTxt",
|
124: "routes.StaticFile",
|
||||||
125: "routes.SitemapXml",
|
125: "routes.RobotsTxt",
|
||||||
126: "routes.BadRoute",
|
126: "routes.SitemapXml",
|
||||||
|
127: "routes.BadRoute",
|
||||||
}
|
}
|
||||||
var osMapEnum = map[string]int{
|
var osMapEnum = map[string]int{
|
||||||
"unknown": 0,
|
"unknown": 0,
|
||||||
|
@ -708,7 +711,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
counters.GlobalViewCounter.Bump()
|
counters.GlobalViewCounter.Bump()
|
||||||
|
|
||||||
if prefix == "/static" {
|
if prefix == "/static" {
|
||||||
counters.RouteViewCounter.Bump(123)
|
counters.RouteViewCounter.Bump(124)
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
routes.StaticFile(w, req)
|
routes.StaticFile(w, req)
|
||||||
return
|
return
|
||||||
|
@ -1586,9 +1589,18 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(89)
|
counters.RouteViewCounter.Bump(89)
|
||||||
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
|
err = routes.AccountEditEmailTokenSubmit(w,req,user,extraData)
|
||||||
|
case "/user/levels/":
|
||||||
|
err = common.MemberOnly(w,req,user)
|
||||||
|
if err != nil {
|
||||||
|
router.handleError(err,w,req,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
counters.RouteViewCounter.Bump(90)
|
||||||
|
err = routes.LevelList(w,req,user)
|
||||||
default:
|
default:
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
counters.RouteViewCounter.Bump(90)
|
counters.RouteViewCounter.Bump(91)
|
||||||
err = routes.ViewProfile(w,req,user)
|
err = routes.ViewProfile(w,req,user)
|
||||||
}
|
}
|
||||||
case "/users":
|
case "/users":
|
||||||
|
@ -1606,7 +1618,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(91)
|
counters.RouteViewCounter.Bump(92)
|
||||||
err = routes.BanUserSubmit(w,req,user,extraData)
|
err = routes.BanUserSubmit(w,req,user,extraData)
|
||||||
case "/users/unban/":
|
case "/users/unban/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1621,7 +1633,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(92)
|
counters.RouteViewCounter.Bump(93)
|
||||||
err = routes.UnbanUser(w,req,user,extraData)
|
err = routes.UnbanUser(w,req,user,extraData)
|
||||||
case "/users/activate/":
|
case "/users/activate/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1636,7 +1648,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(93)
|
counters.RouteViewCounter.Bump(94)
|
||||||
err = routes.ActivateUser(w,req,user,extraData)
|
err = routes.ActivateUser(w,req,user,extraData)
|
||||||
case "/users/ips/":
|
case "/users/ips/":
|
||||||
err = common.MemberOnly(w,req,user)
|
err = common.MemberOnly(w,req,user)
|
||||||
|
@ -1645,7 +1657,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(94)
|
counters.RouteViewCounter.Bump(95)
|
||||||
err = routes.IPSearch(w,req,user)
|
err = routes.IPSearch(w,req,user)
|
||||||
}
|
}
|
||||||
case "/topic":
|
case "/topic":
|
||||||
|
@ -1668,7 +1680,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(95)
|
counters.RouteViewCounter.Bump(96)
|
||||||
err = routes.CreateTopicSubmit(w,req,user)
|
err = routes.CreateTopicSubmit(w,req,user)
|
||||||
case "/topic/edit/submit/":
|
case "/topic/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1683,7 +1695,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(96)
|
counters.RouteViewCounter.Bump(97)
|
||||||
err = routes.EditTopicSubmit(w,req,user,extraData)
|
err = routes.EditTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/delete/submit/":
|
case "/topic/delete/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1699,7 +1711,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
counters.RouteViewCounter.Bump(97)
|
counters.RouteViewCounter.Bump(98)
|
||||||
err = routes.DeleteTopicSubmit(w,req,user)
|
err = routes.DeleteTopicSubmit(w,req,user)
|
||||||
case "/topic/stick/submit/":
|
case "/topic/stick/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1714,7 +1726,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(98)
|
counters.RouteViewCounter.Bump(99)
|
||||||
err = routes.StickTopicSubmit(w,req,user,extraData)
|
err = routes.StickTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/unstick/submit/":
|
case "/topic/unstick/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1729,7 +1741,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(99)
|
counters.RouteViewCounter.Bump(100)
|
||||||
err = routes.UnstickTopicSubmit(w,req,user,extraData)
|
err = routes.UnstickTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/lock/submit/":
|
case "/topic/lock/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1745,7 +1757,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
}
|
}
|
||||||
|
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
counters.RouteViewCounter.Bump(100)
|
counters.RouteViewCounter.Bump(101)
|
||||||
err = routes.LockTopicSubmit(w,req,user)
|
err = routes.LockTopicSubmit(w,req,user)
|
||||||
case "/topic/unlock/submit/":
|
case "/topic/unlock/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1760,7 +1772,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(101)
|
counters.RouteViewCounter.Bump(102)
|
||||||
err = routes.UnlockTopicSubmit(w,req,user,extraData)
|
err = routes.UnlockTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/move/submit/":
|
case "/topic/move/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1775,7 +1787,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(102)
|
counters.RouteViewCounter.Bump(103)
|
||||||
err = routes.MoveTopicSubmit(w,req,user,extraData)
|
err = routes.MoveTopicSubmit(w,req,user,extraData)
|
||||||
case "/topic/like/submit/":
|
case "/topic/like/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1796,10 +1808,10 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(103)
|
counters.RouteViewCounter.Bump(104)
|
||||||
err = routes.LikeTopicSubmit(w,req,user,extraData)
|
err = routes.LikeTopicSubmit(w,req,user,extraData)
|
||||||
default:
|
default:
|
||||||
counters.RouteViewCounter.Bump(104)
|
counters.RouteViewCounter.Bump(105)
|
||||||
err = routes.ViewTopic(w,req,user, extraData)
|
err = routes.ViewTopic(w,req,user, extraData)
|
||||||
}
|
}
|
||||||
case "/reply":
|
case "/reply":
|
||||||
|
@ -1822,7 +1834,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(105)
|
counters.RouteViewCounter.Bump(106)
|
||||||
err = routes.CreateReplySubmit(w,req,user)
|
err = routes.CreateReplySubmit(w,req,user)
|
||||||
case "/reply/edit/submit/":
|
case "/reply/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1837,7 +1849,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(106)
|
counters.RouteViewCounter.Bump(107)
|
||||||
err = routes.ReplyEditSubmit(w,req,user,extraData)
|
err = routes.ReplyEditSubmit(w,req,user,extraData)
|
||||||
case "/reply/delete/submit/":
|
case "/reply/delete/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1852,7 +1864,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(107)
|
counters.RouteViewCounter.Bump(108)
|
||||||
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
|
err = routes.ReplyDeleteSubmit(w,req,user,extraData)
|
||||||
case "/reply/like/submit/":
|
case "/reply/like/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1873,7 +1885,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(108)
|
counters.RouteViewCounter.Bump(109)
|
||||||
err = routes.ReplyLikeSubmit(w,req,user,extraData)
|
err = routes.ReplyLikeSubmit(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
case "/profile":
|
case "/profile":
|
||||||
|
@ -1891,7 +1903,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(109)
|
counters.RouteViewCounter.Bump(110)
|
||||||
err = routes.ProfileReplyCreateSubmit(w,req,user)
|
err = routes.ProfileReplyCreateSubmit(w,req,user)
|
||||||
case "/profile/reply/edit/submit/":
|
case "/profile/reply/edit/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1906,7 +1918,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(110)
|
counters.RouteViewCounter.Bump(111)
|
||||||
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
|
err = routes.ProfileReplyEditSubmit(w,req,user,extraData)
|
||||||
case "/profile/reply/delete/submit/":
|
case "/profile/reply/delete/submit/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1921,7 +1933,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(111)
|
counters.RouteViewCounter.Bump(112)
|
||||||
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
|
err = routes.ProfileReplyDeleteSubmit(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
case "/poll":
|
case "/poll":
|
||||||
|
@ -1939,19 +1951,19 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(112)
|
counters.RouteViewCounter.Bump(113)
|
||||||
err = routes.PollVote(w,req,user,extraData)
|
err = routes.PollVote(w,req,user,extraData)
|
||||||
case "/poll/results/":
|
case "/poll/results/":
|
||||||
counters.RouteViewCounter.Bump(113)
|
counters.RouteViewCounter.Bump(114)
|
||||||
err = routes.PollResults(w,req,user,extraData)
|
err = routes.PollResults(w,req,user,extraData)
|
||||||
}
|
}
|
||||||
case "/accounts":
|
case "/accounts":
|
||||||
switch(req.URL.Path) {
|
switch(req.URL.Path) {
|
||||||
case "/accounts/login/":
|
case "/accounts/login/":
|
||||||
counters.RouteViewCounter.Bump(114)
|
counters.RouteViewCounter.Bump(115)
|
||||||
err = routes.AccountLogin(w,req,user)
|
err = routes.AccountLogin(w,req,user)
|
||||||
case "/accounts/create/":
|
case "/accounts/create/":
|
||||||
counters.RouteViewCounter.Bump(115)
|
counters.RouteViewCounter.Bump(116)
|
||||||
err = routes.AccountRegister(w,req,user)
|
err = routes.AccountRegister(w,req,user)
|
||||||
case "/accounts/logout/":
|
case "/accounts/logout/":
|
||||||
err = common.NoSessionMismatch(w,req,user)
|
err = common.NoSessionMismatch(w,req,user)
|
||||||
|
@ -1966,7 +1978,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(116)
|
counters.RouteViewCounter.Bump(117)
|
||||||
err = routes.AccountLogout(w,req,user)
|
err = routes.AccountLogout(w,req,user)
|
||||||
case "/accounts/login/submit/":
|
case "/accounts/login/submit/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1975,10 +1987,10 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(117)
|
counters.RouteViewCounter.Bump(118)
|
||||||
err = routes.AccountLoginSubmit(w,req,user)
|
err = routes.AccountLoginSubmit(w,req,user)
|
||||||
case "/accounts/mfa_verify/":
|
case "/accounts/mfa_verify/":
|
||||||
counters.RouteViewCounter.Bump(118)
|
counters.RouteViewCounter.Bump(119)
|
||||||
err = routes.AccountLoginMFAVerify(w,req,user)
|
err = routes.AccountLoginMFAVerify(w,req,user)
|
||||||
case "/accounts/mfa_verify/submit/":
|
case "/accounts/mfa_verify/submit/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1987,7 +1999,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(119)
|
counters.RouteViewCounter.Bump(120)
|
||||||
err = routes.AccountLoginMFAVerifySubmit(w,req,user)
|
err = routes.AccountLoginMFAVerifySubmit(w,req,user)
|
||||||
case "/accounts/create/submit/":
|
case "/accounts/create/submit/":
|
||||||
err = common.ParseForm(w,req,user)
|
err = common.ParseForm(w,req,user)
|
||||||
|
@ -1996,7 +2008,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
counters.RouteViewCounter.Bump(120)
|
counters.RouteViewCounter.Bump(121)
|
||||||
err = routes.AccountRegisterSubmit(w,req,user)
|
err = routes.AccountRegisterSubmit(w,req,user)
|
||||||
}
|
}
|
||||||
/*case "/sitemaps": // TODO: Count these views
|
/*case "/sitemaps": // TODO: Count these views
|
||||||
|
@ -2013,7 +2025,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
w.Header().Del("Content-Type")
|
w.Header().Del("Content-Type")
|
||||||
w.Header().Del("Content-Encoding")
|
w.Header().Del("Content-Encoding")
|
||||||
}
|
}
|
||||||
counters.RouteViewCounter.Bump(122)
|
counters.RouteViewCounter.Bump(123)
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
// TODO: Find a way to propagate errors up from this?
|
// TODO: Find a way to propagate errors up from this?
|
||||||
router.UploadHandler(w,req) // TODO: Count these views
|
router.UploadHandler(w,req) // TODO: Count these views
|
||||||
|
@ -2023,14 +2035,14 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
// TODO: Add support for favicons and robots.txt files
|
// TODO: Add support for favicons and robots.txt files
|
||||||
switch(extraData) {
|
switch(extraData) {
|
||||||
case "robots.txt":
|
case "robots.txt":
|
||||||
counters.RouteViewCounter.Bump(124)
|
counters.RouteViewCounter.Bump(125)
|
||||||
err = routes.RobotsTxt(w,req)
|
err = routes.RobotsTxt(w,req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
/*case "sitemap.xml":
|
/*case "sitemap.xml":
|
||||||
counters.RouteViewCounter.Bump(125)
|
counters.RouteViewCounter.Bump(126)
|
||||||
err = routes.SitemapXml(w,req)
|
err = routes.SitemapXml(w,req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
router.handleError(err,w,req,user)
|
router.handleError(err,w,req,user)
|
||||||
|
@ -2046,7 +2058,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
router.RUnlock()
|
router.RUnlock()
|
||||||
|
|
||||||
if ok {
|
if ok {
|
||||||
counters.RouteViewCounter.Bump(121) // TODO: Be more specific about *which* dynamic route it is
|
counters.RouteViewCounter.Bump(122) // TODO: Be more specific about *which* dynamic route it is
|
||||||
req.URL.Path += extraData
|
req.URL.Path += extraData
|
||||||
err = handle(w,req,user)
|
err = handle(w,req,user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2061,7 +2073,7 @@ func (router *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, u
|
||||||
} else {
|
} else {
|
||||||
router.DumpRequest(req,"Bad Route")
|
router.DumpRequest(req,"Bad Route")
|
||||||
}
|
}
|
||||||
counters.RouteViewCounter.Bump(126)
|
counters.RouteViewCounter.Bump(127)
|
||||||
common.NotFound(w,req,nil)
|
common.NotFound(w,req,nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"Name": "english",
|
"Name": "english",
|
||||||
|
|
||||||
"Levels": {
|
"Levels": {
|
||||||
"Level": "Level {0}",
|
"Level": "<span class='level_hideable'>Level </span>{0}",
|
||||||
"LevelMax": ""
|
"LevelMax": ""
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -361,7 +361,6 @@
|
||||||
"topic.plus":"+",
|
"topic.plus":"+",
|
||||||
"topic.plus_one":"+1",
|
"topic.plus_one":"+1",
|
||||||
"topic.gap_up":" up",
|
"topic.gap_up":" up",
|
||||||
"topic.level":"Level",
|
|
||||||
"topic.edit_button_text":"Edit",
|
"topic.edit_button_text":"Edit",
|
||||||
"topic.delete_button_text":"Delete",
|
"topic.delete_button_text":"Delete",
|
||||||
"topic.ip_button_text":"IP",
|
"topic.ip_button_text":"IP",
|
||||||
|
@ -448,7 +447,6 @@
|
||||||
|
|
||||||
"account_dash_2fa_setup":"Setup your two-factor authentication.",
|
"account_dash_2fa_setup":"Setup your two-factor authentication.",
|
||||||
"account_dash_2fa_manage":"Remove or manage your two-factor authentication.",
|
"account_dash_2fa_manage":"Remove or manage your two-factor authentication.",
|
||||||
"account_dash_level":"Level %d",
|
|
||||||
"account_dash_security_notice":"Security",
|
"account_dash_security_notice":"Security",
|
||||||
"account_avatar_select":"Select",
|
"account_avatar_select":"Select",
|
||||||
"account_avatar_update_button":"Upload",
|
"account_avatar_update_button":"Upload",
|
||||||
|
@ -596,7 +594,6 @@
|
||||||
"topic.reply_add_poll_button":"Add Poll",
|
"topic.reply_add_poll_button":"Add Poll",
|
||||||
"topic.reply_add_file_button":"Add File",
|
"topic.reply_add_file_button":"Add File",
|
||||||
|
|
||||||
"topic.level_prefix":"Level ",
|
|
||||||
"topic.your_information":"Your information",
|
"topic.your_information":"Your information",
|
||||||
|
|
||||||
"paginator_less_than":"<",
|
"paginator_less_than":"<",
|
||||||
|
|
|
@ -48,6 +48,7 @@ func buildUserRoutes() {
|
||||||
userGroup := newRouteGroup("/user/")
|
userGroup := newRouteGroup("/user/")
|
||||||
userGroup.Routes(
|
userGroup.Routes(
|
||||||
View("routes.ViewProfile", "/user/").LitBefore("req.URL.Path += extraData"),
|
View("routes.ViewProfile", "/user/").LitBefore("req.URL.Path += extraData"),
|
||||||
|
|
||||||
MemberView("routes.AccountEdit", "/user/edit/"),
|
MemberView("routes.AccountEdit", "/user/edit/"),
|
||||||
MemberView("routes.AccountEditPassword", "/user/edit/password/"),
|
MemberView("routes.AccountEditPassword", "/user/edit/password/"),
|
||||||
Action("routes.AccountEditPasswordSubmit", "/user/edit/password/submit/"), // TODO: Full test this
|
Action("routes.AccountEditPasswordSubmit", "/user/edit/password/submit/"), // TODO: Full test this
|
||||||
|
@ -59,6 +60,8 @@ func buildUserRoutes() {
|
||||||
Action("routes.AccountEditMFADisableSubmit", "/user/edit/mfa/disable/submit/"),
|
Action("routes.AccountEditMFADisableSubmit", "/user/edit/mfa/disable/submit/"),
|
||||||
MemberView("routes.AccountEditEmail", "/user/edit/email/"),
|
MemberView("routes.AccountEditEmail", "/user/edit/email/"),
|
||||||
Action("routes.AccountEditEmailTokenSubmit", "/user/edit/token/", "extraData"),
|
Action("routes.AccountEditEmailTokenSubmit", "/user/edit/token/", "extraData"),
|
||||||
|
|
||||||
|
MemberView("routes.LevelList", "/user/levels/"),
|
||||||
)
|
)
|
||||||
addRouteGroup(userGroup)
|
addRouteGroup(userGroup)
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -761,3 +762,37 @@ func AccountEditEmailTokenSubmit(w http.ResponseWriter, r *http.Request, user co
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LevelList(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 = "Level Progress"
|
||||||
|
|
||||||
|
var fScores = common.GetLevels(20)
|
||||||
|
var levels = make([]common.LevelListItem, len(fScores))
|
||||||
|
for i, fScore := range fScores {
|
||||||
|
var status string
|
||||||
|
if user.Level > i {
|
||||||
|
status = "complete"
|
||||||
|
} else if user.Level < i {
|
||||||
|
status = "future"
|
||||||
|
} else {
|
||||||
|
status = "inprogress"
|
||||||
|
}
|
||||||
|
iScore := int(math.Ceil(fScore))
|
||||||
|
perc := int(math.Ceil((fScore / float64(user.Score)) * 100))
|
||||||
|
levels[i] = common.LevelListItem{i, iScore, status, perc * 2}
|
||||||
|
}
|
||||||
|
|
||||||
|
pi := common.LevelListPage{header, levels[1:]}
|
||||||
|
if common.RunPreRenderHook("pre_render_level_list", w, r, &user, &pi) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := common.Templates.ExecuteTemplate(w, "level_list.html", pi)
|
||||||
|
if err != nil {
|
||||||
|
return common.InternalError(err, w, r)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
</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">Level {{.CurrentUser.Level}}: [{{.CurrentScore}} / {{.NextScore}}] <span class="account_soon">{{lang "account_coming_soon"}}</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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
{{template "header.html" . }}
|
||||||
|
<main>
|
||||||
|
<div class="rowblock rowhead">
|
||||||
|
<div class="rowitem"><h1>{{.Title}}</h1></div>
|
||||||
|
</div>
|
||||||
|
{{range .Levels}}
|
||||||
|
<div class="rowblock">
|
||||||
|
<div class="rowitem passive rowmsg level_{{.Status}}">
|
||||||
|
<div>{{level .Level}}</div>
|
||||||
|
<div class="progressWrap"{{if eq .Status "inprogress"}} style="width: {{.Percentage}}%;"{{end}}>
|
||||||
|
<div>Score: {{.Score}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</main>
|
||||||
|
{{template "footer.html" . }}
|
|
@ -12,10 +12,12 @@
|
||||||
<span class="profileName" title="{{.ProfileOwner.Name}}">{{.ProfileOwner.Name}}</span>{{if .ProfileOwner.Tag}}<span class="username" title="{{.ProfileOwner.Tag}}">{{.ProfileOwner.Tag}}</span>{{end}}
|
<span class="profileName" title="{{.ProfileOwner.Name}}">{{.ProfileOwner.Name}}</span>{{if .ProfileOwner.Tag}}<span class="username" title="{{.ProfileOwner.Tag}}">{{.ProfileOwner.Tag}}</span>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="passiveBlock">
|
<div class="levelBlock">
|
||||||
<div class="rowitem passive">
|
<div class="rowitem passive">
|
||||||
<a class="profile_menu_item">Level {{.ProfileOwner.Level}}: [{{.CurrentScore}} / {{.NextScore}}]</a>
|
<a class="profile_menu_item">{{level .ProfileOwner.Level}}: [{{.CurrentScore}} / {{.NextScore}}]</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="passiveBlock">
|
||||||
{{if not .CurrentUser.Loggedin}}<div class="rowitem passive">
|
{{if not .CurrentUser.Loggedin}}<div class="rowitem passive">
|
||||||
<a class="profile_menu_item">{{lang "profile_login_for_options"}}</a>
|
<a class="profile_menu_item">{{lang "profile_login_for_options"}}</a>
|
||||||
</div>{{else}}
|
</div>{{else}}
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
|
|
||||||
<a class="username hide_on_micro like_count" aria-label="{{lang "topic.like_count_aria"}}">{{.Topic.LikeCount}}</a><a class="username hide_on_micro like_count_label" title="{{lang "topic.like_count_tooltip"}}"></a>
|
<a class="username hide_on_micro like_count" aria-label="{{lang "topic.like_count_aria"}}">{{.Topic.LikeCount}}</a><a class="username hide_on_micro like_count_label" title="{{lang "topic.like_count_tooltip"}}"></a>
|
||||||
|
|
||||||
{{if .Topic.Tag}}<a class="username hide_on_micro user_tag">{{.Topic.Tag}}</a>{{else}}<a class="username hide_on_micro level" aria-label="{{lang "topic.level_aria"}}">{{.Topic.Level}}</a><a class="username hide_on_micro level_label" style="float:right;" title="{{lang "topic.level_tooltip"}}"></a>{{end}}
|
{{if .Topic.Tag}}<a class="username hide_on_micro user_tag">{{.Topic.Tag}}</a>{{else}}<a class="username hide_on_micro level" aria-label="{{lang "topic.level_aria"}}">{{level .Topic.Level}}</a><a class="username hide_on_micro level_label" style="float:right;" title="{{lang "topic.level_tooltip"}}"></a>{{end}}
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
<div class="avatar_item" style="background-image: url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;"> </div>
|
<div class="avatar_item" style="background-image: url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;"> </div>
|
||||||
<div class="user_meta">
|
<div class="user_meta">
|
||||||
<a href="{{.Topic.UserLink}}" class="the_name" rel="author">{{.Topic.CreatedByName}}</a>
|
<a href="{{.Topic.UserLink}}" class="the_name" rel="author">{{.Topic.CreatedByName}}</a>
|
||||||
{{if .Topic.Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Topic.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">{{lang "topic.level_prefix"}}{{.Topic.Level}}</div><div class="tag_post"></div></div>{{end}}
|
{{if .Topic.Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Topic.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">{{level .Topic.Level}}</div><div class="tag_post"></div></div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="poll_voter_{{.Poll.ID}}" class="content_container poll_voter">
|
<div id="poll_voter_{{.Poll.ID}}" class="content_container poll_voter">
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
<div class="avatar_item" style="background-image: url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;"> </div>
|
<div class="avatar_item" style="background-image: url({{.Topic.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;"> </div>
|
||||||
<div class="user_meta">
|
<div class="user_meta">
|
||||||
<a href="{{.Topic.UserLink}}" class="the_name" rel="author">{{.Topic.CreatedByName}}</a>
|
<a href="{{.Topic.UserLink}}" class="the_name" rel="author">{{.Topic.CreatedByName}}</a>
|
||||||
{{if .Topic.Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Topic.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">{{lang "topic.level_prefix"}}{{.Topic.Level}}</div><div class="tag_post"></div></div>{{end}}
|
{{if .Topic.Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Topic.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">{{level .Topic.Level}}</div><div class="tag_post"></div></div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content_container">
|
<div class="content_container">
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
<div class="avatar_item" style="background-image: url({{.CurrentUser.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;"> </div>
|
<div class="avatar_item" style="background-image: url({{.CurrentUser.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;"> </div>
|
||||||
<div class="user_meta">
|
<div class="user_meta">
|
||||||
<a href="{{.CurrentUser.Link}}" class="the_name" rel="author">{{.CurrentUser.Name}}</a>
|
<a href="{{.CurrentUser.Link}}" class="the_name" rel="author">{{.CurrentUser.Name}}</a>
|
||||||
{{if .CurrentUser.Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.CurrentUser.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">{{lang "topic.level_prefix"}}{{.CurrentUser.Level}}</div><div class="tag_post"></div></div>{{end}}
|
{{if .CurrentUser.Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.CurrentUser.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">{{level .CurrentUser.Level}}</div><div class="tag_post"></div></div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="rowblock topic_reply_form quick_create_form" aria-label="{{lang "topic.reply_aria"}}">
|
<div class="rowblock topic_reply_form quick_create_form" aria-label="{{lang "topic.reply_aria"}}">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="avatar_item" style="background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;"> </div>
|
<div class="avatar_item" style="background-image: url({{.Avatar}}), url(/static/white-dot.jpg);background-position: 0px -10px;"> </div>
|
||||||
<div class="user_meta">
|
<div class="user_meta">
|
||||||
<a href="{{.UserLink}}" class="the_name" rel="author">{{.CreatedByName}}</a>
|
<a href="{{.UserLink}}" class="the_name" rel="author">{{.CreatedByName}}</a>
|
||||||
{{if .Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">{{lang "topic.level_prefix"}}{{.Level}}</div><div class="tag_post"></div></div>{{end}}
|
{{if .Tag}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag">{{.Tag}}</div><div class="tag_post"></div></div>{{else}}<div class="tag_block"><div class="tag_pre"></div><div class="post_tag post_level">{{level .Level}}</div><div class="tag_post"></div></div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content_container"{{if .ActionType}} style="margin-left: 0px;"{{end}}>
|
<div class="content_container"{{if .ActionType}} style="margin-left: 0px;"{{end}}>
|
||||||
|
|
|
@ -55,7 +55,9 @@ li a {
|
||||||
padding-bottom: 21px;
|
padding-bottom: 21px;
|
||||||
color: #dddddd;
|
color: #dddddd;
|
||||||
}
|
}
|
||||||
.menu_alerts .alert_bell, .menu_alerts .alert_counter, .menu_alerts:not(.selectedAlert) .alertList {
|
.menu_alerts .alert_bell,
|
||||||
|
.menu_alerts .alert_counter,
|
||||||
|
.menu_alerts:not(.selectedAlert) .alertList {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.alertList {
|
.alertList {
|
||||||
|
@ -70,6 +72,11 @@ li a {
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
padding-right: 16px;
|
padding-right: 16px;
|
||||||
}
|
}
|
||||||
|
.alertItem {
|
||||||
|
padding: 10px;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
.alertItem.withAvatar {
|
.alertItem.withAvatar {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
height: 66px;
|
height: 66px;
|
||||||
|
@ -853,6 +860,44 @@ input[type=checkbox]:checked + label .sel {
|
||||||
background-color: #444444;
|
background-color: #444444;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.level_complete, .level_future, .level_inprogress {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.level_complete {
|
||||||
|
background-color: rgb(68, 93, 68) !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.level_future {
|
||||||
|
background-color: rgb(88, 68, 68) !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.progressWrap {
|
||||||
|
display: flex;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
/* CSS behaves in stupid ways, so we need to be very specific about this */
|
||||||
|
.rowblock:not(.topic_list):not(.rowhead):not(.opthead) .rowitem.level_inprogress:not(.post_item) {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
.level_inprogress > div {
|
||||||
|
display: flex;
|
||||||
|
padding-top: 12px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
padding-left: 12px;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%;
|
||||||
|
background-color: rgb(68, 93, 68) !important;
|
||||||
|
}
|
||||||
|
.level_inprogress .progressWrap {
|
||||||
|
width: 100%;
|
||||||
|
padding-left: 0px;
|
||||||
|
padding-right: 12px;
|
||||||
|
background-color: rgb(68, 68, 68) !important;
|
||||||
|
}
|
||||||
|
.level_inprogress .progressWrap div {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
@media(max-width: 600px) {
|
@media(max-width: 600px) {
|
||||||
.rowhead h1, .opthead h1, .colstack_head h1 {
|
.rowhead h1, .opthead h1, .colstack_head h1 {
|
||||||
font-size: 19px;
|
font-size: 19px;
|
||||||
|
|
|
@ -23,13 +23,13 @@
|
||||||
.profileName {
|
.profileName {
|
||||||
font-size: 21px;
|
font-size: 21px;
|
||||||
}
|
}
|
||||||
.topBlock, .passiveBlock {
|
.topBlock, .levelBlock, .passiveBlock {
|
||||||
background-color: #444444;
|
background-color: #444444;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
width: 180px;
|
width: 180px;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
.passiveBlock {
|
.levelBlock, .passiveBlock {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -316,9 +316,6 @@ a {
|
||||||
.flag_label:before {
|
.flag_label:before {
|
||||||
content: "{{index .Phrases "topic.flag_button_text"}}";
|
content: "{{index .Phrases "topic.flag_button_text"}}";
|
||||||
}
|
}
|
||||||
.level_label:before {
|
|
||||||
content: "{{index .Phrases "topic.level"}}";
|
|
||||||
}
|
|
||||||
|
|
||||||
.like_count_label, .like_count {
|
.like_count_label, .like_count {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
@ -707,6 +707,9 @@ button.username {
|
||||||
color: #505050;
|
color: #505050;
|
||||||
opacity: 0.85;
|
opacity: 0.85;
|
||||||
}
|
}
|
||||||
|
.level_hideable {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.controls {
|
.controls {
|
||||||
margin-top: 23px;
|
margin-top: 23px;
|
||||||
|
|
Loading…
Reference in New Issue