feat(pin): implemented the pin/unpin button on repo main page

- Added the unpin octicon svg from a previous attempt to implement this
  feature.
- Added the template for the button/set of buttons for pinning/unpinning
  a repo.
- Added the use of said template in the header of a repo main page.
- Added the routes for the POST requests for pinning/unpinning to
  user/org.

Co-authored-by: Daniel Carvalho <daniel.m.carvalho@tecnico.ulisboa.pt>
This commit is contained in:
Carlos Felgueiras 2024-05-10 16:14:29 +00:00
parent fd47c82077
commit e8dca1ecd4
7 changed files with 84 additions and 0 deletions

View File

@ -1188,10 +1188,15 @@ fork_from_self = You cannot fork a repository you own.
fork_guest_user = Sign in to fork this repository.
watch_guest_user = Sign in to watch this repository.
star_guest_user = Sign in to star this repository.
pin_guest_user = Sign in to pin this repository.
unwatch = Unwatch
watch = Watch
unstar = Unstar
star = Star
pin = Pin
unpin = Unpin
pin-org = Pin to %s
unpin-org = Unpin from %s
fork = Fork
action.blocked_user = Cannot perform action because you are blocked by the repository owner.
download_archive = Download Repository

View File

@ -0,0 +1 @@
<svg aria-hidden="true" viewBox="0 0 16 16" class="svg octicon-custom-pin-off" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M14.779 13.721 11.061 10l2.205-2.204c.967-.968.5-2.623-.832-2.94l-.73-.174 2.645-2.625a.7.7 0 0 0-.986-.994L1.023 13.308a.7.7 0 0 0 .986.994l2.662-2.642.184.773c.317 1.332 1.972 1.799 2.94.832L10 11.061l3.719 3.719a.75.75 0 0 0 1.08.001.747.747 0 0 0-.02-1.06m-8.045-1.517a.25.25 0 0 1-.42-.121l-.396-1.661 4.532-4.498 1.634.389a.25.25 0 0 1 .12.42zm-2.2-4.677a1 1 0 0 0-.078-.082 3.6 3.6 0 0 0-1.262-.912L1.866 5.92a.252.252 0 0 1-.073-.404l3.722-3.722a.25.25 0 0 1 .405.072l.612 1.327c.27.585.409.881.875 1.293l.012.012q.01.008.019.018l.003-.003a.74.74 0 0 0 .496.197c.41 0 .742-.332.742-.742a.73.73 0 0 0-.147-.421l.007-.007c-.211-.294-.442-.538-.644-.975l-.613-1.327A1.75 1.75 0 0 0 4.456.734L.734 4.456a1.75 1.75 0 0 0 .504 2.826l1.327.613c.428.197.59.272.882.626a.742.742 0 0 0 1.269-.522.72.72 0 0 0-.139-.409"/></svg>

After

Width:  |  Height:  |  Size: 971 B

View File

