diff options
Diffstat (limited to 'routers/web/repo/issue_view.go')
-rw-r--r-- | routers/web/repo/issue_view.go | 92 |
1 files changed, 69 insertions, 23 deletions
diff --git a/routers/web/repo/issue_view.go b/routers/web/repo/issue_view.go index b312f1260a..d4458ed19e 100644 --- a/routers/web/repo/issue_view.go +++ b/routers/web/repo/issue_view.go @@ -9,6 +9,7 @@ import ( "net/http" "net/url" "sort" + "strconv" activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" @@ -31,6 +32,7 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/modules/templates/vars" + "code.gitea.io/gitea/modules/util" asymkey_service "code.gitea.io/gitea/services/asymkey" "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/context/upload" @@ -271,14 +273,29 @@ func combineLabelComments(issue *issues_model.Issue) { } } -// ViewIssue render issue view page -func ViewIssue(ctx *context.Context) { +func prepareIssueViewLoad(ctx *context.Context) *issues_model.Issue { + issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) + if err != nil { + ctx.NotFoundOrServerError("GetIssueByIndex", issues_model.IsErrIssueNotExist, err) + return nil + } + issue.Repo = ctx.Repo.Repository + ctx.Data["Issue"] = issue + + if err = issue.LoadPullRequest(ctx); err != nil { + ctx.ServerError("LoadPullRequest", err) + return nil + } + return issue +} + +func handleViewIssueRedirectExternal(ctx *context.Context) { if ctx.PathParam("type") == "issues" { // If issue was requested we check if repo has external tracker and redirect extIssueUnit, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypeExternalTracker) if err == nil && extIssueUnit != nil { if extIssueUnit.ExternalTrackerConfig().ExternalTrackerStyle == markup.IssueNameStyleNumeric || extIssueUnit.ExternalTrackerConfig().ExternalTrackerStyle == "" { - metas := ctx.Repo.Repository.ComposeMetas(ctx) + metas := ctx.Repo.Repository.ComposeCommentMetas(ctx) metas["index"] = ctx.PathParam("index") res, err := vars.Expand(extIssueUnit.ExternalTrackerConfig().ExternalTrackerFormat, metas) if err != nil { @@ -294,18 +311,18 @@ func ViewIssue(ctx *context.Context) { return } } +} - issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index")) - if err != nil { - if issues_model.IsErrIssueNotExist(err) { - ctx.NotFound(err) - } else { - ctx.ServerError("GetIssueByIndex", err) - } +// ViewIssue render issue view page +func ViewIssue(ctx *context.Context) { + handleViewIssueRedirectExternal(ctx) + if ctx.Written() { return } - if issue.Repo == nil { - issue.Repo = ctx.Repo.Repository + + issue := prepareIssueViewLoad(ctx) + if ctx.Written() { + return } // Make sure type and URL matches. @@ -337,12 +354,12 @@ func ViewIssue(ctx *context.Context) { ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled upload.AddUploadContext(ctx, "comment") - if err = issue.LoadAttributes(ctx); err != nil { + if err := issue.LoadAttributes(ctx); err != nil { ctx.ServerError("LoadAttributes", err) return } - if err = filterXRefComments(ctx, issue); err != nil { + if err := filterXRefComments(ctx, issue); err != nil { ctx.ServerError("filterXRefComments", err) return } @@ -351,7 +368,7 @@ func ViewIssue(ctx *context.Context) { if ctx.IsSigned { // Update issue-user. - if err = activities_model.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { + if err := activities_model.SetIssueReadBy(ctx, issue.ID, ctx.Doer.ID); err != nil { ctx.ServerError("ReadBy", err) return } @@ -365,15 +382,13 @@ func ViewIssue(ctx *context.Context) { prepareFuncs := []func(*context.Context, *issues_model.Issue){ prepareIssueViewContent, - func(ctx *context.Context, issue *issues_model.Issue) { - preparePullViewPullInfo(ctx, issue) - }, prepareIssueViewCommentsAndSidebarParticipants, - preparePullViewReviewAndMerge, prepareIssueViewSidebarWatch, prepareIssueViewSidebarTimeTracker, prepareIssueViewSidebarDependency, prepareIssueViewSidebarPin, + func(ctx *context.Context, issue *issues_model.Issue) { preparePullViewPullInfo(ctx, issue) }, + preparePullViewReviewAndMerge, } for _, prepareFunc := range prepareFuncs { @@ -412,9 +427,29 @@ func ViewIssue(ctx *context.Context) { return user_service.CanBlockUser(ctx, ctx.Doer, blocker, blockee) } + if issue.PullRequest != nil && !issue.PullRequest.IsChecking() && !setting.IsProd { + ctx.Data["PullMergeBoxReloadingInterval"] = 1 // in dev env, force using the reloading logic to make sure it won't break + } + ctx.HTML(http.StatusOK, tplIssueView) } +func ViewPullMergeBox(ctx *context.Context) { + issue := prepareIssueViewLoad(ctx) + if !issue.IsPull { + ctx.NotFound(nil) + return + } + preparePullViewPullInfo(ctx, issue) + preparePullViewReviewAndMerge(ctx, issue) + ctx.Data["PullMergeBoxReloading"] = issue.PullRequest.IsChecking() + + // TODO: it should use a dedicated struct to render the pull merge box, to make sure all data is prepared correctly + ctx.Data["IsIssuePoster"] = ctx.IsSigned && issue.IsPoster(ctx.Doer.ID) + ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) + ctx.HTML(http.StatusOK, tplPullMergeBox) +} + func prepareIssueViewSidebarDependency(ctx *context.Context, issue *issues_model.Issue) { if issue.IsPull && !ctx.Repo.CanRead(unit.TypeIssues) { ctx.Data["IssueDependencySearchType"] = "pulls" @@ -594,7 +629,9 @@ func prepareIssueViewCommentsAndSidebarParticipants(ctx *context.Context, issue comment.Issue = issue if comment.Type == issues_model.CommentTypeComment || comment.Type == issues_model.CommentTypeReview { - rctx := renderhelper.NewRenderContextRepoComment(ctx, issue.Repo) + rctx := renderhelper.NewRenderContextRepoComment(ctx, issue.Repo, renderhelper.RepoCommentOptions{ + FootnoteContextID: strconv.FormatInt(comment.ID, 10), + }) comment.RenderedContent, err = markdown.RenderString(rctx, comment.Content) if err != nil { ctx.ServerError("RenderString", err) @@ -670,7 +707,9 @@ func prepareIssueViewCommentsAndSidebarParticipants(ctx *context.Context, issue } } } else if comment.Type.HasContentSupport() { - rctx := renderhelper.NewRenderContextRepoComment(ctx, issue.Repo) + rctx := renderhelper.NewRenderContextRepoComment(ctx, issue.Repo, renderhelper.RepoCommentOptions{ + FootnoteContextID: strconv.FormatInt(comment.ID, 10), + }) comment.RenderedContent, err = markdown.RenderString(rctx, comment.Content) if err != nil { ctx.ServerError("RenderString", err) @@ -727,6 +766,9 @@ func prepareIssueViewCommentsAndSidebarParticipants(ctx *context.Context, issue } if !ctx.Repo.CanRead(unit.TypeActions) { for _, commit := range comment.Commits { + if commit.Status == nil { + continue + } commit.Status.HideActionsURL(ctx) git_model.CommitStatusesHideActionsURL(ctx, commit.Statuses) } @@ -792,6 +834,8 @@ func preparePullViewReviewAndMerge(ctx *context.Context, issue *issues_model.Iss allowMerge := false canWriteToHeadRepo := false + pull_service.StartPullRequestCheckOnView(ctx, pull) + if ctx.IsSigned { if err := pull.LoadHeadRepo(ctx); err != nil { log.Error("LoadHeadRepo: %v", err) @@ -838,6 +882,7 @@ func preparePullViewReviewAndMerge(ctx *context.Context, issue *issues_model.Iss } } + ctx.Data["PullMergeBoxReloadingInterval"] = util.Iif(pull != nil && pull.IsChecking(), 2000, 0) ctx.Data["CanWriteToHeadRepo"] = canWriteToHeadRepo ctx.Data["ShowMergeInstructions"] = canWriteToHeadRepo ctx.Data["AllowMerge"] = allowMerge @@ -948,7 +993,9 @@ func preparePullViewReviewAndMerge(ctx *context.Context, issue *issues_model.Iss func prepareIssueViewContent(ctx *context.Context, issue *issues_model.Issue) { var err error - rctx := renderhelper.NewRenderContextRepoComment(ctx, ctx.Repo.Repository) + rctx := renderhelper.NewRenderContextRepoComment(ctx, ctx.Repo.Repository, renderhelper.RepoCommentOptions{ + FootnoteContextID: "0", // Set footnote context ID to 0 for the issue content + }) issue.RenderedContent, err = markdown.RenderString(rctx, issue.Content) if err != nil { ctx.ServerError("RenderString", err) @@ -958,5 +1005,4 @@ func prepareIssueViewContent(ctx *context.Context, issue *issues_model.Issue) { ctx.ServerError("roleDescriptor", err) return } - ctx.Data["Issue"] = issue } |