mirror of
https://github.com/go-gitea/gitea.git
synced 2025-11-08 05:02:38 +09:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46bb1cf026 | ||
|
|
13013e90f3 | ||
|
|
785ba171f4 | ||
|
|
fb80265b52 | ||
|
|
6fae585d28 | ||
|
|
670562a9c5 |
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [1.2.1](https://github.com/go-gitea/gitea/releases/tag/v1.2.1) - 2017-10-16
|
||||||
|
* BUGFIXES
|
||||||
|
* Fix PR, milestone and label functionality if issue unit is disabled (#2710) (#2714)
|
||||||
|
* Fix plain readme didn't render correctly on repo home page (#2705) (#2712)
|
||||||
|
* Fix so that user can still fork his own repository to his organizations (#2699) (#2707)
|
||||||
|
* Fix .netrc authentication (#2700) (#2708)
|
||||||
|
* Fix slice out of bounds error in mailer (#2479) (#2696)
|
||||||
|
|
||||||
## [1.2.0](https://github.com/go-gitea/gitea/releases/tag/v1.2.0) - 2017-10-10
|
## [1.2.0](https://github.com/go-gitea/gitea/releases/tag/v1.2.0) - 2017-10-10
|
||||||
* SECURITY
|
* SECURITY
|
||||||
* Sanitation fix from Gogs (#1461)
|
* Sanitation fix from Gogs (#1461)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func testPullCreate(t *testing.T, session *TestSession, user, repo, branch strin
|
|||||||
func TestPullCreate(t *testing.T) {
|
func TestPullCreate(t *testing.T) {
|
||||||
prepareTestEnv(t)
|
prepareTestEnv(t)
|
||||||
session := loginUser(t, "user1")
|
session := loginUser(t, "user1")
|
||||||
testRepoFork(t, session)
|
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
||||||
testEditFile(t, session, "user1", "repo1", "master", "README.md")
|
testEditFile(t, session, "user1", "repo1", "master", "README.md")
|
||||||
testPullCreate(t, session, "user1", "repo1", "master")
|
testPullCreate(t, session, "user1", "repo1", "master")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func testPullCleanUp(t *testing.T, session *TestSession, user, repo, pullnum str
|
|||||||
func TestPullMerge(t *testing.T) {
|
func TestPullMerge(t *testing.T) {
|
||||||
prepareTestEnv(t)
|
prepareTestEnv(t)
|
||||||
session := loginUser(t, "user1")
|
session := loginUser(t, "user1")
|
||||||
testRepoFork(t, session)
|
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
||||||
testEditFile(t, session, "user1", "repo1", "master", "README.md")
|
testEditFile(t, session, "user1", "repo1", "master", "README.md")
|
||||||
|
|
||||||
resp := testPullCreate(t, session, "user1", "repo1", "master")
|
resp := testPullCreate(t, session, "user1", "repo1", "master")
|
||||||
@@ -61,7 +61,7 @@ func TestPullMerge(t *testing.T) {
|
|||||||
func TestPullCleanUpAfterMerge(t *testing.T) {
|
func TestPullCleanUpAfterMerge(t *testing.T) {
|
||||||
prepareTestEnv(t)
|
prepareTestEnv(t)
|
||||||
session := loginUser(t, "user1")
|
session := loginUser(t, "user1")
|
||||||
testRepoFork(t, session)
|
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
||||||
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "feature/test", "README.md")
|
testEditFileToNewBranch(t, session, "user1", "repo1", "master", "feature/test", "README.md")
|
||||||
|
|
||||||
resp := testPullCreate(t, session, "user1", "repo1", "feature/test")
|
resp := testPullCreate(t, session, "user1", "repo1", "feature/test")
|
||||||
|
|||||||
@@ -5,19 +5,24 @@
|
|||||||
package integrations
|
package integrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testRepoFork(t *testing.T, session *TestSession) *TestResponse {
|
func testRepoFork(t *testing.T, session *TestSession, ownerName, repoName, forkOwnerName, forkRepoName string) *TestResponse {
|
||||||
|
forkOwner := models.AssertExistsAndLoadBean(t, &models.User{Name: forkOwnerName}).(*models.User)
|
||||||
|
|
||||||
// Step0: check the existence of the to-fork repo
|
// Step0: check the existence of the to-fork repo
|
||||||
req := NewRequest(t, "GET", "/user1/repo1")
|
req := NewRequestf(t, "GET", "/%s/%s", forkOwnerName, forkRepoName)
|
||||||
resp := session.MakeRequest(t, req, http.StatusNotFound)
|
resp := session.MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
|
||||||
// Step1: go to the main page of repo
|
// Step1: go to the main page of repo
|
||||||
req = NewRequest(t, "GET", "/user2/repo1")
|
req = NewRequestf(t, "GET", "/%s/%s", ownerName, repoName)
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
// Step2: click the fork button
|
// Step2: click the fork button
|
||||||
@@ -31,15 +36,17 @@ func testRepoFork(t *testing.T, session *TestSession) *TestResponse {
|
|||||||
htmlDoc = NewHTMLParser(t, resp.Body)
|
htmlDoc = NewHTMLParser(t, resp.Body)
|
||||||
link, exists = htmlDoc.doc.Find("form.ui.form[action^=\"/repo/fork/\"]").Attr("action")
|
link, exists = htmlDoc.doc.Find("form.ui.form[action^=\"/repo/fork/\"]").Attr("action")
|
||||||
assert.True(t, exists, "The template has changed")
|
assert.True(t, exists, "The template has changed")
|
||||||
|
_, exists = htmlDoc.doc.Find(fmt.Sprintf(".owner.dropdown .item[data-value=\"%d\"]", forkOwner.ID)).Attr("data-value")
|
||||||
|
assert.True(t, exists, fmt.Sprintf("Fork owner '%s' is not present in select box", forkOwnerName))
|
||||||
req = NewRequestWithValues(t, "POST", link, map[string]string{
|
req = NewRequestWithValues(t, "POST", link, map[string]string{
|
||||||
"_csrf": htmlDoc.GetCSRF(),
|
"_csrf": htmlDoc.GetCSRF(),
|
||||||
"uid": "1",
|
"uid": fmt.Sprintf("%d", forkOwner.ID),
|
||||||
"repo_name": "repo1",
|
"repo_name": forkRepoName,
|
||||||
})
|
})
|
||||||
resp = session.MakeRequest(t, req, http.StatusFound)
|
resp = session.MakeRequest(t, req, http.StatusFound)
|
||||||
|
|
||||||
// Step4: check the existence of the forked repo
|
// Step4: check the existence of the forked repo
|
||||||
req = NewRequest(t, "GET", "/user1/repo1")
|
req = NewRequestf(t, "GET", "/%s/%s", forkOwnerName, forkRepoName)
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
return resp
|
return resp
|
||||||
@@ -48,5 +55,19 @@ func testRepoFork(t *testing.T, session *TestSession) *TestResponse {
|
|||||||
func TestRepoFork(t *testing.T) {
|
func TestRepoFork(t *testing.T) {
|
||||||
prepareTestEnv(t)
|
prepareTestEnv(t)
|
||||||
session := loginUser(t, "user1")
|
session := loginUser(t, "user1")
|
||||||
testRepoFork(t, session)
|
testRepoFork(t, session, "user2", "repo1", "user1", "repo1")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRepoForkToOrg(t *testing.T) {
|
||||||
|
prepareTestEnv(t)
|
||||||
|
session := loginUser(t, "user2")
|
||||||
|
testRepoFork(t, session, "user2", "repo1", "user3", "repo1")
|
||||||
|
|
||||||
|
// Check that no more forking is allowed as user2 owns repository
|
||||||
|
// and user3 organization that owner user2 is also now has forked this repository
|
||||||
|
req := NewRequest(t, "GET", "/user2/repo1")
|
||||||
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
|
htmlDoc := NewHTMLParser(t, resp.Body)
|
||||||
|
_, exists := htmlDoc.doc.Find("a.ui.button[href^=\"/repo/fork/\"]").Attr("href")
|
||||||
|
assert.False(t, exists, "Forking should not be allowed anymore")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -409,6 +409,21 @@ func (repo *Repository) UnitEnabled(tp UnitType) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AnyUnitEnabled if this repository has the any of the given units enabled
|
||||||
|
func (repo *Repository) AnyUnitEnabled(tps ...UnitType) bool {
|
||||||
|
if err := repo.getUnits(x); err != nil {
|
||||||
|
log.Warn("Error loading repository (ID: %d) units: %s", repo.ID, err.Error())
|
||||||
|
}
|
||||||
|
for _, unit := range repo.Units {
|
||||||
|
for _, tp := range tps {
|
||||||
|
if unit.Type == tp {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrUnitNotExist organization does not exist
|
// ErrUnitNotExist organization does not exist
|
||||||
ErrUnitNotExist = errors.New("Unit does not exist")
|
ErrUnitNotExist = errors.New("Unit does not exist")
|
||||||
@@ -651,6 +666,25 @@ func (repo *Repository) CanBeForked() bool {
|
|||||||
return !repo.IsBare && repo.UnitEnabled(UnitTypeCode)
|
return !repo.IsBare && repo.UnitEnabled(UnitTypeCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CanUserFork returns true if specified user can fork repository.
|
||||||
|
func (repo *Repository) CanUserFork(user *User) (bool, error) {
|
||||||
|
if user == nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if repo.OwnerID != user.ID && !user.HasForkedRepo(repo.ID) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if err := user.GetOwnedOrganizations(); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
for _, org := range user.OwnedOrgs {
|
||||||
|
if repo.OwnerID != org.ID && !org.HasForkedRepo(repo.ID) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CanEnablePulls returns true if repository meets the requirements of accepting pulls.
|
// CanEnablePulls returns true if repository meets the requirements of accepting pulls.
|
||||||
func (repo *Repository) CanEnablePulls() bool {
|
func (repo *Repository) CanEnablePulls() bool {
|
||||||
return !repo.IsMirror && !repo.IsBare
|
return !repo.IsMirror && !repo.IsBare
|
||||||
|
|||||||
@@ -364,6 +364,11 @@ func RepoAssignment() macaron.Handler {
|
|||||||
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
|
ctx.Data["IsRepositoryAdmin"] = ctx.Repo.IsAdmin()
|
||||||
ctx.Data["IsRepositoryWriter"] = ctx.Repo.IsWriter()
|
ctx.Data["IsRepositoryWriter"] = ctx.Repo.IsWriter()
|
||||||
|
|
||||||
|
if ctx.Data["CanSignedUserFork"], err = ctx.Repo.Repository.CanUserFork(ctx.User); err != nil {
|
||||||
|
ctx.Handle(500, "CanUserFork", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["DisableSSH"] = setting.SSH.Disabled
|
ctx.Data["DisableSSH"] = setting.SSH.Disabled
|
||||||
ctx.Data["ExposeAnonSSH"] = setting.SSH.ExposeAnonymous
|
ctx.Data["ExposeAnonSSH"] = setting.SSH.ExposeAnonymous
|
||||||
ctx.Data["DisableHTTP"] = setting.Repository.DisableHTTPGit
|
ctx.Data["DisableHTTP"] = setting.Repository.DisableHTTPGit
|
||||||
@@ -609,6 +614,15 @@ func CheckUnit(unitType models.UnitType) macaron.Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckAnyUnit will check whether any of the unit types are enabled
|
||||||
|
func CheckAnyUnit(unitTypes ...models.UnitType) macaron.Handler {
|
||||||
|
return func(ctx *Context) {
|
||||||
|
if !ctx.Repo.Repository.AnyUnitEnabled(unitTypes...) {
|
||||||
|
ctx.Handle(404, "CheckAnyUnit", fmt.Errorf("%s: %v", ctx.Tr("units.error.unit_not_allowed"), unitTypes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GitHookService checks if repository Git hooks service has been enabled.
|
// GitHookService checks if repository Git hooks service has been enabled.
|
||||||
func GitHookService() macaron.Handler {
|
func GitHookService() macaron.Handler {
|
||||||
return func(ctx *Context) {
|
return func(ctx *Context) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/base"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ func NewMessageFrom(to []string, from, subject, body string) *Message {
|
|||||||
|
|
||||||
plainBody, err := html2text.FromString(body)
|
plainBody, err := html2text.FromString(body)
|
||||||
if err != nil || setting.MailService.SendAsPlainText {
|
if err != nil || setting.MailService.SendAsPlainText {
|
||||||
if strings.Contains(body[:100], "<html>") {
|
if strings.Contains(base.TruncateString(body, 100), "<html>") {
|
||||||
log.Warn("Mail contains HTML but configured to send as plain text.")
|
log.Warn("Mail contains HTML but configured to send as plain text.")
|
||||||
}
|
}
|
||||||
msg.SetBody("text/plain", plainBody)
|
msg.SetBody("text/plain", plainBody)
|
||||||
|
|||||||
@@ -139,8 +139,16 @@ func HTTP(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if authUser == nil {
|
if authUser == nil {
|
||||||
authUser, err = models.GetUserByName(authUsername)
|
isUsernameToken := len(authPasswd) == 0 || authPasswd == "x-oauth-basic"
|
||||||
|
|
||||||
|
// Assume username is token
|
||||||
|
authToken := authUsername
|
||||||
|
|
||||||
|
if !isUsernameToken {
|
||||||
|
// Assume password is token
|
||||||
|
authToken = authPasswd
|
||||||
|
|
||||||
|
authUser, err = models.GetUserByName(authUsername)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrUserNotExist(err) {
|
if models.IsErrUserNotExist(err) {
|
||||||
ctx.HandleText(http.StatusUnauthorized, "invalid credentials")
|
ctx.HandleText(http.StatusUnauthorized, "invalid credentials")
|
||||||
@@ -149,9 +157,10 @@ func HTTP(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Assume password is a token.
|
// Assume password is a token.
|
||||||
token, err := models.GetAccessTokenBySHA(authPasswd)
|
token, err := models.GetAccessTokenBySHA(authToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err) {
|
if models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err) {
|
||||||
ctx.HandleText(http.StatusUnauthorized, "invalid credentials")
|
ctx.HandleText(http.StatusUnauthorized, "invalid credentials")
|
||||||
@@ -161,7 +170,13 @@ func HTTP(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if authUser.ID != token.UID {
|
if isUsernameToken {
|
||||||
|
authUser, err = models.GetUserByID(token.UID)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Handle(http.StatusInternalServerError, "GetUserByID", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if authUser.ID != token.UID {
|
||||||
ctx.HandleText(http.StatusUnauthorized, "invalid credentials")
|
ctx.HandleText(http.StatusUnauthorized, "invalid credentials")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -170,7 +185,6 @@ func HTTP(ctx *context.Context) {
|
|||||||
if err = models.UpdateAccessToken(token); err != nil {
|
if err = models.UpdateAccessToken(token); err != nil {
|
||||||
ctx.Handle(http.StatusInternalServerError, "UpdateAccessToken", err)
|
ctx.Handle(http.StatusInternalServerError, "UpdateAccessToken", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
_, err = models.GetTwoFactorByUID(authUser.ID)
|
_, err = models.GetTwoFactorByUID(authUser.ID)
|
||||||
|
|
||||||
|
|||||||
@@ -676,11 +676,16 @@ func ViewIssue(ctx *context.Context) {
|
|||||||
func getActionIssue(ctx *context.Context) *models.Issue {
|
func getActionIssue(ctx *context.Context) *models.Issue {
|
||||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrIssueNotExist(err) {
|
ctx.NotFoundOrServerError("GetIssueByIndex", models.IsErrIssueNotExist, err)
|
||||||
ctx.Error(404, "GetIssueByIndex")
|
return nil
|
||||||
} else {
|
|
||||||
ctx.Handle(500, "GetIssueByIndex", err)
|
|
||||||
}
|
}
|
||||||
|
if issue.IsPull && !ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) ||
|
||||||
|
!issue.IsPull && !ctx.Repo.Repository.UnitEnabled(models.UnitTypeIssues) {
|
||||||
|
ctx.Handle(404, "IssueOrPullRequestUnitNotAllowed", nil)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err = issue.LoadAttributes(); err != nil {
|
||||||
|
ctx.Handle(500, "LoadAttributes", nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return issue
|
return issue
|
||||||
@@ -705,6 +710,19 @@ func getActionIssues(ctx *context.Context) []*models.Issue {
|
|||||||
ctx.Handle(500, "GetIssuesByIDs", err)
|
ctx.Handle(500, "GetIssuesByIDs", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// Check access rights for all issues
|
||||||
|
issueUnitEnabled := ctx.Repo.Repository.UnitEnabled(models.UnitTypeIssues)
|
||||||
|
prUnitEnabled := ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests)
|
||||||
|
for _, issue := range issues {
|
||||||
|
if issue.IsPull && !prUnitEnabled || !issue.IsPull && !issueUnitEnabled {
|
||||||
|
ctx.Handle(404, "IssueOrPullRequestUnitNotAllowed", nil)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err = issue.LoadAttributes(); err != nil {
|
||||||
|
ctx.Handle(500, "LoadAttributes", nil)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
return issues
|
return issues
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -840,9 +858,8 @@ func UpdateIssueStatus(ctx *context.Context) {
|
|||||||
|
|
||||||
// NewComment create a comment for issue
|
// NewComment create a comment for issue
|
||||||
func NewComment(ctx *context.Context, form auth.CreateCommentForm) {
|
func NewComment(ctx *context.Context, form auth.CreateCommentForm) {
|
||||||
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
|
issue := getActionIssue(ctx)
|
||||||
if err != nil {
|
if ctx.Written() {
|
||||||
ctx.NotFoundOrServerError("GetIssueByIndex", models.IsErrIssueNotExist, err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -869,7 +886,7 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) {
|
|||||||
|
|
||||||
if form.Status == "reopen" && issue.IsPull {
|
if form.Status == "reopen" && issue.IsPull {
|
||||||
pull := issue.PullRequest
|
pull := issue.PullRequest
|
||||||
pr, err = models.GetUnmergedPullRequest(pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch)
|
pr, err := models.GetUnmergedPullRequest(pull.HeadRepoID, pull.BaseRepoID, pull.HeadBranch, pull.BaseBranch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !models.IsErrPullRequestNotExist(err) {
|
if !models.IsErrPullRequestNotExist(err) {
|
||||||
ctx.Handle(500, "GetUnmergedPullRequest", err)
|
ctx.Handle(500, "GetUnmergedPullRequest", err)
|
||||||
@@ -891,7 +908,7 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) {
|
|||||||
if pr != nil {
|
if pr != nil {
|
||||||
ctx.Flash.Info(ctx.Tr("repo.pulls.open_unmerged_pull_exists", pr.Index))
|
ctx.Flash.Info(ctx.Tr("repo.pulls.open_unmerged_pull_exists", pr.Index))
|
||||||
} else {
|
} else {
|
||||||
if err = issue.ChangeStatus(ctx.User, ctx.Repo.Repository, form.Status == "close"); err != nil {
|
if err := issue.ChangeStatus(ctx.User, ctx.Repo.Repository, form.Status == "close"); err != nil {
|
||||||
log.Error(4, "ChangeStatus: %v", err)
|
log.Error(4, "ChangeStatus: %v", err)
|
||||||
} else {
|
} else {
|
||||||
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)
|
||||||
@@ -918,7 +935,7 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
comment, err = models.CreateIssueComment(ctx.User, ctx.Repo.Repository, issue, form.Content, attachments)
|
comment, err := models.CreateIssueComment(ctx.User, ctx.Repo.Repository, issue, form.Content, attachments)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, "CreateIssueComment", err)
|
ctx.Handle(500, "CreateIssueComment", err)
|
||||||
return
|
return
|
||||||
@@ -988,10 +1005,6 @@ func DeleteComment(ctx *context.Context) {
|
|||||||
|
|
||||||
// Milestones render milestones page
|
// Milestones render milestones page
|
||||||
func Milestones(ctx *context.Context) {
|
func Milestones(ctx *context.Context) {
|
||||||
MustEnableIssues(ctx)
|
|
||||||
if ctx.Written() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Title"] = ctx.Tr("repo.milestones")
|
ctx.Data["Title"] = ctx.Tr("repo.milestones")
|
||||||
ctx.Data["PageIsIssueList"] = true
|
ctx.Data["PageIsIssueList"] = true
|
||||||
ctx.Data["PageIsMilestones"] = true
|
ctx.Data["PageIsMilestones"] = true
|
||||||
|
|||||||
@@ -18,10 +18,6 @@ const (
|
|||||||
|
|
||||||
// Labels render issue's labels page
|
// Labels render issue's labels page
|
||||||
func Labels(ctx *context.Context) {
|
func Labels(ctx *context.Context) {
|
||||||
MustEnableIssues(ctx)
|
|
||||||
if ctx.Written() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Title"] = ctx.Tr("repo.labels")
|
ctx.Data["Title"] = ctx.Tr("repo.labels")
|
||||||
ctx.Data["PageIsIssueList"] = true
|
ctx.Data["PageIsIssueList"] = true
|
||||||
ctx.Data["PageIsLabels"] = true
|
ctx.Data["PageIsLabels"] = true
|
||||||
|
|||||||
@@ -21,10 +21,8 @@ func IssueWatch(c *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
issueIndex := c.ParamsInt64("index")
|
issue := getActionIssue(c)
|
||||||
issue, err := models.GetIssueByIndex(c.Repo.Repository.ID, issueIndex)
|
if c.Written() {
|
||||||
if err != nil {
|
|
||||||
c.Handle(http.StatusInternalServerError, "GetIssueByIndex", err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,6 +31,6 @@ func IssueWatch(c *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
url := fmt.Sprintf("%s/issues/%d", c.Repo.RepoLink, issueIndex)
|
url := fmt.Sprintf("%s/issues/%d", c.Repo.RepoLink, issue.Index)
|
||||||
c.Redirect(url, http.StatusSeeOther)
|
c.Redirect(url, http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ func getForkRepository(ctx *context.Context) *models.Repository {
|
|||||||
ctx.Data["repo_name"] = forkRepo.Name
|
ctx.Data["repo_name"] = forkRepo.Name
|
||||||
ctx.Data["description"] = forkRepo.Description
|
ctx.Data["description"] = forkRepo.Description
|
||||||
ctx.Data["IsPrivate"] = forkRepo.IsPrivate
|
ctx.Data["IsPrivate"] = forkRepo.IsPrivate
|
||||||
|
canForkToUser := forkRepo.OwnerID != ctx.User.ID && !ctx.User.HasForkedRepo(forkRepo.ID)
|
||||||
|
ctx.Data["CanForkToUser"] = canForkToUser
|
||||||
|
|
||||||
if err = forkRepo.GetOwner(); err != nil {
|
if err = forkRepo.GetOwner(); err != nil {
|
||||||
ctx.Handle(500, "GetOwner", err)
|
ctx.Handle(500, "GetOwner", err)
|
||||||
@@ -69,11 +71,23 @@ func getForkRepository(ctx *context.Context) *models.Repository {
|
|||||||
ctx.Data["ForkFrom"] = forkRepo.Owner.Name + "/" + forkRepo.Name
|
ctx.Data["ForkFrom"] = forkRepo.Owner.Name + "/" + forkRepo.Name
|
||||||
ctx.Data["ForkFromOwnerID"] = forkRepo.Owner.ID
|
ctx.Data["ForkFromOwnerID"] = forkRepo.Owner.ID
|
||||||
|
|
||||||
if err := ctx.User.GetOrganizations(true); err != nil {
|
if err := ctx.User.GetOwnedOrganizations(); err != nil {
|
||||||
ctx.Handle(500, "GetOrganizations", err)
|
ctx.Handle(500, "GetOwnedOrganizations", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ctx.Data["Orgs"] = ctx.User.Orgs
|
var orgs []*models.User
|
||||||
|
for _, org := range ctx.User.OwnedOrgs {
|
||||||
|
if forkRepo.OwnerID != org.ID && !org.HasForkedRepo(forkRepo.ID) {
|
||||||
|
orgs = append(orgs, org)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.Data["Orgs"] = orgs
|
||||||
|
|
||||||
|
if canForkToUser {
|
||||||
|
ctx.Data["ContextUser"] = ctx.User
|
||||||
|
} else if len(orgs) > 0 {
|
||||||
|
ctx.Data["ContextUser"] = orgs[0]
|
||||||
|
}
|
||||||
|
|
||||||
return forkRepo
|
return forkRepo
|
||||||
}
|
}
|
||||||
@@ -87,7 +101,6 @@ func Fork(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["ContextUser"] = ctx.User
|
|
||||||
ctx.HTML(200, tplFork)
|
ctx.HTML(200, tplFork)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,15 +108,16 @@ func Fork(ctx *context.Context) {
|
|||||||
func ForkPost(ctx *context.Context, form auth.CreateRepoForm) {
|
func ForkPost(ctx *context.Context, form auth.CreateRepoForm) {
|
||||||
ctx.Data["Title"] = ctx.Tr("new_fork")
|
ctx.Data["Title"] = ctx.Tr("new_fork")
|
||||||
|
|
||||||
|
ctxUser := checkContextUser(ctx, form.UID)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
forkRepo := getForkRepository(ctx)
|
forkRepo := getForkRepository(ctx)
|
||||||
if ctx.Written() {
|
if ctx.Written() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctxUser := checkContextUser(ctx, form.UID)
|
|
||||||
if ctx.Written() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["ContextUser"] = ctxUser
|
ctx.Data["ContextUser"] = ctxUser
|
||||||
|
|
||||||
if ctx.HasError() {
|
if ctx.HasError() {
|
||||||
|
|||||||
@@ -93,16 +93,12 @@ func renderDirectory(ctx *context.Context, treeLink string) {
|
|||||||
if isTextFile {
|
if isTextFile {
|
||||||
d, _ := ioutil.ReadAll(dataRc)
|
d, _ := ioutil.ReadAll(dataRc)
|
||||||
buf = append(buf, d...)
|
buf = append(buf, d...)
|
||||||
newbuf := markup.Render(readmeFile.Name(), buf, treeLink, ctx.Repo.Repository.ComposeMetas())
|
ctx.Data["IsRenderedHTML"] = true
|
||||||
if newbuf != nil {
|
if markup.Type(readmeFile.Name()) != "" {
|
||||||
ctx.Data["IsMarkdown"] = true
|
ctx.Data["FileContent"] = string(markup.Render(readmeFile.Name(), buf, treeLink, ctx.Repo.Repository.ComposeMetas()))
|
||||||
} else {
|
} else {
|
||||||
// FIXME This is the only way to show non-markdown files
|
ctx.Data["FileContent"] = string(bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1))
|
||||||
// instead of a broken "View Raw" link
|
|
||||||
ctx.Data["IsMarkdown"] = true
|
|
||||||
newbuf = bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1)
|
|
||||||
}
|
}
|
||||||
ctx.Data["FileContent"] = string(newbuf)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,15 +184,14 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
|||||||
d, _ := ioutil.ReadAll(dataRc)
|
d, _ := ioutil.ReadAll(dataRc)
|
||||||
buf = append(buf, d...)
|
buf = append(buf, d...)
|
||||||
|
|
||||||
tp := markup.Type(blob.Name())
|
readmeExist := markup.IsReadmeFile(blob.Name())
|
||||||
isSupportedMarkup := tp != ""
|
|
||||||
// FIXME: currently set IsMarkdown for compatible
|
|
||||||
ctx.Data["IsMarkdown"] = isSupportedMarkup
|
|
||||||
|
|
||||||
readmeExist := isSupportedMarkup || markup.IsReadmeFile(blob.Name())
|
|
||||||
ctx.Data["ReadmeExist"] = readmeExist
|
ctx.Data["ReadmeExist"] = readmeExist
|
||||||
if readmeExist && isSupportedMarkup {
|
if markup.Type(blob.Name()) != "" {
|
||||||
|
ctx.Data["IsRenderedHTML"] = true
|
||||||
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
|
ctx.Data["FileContent"] = string(markup.Render(blob.Name(), buf, path.Dir(treeLink), ctx.Repo.Repository.ComposeMetas()))
|
||||||
|
} else if readmeExist {
|
||||||
|
ctx.Data["IsRenderedHTML"] = true
|
||||||
|
ctx.Data["FileContent"] = string(bytes.Replace(buf, []byte("\n"), []byte(`<br>`), -1))
|
||||||
} else {
|
} else {
|
||||||
// Building code view blocks with line number on server side.
|
// Building code view blocks with line number on server side.
|
||||||
var fileContent string
|
var fileContent string
|
||||||
|
|||||||
@@ -471,12 +471,13 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action)
|
m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action)
|
||||||
|
|
||||||
m.Group("/:username/:reponame", func() {
|
m.Group("/:username/:reponame", func() {
|
||||||
// FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest.
|
|
||||||
// So they can apply their own enable/disable logic on routers.
|
|
||||||
m.Group("/issues", func() {
|
m.Group("/issues", func() {
|
||||||
m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue).
|
m.Combo("/new", repo.MustEnableIssues).Get(context.RepoRef(), repo.NewIssue).
|
||||||
Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
|
Post(bindIgnErr(auth.CreateIssueForm{}), repo.NewIssuePost)
|
||||||
|
}, context.CheckUnit(models.UnitTypeIssues))
|
||||||
|
// FIXME: should use different URLs but mostly same logic for comments of issue and pull reuqest.
|
||||||
|
// So they can apply their own enable/disable logic on routers.
|
||||||
|
m.Group("/issues", func() {
|
||||||
m.Group("/:index", func() {
|
m.Group("/:index", func() {
|
||||||
m.Post("/title", repo.UpdateIssueTitle)
|
m.Post("/title", repo.UpdateIssueTitle)
|
||||||
m.Post("/content", repo.UpdateIssueContent)
|
m.Post("/content", repo.UpdateIssueContent)
|
||||||
@@ -484,21 +485,21 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
m.Combo("/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
|
m.Combo("/comments").Post(bindIgnErr(auth.CreateCommentForm{}), repo.NewComment)
|
||||||
})
|
})
|
||||||
|
|
||||||
m.Post("/labels", repo.UpdateIssueLabel, reqRepoWriter)
|
m.Post("/labels", reqRepoWriter, repo.UpdateIssueLabel)
|
||||||
m.Post("/milestone", repo.UpdateIssueMilestone, reqRepoWriter)
|
m.Post("/milestone", reqRepoWriter, repo.UpdateIssueMilestone)
|
||||||
m.Post("/assignee", repo.UpdateIssueAssignee, reqRepoWriter)
|
m.Post("/assignee", reqRepoWriter, repo.UpdateIssueAssignee)
|
||||||
m.Post("/status", repo.UpdateIssueStatus, reqRepoWriter)
|
m.Post("/status", reqRepoWriter, repo.UpdateIssueStatus)
|
||||||
}, context.CheckUnit(models.UnitTypeIssues))
|
})
|
||||||
m.Group("/comments/:id", func() {
|
m.Group("/comments/:id", func() {
|
||||||
m.Post("", repo.UpdateCommentContent)
|
m.Post("", repo.UpdateCommentContent)
|
||||||
m.Post("/delete", repo.DeleteComment)
|
m.Post("/delete", repo.DeleteComment)
|
||||||
}, context.CheckUnit(models.UnitTypeIssues))
|
}, context.CheckAnyUnit(models.UnitTypeIssues, models.UnitTypePullRequests))
|
||||||
m.Group("/labels", func() {
|
m.Group("/labels", func() {
|
||||||
m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
|
m.Post("/new", bindIgnErr(auth.CreateLabelForm{}), repo.NewLabel)
|
||||||
m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
|
m.Post("/edit", bindIgnErr(auth.CreateLabelForm{}), repo.UpdateLabel)
|
||||||
m.Post("/delete", repo.DeleteLabel)
|
m.Post("/delete", repo.DeleteLabel)
|
||||||
m.Post("/initialize", bindIgnErr(auth.InitializeLabelsForm{}), repo.InitializeLabels)
|
m.Post("/initialize", bindIgnErr(auth.InitializeLabelsForm{}), repo.InitializeLabels)
|
||||||
}, reqRepoWriter, context.RepoRef(), context.CheckUnit(models.UnitTypeIssues))
|
}, reqRepoWriter, context.RepoRef(), context.CheckAnyUnit(models.UnitTypeIssues, models.UnitTypePullRequests))
|
||||||
m.Group("/milestones", func() {
|
m.Group("/milestones", func() {
|
||||||
m.Combo("/new").Get(repo.NewMilestone).
|
m.Combo("/new").Get(repo.NewMilestone).
|
||||||
Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
|
Post(bindIgnErr(auth.CreateMilestoneForm{}), repo.NewMilestonePost)
|
||||||
@@ -506,7 +507,7 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
|
m.Post("/:id/edit", bindIgnErr(auth.CreateMilestoneForm{}), repo.EditMilestonePost)
|
||||||
m.Get("/:id/:action", repo.ChangeMilestonStatus)
|
m.Get("/:id/:action", repo.ChangeMilestonStatus)
|
||||||
m.Post("/delete", repo.DeleteMilestone)
|
m.Post("/delete", repo.DeleteMilestone)
|
||||||
}, reqRepoWriter, context.RepoRef(), context.CheckUnit(models.UnitTypeIssues))
|
}, reqRepoWriter, context.RepoRef(), context.CheckAnyUnit(models.UnitTypeIssues, models.UnitTypePullRequests))
|
||||||
|
|
||||||
m.Combo("/compare/*", repo.MustAllowPulls, repo.SetEditorconfigIfExists).
|
m.Combo("/compare/*", repo.MustAllowPulls, repo.SetEditorconfigIfExists).
|
||||||
Get(repo.CompareAndPullRequest).
|
Get(repo.CompareAndPullRequest).
|
||||||
@@ -573,8 +574,8 @@ func RegisterRoutes(m *macaron.Macaron) {
|
|||||||
m.Group("", func() {
|
m.Group("", func() {
|
||||||
m.Get("/^:type(issues|pulls)$", repo.RetrieveLabels, repo.Issues)
|
m.Get("/^:type(issues|pulls)$", repo.RetrieveLabels, repo.Issues)
|
||||||
m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue)
|
m.Get("/^:type(issues|pulls)$/:index", repo.ViewIssue)
|
||||||
m.Get("/labels/", repo.RetrieveLabels, repo.Labels)
|
m.Get("/labels/", context.CheckAnyUnit(models.UnitTypeIssues, models.UnitTypePullRequests), repo.RetrieveLabels, repo.Labels)
|
||||||
m.Get("/milestones", repo.Milestones)
|
m.Get("/milestones", context.CheckAnyUnit(models.UnitTypeIssues, models.UnitTypePullRequests), repo.Milestones)
|
||||||
}, context.RepoRef())
|
}, context.RepoRef())
|
||||||
|
|
||||||
m.Group("/wiki", func() {
|
m.Group("/wiki", func() {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{{if .CanBeForked}}
|
{{if .CanBeForked}}
|
||||||
<div class="ui compact labeled button" tabindex="0">
|
<div class="ui compact labeled button" tabindex="0">
|
||||||
<a class="ui compact button {{if eq .OwnerID $.SignedUserID}}poping up{{end}}" {{if not (eq .OwnerID $.SignedUserID)}}href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{else}} data-content="{{$.i18n.Tr "repo.fork_from_self"}}" data-position="top center" data-variation="tiny"{{end}}>
|
<a class="ui compact button {{if not $.CanSignedUserFork}}poping up{{end}}" {{if $.CanSignedUserFork}}href="{{AppSubUrl}}/repo/fork/{{.ID}}"{{else}} data-content="{{$.i18n.Tr "repo.fork_from_self"}}" data-position="top center" data-variation="tiny"{{end}}>
|
||||||
<i class="octicon octicon-repo-forked"></i>{{$.i18n.Tr "repo.fork"}}
|
<i class="octicon octicon-repo-forked"></i>{{$.i18n.Tr "repo.fork"}}
|
||||||
</a>
|
</a>
|
||||||
<a class="ui basic label" href="{{.Link}}/forks">
|
<a class="ui basic label" href="{{.Link}}/forks">
|
||||||
|
|||||||
@@ -103,8 +103,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="issue-actions">
|
<div class="issue-actions">
|
||||||
<div class="ui basic status buttons">
|
<div class="ui basic status buttons">
|
||||||
<div class="ui green active basic button issue-action" data-action="open" data-url="{{$.Link}}/status">{{.i18n.Tr "repo.issues.action_open"}}</div>
|
<div class="ui green active basic button issue-action" data-action="open" data-url="{{$.RepoLink}}/issues/status">{{.i18n.Tr "repo.issues.action_open"}}</div>
|
||||||
<div class="ui red active basic button issue-action" data-action="close" data-url="{{$.Link}}/status">{{.i18n.Tr "repo.issues.action_close"}}</div>
|
<div class="ui red active basic button issue-action" data-action="close" data-url="{{$.RepoLink}}/issues/status">{{.i18n.Tr "repo.issues.action_close"}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ui secondary filter menu floated right">
|
<div class="ui secondary filter menu floated right">
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
{{range .Labels}}
|
{{range .Labels}}
|
||||||
<div class="item issue-action" data-action="toggle" data-element-id="{{.ID}}" data-url="{{$.Link}}/labels">
|
<div class="item issue-action" data-action="toggle" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/labels">
|
||||||
<span class="octicon {{if eq $.SelectLabels .ID}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name | Sanitize}}
|
<span class="octicon {{if eq $.SelectLabels .ID}}octicon-check{{end}}"></span><span class="label color" style="background-color: {{.Color}}"></span> {{.Name | Sanitize}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
{{.i18n.Tr "repo.issues.action_milestone_no_select"}}
|
{{.i18n.Tr "repo.issues.action_milestone_no_select"}}
|
||||||
</div>
|
</div>
|
||||||
{{range .Milestones}}
|
{{range .Milestones}}
|
||||||
<div class="item issue-action" data-element-id="{{.ID}}" data-url="{{$.Link}}/milestone">
|
<div class="item issue-action" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/milestone">
|
||||||
{{.Name | Sanitize}}
|
{{.Name | Sanitize}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
{{.i18n.Tr "repo.issues.action_assignee_no_select"}}
|
{{.i18n.Tr "repo.issues.action_assignee_no_select"}}
|
||||||
</div>
|
</div>
|
||||||
{{range .Assignees}}
|
{{range .Assignees}}
|
||||||
<div class="item issue-action" data-element-id="{{.ID}}" data-url="{{$.Link}}/assignee">
|
<div class="item issue-action" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/assignee">
|
||||||
<img src="{{.RelAvatarLink}}"> {{.Name}}
|
<img src="{{.RelAvatarLink}}"> {{.Name}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -19,18 +19,18 @@
|
|||||||
</span>
|
</span>
|
||||||
<i class="dropdown icon"></i>
|
<i class="dropdown icon"></i>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
|
{{if .CanForkToUser}}
|
||||||
<div class="item" data-value="{{.SignedUser.ID}}">
|
<div class="item" data-value="{{.SignedUser.ID}}">
|
||||||
<img class="ui mini image" src="{{.SignedUser.RelAvatarLink}}">
|
<img class="ui mini image" src="{{.SignedUser.RelAvatarLink}}">
|
||||||
{{.SignedUser.ShortName 20}}
|
{{.SignedUser.ShortName 20}}
|
||||||
</div>
|
</div>
|
||||||
|
{{end}}
|
||||||
{{range .Orgs}}
|
{{range .Orgs}}
|
||||||
{{if and (.IsOwnedBy $.SignedUser.ID) (ne .ID $.ForkFromOwnerID)}}
|
|
||||||
<div class="item" data-value="{{.ID}}">
|
<div class="item" data-value="{{.ID}}">
|
||||||
<img class="ui mini image" src="{{.RelAvatarLink}}">
|
<img class="ui mini image" src="{{.RelAvatarLink}}">
|
||||||
{{.ShortName 20}}
|
{{.ShortName 20}}
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{end}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -36,8 +36,8 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="ui attached table segment">
|
<div class="ui attached table segment">
|
||||||
<div class="file-view {{if .IsMarkdown}}markdown{{else if .IsTextFile}}code-view{{end}} has-emoji">
|
<div class="file-view {{if .IsRenderedHTML}}markdown{{else if .IsTextFile}}code-view{{end}} has-emoji">
|
||||||
{{if .IsMarkdown}}
|
{{if .IsRenderedHTML}}
|
||||||
{{if .FileContent}}{{.FileContent | Str2html}}{{end}}
|
{{if .FileContent}}{{.FileContent | Str2html}}{{end}}
|
||||||
{{else if not .IsTextFile}}
|
{{else if not .IsTextFile}}
|
||||||
<div class="view-raw ui center">
|
<div class="view-raw ui center">
|
||||||
|
|||||||
Reference in New Issue
Block a user