parent
c62a6b7a12
commit
a49af93faf
File diff suppressed because one or more lines are too long
@ -0,0 +1,121 @@
|
|||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
api "github.com/gogits/go-gogs-client"
|
||||||
|
|
||||||
|
"github.com/gogits/gogs/models"
|
||||||
|
"github.com/gogits/gogs/modules/middleware"
|
||||||
|
"github.com/gogits/gogs/routers/api/v1/convert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func responseApiUsers(ctx *middleware.Context, users []*models.User) {
|
||||||
|
apiUsers := make([]*api.User, len(users))
|
||||||
|
for i := range users {
|
||||||
|
apiUsers[i] = convert.ToApiUser(users[i])
|
||||||
|
}
|
||||||
|
ctx.JSON(200, &apiUsers)
|
||||||
|
}
|
||||||
|
|
||||||
|
func listUserFollowers(ctx *middleware.Context, u *models.User) {
|
||||||
|
users, err := u.GetFollowers(ctx.QueryInt("page"))
|
||||||
|
if err != nil {
|
||||||
|
ctx.APIError(500, "GetUserFollowers", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
responseApiUsers(ctx, users)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListMyFollowers(ctx *middleware.Context) {
|
||||||
|
listUserFollowers(ctx, ctx.User)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#list-followers-of-a-user
|
||||||
|
func ListFollowers(ctx *middleware.Context) {
|
||||||
|
u := GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
listUserFollowers(ctx, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
func listUserFollowing(ctx *middleware.Context, u *models.User) {
|
||||||
|
users, err := u.GetFollowing(ctx.QueryInt("page"))
|
||||||
|
if err != nil {
|
||||||
|
ctx.APIError(500, "GetFollowing", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
responseApiUsers(ctx, users)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListMyFollowing(ctx *middleware.Context) {
|
||||||
|
listUserFollowing(ctx, ctx.User)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#list-users-followed-by-another-user
|
||||||
|
func ListFollowing(ctx *middleware.Context) {
|
||||||
|
u := GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
listUserFollowing(ctx, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkUserFollowing(ctx *middleware.Context, u *models.User, followID int64) {
|
||||||
|
if u.IsFollowing(followID) {
|
||||||
|
ctx.Status(204)
|
||||||
|
} else {
|
||||||
|
ctx.Error(404)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#check-if-you-are-following-a-user
|
||||||
|
func CheckMyFollowing(ctx *middleware.Context) {
|
||||||
|
target := GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
checkUserFollowing(ctx, ctx.User, target.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#check-if-one-user-follows-another
|
||||||
|
func CheckFollowing(ctx *middleware.Context) {
|
||||||
|
u := GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
target := GetUserByParamsName(ctx, ":target")
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
checkUserFollowing(ctx, u, target.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#follow-a-user
|
||||||
|
func Follow(ctx *middleware.Context) {
|
||||||
|
target := GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := models.FollowUser(ctx.User.Id, target.Id); err != nil {
|
||||||
|
ctx.APIError(500, "FollowUser", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Status(204)
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/gogits/go-gogs-client/wiki/Users-Followers#unfollow-a-user
|
||||||
|
func Unfollow(ctx *middleware.Context) {
|
||||||
|
target := GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := models.UnfollowUser(ctx.User.Id, target.Id); err != nil {
|
||||||
|
ctx.APIError(500, "UnfollowUser", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Status(204)
|
||||||
|
}
|
@ -0,0 +1,145 @@
|
|||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gogits/gogs/models"
|
||||||
|
"github.com/gogits/gogs/modules/base"
|
||||||
|
"github.com/gogits/gogs/modules/middleware"
|
||||||
|
"github.com/gogits/gogs/modules/setting"
|
||||||
|
"github.com/gogits/gogs/routers/repo"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FOLLOWERS base.TplName = "user/meta/followers"
|
||||||
|
STARS base.TplName = "user/meta/stars"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetUserByParams returns user whose name is presented in URL paramenter.
|
||||||
|
func GetUserByParams(ctx *middleware.Context) *models.User {
|
||||||
|
user, err := models.GetUserByName(ctx.Params(":username"))
|
||||||
|
if err != nil {
|
||||||
|
if models.IsErrUserNotExist(err) {
|
||||||
|
ctx.Error(404)
|
||||||
|
} else {
|
||||||
|
ctx.Handle(500, "GetUserByName", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
|
func Profile(ctx *middleware.Context) {
|
||||||
|
uname := ctx.Params(":username")
|
||||||
|
// Special handle for FireFox requests favicon.ico.
|
||||||
|
if uname == "favicon.ico" {
|
||||||
|
ctx.Redirect(setting.AppSubUrl + "/img/favicon.png")
|
||||||
|
return
|
||||||
|
} else if strings.HasSuffix(uname, ".png") {
|
||||||
|
ctx.Error(404)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isShowKeys := false
|
||||||
|
if strings.HasSuffix(uname, ".keys") {
|
||||||
|
isShowKeys = true
|
||||||
|
}
|
||||||
|
|
||||||
|
u := GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show SSH keys.
|
||||||
|
if isShowKeys {
|
||||||
|
ShowSSHKeys(ctx, u.Id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if u.IsOrganization() {
|
||||||
|
showOrgProfile(ctx)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Data["Title"] = u.DisplayName()
|
||||||
|
ctx.Data["PageIsUserProfile"] = true
|
||||||
|
ctx.Data["Owner"] = u
|
||||||
|
|
||||||
|
tab := ctx.Query("tab")
|
||||||
|
ctx.Data["TabName"] = tab
|
||||||
|
switch tab {
|
||||||
|
case "activity":
|
||||||
|
retrieveFeeds(ctx, u.Id, 0, true)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
var err error
|
||||||
|
ctx.Data["Repos"], err = models.GetRepositories(u.Id, ctx.IsSigned && ctx.User.Id == u.Id)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Handle(500, "GetRepositories", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.HTML(200, PROFILE)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Followers(ctx *middleware.Context) {
|
||||||
|
u := GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["Title"] = u.DisplayName()
|
||||||
|
ctx.Data["CardsTitle"] = ctx.Tr("user.followers")
|
||||||
|
ctx.Data["PageIsFollowers"] = true
|
||||||
|
ctx.Data["Owner"] = u
|
||||||
|
repo.RenderUserCards(ctx, u.NumFollowers, u.GetFollowers, FOLLOWERS)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Following(ctx *middleware.Context) {
|
||||||
|
u := GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["Title"] = u.DisplayName()
|
||||||
|
ctx.Data["CardsTitle"] = ctx.Tr("user.following")
|
||||||
|
ctx.Data["PageIsFollowing"] = true
|
||||||
|
ctx.Data["Owner"] = u
|
||||||
|
repo.RenderUserCards(ctx, u.NumFollowing, u.GetFollowing, FOLLOWERS)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Stars(ctx *middleware.Context) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func Action(ctx *middleware.Context) {
|
||||||
|
u := GetUserByParams(ctx)
|
||||||
|
if ctx.Written() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
switch ctx.Params(":action") {
|
||||||
|
case "follow":
|
||||||
|
err = models.FollowUser(ctx.User.Id, u.Id)
|
||||||
|
case "unfollow":
|
||||||
|
err = models.UnfollowUser(ctx.User.Id, u.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ctx.Handle(500, fmt.Sprintf("Action (%s)", ctx.Params(":action")), err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
redirectTo := ctx.Query("redirect_to")
|
||||||
|
if len(redirectTo) == 0 {
|
||||||
|
redirectTo = u.HomeLink()
|
||||||
|
}
|
||||||
|
ctx.Redirect(redirectTo)
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
0.8.12.1219
|
0.8.13.1221
|
@ -0,0 +1,47 @@
|
|||||||
|
<div class="ui container user-cards">
|
||||||
|
<h2 class="ui dividing header">
|
||||||
|
{{.CardsTitle}}
|
||||||
|
</h2>
|
||||||
|
<ul class="list">
|
||||||
|
{{range .Cards}}
|
||||||
|
<li class="item ui segment">
|
||||||
|
<a href="{{.HomeLink}}">
|
||||||
|
<img class="avatar" src="{{.AvatarLink}}"/>
|
||||||
|
</a>
|
||||||
|
<h3 class="name"><a href="{{.HomeLink}}">{{.DisplayName}}</a></h3>
|
||||||
|
|
||||||
|
<div class="meta">
|
||||||
|
{{if .Website}}
|
||||||
|
<span class="icon octicon octicon-link"></span> <a href="{{.Website}}" target="_blank">{{.Website}}</a>
|
||||||
|
{{else if .Location}}
|
||||||
|
<span class="icon octicon octicon-location"></span> {{.Location}}
|
||||||
|
{{else}}
|
||||||
|
<span class="icon octicon octicon-clock"></span> {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}}
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{with .Page}}
|
||||||
|
{{if gt .TotalPages 1}}
|
||||||
|
<div class="center page buttons">
|
||||||
|
<div class="ui borderless pagination menu">
|
||||||
|
<a class="{{if not .HasPrevious}}disabled{{end}} item" {{if .HasPrevious}}href="{{$.Link}}?page={{.Previous}}"{{end}}>
|
||||||
|
<i class="left arrow icon"></i> {{$.i18n.Tr "repo.issues.previous"}}
|
||||||
|
</a>
|
||||||
|
{{range .Pages}}
|
||||||
|
{{if eq .Num -1}}
|
||||||
|
<a class="disabled item">...</a>
|
||||||
|
{{else}}
|
||||||
|
<a class="{{if .IsCurrent}}active{{end}} item" {{if not .IsCurrent}}href="{{$.Link}}?page={{.Num}}"{{end}}>{{.Num}}</a>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
<a class="{{if not .HasNext}}disabled{{end}} item" {{if .HasNext}}href="{{$.Link}}?page={{.Next}}"{{end}}>
|
||||||
|
{{$.i18n.Tr "repo.issues.next"}} <i class="icon right arrow"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</div>
|
@ -1,56 +1,6 @@
|
|||||||
{{template "base/head" .}}
|
{{template "base/head" .}}
|
||||||
<div class="repository watchers">
|
<div class="repository watchers">
|
||||||
{{template "repo/header" .}}
|
{{template "repo/header" .}}
|
||||||
<div class="ui container">
|
{{template "repo/user_cards" .}}
|
||||||
<h2 class="ui dividing header">
|
|
||||||
{{if .PageIsWatchers}}
|
|
||||||
{{.i18n.Tr "repo.watchers"}}
|
|
||||||
{{else}}
|
|
||||||
{{.i18n.Tr "repo.stargazers"}}
|
|
||||||
{{end}}
|
|
||||||
</h2>
|
|
||||||
<ul class="list">
|
|
||||||
{{range .Watchers}}
|
|
||||||
<li class="item ui segment">
|
|
||||||
<a href="{{.HomeLink}}">
|
|
||||||
<img class="avatar" src="{{.AvatarLink}}"/>
|
|
||||||
</a>
|
|
||||||
<h3 class="name"><a href="{{.HomeLink}}">{{.DisplayName}}</a></h3>
|
|
||||||
|
|
||||||
<div class="meta">
|
|
||||||
{{if .Website}}
|
|
||||||
<span class="icon octicon octicon-link"></span> <a href="{{.Website}}" target="_blank">{{.Website}}</a>
|
|
||||||
{{else if .Location}}
|
|
||||||
<span class="icon octicon octicon-location"></span> {{.Location}}
|
|
||||||
{{else}}
|
|
||||||
<span class="icon octicon octicon-clock"></span> {{$.i18n.Tr "user.join_on"}} {{DateFmtShort .Created}}
|
|
||||||
{{end}}
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{{with .Page}}
|
|
||||||
{{if gt .TotalPages 1}}
|
|
||||||
<div class="center page buttons">
|
|
||||||
<div class="ui borderless pagination menu">
|
|
||||||
<a class="{{if not .HasPrevious}}disabled{{end}} item" {{if .HasPrevious}}href="{{$.Link}}?page={{.Previous}}"{{end}}>
|
|
||||||
<i class="left arrow icon"></i> {{$.i18n.Tr "repo.issues.previous"}}
|
|
||||||
</a>
|
|
||||||
{{range .Pages}}
|
|
||||||
{{if eq .Num -1}}
|
|
||||||
<a class="disabled item">...</a>
|
|
||||||
{{else}}
|
|
||||||
<a class="{{if .IsCurrent}}active{{end}} item" {{if not .IsCurrent}}href="{{$.Link}}?page={{.Num}}"{{end}}>{{.Num}}</a>
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
<a class="{{if not .HasNext}}disabled{{end}} item" {{if .HasNext}}href="{{$.Link}}?page={{.Next}}"{{end}}>
|
|
||||||
{{$.i18n.Tr "repo.issues.next"}} <i class="icon right arrow"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
{{end}}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{{template "base/footer" .}}
|
{{template "base/footer" .}}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
{{template "base/head" .}}
|
||||||
|
<div class="user followers">
|
||||||
|
{{template "user/meta/header" .}}
|
||||||
|
{{template "repo/user_cards" .}}
|
||||||
|
</div>
|
||||||
|
{{template "base/footer" .}}
|
@ -0,0 +1,25 @@
|
|||||||
|
{{with .Owner}}
|
||||||
|
<div class="ui container">
|
||||||
|
<img class="ui avatar image" src="{{.AvatarLink}}">
|
||||||
|
<span class="header name">
|
||||||
|
<a href="{{.HomeLink}}">{{.Name}}</a>
|
||||||
|
{{with .FullName}}({{.}}){{end}}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="ui right">
|
||||||
|
|
||||||
|
{{if or $.PageIsFollowers $.PageIsFollowing}}
|
||||||
|
{{if and $.IsSigned (ne $.SignedUserName .Name)}}
|
||||||
|
<div class="follow">
|
||||||
|
{{if $.SignedUser.IsFollowing .Id}}
|
||||||
|
<a class="ui small basic red button" href="{{.HomeLink}}/action/unfollow?redirect_to={{$.Link}}"><i class="octicon octicon-person"></i> {{$.i18n.Tr "user.unfollow"}}</a>
|
||||||
|
{{else}}
|
||||||
|
<a class="ui small basic green button" href="{{.HomeLink}}/action/follow?redirect_to={{$.Link}}"><i class="octicon octicon-person"></i> {{$.i18n.Tr "user.follow"}}</a>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
<div class="ui divider"></div>
|
Loading…
Reference in new issue