@@ -1279,7 +1279,7 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, opts ...Cr | |||
} | |||
if setting.Service.AutoWatchNewRepos { | |||
if err = watchRepo(ctx.e, doer.ID, repo.ID, true); err != nil { | |||
if err = watchRepo(ctx.e, doer.ID, repo.ID, true, ReceiveAllNotification); err != nil { | |||
return fmt.Errorf("watchRepo: %v", err) | |||
} | |||
} | |||
@@ -24,6 +24,14 @@ const ( | |||
RepoWatchModeAuto // 3 | |||
) | |||
// NotifyType specifies what kind of watch the user has on a repository | |||
type NotifyType int8 | |||
const ( | |||
RejectAllNotification NotifyType = 0 | |||
ReceiveAllNotification NotifyType = 9 | |||
) | |||
var ActionChan = make(chan *Action, 200) | |||
var ActionChan4Task = make(chan Action, 200) | |||
@@ -34,6 +42,7 @@ type Watch struct { | |||
RepoID int64 `xorm:"UNIQUE(watch)"` | |||
Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` | |||
CreatedUnix int64 `xorm:"created"` | |||
NotifyType NotifyType `xorm:"SMALLINT NOT NULL DEFAULT 0"` | |||
} | |||
// getWatch gets what kind of subscription a user has on a given repository; returns dummy record if none found | |||
@@ -60,8 +69,20 @@ func IsWatching(userID, repoID int64) bool { | |||
return err == nil && isWatchMode(watch.Mode) | |||
} | |||
// GetWatchNotifyType | |||
func GetWatchNotifyType(userID, repoID int64) NotifyType { | |||
watch, err := getWatch(x, userID, repoID) | |||
if err != nil { | |||
return RejectAllNotification | |||
} | |||
return watch.NotifyType | |||
} | |||
func watchRepoMode(e Engine, watch Watch, mode RepoWatchMode) (err error) { | |||
if watch.Mode == mode { | |||
if _, err := e.ID(watch.ID).Cols("notify_type").Update(watch); err != nil { | |||
return err | |||
} | |||
return nil | |||
} | |||
if mode == RepoWatchModeAuto && (watch.Mode == RepoWatchModeDont || isWatchMode(watch.Mode)) { | |||
@@ -109,7 +130,7 @@ func WatchRepoMode(userID, repoID int64, mode RepoWatchMode) (err error) { | |||
return watchRepoMode(x, watch, mode) | |||
} | |||
func watchRepo(e Engine, userID, repoID int64, doWatch bool) (err error) { | |||
func watchRepo(e Engine, userID, repoID int64, doWatch bool, notifyTypes ...NotifyType) (err error) { | |||
var watch Watch | |||
if watch, err = getWatch(e, userID, repoID); err != nil { | |||
return err | |||
@@ -119,14 +140,19 @@ func watchRepo(e Engine, userID, repoID int64, doWatch bool) (err error) { | |||
} else if !doWatch { | |||
err = watchRepoMode(e, watch, RepoWatchModeNone) | |||
} else { | |||
notifyType := RejectAllNotification | |||
if len(notifyTypes) > 0 { | |||
notifyType = notifyTypes[0] | |||
} | |||
watch.NotifyType = notifyType | |||
err = watchRepoMode(e, watch, RepoWatchModeNormal) | |||
} | |||
return err | |||
} | |||
// WatchRepo watch or unwatch repository. | |||
func WatchRepo(userID, repoID int64, watch bool) (err error) { | |||
return watchRepo(x, userID, repoID, watch) | |||
func WatchRepo(userID, repoID int64, watch bool, notifyType ...NotifyType) (err error) { | |||
return watchRepo(x, userID, repoID, watch, notifyType...) | |||
} | |||
func getWatchers(e Engine, repoID int64) ([]*Watch, error) { | |||
@@ -156,6 +182,7 @@ func getRepoWatchersIDs(e Engine, repoID int64) ([]int64, error) { | |||
return ids, e.Table("watch"). | |||
Where("watch.repo_id=?", repoID). | |||
And("watch.mode<>?", RepoWatchModeDont). | |||
And("watch.notify_type > ?", RejectAllNotification). | |||
Select("user_id"). | |||
Find(&ids) | |||
} | |||
@@ -216,6 +216,27 @@ func (email *EmailAddress) updateActivation(e Engine, activate bool) error { | |||
return updateUserCols(e, user, "rands") | |||
} | |||
// UpdateEmailAddress update an email address of given user. | |||
func (email *EmailAddress) UpdateEmailAddress(newEmailAddress string) error { | |||
return email.updateEmailAddress(x, newEmailAddress) | |||
} | |||
func (email *EmailAddress) updateEmailAddress(e Engine, newEmailAddress string) error { | |||
user, err := getUserByID(e, email.UID) | |||
if err != nil { | |||
return err | |||
} | |||
if user.Rands, err = GetUserSalt(); err != nil { | |||
return err | |||
} | |||
user.Email = newEmailAddress | |||
user.AvatarEmail = newEmailAddress | |||
email.Email = newEmailAddress | |||
if _, err := e.ID(email.ID).Cols("email").Update(email); err != nil { | |||
return err | |||
} | |||
return updateUserCols(e, user, "email", "avatar_email") | |||
} | |||
// DeleteEmailAddress deletes an email address of given user. | |||
func DeleteEmailAddress(email *EmailAddress) (err error) { | |||
var deleted int64 | |||
@@ -88,6 +88,10 @@ type RegisterForm struct { | |||
Agree bool | |||
} | |||
type UpdateEmailForm struct { | |||
NewEmail string `binding:"Required;MaxSize(254)"` | |||
} | |||
// Validate valideates the fields | |||
func (f *RegisterForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
return validate(errs, ctx.Data, f, ctx.Locale) | |||
@@ -474,6 +474,7 @@ func RepoAssignment() macaron.Handler { | |||
if ctx.IsSigned { | |||
ctx.Data["IsWatchingRepo"] = models.IsWatching(ctx.User.ID, repo.ID) | |||
ctx.Data["WatchNotifyType"] = models.GetWatchNotifyType(ctx.User.ID, repo.ID) | |||
ctx.Data["IsStaringRepo"] = models.IsStaring(ctx.User.ID, repo.ID) | |||
ctx.Data["IsStaringDataset"] = models.IsDatasetStaringByRepoId(ctx.User.ID, repo.ID) | |||
@@ -389,9 +389,12 @@ authorize_application_created_by = This application was created by %s. | |||
authorize_application_description = If you grant the access, it will be able to access and write to all your account information, including private repos and organisations. | |||
authorize_title = Authorize "%s" to access your account? | |||
authorization_failed = Authorization failed | |||
authorization_failed_desc = The authorization failed because we detected an invalid request. Please contact the maintainer of the app you've tried to authorize. | |||
authorization_failed_desc = The authorization failed because we detected an invalid request. Please contact the maintainer of the app you have tried to authorize. | |||
disable_forgot_password_mail = Account recovery is disabled. Please contact your site administrator. | |||
sspi_auth_failed = SSPI authentication failed | |||
change_email = Change email | |||
change_email_address = Change email address | |||
new_email_address = New email address | |||
[phone] | |||
format_err=The format of phone number is wrong. | |||
query_err=Fail to query phone number, please try again later. | |||
@@ -1400,6 +1403,11 @@ star = Star | |||
fork = Fork | |||
download_archive = Download Repository | |||
star_fail=Failed to %s the dataset. | |||
watched=Watched | |||
notWatched=Not watched | |||
un_watch=Unwatch | |||
watch_all=Watch all | |||
watch_no_notify=Watch but not notify | |||
no_desc = No Description | |||
no_label = No labels | |||
@@ -396,6 +396,9 @@ authorization_failed=授权失败 | |||
authorization_failed_desc=授权失败,这是一个无效的请求。请联系尝试授权应用的管理员。 | |||
disable_forgot_password_mail = Account recovery is disabled. Please contact your site administrator. | |||
sspi_auth_failed=SSPI 认证失败 | |||
change_email=修改邮箱 | |||
change_email_address=修改邮箱地址 | |||
new_email_address=新邮箱地址 | |||
[phone] | |||
format_err=手机号格式错误。 | |||
query_err=查询手机号失败,请稍后再试。 | |||
@@ -1416,6 +1419,11 @@ star=点赞 | |||
fork=派生 | |||
download_archive=下载此项目 | |||
star_fail=%s失败。 | |||
watched=已关注 | |||
notWatched=未关注 | |||
un_watch=不关注 | |||
watch_all=关注所有动态 | |||
watch_no_notify=关注但不提醒动态 | |||
no_desc=暂无描述 | |||
@@ -123,8 +123,9 @@ func GetOverviewDuration(ctx *context.Context) { | |||
recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix | |||
now := time.Now() | |||
endTime := now | |||
// worker_server_num := 1 | |||
// cardNum := 1 | |||
var workServerNumber int64 | |||
var cardNum int64 | |||
durationAllSum := int64(0) | |||
cardDuSum := int64(0) | |||
@@ -138,52 +139,60 @@ func GetOverviewDuration(ctx *context.Context) { | |||
c2NetDuration := int64(0) | |||
cDCenterDuration := int64(0) | |||
cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||
Type: models.TypeCloudBrainAll, | |||
BeginTimeUnix: int64(recordBeginTime), | |||
EndTimeUnix: endTime.Unix(), | |||
}) | |||
if err != nil { | |||
ctx.ServerError("Get cloudbrains failed:", err) | |||
return | |||
} | |||
models.LoadSpecs4CloudbrainInfo(cloudbrains) | |||
for _, cloudbrain := range cloudbrains { | |||
cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain) | |||
CardDurationString := repo.GetCloudbrainCardDuration(cloudbrain.Cloudbrain) | |||
CardDuration := models.ConvertStrToDuration(CardDurationString) | |||
// if cloudbrain.Cloudbrain.WorkServerNumber >= 1 { | |||
// worker_server_num = cloudbrain.Cloudbrain.WorkServerNumber | |||
// } else { | |||
// worker_server_num = 1 | |||
// } | |||
// if cloudbrain.Cloudbrain.Spec == nil { | |||
// cardNum = 1 | |||
// } else { | |||
// cardNum = cloudbrain.Cloudbrain.Spec.AccCardsNum | |||
// } | |||
// duration := cloudbrain.Duration | |||
// duration := cloudbrain.Duration | |||
duration := models.ConvertStrToDuration(cloudbrain.TrainJobDuration) | |||
// CardDuration := cloudbrain.Duration * int64(worker_server_num) * int64(cardNum) | |||
if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne { | |||
cloudBrainOneDuration += duration | |||
cloudBrainOneCardDuSum += CardDuration | |||
} else if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo { | |||
cloudBrainTwoDuration += duration | |||
cloudBrainTwoCardDuSum += CardDuration | |||
} else if cloudbrain.Cloudbrain.Type == models.TypeC2Net { | |||
c2NetDuration += duration | |||
c2NetCardDuSum += CardDuration | |||
} else if cloudbrain.Cloudbrain.Type == models.TypeCDCenter { | |||
cDCenterDuration += duration | |||
cDNetCardDuSum += CardDuration | |||
page := 1 | |||
pagesize := 10000 | |||
count := pagesize | |||
// Each time a maximum of 10000 pieces of data are detected to the memory, batch processing | |||
for count == pagesize && count != 0 { | |||
cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{ | |||
ListOptions: models.ListOptions{ | |||
Page: page, | |||
PageSize: pagesize, | |||
}, | |||
Type: models.TypeCloudBrainAll, | |||
BeginTimeUnix: int64(recordBeginTime), | |||
EndTimeUnix: endTime.Unix(), | |||
}) | |||
if err != nil { | |||
ctx.ServerError("Get cloudbrains failed:", err) | |||
return | |||
} | |||
models.LoadSpecs4CloudbrainInfo(cloudbrains) | |||
for _, cloudbrain := range cloudbrains { | |||
cloudbrain = cloudbrainService.UpdateCloudbrainAiCenter(cloudbrain) | |||
if cloudbrain.Cloudbrain.Spec != nil { | |||
cardNum = int64(cloudbrain.Cloudbrain.Spec.AccCardsNum) | |||
} else { | |||
cardNum = 1 | |||
} | |||
if cloudbrain.Cloudbrain.WorkServerNumber >= 1 { | |||
workServerNumber = int64(cloudbrain.Cloudbrain.WorkServerNumber) | |||
} else { | |||
workServerNumber = 1 | |||
} | |||
duration := models.ConvertStrToDuration(cloudbrain.TrainJobDuration) | |||
CardDuration := workServerNumber * int64(cardNum) * duration | |||
if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne { | |||
cloudBrainOneDuration += duration | |||
cloudBrainOneCardDuSum += CardDuration | |||
} else if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo { | |||
cloudBrainTwoDuration += duration | |||
cloudBrainTwoCardDuSum += CardDuration | |||
} else if cloudbrain.Cloudbrain.Type == models.TypeC2Net { | |||
c2NetDuration += duration | |||
c2NetCardDuSum += CardDuration | |||
} else if cloudbrain.Cloudbrain.Type == models.TypeCDCenter { | |||
cDCenterDuration += duration | |||
cDNetCardDuSum += CardDuration | |||
} | |||
durationAllSum += duration | |||
cardDuSum += CardDuration | |||
durationAllSum += duration | |||
cardDuSum += CardDuration | |||
} | |||
count = len(cloudbrains) | |||
page += 1 | |||
} | |||
ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
"cloudBrainOneCardDuSum": cloudBrainOneCardDuSum, | |||
@@ -246,13 +246,20 @@ func getcloudBrainCenterCodeAndCardTypeInfo(ciTasks []*models.CloudbrainInfo, be | |||
func CloudbrainUpdateHistoryData(ctx *context.Context) { | |||
beginTimeStr := ctx.QueryTrim("beginTime") | |||
endTimeStr := ctx.QueryTrim("endTime") | |||
beginTime, _ := time.ParseInLocation("2006-01-02 15:04:05", beginTimeStr, time.Local) | |||
endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", endTimeStr, time.Local) | |||
beginTimeUnix := timeutil.TimeStamp(beginTime.Unix()) | |||
endTimeUnix := timeutil.TimeStamp(endTime.Unix()) | |||
var count int64 | |||
var err error | |||
if beginTimeStr != "" && endTimeStr != "" { | |||
beginTime, _ := time.ParseInLocation("2006-01-02 15:04:05", beginTimeStr, time.Local) | |||
endTime, _ := time.ParseInLocation("2006-01-02 15:04:05", endTimeStr, time.Local) | |||
if time.Now().Before(endTime) { | |||
endTime = time.Now() | |||
} | |||
beginTimeUnix := timeutil.TimeStamp(beginTime.Unix()) | |||
endTimeUnix := timeutil.TimeStamp(endTime.Unix()) | |||
err := models.DeleteCloudbrainDurationStatistic(beginTimeUnix, endTimeUnix) | |||
count := UpdateDurationStatisticHistoryData(beginTime, endTime) | |||
err = models.DeleteCloudbrainDurationStatistic(beginTimeUnix, endTimeUnix) | |||
count = UpdateDurationStatisticHistoryData(beginTime.Add(+1*time.Hour), endTime) | |||
} | |||
ctx.JSON(http.StatusOK, map[string]interface{}{ | |||
"message": 0, | |||
"count": count, | |||
@@ -414,7 +414,9 @@ func Action(ctx *context.Context) { | |||
var err error | |||
switch ctx.Params(":action") { | |||
case "watch": | |||
err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true) | |||
err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true, models.ReceiveAllNotification) | |||
case "watch_but_reject": | |||
err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, true, models.RejectAllNotification) | |||
case "unwatch": | |||
err = models.WatchRepo(ctx.User.ID, ctx.Repo.Repository.ID, false) | |||
case "star": | |||
@@ -518,6 +518,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
// r.Get("/feeds", binding.Bind(auth.FeedsForm{}), user.Feeds) | |||
m.Any("/activate", user.Activate, reqSignIn) | |||
m.Any("/activate_email", user.ActivateEmail) | |||
m.Post("/update_email", bindIgnErr(auth.UpdateEmailForm{}), user.UpdateEmailPost) | |||
m.Get("/avatar/:username/:size", user.Avatar) | |||
m.Get("/email2user", user.Email2User) | |||
m.Get("/recover_account", user.ResetPasswd) | |||
@@ -1413,6 +1413,34 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo | |||
handleSignInFull(ctx, u, false, true) | |||
} | |||
//update user emailAddress | |||
func UpdateEmailPost(ctx *context.Context, form auth.UpdateEmailForm) { | |||
newEmailAddress := ctx.Query("NewEmail") | |||
if newEmailAddress == "" { | |||
log.Error("please input the newEmail") | |||
return | |||
} | |||
if used, _ := models.IsEmailUsed(newEmailAddress); used { | |||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), TplActivate, &form) | |||
return | |||
} | |||
user := ctx.User | |||
email, err := models.GetEmailAddressByIDAndEmail(user.ID, user.Email) | |||
if err != nil { | |||
ctx.ServerError("GetEmailAddressByIDAndEmail failed", err) | |||
return | |||
} | |||
err = email.UpdateEmailAddress(newEmailAddress) | |||
if err != nil { | |||
ctx.ServerError("UpdateEmailAddress failed", err) | |||
return | |||
} | |||
ctx.Data["Email"] = newEmailAddress | |||
ctx.User.Email = newEmailAddress | |||
Activate(ctx) | |||
} | |||
// Activate render activate user page | |||
func Activate(ctx *context.Context) { | |||
code := ctx.Query("code") | |||
@@ -362,7 +362,7 @@ | |||
</tr> | |||
<tr class="ti-no-ng-animate"> | |||
<td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
创建人 | |||
{{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
</td> | |||
<td class="ti-text-form-content"> | |||
@@ -444,6 +444,7 @@ | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.BranchName}} | |||
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||
</div> | |||
</td> | |||
</tr> | |||
@@ -337,6 +337,7 @@ | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w" id="{{.VersionName}}-code"> | |||
{{.BranchName}} | |||
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||
</div> | |||
</td> | |||
</tr> | |||
@@ -410,6 +410,7 @@ | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.BranchName}} | |||
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||
</div> | |||
</td> | |||
</tr> | |||
@@ -422,6 +422,7 @@ | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.BranchName}} | |||
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||
</div> | |||
</td> | |||
</tr> | |||
@@ -51,6 +51,49 @@ | |||
</div> | |||
{{if not .IsBeingCreated}} | |||
<div class="repo-buttons"> | |||
<div class="ui labeled button" tabindex="0"> | |||
<div class="ui compact basic button" onclick="$('.__watch_btn__').dropdown('show')"> | |||
<i class="icon fa-eye{{if not $.IsWatchingRepo}}-slash{{end}}"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.watched"}}{{else}}{{$.i18n.Tr "repo.notWatched"}}{{end}} | |||
<i class="dropdown icon" style="margin:0 -8px 0 4px"></i> | |||
<div class="ui dropdown floating __watch_btn__" onclick="event.stopPropagation();"> | |||
<div class="text" style="display:none;"></div> | |||
{{$WatchNotifyType := or $.WatchNotifyType 0}} | |||
<div class="menu" style="margin-left:-64px;"> | |||
<div class="item {{if not $.IsWatchingRepo}}active selected{{end}}"> | |||
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/unwatch?redirect_to={{$.Link}}"> | |||
{{$.CsrfTokenHtml}} | |||
<button type="submit" style="border:none;background:transparent;width:100%;text-align:left;font-weight:inherit;cursor:pointer;"> | |||
<i class="check icon" style="{{if $.IsWatchingRepo}}opacity:0{{end}}"></i> | |||
{{$.i18n.Tr "repo.un_watch"}} | |||
</button> | |||
</form> | |||
</div> | |||
<div class="item {{if and $.IsWatchingRepo (eq $WatchNotifyType 9)}}active selected{{end}}"> | |||
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/watch?redirect_to={{$.Link}}"> | |||
{{$.CsrfTokenHtml}} | |||
<button type="submit" style="border:none;background:transparent;width:100%;text-align:left;font-weight:inherit;cursor:pointer;"> | |||
<i class="check icon" style="{{if not (and $.IsWatchingRepo (eq $WatchNotifyType 9))}}opacity:0{{end}}"></i> | |||
{{$.i18n.Tr "repo.watch_all"}} | |||
</button> | |||
</form> | |||
</div> | |||
<div class="item {{if and $.IsWatchingRepo (eq $WatchNotifyType 0)}}active selected{{end}}"> | |||
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/watch_but_reject?redirect_to={{$.Link}}"> | |||
{{$.CsrfTokenHtml}} | |||
<button type="submit" style="border:none;background:transparent;width:100%;text-align:left;font-weight:inherit;cursor:pointer;"> | |||
<i class="check icon" style="{{if not (and $.IsWatchingRepo (eq $WatchNotifyType 0))}}opacity:0{{end}}"></i> | |||
{{$.i18n.Tr "repo.watch_no_notify"}} | |||
</button> | |||
</form> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
<a class="ui basic label" href="{{.Link}}/watchers"> | |||
{{.NumWatches}} | |||
</a> | |||
</div> | |||
<!-- | |||
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}"> | |||
{{$.CsrfTokenHtml}} | |||
<div class="ui labeled button" tabindex="0"> | |||
@@ -61,7 +104,7 @@ | |||
{{.NumWatches}} | |||
</a> | |||
</div> | |||
</form> | |||
</form> --> | |||
<form method="post" style="margin: 0;" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}"> | |||
{{$.CsrfTokenHtml}} | |||
<div class="ui labeled button" tabindex="0"> | |||
@@ -388,6 +388,7 @@ td, th { | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.BranchName}} | |||
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||
</div> | |||
</td> | |||
</tr> | |||
@@ -442,6 +442,7 @@ | |||
<td class="ti-text-form-content"> | |||
<div class="text-span text-span-w"> | |||
{{.BranchName}} | |||
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span> | |||
</div> | |||
</td> | |||
</tr> | |||
@@ -833,6 +833,7 @@ | |||
$(`[vfield="Description"]`).text(res['Description'] || '--'); | |||
$(`[vfield="Parameters"]`).text(res['Parameters'] || '--'); | |||
$(`[vfield="BranchName"]`).html(res['BranchName'] + '<span style="margin-left:1rem" class="ui label">' + res['CommitID'].slice(0, 10) + '</span>'); | |||
var imageName = res['Image'] || res['EngineName']; | |||
$(`[vimagetitle="Image"] span`).hide(); | |||
@@ -15,7 +15,7 @@ | |||
{{else if .ResendLimited}} | |||
<p class="center">{{.i18n.Tr "auth.resent_limit_prompt"}}</p> | |||
{{else}} | |||
<p>{{.i18n.Tr "auth.confirmation_mail_sent_prompt" .SignedUser.Email .ActiveCodeLives | Str2html}}</p> | |||
<p>{{.i18n.Tr "auth.confirmation_mail_sent_prompt" .Email .ActiveCodeLives | Str2html}}</p> | |||
{{end}} | |||
{{else}} | |||
{{if .IsSendRegisterMail}} | |||
@@ -26,6 +26,7 @@ | |||
<p>{{.i18n.Tr "auth.has_unconfirmed_mail" .SignedUser.Name .SignedUser.Email | Str2html}}</p> | |||
<div class="ui divider"></div> | |||
<div class="text right"> | |||
<button type="button" class="ui blue button change">{{.i18n.Tr "auth.change_email"}}</button> | |||
<button class="ui blue button">{{.i18n.Tr "auth.resend_mail"}}</button> | |||
</div> | |||
{{end}} | |||
@@ -34,5 +35,32 @@ | |||
</form> | |||
</div> | |||
</div> | |||
<div> | |||
<div class="ui modal chang-email"> | |||
<div class="header" style="padding: 1rem;background-color: rgba(240, 240, 240, 100);"> | |||
<h4>{{.i18n.Tr "auth.change_email_address"}}</h4> | |||
</div> | |||
<form id="formId" action="{{AppSubUrl}}/user/update_email" method="POST" class="ui form"> | |||
<div class="content content-padding"> | |||
<div class="ui error message"> | |||
</div> | |||
{{$.CsrfTokenHtml}} | |||
<div class="inline required field"> | |||
<label>{{.i18n.Tr "auth.new_email_address"}}</label> | |||
<input style="width: 80%;" id="label" name="NewEmail" maxlength="255" value="{{.SignedUser.Email}}"> | |||
</div> | |||
</div> | |||
<div class="center actions"> | |||
<button class="ui green button">{{.i18n.Tr "repo.confirm_choice"}}</button> | |||
<div class="ui deny button">{{.i18n.Tr "cancel"}}</div> | |||
</div> | |||
</form> | |||
</div> | |||
</div> | |||
</div> | |||
{{template "base/footer" .}} | |||
<script> | |||
$('.ui.blue.button.change').on('click',function(){ | |||
$('.ui.modal').modal('show') | |||
}) | |||
</script> |
@@ -1301,3 +1301,17 @@ i.SUCCEEDED { | |||
max-height: 500px; | |||
overflow: auto; | |||
} | |||
.chang-email .content { | |||
display: block; | |||
width: 100%; | |||
font-size: 1em; | |||
line-height: 1.4; | |||
padding: 1.5rem; | |||
background: #fff; | |||
} | |||
.chang-email .actions { | |||
background: #f9fafb; | |||
padding: 1rem 1rem; | |||
border-top: 1px solid rgba(34,36,38,.15); | |||
text-align: right; | |||
} |
@@ -228,7 +228,7 @@ const en = { | |||
local: 'Local', | |||
online: 'Online', | |||
createModel: 'Create Model', | |||
importLocalModel: 'Import Lacal Model', | |||
importLocalModel: 'Import Local Model', | |||
importOnlineModel: 'Import Online Model', | |||
modifyModelInfo: 'Modify model information', | |||
addModelFiles: 'Add model files', | |||