Fix issue pages URL params
parent
34f4af9ebf
commit
eb6021f73f
|
@ -22,6 +22,7 @@ type Issue struct {
|
||||||
Index int64 // Index in one repository.
|
Index int64 // Index in one repository.
|
||||||
Name string
|
Name string
|
||||||
RepoId int64 `xorm:"index"`
|
RepoId int64 `xorm:"index"`
|
||||||
|
Repo *Repository `xorm:"-"`
|
||||||
PosterId int64
|
PosterId int64
|
||||||
Poster *User `xorm:"-"`
|
Poster *User `xorm:"-"`
|
||||||
MilestoneId int64
|
MilestoneId int64
|
||||||
|
|
|
@ -436,7 +436,8 @@ func GetRepositoryByName(userId int64, repoName string) (*Repository, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRepositoryById returns the repository by given id if exists.
|
// GetRepositoryById returns the repository by given id if exists.
|
||||||
func GetRepositoryById(id int64) (repo *Repository, err error) {
|
func GetRepositoryById(id int64) (*Repository, error) {
|
||||||
|
repo := &Repository{}
|
||||||
has, err := orm.Id(id).Get(repo)
|
has, err := orm.Id(id).Get(repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -47,6 +47,7 @@ func HashEmail(email string) string {
|
||||||
return hex.EncodeToString(h.Sum(nil))
|
return hex.EncodeToString(h.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avatar represents the avatar object.
|
||||||
type Avatar struct {
|
type Avatar struct {
|
||||||
Hash string
|
Hash string
|
||||||
AlterImage string // image path
|
AlterImage string // image path
|
||||||
|
@ -96,8 +97,8 @@ func (this *Avatar) Encode(wr io.Writer, size int) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer fd.Close()
|
defer fd.Close()
|
||||||
img, err = jpeg.Decode(fd)
|
|
||||||
if err != nil {
|
if img, err = jpeg.Decode(fd); err != nil {
|
||||||
fd.Seek(0, os.SEEK_SET)
|
fd.Seek(0, os.SEEK_SET)
|
||||||
img, err = png.Decode(fd)
|
img, err = png.Decode(fd)
|
||||||
}
|
}
|
||||||
|
@ -110,8 +111,8 @@ func (this *Avatar) Encode(wr io.Writer, size int) (err error) {
|
||||||
}
|
}
|
||||||
imgPath = this.AlterImage
|
imgPath = this.AlterImage
|
||||||
}
|
}
|
||||||
img, err = decodeImageFile(imgPath)
|
|
||||||
if err != nil {
|
if img, err = decodeImageFile(imgPath); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
m := resize.Resize(uint(size), 0, img, resize.Lanczos3)
|
m := resize.Resize(uint(size), 0, img, resize.Lanczos3)
|
||||||
|
@ -124,8 +125,7 @@ func (this *Avatar) Update() {
|
||||||
this.imagePath)
|
this.imagePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *Avatar) UpdateTimeout(timeout time.Duration) error {
|
func (this *Avatar) UpdateTimeout(timeout time.Duration) (err error) {
|
||||||
var err error
|
|
||||||
select {
|
select {
|
||||||
case <-time.After(timeout):
|
case <-time.After(timeout):
|
||||||
err = fmt.Errorf("get gravatar image %s timeout", this.Hash)
|
err = fmt.Errorf("get gravatar image %s timeout", this.Hash)
|
||||||
|
@ -140,8 +140,7 @@ type service struct {
|
||||||
altImage string
|
altImage string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *service) mustInt(r *http.Request, defaultValue int, keys ...string) int {
|
func (this *service) mustInt(r *http.Request, defaultValue int, keys ...string) (v int) {
|
||||||
var v int
|
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
if _, err := fmt.Sscanf(r.FormValue(k), "%d", &v); err == nil {
|
if _, err := fmt.Sscanf(r.FormValue(k), "%d", &v); err == nil {
|
||||||
defaultValue = v
|
defaultValue = v
|
||||||
|
@ -176,8 +175,8 @@ func (this *service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("ETag", etag)
|
w.Header().Set("ETag", etag)
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "image/jpeg")
|
w.Header().Set("Content-Type", "image/jpeg")
|
||||||
err := avatar.Encode(w, size)
|
|
||||||
if err != nil {
|
if err := avatar.Encode(w, size); err != nil {
|
||||||
log.Warn("avatar encode error: %v", err)
|
log.Warn("avatar encode error: %v", err)
|
||||||
w.WriteHeader(500)
|
w.WriteHeader(500)
|
||||||
}
|
}
|
||||||
|
|
|
@ -412,6 +412,11 @@ func (f StrTo) Int() (int, error) {
|
||||||
return int(v), err
|
return int(v), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f StrTo) Int64() (int64, error) {
|
||||||
|
v, err := strconv.ParseInt(f.String(), 10, 64)
|
||||||
|
return int64(v), err
|
||||||
|
}
|
||||||
|
|
||||||
func (f StrTo) String() string {
|
func (f StrTo) String() string {
|
||||||
if f.Exist() {
|
if f.Exist() {
|
||||||
return string(f)
|
return string(f)
|
||||||
|
@ -541,16 +546,10 @@ func ActionDesc(act Actioner, avatarLink string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DiffTypeToStr(diffType int) string {
|
func DiffTypeToStr(diffType int) string {
|
||||||
switch diffType {
|
diffTypes := map[int]string{
|
||||||
case 1:
|
1: "add", 2: "modify", 3: "del",
|
||||||
return "add"
|
|
||||||
case 2:
|
|
||||||
return "modify"
|
|
||||||
case 3:
|
|
||||||
return "del"
|
|
||||||
default:
|
|
||||||
return "unknown"
|
|
||||||
}
|
}
|
||||||
|
return diffTypes[diffType]
|
||||||
}
|
}
|
||||||
|
|
||||||
func DiffLineTypeToStr(diffType int) string {
|
func DiffLineTypeToStr(diffType int) string {
|
||||||
|
|
|
@ -289,6 +289,9 @@ func Issues(ctx *middleware.Context) {
|
||||||
ctx.Data["ViewType"] = "all"
|
ctx.Data["ViewType"] = "all"
|
||||||
|
|
||||||
page, _ := base.StrTo(ctx.Query("page")).Int()
|
page, _ := base.StrTo(ctx.Query("page")).Int()
|
||||||
|
repoId, _ := base.StrTo(ctx.Query("repoid")).Int64()
|
||||||
|
|
||||||
|
ctx.Data["RepoId"] = repoId
|
||||||
|
|
||||||
var posterId int64 = 0
|
var posterId int64 = 0
|
||||||
if ctx.Query("type") == "created_by" {
|
if ctx.Query("type") == "created_by" {
|
||||||
|
@ -299,10 +302,12 @@ func Issues(ctx *middleware.Context) {
|
||||||
// Get all repositories.
|
// Get all repositories.
|
||||||
repos, err := models.GetRepositories(ctx.User)
|
repos, err := models.GetRepositories(ctx.User)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(200, "user.Issues(get repository)", err)
|
ctx.Handle(200, "user.Issues(get repositories)", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showRepos := make([]models.Repository, 0, len(repos))
|
||||||
|
|
||||||
var closedIssueCount, createdByCount int
|
var closedIssueCount, createdByCount int
|
||||||
|
|
||||||
// Get all issues.
|
// Get all issues.
|
||||||
|
@ -315,8 +320,18 @@ func Issues(ctx *middleware.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
closedIssueCount += repo.NumClosedIssues
|
closedIssueCount += repo.NumClosedIssues
|
||||||
repos[i].NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
|
|
||||||
|
// Set repository information to issues.
|
||||||
|
for j := range issues {
|
||||||
|
issues[j].Repo = &repos[i]
|
||||||
|
}
|
||||||
allIssues = append(allIssues, issues...)
|
allIssues = append(allIssues, issues...)
|
||||||
|
|
||||||
|
repos[i].NumOpenIssues = repo.NumIssues - repo.NumClosedIssues
|
||||||
|
if repos[i].NumOpenIssues > 0 {
|
||||||
|
showRepos = append(showRepos, repos[i])
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showIssues := make([]models.Issue, 0, len(allIssues))
|
showIssues := make([]models.Issue, 0, len(allIssues))
|
||||||
|
@ -335,12 +350,16 @@ func Issues(ctx *middleware.Context) {
|
||||||
createdByCount++
|
createdByCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if repoId > 0 && repoId != allIssues[i].Repo.Id {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if isShowClosed == allIssues[i].IsClosed {
|
if isShowClosed == allIssues[i].IsClosed {
|
||||||
showIssues = append(showIssues, allIssues[i])
|
showIssues = append(showIssues, allIssues[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["Repos"] = repos
|
ctx.Data["Repos"] = showRepos
|
||||||
ctx.Data["Issues"] = showIssues
|
ctx.Data["Issues"] = showIssues
|
||||||
ctx.Data["AllIssueCount"] = len(allIssues)
|
ctx.Data["AllIssueCount"] = len(allIssues)
|
||||||
ctx.Data["ClosedIssueCount"] = closedIssueCount
|
ctx.Data["ClosedIssueCount"] = closedIssueCount
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<div class="filter-option">
|
<div class="filter-option">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<a class="btn btn-default issue-open{{if not .IsShowClosed}} active{{end}}" href="/{{.RepositoryLink}}/issues">{{.OpenCount}} Open</a>
|
<a class="btn btn-default issue-open{{if not .IsShowClosed}} active{{end}}" href="/{{.RepositoryLink}}/issues?type={{.ViewType}}">{{.OpenCount}} Open</a>
|
||||||
<a class="btn btn-default issue-close{{if .IsShowClosed}} active{{end}}" href="/{{.RepositoryLink}}/issues?state=closed">{{.ClosedCount}} Closed</a>
|
<a class="btn btn-default issue-close{{if .IsShowClosed}} active{{end}}" href="/{{.RepositoryLink}}/issues?state=closed&type={{.ViewType}}">{{.ClosedCount}} Closed</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="issues list-group">
|
<div class="issues list-group">
|
||||||
|
|
|
@ -21,22 +21,22 @@
|
||||||
<li><a href="/issues?type=created_by"{{if eq .ViewType "created_by"}} class="active"{{end}}>Created by you <strong class="pull-right">{{.CreatedByCount}}</strong></a></li>
|
<li><a href="/issues?type=created_by"{{if eq .ViewType "created_by"}} class="active"{{end}}>Created by you <strong class="pull-right">{{.CreatedByCount}}</strong></a></li>
|
||||||
<li><hr/></li>
|
<li><hr/></li>
|
||||||
{{range .Repos}}
|
{{range .Repos}}
|
||||||
<li><a href="" class="sm">{{.OwnerId}}/{{.Name}} <strong class="pull-right">{{.NumOpenIssues}}</strong></a></li>
|
<li><a href="/issues?type={{$.ViewType}}{{if eq $.RepoId .Id}}{{else}}&repoid={{.Id}}{{end}}" class="sm{{if eq $.RepoId .Id}} active{{end}}">{{$.SignedUser.Name}}/{{.Name}} <strong class="pull-right">{{.NumOpenIssues}}</strong></a></li>
|
||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<div class="filter-option">
|
<div class="filter-option">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<a class="btn btn-default issue-open{{if not .IsShowClosed}} active{{end}}" href="/issues">{{.OpenIssueCount}} Open</a>
|
<a class="btn btn-default issue-open{{if not .IsShowClosed}} active{{end}}" href="/issues?type={{.ViewType}}&repoid={{.RepoId}}">{{.OpenIssueCount}} Open</a>
|
||||||
<a class="btn btn-default issue-close{{if .IsShowClosed}} active{{end}}" href="/issues?state=closed">{{.ClosedIssueCount}} Close</a>
|
<a class="btn btn-default issue-close{{if .IsShowClosed}} active{{end}}" href="/issues?state=closed&type={{.ViewType}}&repoid={{.RepoId}}">{{.ClosedIssueCount}} Close</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="issues list-group">
|
<div class="issues list-group">
|
||||||
{{range .Issues}}
|
{{range .Issues}}
|
||||||
<div class="list-group-item issue-item" id="issue-{{.Id}}">
|
<div class="list-group-item issue-item" id="issue-{{.Id}}">
|
||||||
<span class="number pull-right">#{{.Index}}</span>
|
<span class="number pull-right">#{{.Index}}</span>
|
||||||
<h5 class="title"><a href="/{{$.RepositoryLink}}/issues/{{.Index}}">{{.Name}}</a></h5>
|
<h5 class="title"><a href="/{{$.SignedUser.Name}}/{{.Repo.Name}}/issues/{{.Index}}">{{.Name}}</a></h5>
|
||||||
<p class="info">
|
<p class="info">
|
||||||
<span class="author"><img class="avatar" src="{{.Poster.AvatarLink}}" alt="" width="20"/>
|
<span class="author"><img class="avatar" src="{{.Poster.AvatarLink}}" alt="" width="20"/>
|
||||||
<a href="/user/{{.Poster.Name}}">{{.Poster.Name}}</a></span>
|
<a href="/user/{{.Poster.Name}}">{{.Poster.Name}}</a></span>
|
||||||
|
|
Loading…
Reference in New Issue