mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-29 19:58:57 +03:00
Add follow organization and fix the logic of following page (#24345)
![image](https://user-images.githubusercontent.com/18380374/234740589-066f2e5c-30c7-4fc3-a539-066100e1f138.png) ![image](https://user-images.githubusercontent.com/18380374/234740605-88efe55d-7eaa-422e-ab86-0b5a402ca11c.png) Maybe we can fix user card tmpl in #24319? Or maybe a list is better here ![image](https://user-images.githubusercontent.com/18380374/234451417-7f93df20-4b19-4abb-a62d-4c67e1aa2220.png) --------- Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Giteabot <teabot@gitea.io>
This commit is contained in:
parent
94d6b5b09d
commit
cc64a92560
5 changed files with 51 additions and 29 deletions
|
@ -346,7 +346,7 @@ func GetUserFollowing(ctx context.Context, u, viewer *User, listOptions db.ListO
|
||||||
Select("`user`.*").
|
Select("`user`.*").
|
||||||
Join("LEFT", "follow", "`user`.id=follow.follow_id").
|
Join("LEFT", "follow", "`user`.id=follow.follow_id").
|
||||||
Where("follow.user_id=?", u.ID).
|
Where("follow.user_id=?", u.ID).
|
||||||
And("`user`.type=?", UserTypeIndividual).
|
And("`user`.type IN (?, ?)", UserTypeIndividual, UserTypeOrganization).
|
||||||
And(isUserVisibleToViewerCond(viewer))
|
And(isUserVisibleToViewerCond(viewer))
|
||||||
|
|
||||||
if listOptions.Page != 0 {
|
if listOptions.Page != 0 {
|
||||||
|
@ -1210,23 +1210,25 @@ func isUserVisibleToViewerCond(viewer *User) builder.Cond {
|
||||||
return builder.Neq{
|
return builder.Neq{
|
||||||
"`user`.visibility": structs.VisibleTypePrivate,
|
"`user`.visibility": structs.VisibleTypePrivate,
|
||||||
}.Or(
|
}.Or(
|
||||||
|
// viewer's following
|
||||||
builder.In("`user`.id",
|
builder.In("`user`.id",
|
||||||
builder.
|
builder.
|
||||||
Select("`follow`.user_id").
|
Select("`follow`.user_id").
|
||||||
From("follow").
|
From("follow").
|
||||||
Where(builder.Eq{"`follow`.follow_id": viewer.ID})),
|
Where(builder.Eq{"`follow`.follow_id": viewer.ID})),
|
||||||
builder.In("`user`.id",
|
// viewer's org user
|
||||||
builder.
|
|
||||||
Select("`team_user`.uid").
|
|
||||||
From("team_user").
|
|
||||||
Join("INNER", "`team_user` AS t2", "`team_user`.id = `t2`.id").
|
|
||||||
Where(builder.Eq{"`t2`.uid": viewer.ID})),
|
|
||||||
builder.In("`user`.id",
|
builder.In("`user`.id",
|
||||||
builder.
|
builder.
|
||||||
Select("`team_user`.uid").
|
Select("`team_user`.uid").
|
||||||
From("team_user").
|
From("team_user").
|
||||||
Join("INNER", "`team_user` AS t2", "`team_user`.org_id = `t2`.org_id").
|
Join("INNER", "`team_user` AS t2", "`team_user`.org_id = `t2`.org_id").
|
||||||
Where(builder.Eq{"`t2`.uid": viewer.ID})))
|
Where(builder.Eq{"`t2`.uid": viewer.ID})),
|
||||||
|
// viewer's org
|
||||||
|
builder.In("`user`.id",
|
||||||
|
builder.
|
||||||
|
Select("`team_user`.org_id").
|
||||||
|
From("team_user").
|
||||||
|
Where(builder.Eq{"`team_user`.uid": viewer.ID})))
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsUserVisibleToViewer check if viewer is able to see user profile
|
// IsUserVisibleToViewer check if viewer is able to see user profile
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
"code.gitea.io/gitea/models/organization"
|
"code.gitea.io/gitea/models/organization"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/base"
|
"code.gitea.io/gitea/modules/base"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/markup"
|
"code.gitea.io/gitea/modules/markup"
|
||||||
|
@ -143,6 +144,11 @@ func Home(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isFollowing bool
|
||||||
|
if ctx.Doer != nil {
|
||||||
|
isFollowing = user_model.IsFollowing(ctx.Doer.ID, ctx.ContextUser.ID)
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["Repos"] = repos
|
ctx.Data["Repos"] = repos
|
||||||
ctx.Data["Total"] = count
|
ctx.Data["Total"] = count
|
||||||
ctx.Data["MembersTotal"] = membersCount
|
ctx.Data["MembersTotal"] = membersCount
|
||||||
|
@ -150,6 +156,7 @@ func Home(ctx *context.Context) {
|
||||||
ctx.Data["Teams"] = ctx.Org.Teams
|
ctx.Data["Teams"] = ctx.Org.Teams
|
||||||
ctx.Data["DisableNewPullMirrors"] = setting.Mirror.DisableNewPull
|
ctx.Data["DisableNewPullMirrors"] = setting.Mirror.DisableNewPull
|
||||||
ctx.Data["PageIsViewRepositories"] = true
|
ctx.Data["PageIsViewRepositories"] = true
|
||||||
|
ctx.Data["IsFollowing"] = isFollowing
|
||||||
|
|
||||||
pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
||||||
pager.SetDefaultParams(ctx)
|
pager.SetDefaultParams(ctx)
|
||||||
|
|
|
@ -167,30 +167,31 @@ func Profile(ctx *context.Context) {
|
||||||
language := ctx.FormTrim("language")
|
language := ctx.FormTrim("language")
|
||||||
ctx.Data["Language"] = language
|
ctx.Data["Language"] = language
|
||||||
|
|
||||||
|
followers, numFollowers, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{
|
||||||
|
PageSize: pagingNum,
|
||||||
|
Page: page,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("GetUserFollowers", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["NumFollowers"] = numFollowers
|
||||||
|
following, numFollowing, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{
|
||||||
|
PageSize: pagingNum,
|
||||||
|
Page: page,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ctx.ServerError("GetUserFollowing", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Data["NumFollowing"] = numFollowing
|
||||||
|
|
||||||
switch tab {
|
switch tab {
|
||||||
case "followers":
|
case "followers":
|
||||||
items, count, err := user_model.GetUserFollowers(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{
|
ctx.Data["Cards"] = followers
|
||||||
PageSize: pagingNum,
|
|
||||||
Page: page,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetUserFollowers", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Cards"] = items
|
|
||||||
|
|
||||||
total = int(count)
|
total = int(count)
|
||||||
case "following":
|
case "following":
|
||||||
items, count, err := user_model.GetUserFollowing(ctx, ctx.ContextUser, ctx.Doer, db.ListOptions{
|
ctx.Data["Cards"] = following
|
||||||
PageSize: pagingNum,
|
|
||||||
Page: page,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ctx.ServerError("GetUserFollowing", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Data["Cards"] = items
|
|
||||||
|
|
||||||
total = int(count)
|
total = int(count)
|
||||||
case "activity":
|
case "activity":
|
||||||
date := ctx.FormString("date")
|
date := ctx.FormString("date")
|
||||||
|
|
|
@ -19,6 +19,18 @@
|
||||||
{{if .Org.Website}}<div class="item">{{svg "octicon-link"}} <a target="_blank" rel="noopener noreferrer me" href="{{.Org.Website}}">{{.Org.Website}}</a></div>{{end}}
|
{{if .Org.Website}}<div class="item">{{svg "octicon-link"}} <a target="_blank" rel="noopener noreferrer me" href="{{.Org.Website}}">{{.Org.Website}}</a></div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="right stackable menu">
|
||||||
|
<form method="post" action="{{.Link}}?action={{if $.IsFollowing}}unfollow{{else}}follow{{end}}&redirect_to={{$.Link}}">
|
||||||
|
{{$.CsrfTokenHtml}}
|
||||||
|
<button type="submit" class="ui basic button gt-mr-0">
|
||||||
|
{{if $.IsFollowing}}
|
||||||
|
{{.locale.Tr "user.unfollow"}}
|
||||||
|
{{else}}
|
||||||
|
{{.locale.Tr "user.follow"}}
|
||||||
|
{{end}}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{template "org/menu" .}}
|
{{template "org/menu" .}}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<a href="{{.ContextUser.HomeLink}}.rss"><i class="ui text grey gt-ml-3" data-tooltip-content="{{.locale.Tr "rss_feed"}}">{{svg "octicon-rss" 18}}</i></a>
|
<a href="{{.ContextUser.HomeLink}}.rss"><i class="ui text grey gt-ml-3" data-tooltip-content="{{.locale.Tr "rss_feed"}}">{{svg "octicon-rss" 18}}</i></a>
|
||||||
{{end}}
|
{{end}}
|
||||||
<div class="gt-mt-3">
|
<div class="gt-mt-3">
|
||||||
<a class="muted" href="{{.ContextUser.HomeLink}}?tab=followers">{{svg "octicon-person" 18 "gt-mr-2"}}{{.ContextUser.NumFollowers}} {{.locale.Tr "user.followers"}}</a> · <a class="muted" href="{{.ContextUser.HomeLink}}?tab=following">{{.ContextUser.NumFollowing}} {{.locale.Tr "user.following"}}</a>
|
<a class="muted" href="{{.ContextUser.HomeLink}}?tab=followers">{{svg "octicon-person" 18 "gt-mr-2"}}{{.NumFollowers}} {{.locale.Tr "user.followers"}}</a> · <a class="muted" href="{{.ContextUser.HomeLink}}?tab=following">{{.NumFollowing}} {{.locale.Tr "user.following"}}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="extra content gt-word-break">
|
<div class="extra content gt-word-break">
|
||||||
|
|
Loading…
Reference in a new issue