@ -36,6 +36,7 @@ import (
repo_service "code.gitea.io/gitea/services/repository"
archiver_service "code.gitea.io/gitea/services/repository/archiver"
commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
user_service "code.gitea.io/gitea/services/user"
)
const (
@ -321,6 +322,14 @@ func Action(ctx *context.Context) {
err = repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, true)
case "unstar":
err = repo_model.StarRepo(ctx, ctx.Doer, ctx.Repo.Repository, false)
case "pin":
err = user_service.PinRepo(ctx, ctx.Doer, ctx.Repo.Repository, true, false)
case "unpin":
err = user_service.PinRepo(ctx, ctx.Doer, ctx.Repo.Repository, false, false)
case "pin-org":
err = user_service.PinRepo(ctx, ctx.Doer, ctx.Repo.Repository, true, true)
case "unpin-org":
err = user_service.PinRepo(ctx, ctx.Doer, ctx.Repo.Repository, false, true)
case "accept_transfer":
err = acceptOrRejectRepoTransfer(ctx, true)
case "reject_transfer":

View File

@ -29,6 +29,7 @@ import (
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
issue_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/organization"
repo_model "code.gitea.io/gitea/models/repo"
unit_model "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
@ -50,6 +51,7 @@ import (
"code.gitea.io/gitea/services/context"
issue_service "code.gitea.io/gitea/services/issue"
files_service "code.gitea.io/gitea/services/repository/files"
user_services "code.gitea.io/gitea/services/user"
"github.com/nektos/act/pkg/model"
@ -791,6 +793,13 @@ func Home(ctx *context.Context) {
return
}
if ctx.IsSigned {
err := loadPinData(ctx)
if err != nil {
ctx.ServerError("loadPinData", err)
}
}
renderHomeCode(ctx)
}
@ -1168,3 +1177,31 @@ func Forks(ctx *context.Context) {
ctx.HTML(http.StatusOK, tplForks)
}
func loadPinData(ctx *context.Context) error {
// First, cleanup any pins that are no longer valid
err := user_services.CleanupPins(ctx, ctx.Doer)
if err != nil {
return err
}
ctx.Data["IsPinningRepo"] = repo_model.IsPinned(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID)
ctx.Data["CanPinRepo"] = user_services.CanPin(ctx, ctx.Doer, ctx.Repo.Repository)
if ctx.Repo.Repository.Owner.IsOrganization() {
org := organization.OrgFromUser(ctx.Repo.Repository.Owner)
isAdmin, err := org.IsOrgAdmin(ctx, ctx.Doer.ID)
if err != nil {
return err
}
if isAdmin {
ctx.Data["CanUserPinToOrg"] = true
ctx.Data["IsOrgPinningRepo"] = repo_model.IsPinned(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID)
ctx.Data["CanOrgPinRepo"] = user_services.CanPin(ctx, ctx.Repo.Repository.Owner, ctx.Repo.Repository)
}
}
return nil
}

View File

@ -60,6 +60,7 @@
{{svg "octicon-rss" 16}}
</a>
{{end}}
{{template "repo/pin_unpin" $}}
{{template "repo/watch_unwatch" $}}
{{if not $.DisableStars}}
{{template "repo/star_unstar" $}}

View File

@ -0,0 +1,30 @@
<div class="ui buttons">
<form hx-boost="true" hx-target="this" method="post" action="{{$.RepoLink}}/action/{{if .IsPinningRepo}}unpin{{else}}pin{{end}}">
<div class="ui labeled item" {{if not $.IsSigned}}data-tooltip-content="{{ctx.Locale.Tr "repo.pin_guest_user"}}"{{end}}>
{{$buttonText := ctx.Locale.Tr "repo.pin"}}
{{if $.IsPinningRepo}}{{$buttonText = ctx.Locale.Tr "repo.unpin"}}{{end}}
<button type="submit" class="ui compact small basic button"{{if or (not $.IsSigned) (and (not $.IsPinningRepo) (not .CanPinRepo))}} disabled{{end}} aria-label="{{$buttonText}}">
{{if $.IsPinningRepo}}{{svg "octicon-custom-pin-off"}}{{else}}{{svg "octicon-pin"}}{{end}}
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
</button>
</div>
</form>
{{if .CanUserPinToOrg}}
<div class="ui floating dropdown icon button">
<i class="dropdown icon"></i>
<div class="compact menu">
<form hx-boost="true" hx-target="this" method="post" action="{{$.RepoLink}}/action/{{if .IsOrgPinningRepo}}unpin{{else}}pin{{end}}-org">
<div class="ui labeled button item" {{if not $.IsSigned}}data-tooltip-content="{{ctx.Locale.Tr "repo.pin_guest_user"}}"{{end}}>
{{$buttonText = ctx.Locale.Tr "repo.pin-org" .Owner.Name}}
{{if $.IsOrgPinningRepo}}{{$buttonText = ctx.Locale.Tr "repo.unpin-org" .Owner.Name}}{{end}}
<button type="submit" class="ui compact small basic button"{{if or (not $.IsSigned) (and (not $.IsOrgPinningRepo) (not .CanOrgPinRepo))}} disabled{{end}} aria-label="{{$buttonText}}">
{{if $.IsOrgPinningRepo}}{{svg "octicon-custom-pin-off"}}{{else}}{{svg "octicon-pin"}}{{end}}
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
</button>
</div>
</form>
</div>
</div>
{{end}}
</div>

View File

@ -0,0 +1 @@
<svg aria-hidden="true" viewBox="0 0 16 16" width="16" height="16"><path d="M14.779 13.721 11.061 10l2.205-2.204c.967-.968.5-2.623-.832-2.94l-.73-.174 2.645-2.625a.7.7 0 0 0-.986-.994L1.023 13.308a.7.7 0 0 0 .986.994l2.662-2.642.184.773c.317 1.332 1.972 1.799 2.94.832L10 11.061l3.719 3.719a.751.751 0 0 0 1.08.001.747.747 0 0 0-.02-1.06zm-8.045-1.517a.25.25 0 0 1-.42-.121l-.396-1.661 4.532-4.498 1.634.389a.25.25 0 0 1 .12.42l-5.47 5.471zM4.534 7.527a.86.86 0 0 0-.078-.082 3.634 3.634 0 0 0-1.262-.912L1.866 5.92a.252.252 0 0 1-.073-.404l3.722-3.722a.251.251 0 0 1 .405.072l.612 1.327c.27.585.409.881.875 1.293l.012.012c.007.005.012.012.019.018l.003-.003a.74.74 0 0 0 .496.197c.41 0 .742-.332.742-.742a.73.73 0 0 0-.147-.421l.007-.007c-.211-.294-.442-.538-.644-.975l-.613-1.327A1.75 1.75 0 0 0 4.456.734L.734 4.456a1.75 1.75 0 0 0 .504 2.826l1.327.613c.428.197.59.272.882.626a.742.742 0 0 0 1.269-.522.724.724 0 0 0-.139-.409"/></svg>

After

Width:  |  Height:  |  Size: 937 B