diff --git a/models/user.go b/models/user.go index f16fbca34..1a5970618 100644 --- a/models/user.go +++ b/models/user.go @@ -15,6 +15,7 @@ import ( "image/jpeg" "os" "path/filepath" + "sort" "strings" "time" @@ -106,6 +107,25 @@ type EmailAddress struct { IsPrimary bool `xorm:"-"` } +// ByEmail implements sort.Interface for []*EmailAddress based on +// the Email field. +type ByEmail []*EmailAddress + +func (e ByEmail) Len() int { + return len(e) +} + +func (e ByEmail) Swap(i, j int) { + e[i], e[j] = e[j], e[i] +} + +func (e ByEmail) Less(i, j int) bool { + if e[i].IsPrimary { + return true + } + return e[i].Email < e[j].Email +} + // DashboardLink returns the user dashboard page link. func (u *User) DashboardLink() string { if u.IsOrganization() { @@ -629,7 +649,7 @@ func GetUserIdsByNames(names []string) []int64 { // Get all email addresses func GetEmailAddresses(uid int64) ([]*EmailAddress, error) { emails := make([]*EmailAddress, 0, 5) - err := x.Where("uid=?", uid).Find(&emails) + err := x.Where("uid=?", uid).Asc("Email").Find(&emails) if err != nil { return nil, err } @@ -650,11 +670,16 @@ func GetEmailAddresses(uid int64) ([]*EmailAddress, error) { } } - // We alway want the primary email address displayed, even if it's not in - // the emailaddress table (yet) + // We always want the primary email address displayed, even if it's not in + // the emailaddress table (yet). if !isPrimaryFound { emails = append(emails, &EmailAddress{Email: u.Email, IsActivated: true, IsPrimary: true}) } + + // We want the list of email adresses to be sorted with the primary + // address always on top. + sort.Sort(ByEmail(emails)) + return emails, nil } diff --git a/public/ng/css/gogs.css b/public/ng/css/gogs.css index 12ae89ed4..f29282247 100644 --- a/public/ng/css/gogs.css +++ b/public/ng/css/gogs.css @@ -1813,6 +1813,7 @@ The register and sign-in page style #repo-hooks-history-panel, #user-social-panel, #user-applications-panel, +#user-email-panel, #user-ssh-panel { margin-bottom: 20px; } @@ -1820,6 +1821,7 @@ The register and sign-in page style #repo-hooks-history-panel .setting-list, #user-social-panel .setting-list, #user-applications-panel .setting-list, +#user-email-panel .setting-list, #user-ssh-panel .setting-list { background-color: #FFF; } @@ -1827,6 +1829,7 @@ The register and sign-in page style #repo-hooks-history-panel .setting-list li, #user-social-panel .setting-list li, #user-applications-panel .setting-list li, +#user-email-panel .setting-list li, #user-ssh-panel .setting-list li { padding: 8px 20px; border-bottom: 1px solid #eaeaea; @@ -1835,6 +1838,7 @@ The register and sign-in page style #repo-hooks-history-panel .setting-list li.ssh:hover, #user-social-panel .setting-list li.ssh:hover, #user-applications-panel .setting-list li.ssh:hover, +#user-email-panel .setting-list li.ssh:hover, #user-ssh-panel .setting-list li.ssh:hover { background-color: #ffffEE; } @@ -1842,6 +1846,7 @@ The register and sign-in page style #repo-hooks-history-panel .setting-list li i, #user-social-panel .setting-list li i, #user-applications-panel .setting-list li i, +#user-email-panel .setting-list li i, #user-ssh-panel .setting-list li i { padding-right: 5px; } @@ -1849,6 +1854,7 @@ The register and sign-in page style #repo-hooks-history-panel .active-icon, #user-social-panel .active-icon, #user-applications-panel .active-icon, +#user-email-panel .active-icon, #user-ssh-panel .active-icon { width: 10px; height: 10px; @@ -1861,6 +1867,7 @@ The register and sign-in page style #repo-hooks-history-panel .ssh-content, #user-social-panel .ssh-content, #user-applications-panel .ssh-content, +#user-email-panel .ssh-content, #user-ssh-panel .ssh-content { margin-left: 24px; } @@ -1868,6 +1875,7 @@ The register and sign-in page style #repo-hooks-history-panel .ssh-content .octicon, #user-social-panel .ssh-content .octicon, #user-applications-panel .ssh-content .octicon, +#user-email-panel .ssh-content .octicon, #user-ssh-panel .ssh-content .octicon { margin-right: 4px; } @@ -1875,16 +1883,19 @@ The register and sign-in page style #repo-hooks-history-panel .ssh-content .print, #user-social-panel .ssh-content .print, #user-applications-panel .ssh-content .print, +#user-email-panel .ssh-content .print, #user-ssh-panel .ssh-content .print, #repo-hooks-panel .ssh-content .access, #repo-hooks-history-panel .ssh-content .access, #user-social-panel .ssh-content .access, #user-applications-panel .ssh-content .access, +#user-email-panel .ssh-content .access, #user-ssh-panel .ssh-content .access, #repo-hooks-panel .ssh-content .activity, #repo-hooks-history-panel .ssh-content .activity, #user-social-panel .ssh-content .activity, #user-applications-panel .ssh-content .activity, +#user-email-panel .ssh-content .activity, #user-ssh-panel .ssh-content .activity { color: #888; } @@ -1892,6 +1903,7 @@ The register and sign-in page style #repo-hooks-history-panel .ssh-content .access, #user-social-panel .ssh-content .access, #user-applications-panel .ssh-content .access, +#user-email-panel .ssh-content .access, #user-ssh-panel .ssh-content .access { max-width: 500px; } @@ -1899,9 +1911,14 @@ The register and sign-in page style #repo-hooks-history-panel .ssh-btn, #user-social-panel .ssh-btn, #user-applications-panel .ssh-btn, +#user-email-panel .ssh-btn, #user-ssh-panel .ssh-btn { margin-top: 6px; } +#user-email-panel .setting-list .field { + padding: 8px 20px; + border-bottom: 1px solid #eaeaea; +} .form-settings-add .panel-body { background-color: #FFF; padding: 30px 0; diff --git a/routers/user/setting.go b/routers/user/setting.go index 419e84b39..0db0e650d 100644 --- a/routers/user/setting.go +++ b/routers/user/setting.go @@ -131,7 +131,7 @@ func SettingsAvatar(ctx *middleware.Context, form auth.UploadAvatarForm) { func SettingsEmails(ctx *middleware.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsUserSettings"] = true - ctx.Data["PageIsSettingsEmails"] = true + ctx.Data["PageIsSettingsEmail"] = true var err error ctx.Data["Emails"], err = models.GetEmailAddresses(ctx.User.Id) @@ -147,7 +147,7 @@ func SettingsEmails(ctx *middleware.Context) { func SettingsEmailPost(ctx *middleware.Context, form auth.AddEmailForm) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsUserSettings"] = true - ctx.Data["PageIsSettingsEmails"] = true + ctx.Data["PageIsSettingsEmail"] = true var err error ctx.Data["Emails"], err = models.GetEmailAddresses(ctx.User.Id) diff --git a/templates/user/settings/email.tmpl b/templates/user/settings/email.tmpl index fc8bcbbcf..512f4799d 100644 --- a/templates/user/settings/email.tmpl +++ b/templates/user/settings/email.tmpl @@ -41,11 +41,8 @@

{{.i18n.Tr "settings.add_new_email"}}

- -

-

- - + +

@@ -55,4 +52,4 @@ -{{template "ng/base/footer" .}} \ No newline at end of file +{{template "ng/base/footer" .}}