| @@ -80,6 +80,18 @@ func GetEmailAddressByID(uid, id int64) (*EmailAddress, error) { | |||
| return email, nil | |||
| } | |||
| // GetEmailAddressByIDAndEmail gets a user's email address by ID and email | |||
| func GetEmailAddressByIDAndEmail(uid int64, emailAddr string) (*EmailAddress, error) { | |||
| // User ID is required for security reasons | |||
| email := &EmailAddress{UID: uid, Email: emailAddr} | |||
| if has, err := x.Get(email); err != nil { | |||
| return nil, err | |||
| } else if !has { | |||
| return nil, nil | |||
| } | |||
| return email, nil | |||
| } | |||
| func isEmailActive(e Engine, email string, userID, emailID int64) (bool, error) { | |||
| if len(email) == 0 { | |||
| return true, nil | |||
| @@ -590,20 +590,31 @@ func Home(ctx *context.Context) { | |||
| if err == nil && contributors != nil { | |||
| var contributorInfos []*ContributorInfo | |||
| for _, c := range contributors { | |||
| // get user info from committer email | |||
| user, err := models.GetUserByEmail(c.Email) | |||
| if err == nil { | |||
| // committer is system user, get info through user's primary email | |||
| existedContributorInfo := getContributorInfo(contributorInfos,user.Email) | |||
| if existedContributorInfo != nil { | |||
| // existed: same primary email, different committer name | |||
| existedContributorInfo.CommitCnt += c.CommitCnt | |||
| }else{ | |||
| // new committer info | |||
| contributorInfos = append(contributorInfos, &ContributorInfo{ | |||
| user, user.Email,c.CommitCnt, | |||
| }) | |||
| } | |||
| } else { | |||
| contributorInfos = append(contributorInfos, &ContributorInfo{ | |||
| nil, c.Email,c.CommitCnt, | |||
| }) | |||
| // committer is not system user | |||
| existedContributorInfo := getContributorInfo(contributorInfos,c.Email) | |||
| if existedContributorInfo != nil { | |||
| // existed: same primary email, different committer name | |||
| existedContributorInfo.CommitCnt += c.CommitCnt | |||
| }else{ | |||
| contributorInfos = append(contributorInfos, &ContributorInfo{ | |||
| nil, c.Email,c.CommitCnt, | |||
| }) | |||
| } | |||
| } | |||
| } | |||
| ctx.Data["ContributorInfo"] = contributorInfos | |||
| @@ -1266,6 +1266,15 @@ func Activate(ctx *context.Context) { | |||
| log.Error("Error storing session: %v", err) | |||
| } | |||
| email, err := models.GetEmailAddressByIDAndEmail(user.ID, user.Email) | |||
| if err != nil || email == nil{ | |||
| log.Error("GetEmailAddressByIDAndEmail failed", ctx.Data["MsgID"]) | |||
| } else { | |||
| if err := email.Activate(); err != nil { | |||
| log.Error("Activate failed: %v", err, ctx.Data["MsgID"]) | |||
| } | |||
| } | |||
| ctx.Flash.Success(ctx.Tr("auth.account_activated")) | |||
| ctx.Redirect(setting.AppSubURL + "/") | |||
| return | |||
| @@ -96,6 +96,18 @@ func ProfilePost(ctx *context.Context, form auth.UpdateProfileForm) { | |||
| ctx.User.Location = form.Location | |||
| ctx.User.Language = form.Language | |||
| ctx.User.Description = form.Description | |||
| isUsed, err := models.IsEmailUsed(form.Email) | |||
| if err != nil { | |||
| ctx.ServerError("IsEmailUsed", err) | |||
| return | |||
| } | |||
| if isUsed { | |||
| ctx.Flash.Error(ctx.Tr("form.email_been_used")) | |||
| ctx.Redirect(setting.AppSubURL + "/user/settings") | |||
| return | |||
| } | |||
| if err := models.UpdateUserSetting(ctx.User); err != nil { | |||
| if _, ok := err.(models.ErrEmailAlreadyUsed); ok { | |||
| ctx.Flash.Error(ctx.Tr("form.email_been_used")) | |||
| @@ -4,6 +4,48 @@ | |||
| font-size: 1.0em; | |||
| margin-bottom: 1.0rem; | |||
| } | |||
| #contributorInfo > a:nth-child(n+25){ | |||
| display:none; | |||
| } | |||
| #contributorInfo > a{ | |||
| width: 2.0em; | |||
| float: left; | |||
| margin: .25em; | |||
| } | |||
| #contributorInfo > a.circular{ | |||
| height: 2.0em; | |||
| padding: 0; | |||
| overflow: hidden; | |||
| letter-spacing:1.0em; | |||
| text-indent: 0.6em; | |||
| line-height: 2.0em; | |||
| text-transform:capitalize; | |||
| color: #FFF; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+1){ | |||
| background-color: #4ccdec; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+2){ | |||
| background-color: #e0b265; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+3){ | |||
| background-color: #d884b7; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+4){ | |||
| background-color: #8c6bdc; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+5){ | |||
| background-color: #3cb99f; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+6){ | |||
| background-color: #6995b9; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+7){ | |||
| background-color: #ab91a7; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+8){ | |||
| background-color: #bfd0aa; | |||
| } | |||
| </style> | |||
| <div class="repository file list"> | |||
| {{template "repo/header" .}} | |||
| @@ -193,17 +235,15 @@ | |||
| <h4 class="ui header"> | |||
| <strong>贡献者 ({{len .ContributorInfo}})</strong> | |||
| <div class="ui right"> | |||
| <a class="text grey" href="">全部 {{svg "octicon-chevron-right" 16}}</a> | |||
| <a class="membersmore text grey" href="javascript:;">全部 {{svg "octicon-chevron-right" 16}}</a> | |||
| </div> | |||
| </h4> | |||
| <div class="ui members"> | |||
| <div class="ui members" id="contributorInfo"> | |||
| {{range .ContributorInfo}} | |||
| {{/*<img class="ui avatar image" src="{{.UserInfo.RelAvatarLink}}" alt=""/> <a href="{{AppSubUrl}}/{{.UserInfo.Name}}">{{.UserInfo.Name}}</a>*/}} | |||
| {{if .UserInfo}} | |||
| <a href="{{AppSubUrl}}/{{.UserInfo.Name}}"><img class="ui avatar image" src="{{.UserInfo.RelAvatarLink}}" alt=""/></a> | |||
| <a href="{{AppSubUrl}}/{{.UserInfo.Name}}"><img class="ui avatar image" src="{{.UserInfo.RelAvatarLink}}"></a> | |||
| {{else if .Email}} | |||
| <a href="mailto:{{.Email}}"><img class="ui avatar image" src="{{AvatarLink .Email}}" alt=""/></a> | |||
| <a href="mailto:{{.Email}}" class="circular ui button">{{.Email}}</a> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| @@ -215,4 +255,12 @@ | |||
| </div> | |||
| </div> | |||
| <script type="text/javascript"> | |||
| $(document).ready(function(){ | |||
| $(".membersmore").click(function(){ | |||
| $("#contributorInfo > a:nth-child(n+25)").show(); | |||
| }); | |||
| }); | |||
| </script> | |||
| {{template "base/footer" .}} | |||