Added level progress indicators, still WIP.

Fixed a bug where GetLevelScore wouldn't work and simplified it slightly.
Removed the account_dash_next_level phrase.
Added the account_dash_level phrase.
This commit is contained in:
Azareal 2018-10-08 15:34:25 +10:00
parent 4d75c543d2
commit de78268b20
8 changed files with 35 additions and 22 deletions

View File

@ -130,6 +130,8 @@ type ProfilePage struct {
*Header *Header
ItemList []ReplyUser ItemList []ReplyUser
ProfileOwner User ProfileOwner User
CurrentScore int
NextScore int
} }
type CreateTopicPage struct { type CreateTopicPage struct {
@ -153,6 +155,9 @@ type EmailListPage struct {
type AccountDashPage struct { type AccountDashPage struct {
*Header *Header
MFASetup bool MFASetup bool
CurrentScore int
NextScore int
NextLevel int
} }
type PanelStats struct { type PanelStats struct {

View File

@ -214,7 +214,7 @@ func CompileTemplates() error {
varList = make(map[string]tmpl.VarItem) varList = make(map[string]tmpl.VarItem)
header.Title = "User 526" header.Title = "User 526"
ppage := ProfilePage{header, replyList, user} ppage := ProfilePage{header, replyList, user, 0, 0} // TODO: Use the score from user to generate the currentScore and nextScore
profileTmpl, err := compile("profile", "common.ProfilePage", ppage) profileTmpl, err := compile("profile", "common.ProfilePage", ppage)
if err != nil { if err != nil {
return err return err

View File

@ -114,9 +114,8 @@ func RelativeTime(t time.Time) string {
return fmt.Sprintf("%d minutes ago", int(seconds/60)) return fmt.Sprintf("%d minutes ago", int(seconds/60))
case seconds < 7200: case seconds < 7200:
return "an hour ago" return "an hour ago"
default:
return fmt.Sprintf("%d hours ago", int(seconds/60/60))
} }
return fmt.Sprintf("%d hours ago", int(seconds/60/60))
} }
// TODO: Write a test for this // TODO: Write a test for this
@ -192,9 +191,8 @@ func ConvertUnit(num int) (int, string) {
return num / 1000000, "M" return num / 1000000, "M"
case num >= 1000: case num >= 1000:
return num / 1000, "K" return num / 1000, "K"
default:
return num, ""
} }
return num, ""
} }
// TODO: Write a test for this // TODO: Write a test for this
@ -212,9 +210,8 @@ func ConvertFriendlyUnit(num int) (int, string) {
return num / 1000000, " million" return num / 1000000, " million"
case num >= 1000: case num >= 1000:
return num / 1000, " thousand" return num / 1000, " thousand"
default:
return num, ""
} }
return num, ""
} }
// TODO: Make slugs optional for certain languages across the entirety of Gosora? // TODO: Make slugs optional for certain languages across the entirety of Gosora?
@ -369,6 +366,7 @@ func WordCount(input string) (count int) {
if input == "" { if input == "" {
return 0 return 0
} }
var inSpace bool var inSpace bool
for _, value := range input { for _, value := range input {
if unicode.IsSpace(value) || unicode.IsPunct(value) { if unicode.IsSpace(value) || unicode.IsPunct(value) {
@ -380,6 +378,7 @@ func WordCount(input string) (count int) {
inSpace = false inSpace = false
} }
} }
return count + 1 return count + 1
} }
@ -407,21 +406,17 @@ func GetLevel(score int) (level int) {
// TODO: Write a test for this // TODO: Write a test for this
func GetLevelScore(getLevel int) (score int) { func GetLevelScore(getLevel int) (score int) {
var base float64 = 25 var base float64 = 25
var current, prev float64 var current float64
var level int var expFactor = 2.8
expFactor := 2.8
for i := 1; ; i++ { for i := 1; i <= getLevel; i++ {
_, bit := math.Modf(float64(i) / 10) _, bit := math.Modf(float64(i) / 10)
if bit == 0 { if bit == 0 {
expFactor += 0.1 expFactor += 0.1
} }
current = base + math.Pow(float64(i), expFactor) + (prev / 3) current = base + math.Pow(float64(i), expFactor) + (current / 3)
prev = current //fmt.Println("level: ", i)
level++ //fmt.Println("current: ", current)
if level <= getLevel {
break
}
} }
return int(math.Ceil(current)) return int(math.Ceil(current))
} }

View File

@ -448,7 +448,7 @@
"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_next_level":"Progress to next level.", "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",

View File

@ -389,7 +389,12 @@ func AccountEdit(w http.ResponseWriter, r *http.Request, user common.User) commo
mfaSetup = true mfaSetup = true
} }
pi := common.AccountDashPage{header, mfaSetup} // Normalise the score so that the user sees their relative progress to the next level rather than showing them their total score
prevScore := common.GetLevelScore(user.Level)
currentScore := user.Score - prevScore
nextScore := common.GetLevelScore(user.Level+1) - prevScore
pi := common.AccountDashPage{header, mfaSetup, currentScore, nextScore, user.Level + 1}
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

@ -116,7 +116,12 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user common.User) commo
return common.InternalError(err, w, r) return common.InternalError(err, w, r)
} }
ppage := common.ProfilePage{header, replyList, *puser} // Normalise the score so that the user sees their relative progress to the next level rather than showing them their total score
prevScore := common.GetLevelScore(puser.Level)
currentScore := puser.Score - prevScore
nextScore := common.GetLevelScore(puser.Level+1) - prevScore
ppage := common.ProfilePage{header, replyList, *puser, currentScore, nextScore}
if common.RunPreRenderHook("pre_render_profile", w, r, &user, &ppage) { if common.RunPreRenderHook("pre_render_profile", w, r, &user, &ppage) {
return nil return nil
} }

View File

@ -21,7 +21,7 @@
</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">{{lang "account_dash_next_level"}} <span class="account_soon">{{lang "account_coming_soon"}}</span></div> <div class="rowitem">Level {{.CurrentUser.Level}}: [{{.CurrentScore}} / {{.NextScore}}] <span class="account_soon">{{lang "account_coming_soon"}}</span></div>
</div> </div>
</div> </div>
</main> </main>

View File

@ -13,6 +13,9 @@
</div> </div>
</div> </div>
<div class="passiveBlock"> <div class="passiveBlock">
<div class="rowitem passive">
<a class="profile_menu_item">Level {{.ProfileOwner.Level}}: [{{.CurrentScore}} / {{.NextScore}}]</a>
</div>
{{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}}