]> source.dussan.org Git - gitea.git/commitdiff
Don't do a full page load when clicking the follow button (#28872)
authorYarden Shoham <git@yardenshoham.com>
Sat, 20 Jan 2024 22:37:22 +0000 (00:37 +0200)
committerGitHub <noreply@github.com>
Sat, 20 Jan 2024 22:37:22 +0000 (23:37 +0100)
- Use htmx to perform the button request
- `hx-headers='{"x-csrf-token": "{{.CsrfToken}}"}'` to authenticate (we
should probably learn to reuse this)
- `hx-post="{{.ContextUser.HomeLink}}?action=follow"` to send a POST
request to follow the user
- `hx-target="#profile-avatar-card"` to target the card div for
replacement
- `hx-swap="outerHTML"` to replace the card (as opposed to its inner
content) with the new card that shows the new follower count and button
color
- Change the backend response to return a `<div>` tag (the card) instead
of a redirect to the user page

# Before

![before](https://github.com/go-gitea/gitea/assets/20454870/86899d15-41c9-42ed-bd85-253b9caac7f8)

# After

![after](https://github.com/go-gitea/gitea/assets/20454870/59455d96-548c-4a81-a5b0-fab1dc1e87ef)

Signed-off-by: Yarden Shoham <git@yardenshoham.com>
routers/web/user/profile.go
templates/shared/user/profile_big_avatar.tmpl

index c5305ebcd9f4ba13cea533abcfe4e269fe3d9eea..73ab93caed5a5f0633d251d8ae9e320a0176c597 100644 (file)
@@ -14,6 +14,7 @@ import (
        "code.gitea.io/gitea/models/db"
        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/context"
        "code.gitea.io/gitea/modules/git"
        "code.gitea.io/gitea/modules/log"
@@ -26,6 +27,10 @@ import (
        shared_user "code.gitea.io/gitea/routers/web/shared/user"
 )
 
+const (
+       tplProfileBigAvatar base.TplName = "shared/user/profile_big_avatar"
+)
+
 // OwnerProfile render profile page for a user or a organization (aka, repo owner)
 func OwnerProfile(ctx *context.Context) {
        if strings.Contains(ctx.Req.Header.Get("Accept"), "application/rss+xml") {
@@ -309,8 +314,10 @@ func Action(ctx *context.Context) {
 
        if err != nil {
                log.Error("Failed to apply action %q: %v", ctx.FormString("action"), err)
-               ctx.JSONError(fmt.Sprintf("Action %q failed", ctx.FormString("action")))
+               ctx.Error(http.StatusBadRequest, fmt.Sprintf("Action %q failed", ctx.FormString("action")))
                return
        }
-       ctx.JSONOK()
+
+       shared_user.PrepareContextForProfileBigAvatar(ctx)
+       ctx.HTML(http.StatusOK, tplProfileBigAvatar)
 }
index a637a9a5f91515742bdf42e67039dacbf7161c6a..7afc852d1b57cdc3e82ae4e965facbef96285cf6 100644 (file)
@@ -1,4 +1,4 @@
-<div class="ui card">
+<div id="profile-avatar-card" class="ui card">
        <div id="profile-avatar" class="content gt-df">
        {{if eq .SignedUserID .ContextUser.ID}}
                <a class="image" href="{{AppSubUrl}}/user/settings" data-tooltip-content="{{ctx.Locale.Tr "user.change_avatar"}}">
                        </li>
                        {{end}}
                        {{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}}
-                       <li class="follow">
+                       <li class="follow" hx-headers='{"x-csrf-token": "{{.CsrfToken}}"}' hx-target="#profile-avatar-card" hx-swap="outerHTML">
                                {{if $.IsFollowing}}
-                                       <button class="ui basic red button link-action" data-url="{{.ContextUser.HomeLink}}?action=unfollow">
+                                       <button hx-post="{{.ContextUser.HomeLink}}?action=unfollow" class="ui basic red button">
                                                {{svg "octicon-person"}} {{ctx.Locale.Tr "user.unfollow"}}
                                        </button>
                                {{else}}
-                                       <button class="ui basic primary button link-action" data-url="{{.ContextUser.HomeLink}}?action=follow">
+                                       <button hx-post="{{.ContextUser.HomeLink}}?action=follow" class="ui basic primary button">
                                                {{svg "octicon-person"}} {{ctx.Locale.Tr "user.follow"}}
                                        </button>
                                {{end}}