* Don't display buttons if there are no notices * clear stopwatch on merging a PR * remove redundant gt check * use ctx.Flash as per @bkcsoft comment * stop timer on closing issues/PRs too * updated translation as per review * redirect to login page after successfully activating account * remove unrelated changes * stop timer for issues that are closed via commits too..Not just the 'close' UI buttontags/v1.21.12.1
| @@ -491,15 +491,27 @@ func changeIssueStatus(repo *Repository, doer *User, ref string, refMarked map[i | |||||
| return nil | return nil | ||||
| } | } | ||||
| stopTimerIfAvailable := func(doer *User, issue *Issue) error { | |||||
| if StopwatchExists(doer.ID, issue.ID) { | |||||
| if err := CreateOrStopIssueStopwatch(doer, issue); err != nil { | |||||
| return err | |||||
| } | |||||
| } | |||||
| return nil | |||||
| } | |||||
| issue.Repo = repo | issue.Repo = repo | ||||
| if err = issue.ChangeStatus(doer, status); err != nil { | if err = issue.ChangeStatus(doer, status); err != nil { | ||||
| // Don't return an error when dependencies are open as this would let the push fail | // Don't return an error when dependencies are open as this would let the push fail | ||||
| if IsErrDependenciesLeft(err) { | if IsErrDependenciesLeft(err) { | ||||
| return nil | |||||
| return stopTimerIfAvailable(doer, issue) | |||||
| } | } | ||||
| return err | return err | ||||
| } | } | ||||
| return nil | |||||
| return stopTimerIfAvailable(doer, issue) | |||||
| } | } | ||||
| // UpdateIssuesCommit checks if issues are manipulated by commit message. | // UpdateIssuesCommit checks if issues are manipulated by commit message. | ||||
| @@ -781,6 +781,7 @@ issues.tracker = Time Tracker | |||||
| issues.start_tracking_short = Start | issues.start_tracking_short = Start | ||||
| issues.start_tracking = Start Time Tracking | issues.start_tracking = Start Time Tracking | ||||
| issues.start_tracking_history = `started working %s` | issues.start_tracking_history = `started working %s` | ||||
| issues.tracker_auto_close = Timer will be stopped automatically when this issue gets closed | |||||
| issues.tracking_already_started = `You have already started time tracking on this <a href="%s">issue</a>!` | issues.tracking_already_started = `You have already started time tracking on this <a href="%s">issue</a>!` | ||||
| issues.stop_tracking = Stop | issues.stop_tracking = Stop | ||||
| issues.stop_tracking_history = `stopped working %s` | issues.stop_tracking_history = `stopped working %s` | ||||
| @@ -1181,6 +1181,12 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) { | |||||
| return | return | ||||
| } | } | ||||
| } else { | } else { | ||||
| if err := stopTimerIfAvailable(ctx.User, issue); err != nil { | |||||
| ctx.ServerError("CreateOrStopIssueStopwatch", err) | |||||
| return | |||||
| } | |||||
| log.Trace("Issue [%d] status changed to closed: %v", issue.ID, issue.IsClosed) | log.Trace("Issue [%d] status changed to closed: %v", issue.ID, issue.IsClosed) | ||||
| notification.NotifyIssueChangeStatus(ctx.User, issue, isClosed) | notification.NotifyIssueChangeStatus(ctx.User, issue, isClosed) | ||||
| @@ -17,6 +17,13 @@ func IssueStopwatch(c *context.Context) { | |||||
| if c.Written() { | if c.Written() { | ||||
| return | return | ||||
| } | } | ||||
| var showSuccessMessage bool | |||||
| if !models.StopwatchExists(c.User.ID, issue.ID) { | |||||
| showSuccessMessage = true | |||||
| } | |||||
| if !c.Repo.CanUseTimetracker(issue, c.User) { | if !c.Repo.CanUseTimetracker(issue, c.User) { | ||||
| c.NotFound("CanUseTimetracker", nil) | c.NotFound("CanUseTimetracker", nil) | ||||
| return | return | ||||
| @@ -27,6 +34,10 @@ func IssueStopwatch(c *context.Context) { | |||||
| return | return | ||||
| } | } | ||||
| if showSuccessMessage { | |||||
| c.Flash.Success(c.Tr("repo.issues.tracker_auto_close")) | |||||
| } | |||||
| url := issue.HTMLURL() | url := issue.HTMLURL() | ||||
| c.Redirect(url, http.StatusSeeOther) | c.Redirect(url, http.StatusSeeOther) | ||||
| } | } | ||||
| @@ -590,12 +590,28 @@ func MergePullRequest(ctx *context.Context, form auth.MergePullRequestForm) { | |||||
| return | return | ||||
| } | } | ||||
| if err := stopTimerIfAvailable(ctx.User, issue); err != nil { | |||||
| ctx.ServerError("CreateOrStopIssueStopwatch", err) | |||||
| return | |||||
| } | |||||
| notification.NotifyMergePullRequest(pr, ctx.User, ctx.Repo.GitRepo) | notification.NotifyMergePullRequest(pr, ctx.User, ctx.Repo.GitRepo) | ||||
| log.Trace("Pull request merged: %d", pr.ID) | log.Trace("Pull request merged: %d", pr.ID) | ||||
| ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pr.Index)) | ctx.Redirect(ctx.Repo.RepoLink + "/pulls/" + com.ToStr(pr.Index)) | ||||
| } | } | ||||
| func stopTimerIfAvailable(user *models.User, issue *models.Issue) error { | |||||
| if models.StopwatchExists(user.ID, issue.ID) { | |||||
| if err := models.CreateOrStopIssueStopwatch(user, issue); err != nil { | |||||
| return err | |||||
| } | |||||
| } | |||||
| return nil | |||||
| } | |||||
| // ParseCompareInfo parse compare info between two commit for preparing pull request | // ParseCompareInfo parse compare info between two commit for preparing pull request | ||||
| func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *git.Repository, *git.PullRequestInfo, string, string) { | func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *git.Repository, *git.PullRequestInfo, string, string) { | ||||
| baseRepo := ctx.Repo.Repository | baseRepo := ctx.Repo.Repository | ||||
| @@ -1,3 +1,4 @@ | |||||
| {{ template "base/alert" }} | |||||
| {{range .Issue.Comments}} | {{range .Issue.Comments}} | ||||
| {{ $createdStr:= TimeSinceUnix .CreatedUnix $.Lang }} | {{ $createdStr:= TimeSinceUnix .CreatedUnix $.Lang }} | ||||