diff options
author | Unknwon <u@gogs.io> | 2018-12-06 22:58:02 -0500 |
---|---|---|
committer | Unknwon <u@gogs.io> | 2018-12-06 22:58:02 -0500 |
commit | f545faa06d553750b9f4018336e810530389f88c (patch) | |
tree | a906d0d46d9f07a093b7eb8faf01e2648b2540b9 | |
parent | 458aadbb10a50948bbc237c5c2ab62d8710d2b4a (diff) |
templates: make state changing routes to POST method (#5541)
- pkg/context: add ParamsUser to unify the injection process
-rw-r--r-- | cmd/web.go | 10 | ||||
-rw-r--r-- | gogs.go | 2 | ||||
-rw-r--r-- | pkg/context/user.go | 30 | ||||
-rw-r--r-- | public/css/gogs.css | 6 | ||||
-rw-r--r-- | public/js/gogs.js | 116 | ||||
-rw-r--r-- | public/less/_base.less | 5 | ||||
-rw-r--r-- | public/less/_user.less | 3 | ||||
-rw-r--r-- | routes/user/profile.go | 102 | ||||
-rw-r--r-- | templates/.VERSION | 2 | ||||
-rw-r--r-- | templates/base/head.tmpl | 10 | ||||
-rw-r--r-- | templates/repo/header.tmpl | 38 | ||||
-rw-r--r-- | templates/user/profile.tmpl | 32 |
12 files changed, 190 insertions, 166 deletions
@@ -257,7 +257,7 @@ func runWeb(c *cli.Context) error { m.Get("/email2user", user.Email2User) m.Get("/forget_password", user.ForgotPasswd) m.Post("/forget_password", user.ForgotPasswdPost) - m.Get("/logout", user.SignOut) + m.Post("/logout", user.SignOut) }) // ***** END: User ***** @@ -308,7 +308,7 @@ func runWeb(c *cli.Context) error { m.Get("/followers", user.Followers) m.Get("/following", user.Following) m.Get("/stars", user.Stars) - }) + }, context.InjectParamsUser()) m.Get("/attachments/:uuid", func(c *context.Context) { attach, err := models.GetAttachmentByUUID(c.Params(":uuid")) @@ -340,8 +340,8 @@ func runWeb(c *cli.Context) error { }, ignSignIn) m.Group("/:username", func() { - m.Get("/action/:action", user.Action) - }, reqSignIn) + m.Post("/action/:action", user.Action) + }, reqSignIn, context.InjectParamsUser()) if macaron.Env == macaron.DEV { m.Get("/template/*", dev.TemplatePreview) @@ -484,7 +484,7 @@ func runWeb(c *cli.Context) error { }) }, reqSignIn, context.RepoAssignment(), reqRepoAdmin, context.RepoRef()) - m.Get("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action) + m.Post("/:username/:reponame/action/:action", reqSignIn, context.RepoAssignment(), repo.Action) m.Group("/:username/:reponame", func() { m.Get("/issues", repo.RetrieveLabels, repo.Issues) m.Get("/issues/:index", repo.ViewIssue) @@ -16,7 +16,7 @@ import ( "github.com/gogs/gogs/pkg/setting" ) -const APP_VER = "0.11.76.1204" +const APP_VER = "0.11.77.1206" func init() { setting.AppVer = APP_VER diff --git a/pkg/context/user.go b/pkg/context/user.go new file mode 100644 index 00000000..a2297da8 --- /dev/null +++ b/pkg/context/user.go @@ -0,0 +1,30 @@ +// Copyright 2018 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 context + +import ( + "gopkg.in/macaron.v1" + + "github.com/gogs/gogs/models" + "github.com/gogs/gogs/models/errors" +) + +// ParamsUser is the wrapper type of the target user defined by URL parameter, namely ':username'. +type ParamsUser struct { + *models.User +} + +// InjectParamsUser returns a handler that retrieves target user based on URL parameter ':username', +// and injects it as *ParamsUser. +func InjectParamsUser() macaron.Handler { + return func(c *Context) { + user, err := models.GetUserByName(c.Params(":username")) + if err != nil { + c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err) + return + } + c.Map(&ParamsUser{user}) + } +} diff --git a/public/css/gogs.css b/public/css/gogs.css index 9e60fff6..2d56467a 100644 --- a/public/css/gogs.css +++ b/public/css/gogs.css @@ -347,6 +347,9 @@ footer .ui.language .menu { .hide { display: none; } +.display.inline { + display: inline; +} .center { text-align: center; } @@ -2934,6 +2937,9 @@ footer .ui.language .menu { margin-top: 5px; margin-right: 8px; } +.user.profile .ui.card .profile-avatar { + height: 287px; +} .user.profile .ui.card .header { word-break: break-all; } diff --git a/public/js/gogs.js b/public/js/gogs.js index e518bde4..eb161d17 100644 --- a/public/js/gogs.js +++ b/public/js/gogs.js @@ -9,11 +9,11 @@ function initCommentPreviewTab($form) { $tabMenu.find('.item[data-tab="' + $tabMenu.data('preview') + '"]').click(function () { var $this = $(this); $.post($this.data('url'), { - "_csrf": csrf, - "mode": "gfm", - "context": $this.data('context'), - "text": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() - }, + "_csrf": csrf, + "mode": "gfm", + "context": $this.data('context'), + "text": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() + }, function (data) { var $previewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('preview') + '"]'); $previewPanel.html(data); @@ -39,11 +39,11 @@ function initEditPreviewTab($form) { $previewTab.click(function () { var $this = $(this); $.post($this.data('url'), { - "_csrf": csrf, - "mode": "gfm", - "context": $this.data('context'), - "text": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() - }, + "_csrf": csrf, + "mode": "gfm", + "context": $this.data('context'), + "text": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() + }, function (data) { var $previewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('preview') + '"]'); $previewPanel.html(data); @@ -63,9 +63,9 @@ function initEditDiffTab($form) { $tabMenu.find('.item[data-tab="' + $tabMenu.data('diff') + '"]').click(function () { var $this = $(this); $.post($this.data('url'), { - "_csrf": csrf, - "content": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() - }, + "_csrf": csrf, + "content": $form.find('.tab.segment[data-tab="' + $tabMenu.data('write') + '"] textarea').val() + }, function (data) { var $diffPreviewPanel = $form.find('.tab.segment[data-tab="' + $tabMenu.data('diff') + '"]'); $diffPreviewPanel.html(data); @@ -221,7 +221,7 @@ function initRepository() { window.location.href = $choice.data('url'); console.log($choice.data('url')) }, - message: {noResults: $dropdown.data('no-results')} + message: { noResults: $dropdown.data('no-results') } }); } @@ -346,9 +346,9 @@ function initRepository() { } $.post($(this).data('update-url'), { - "_csrf": csrf, - "title": $editInput.val() - }, + "_csrf": csrf, + "title": $editInput.val() + }, function (data) { $editInput.val(data.title); $issueTitle.text(data.title); @@ -390,10 +390,10 @@ function initRepository() { $editContentZone.hide(); $.post($editContentZone.data('update-url'), { - "_csrf": csrf, - "content": $textarea.val(), - "context": $editContentZone.data('context') - }, + "_csrf": csrf, + "content": $textarea.val(), + "context": $editContentZone.data('context') + }, function (data) { if (data.length == 0) { $renderContent.html($('#no-content').html()); @@ -500,14 +500,14 @@ function initRepository() { initFilterSearchDropdown('.choose.branch .dropdown'); } if ($('.repository.view.pull').length > 0) { - $('.comment.merge.box input[name=merge_style]').change(function () { - if ($(this).val() === 'create_merge_commit') { - $('.commit.description.field').show(); - } else { - $('.commit.description.field').hide(); - } - }) - } + $('.comment.merge.box input[name=merge_style]').change(function () { + if ($(this).val() === 'create_merge_commit') { + $('.commit.description.field').show(); + } else { + $('.commit.description.field').hide(); + } + }) + } } function initWikiForm() { @@ -521,11 +521,11 @@ function initWikiForm() { setTimeout(function () { // FIXME: still send render request when return back to edit mode $.post($editArea.data('url'), { - "_csrf": csrf, - "mode": "gfm", - "context": $editArea.data('context'), - "text": plainText - }, + "_csrf": csrf, + "mode": "gfm", + "context": $editArea.data('context'), + "text": plainText + }, function (data) { preview.innerHTML = '<div class="markdown">' + data + '</div>'; emojify.run($('.editor-preview')[0]); @@ -603,11 +603,11 @@ function setSimpleMDE($editArea) { setTimeout(function () { // FIXME: still send render request when return back to edit mode $.post($editArea.data('url'), { - "_csrf": csrf, - "mode": "gfm", - "context": $editArea.data('context'), - "text": plainText - }, + "_csrf": csrf, + "mode": "gfm", + "context": $editArea.data('context'), + "text": plainText + }, function (data) { preview.innerHTML = '<div class="markdown">' + data + '</div>'; emojify.run($('.editor-preview')[0]); @@ -652,10 +652,10 @@ function initEditor() { $('.js-quick-pull-choice-option').change(function () { if ($(this).val() == 'commit-to-new-branch') { $('.quick-pull-branch-name').show(); - $('.quick-pull-branch-name input').prop('required',true); + $('.quick-pull-branch-name input').prop('required', true); } else { $('.quick-pull-branch-name').hide(); - $('.quick-pull-branch-name input').prop('required',false); + $('.quick-pull-branch-name input').prop('required', false); } }); @@ -705,7 +705,7 @@ function initEditor() { var tree_path = parts.join('/'); $('#tree_path').val(tree_path); - $('#preview-tab').data('context', $('#preview-tab').data('root-context') + tree_path.substring(0, tree_path.lastIndexOf("/")+1)); + $('#preview-tab').data('context', $('#preview-tab').data('root-context') + tree_path.substring(0, tree_path.lastIndexOf("/") + 1)); }).trigger('keyup'); var $editArea = $('.repository.editor textarea#edit_area'); @@ -775,7 +775,7 @@ function initEditor() { value = value.split('/'); value = value[value.length - 1]; - $.getJSON($editFilename.data('ec-url-prefix')+value, function(editorconfig) { + $.getJSON($editFilename.data('ec-url-prefix') + value, function (editorconfig) { if (editorconfig.indent_style === 'tab') { codeMirrorEditor.setOption("indentWithTabs", true); codeMirrorEditor.setOption('extraKeys', {}); @@ -785,7 +785,7 @@ function initEditor() { // - https://github.com/codemirror/CodeMirror/issues/988 // - https://codemirror.net/doc/manual.html#keymaps codeMirrorEditor.setOption('extraKeys', { - Tab: function(cm) { + Tab: function (cm) { var spaces = Array(parseInt(cm.getOption("indentUnit")) + 1).join(" "); cm.replaceSelection(spaces); } @@ -1131,7 +1131,7 @@ function initWebhookSettings() { $($(this).data('target') + ' .nohighlight').each(function () { var $this = $(this); $this.removeClass('nohighlight'); - setTimeout(function(){ hljs.highlightBlock($this[0]) }, 500); + setTimeout(function () { hljs.highlightBlock($this[0]) }, 500); }) }) @@ -1213,7 +1213,7 @@ $(document).ready(function () { var filenameDict = {}; $dropzone.dropzone({ url: $dropzone.data('upload-url'), - headers: {"X-Csrf-Token": csrf}, + headers: { "X-Csrf-Token": csrf }, maxFiles: $dropzone.data('max-file'), maxFilesize: $dropzone.data('max-size'), acceptedFiles: ($dropzone.data('accepts') === '*/*') ? null : $dropzone.data('accepts'), @@ -1336,6 +1336,10 @@ $(document).ready(function () { window.location.href = $this.data('done-url'); }); }); + // To make arbitrary form element to behave like a submit button + $('.submit-button').click(function () { + $($(this).data('form')).submit(); + }); // Check or select on option to enable/disable target region $('.enable-system').change(function () { @@ -1459,7 +1463,7 @@ $(function () { $('form').areYouSure(); }); - // getByteLen counts bytes in a string's UTF-8 representation. +// getByteLen counts bytes in a string's UTF-8 representation. function getByteLen(normalVal) { // Force string type normalVal = String(normalVal); @@ -1467,19 +1471,19 @@ function getByteLen(normalVal) { var byteLen = 0; for (var i = 0; i < normalVal.length; i++) { var c = normalVal.charCodeAt(i); - byteLen += c < (1 << 7) ? 1 : - c < (1 << 11) ? 2 : - c < (1 << 16) ? 3 : - c < (1 << 21) ? 4 : - c < (1 << 26) ? 5 : - c < (1 << 31) ? 6 : Number.NaN; + byteLen += c < (1 << 7) ? 1 : + c < (1 << 11) ? 2 : + c < (1 << 16) ? 3 : + c < (1 << 21) ? 4 : + c < (1 << 26) ? 5 : + c < (1 << 31) ? 6 : Number.NaN; } return byteLen; } function showMessageMaxLength(maxLen, textElemId, counterId) { - var $msg = $('#'+textElemId); - $('#'+counterId).html(maxLen - getByteLen($msg.val())); + var $msg = $('#' + textElemId); + $('#' + counterId).html(maxLen - getByteLen($msg.val())); var onMessageKey = function (e) { var $msg = $(this); @@ -1492,7 +1496,7 @@ function showMessageMaxLength(maxLen, textElemId, counterId) { remainder = 0; } - $('#'+counterId).html(remainder); + $('#' + counterId).html(remainder); }; $msg.keyup(onMessageKey).keydown(onMessageKey); diff --git a/public/less/_base.less b/public/less/_base.less index 4f4c1ed5..a8a8f91a 100644 --- a/public/less/_base.less +++ b/public/less/_base.less @@ -384,6 +384,11 @@ footer { .hide { display: none; } +.display { + &.inline { + display: inline; + } +} .center { text-align: center; } diff --git a/public/less/_user.less b/public/less/_user.less index 8e52a980..3815434b 100644 --- a/public/less/_user.less +++ b/public/less/_user.less @@ -60,6 +60,9 @@ &.profile { .ui.card { + .profile-avatar { + height: 287px; + } .header { word-break: break-all; } diff --git a/routes/user/profile.go b/routes/user/profile.go index dfdc80d5..3d96f4cb 100644 --- a/routes/user/profile.go +++ b/routes/user/profile.go @@ -6,13 +6,11 @@ package user import ( "fmt" - "path" "strings" "github.com/Unknwon/paginater" "github.com/gogs/gogs/models" - "github.com/gogs/gogs/models/errors" "github.com/gogs/gogs/pkg/context" "github.com/gogs/gogs/pkg/setting" "github.com/gogs/gogs/pkg/tool" @@ -24,59 +22,30 @@ const ( STARS = "user/meta/stars" ) -func GetUserByName(c *context.Context, name string) *models.User { - user, err := models.GetUserByName(name) - if err != nil { - c.NotFoundOrServerError("GetUserByName", errors.IsUserNotExist, err) - return nil - } - return user -} - -// GetUserByParams returns user whose name is presented in URL paramenter. -func GetUserByParams(c *context.Context) *models.User { - return GetUserByName(c, c.Params(":username")) -} - -func Profile(c *context.Context) { - uname := c.Params(":username") - // Special handle for FireFox requests favicon.ico. - if uname == "favicon.ico" { - c.ServeFile(path.Join(setting.StaticRootPath, "public/img/favicon.png")) - return - } else if strings.HasSuffix(uname, ".png") { - c.Error(404) - return - } - +func Profile(c *context.Context, puser *context.ParamsUser) { isShowKeys := false - if strings.HasSuffix(uname, ".keys") { + if strings.HasSuffix(c.Params(":username"), ".keys") { isShowKeys = true } - ctxUser := GetUserByName(c, strings.TrimSuffix(uname, ".keys")) - if c.Written() { - return - } - // Show SSH keys. if isShowKeys { - ShowSSHKeys(c, ctxUser.ID) + ShowSSHKeys(c, puser.ID) return } - if ctxUser.IsOrganization() { + if puser.IsOrganization() { showOrgProfile(c) return } - c.Data["Title"] = ctxUser.DisplayName() - c.Data["PageIsUserProfile"] = true - c.Data["Owner"] = ctxUser + c.Title(puser.DisplayName()) + c.PageIs("UserProfile") + c.Data["Owner"] = puser - orgs, err := models.GetOrgsByUserID(ctxUser.ID, c.IsLogged && (c.User.IsAdmin || c.User.ID == ctxUser.ID)) + orgs, err := models.GetOrgsByUserID(puser.ID, c.IsLogged && (c.User.IsAdmin || c.User.ID == puser.ID)) if err != nil { - c.Handle(500, "GetOrgsByUserIDDesc", err) + c.ServerError("GetOrgsByUserIDDesc", err) return } @@ -86,7 +55,7 @@ func Profile(c *context.Context) { c.Data["TabName"] = tab switch tab { case "activity": - retrieveFeeds(c, ctxUser, -1, true) + retrieveFeeds(c, puser.User, -1, true) if c.Written() { return } @@ -96,65 +65,52 @@ func Profile(c *context.Context) { page = 1 } - showPrivate := c.IsLogged && (ctxUser.ID == c.User.ID || c.User.IsAdmin) + showPrivate := c.IsLogged && (puser.ID == c.User.ID || c.User.IsAdmin) c.Data["Repos"], err = models.GetUserRepositories(&models.UserRepoOptions{ - UserID: ctxUser.ID, + UserID: puser.ID, Private: showPrivate, Page: page, PageSize: setting.UI.User.RepoPagingNum, }) if err != nil { - c.Handle(500, "GetRepositories", err) + c.ServerError("GetRepositories", err) return } - count := models.CountUserRepositories(ctxUser.ID, showPrivate) + count := models.CountUserRepositories(puser.ID, showPrivate) c.Data["Page"] = paginater.New(int(count), setting.UI.User.RepoPagingNum, page, 5) } - c.HTML(200, PROFILE) + c.Success(PROFILE) } -func Followers(c *context.Context) { - u := GetUserByParams(c) - if c.Written() { - return - } - c.Data["Title"] = u.DisplayName() +func Followers(c *context.Context, puser *context.ParamsUser) { + c.Title(puser.DisplayName()) + c.PageIs("Followers") c.Data["CardsTitle"] = c.Tr("user.followers") - c.Data["PageIsFollowers"] = true - c.Data["Owner"] = u - repo.RenderUserCards(c, u.NumFollowers, u.GetFollowers, FOLLOWERS) + c.Data["Owner"] = puser + repo.RenderUserCards(c, puser.NumFollowers, puser.GetFollowers, FOLLOWERS) } -func Following(c *context.Context) { - u := GetUserByParams(c) - if c.Written() { - return - } - c.Data["Title"] = u.DisplayName() +func Following(c *context.Context, puser *context.ParamsUser) { + c.Title(puser.DisplayName()) + c.PageIs("Following") c.Data["CardsTitle"] = c.Tr("user.following") - c.Data["PageIsFollowing"] = true - c.Data["Owner"] = u - repo.RenderUserCards(c, u.NumFollowing, u.GetFollowing, FOLLOWERS) + c.Data["Owner"] = puser + repo.RenderUserCards(c, puser.NumFollowing, puser.GetFollowing, FOLLOWERS) } func Stars(c *context.Context) { } -func Action(c *context.Context) { - u := GetUserByParams(c) - if c.Written() { - return - } - +func Action(c *context.Context, puser *context.ParamsUser) { var err error switch c.Params(":action") { case "follow": - err = models.FollowUser(c.User.ID, u.ID) + err = models.FollowUser(c.UserID(), puser.ID) case "unfollow": - err = models.UnfollowUser(c.User.ID, u.ID) + err = models.UnfollowUser(c.UserID(), puser.ID) } if err != nil { @@ -164,7 +120,7 @@ func Action(c *context.Context) { redirectTo := c.Query("redirect_to") if !tool.IsSameSiteURLPath(redirectTo) { - redirectTo = u.HomeLink() + redirectTo = puser.HomeLink() } c.Redirect(redirectTo) } diff --git a/templates/.VERSION b/templates/.VERSION index 31eb16e2..a87c12f6 100644 --- a/templates/.VERSION +++ b/templates/.VERSION @@ -1 +1 @@ -0.11.76.1204 +0.11.77.1206 diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index 96f77722..27b2f4c7 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -160,9 +160,13 @@ {{end}} <div class="divider"></div> - <a class="item" href="{{AppSubURL}}/user/logout"> - <i class="octicon octicon-sign-out"></i> {{.i18n.Tr "sign_out"}} - </a> + + <form id="logout-form" class="item" action="{{AppSubURL}}/user/logout" method="POST"> + {{.CSRFTokenHTML}} + <div class="submit-button" data-form="#logout-form"> + <i class="octicon octicon-sign-out"></i> {{.i18n.Tr "sign_out"}} + </div> + </form> </div><!-- end content avatar menu --> </div><!-- end dropdown avatar menu --> </div><!-- end signed user right menu --> diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index d15b5dde..cacda1ed 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -20,22 +20,28 @@ {{if not $.IsGuest}} <div class="ui right"> - <div class="ui labeled button" tabindex="0"> - <a class="ui basic button" href="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}"> - <i class="eye{{if not $.IsWatchingRepo}} slash outline{{end}} icon"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.unwatch"}}{{else}}{{$.i18n.Tr "repo.watch"}}{{end}} - </a> - <a class="ui basic label" href="{{.Link}}/watchers"> - {{.NumWatches}} - </a> - </div> - <div class="ui labeled button" tabindex="0"> - <a class="ui basic button" href="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}"> - <i class="star{{if not $.IsStaringRepo}} outline{{end}} icon"></i>{{if $.IsStaringRepo}}{{$.i18n.Tr "repo.unstar"}}{{else}}{{$.i18n.Tr "repo.star"}}{{end}} - </a> - <a class="ui basic label" href="{{.Link}}/stars"> - {{.NumStars}} - </a> - </div> + <form class="display inline" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}un{{end}}watch?redirect_to={{$.Link}}" method="POST"> + {{$.CSRFTokenHTML}} + <div class="ui labeled button" tabindex="0"> + <button class="ui basic button"> + <i class="eye{{if not $.IsWatchingRepo}} slash outline{{end}} icon"></i>{{if $.IsWatchingRepo}}{{$.i18n.Tr "repo.unwatch"}}{{else}}{{$.i18n.Tr "repo.watch"}}{{end}} + </button> + <a class="ui basic label" href="{{.Link}}/watchers"> + {{.NumWatches}} + </a> + </div> + </form> + <form class="display inline" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}un{{end}}star?redirect_to={{$.Link}}" method="POST"> + {{$.CSRFTokenHTML}} + <div class="ui labeled button" tabindex="0"> + <button class="ui basic button"> + <i class="star{{if not $.IsStaringRepo}} outline{{end}} icon"></i>{{if $.IsStaringRepo}}{{$.i18n.Tr "repo.unstar"}}{{else}}{{$.i18n.Tr "repo.star"}}{{end}} + </button> + <a class="ui basic label" href="{{.Link}}/stars"> + {{.NumStars}} + </a> + </div> + </form> {{if .CanBeForked}} <div class="ui labeled button" tabindex="0"> <a class="ui basic button {{if eq .OwnerID $.LoggedUserID}}poping up{{end}}" href="{{AppSubURL}}/repo/fork/{{.ID}}"> diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl index d60fce56..285aa12c 100644 --- a/templates/user/profile.tmpl +++ b/templates/user/profile.tmpl @@ -5,12 +5,12 @@ <div class="ui five wide column"> <div class="ui card"> {{if eq .LoggedUserName .Owner.Name}} - <a class="image poping up" href="{{AppSubURL}}/user/settings/avatar" id="profile-avatar" data-content="{{.i18n.Tr "user.change_avatar"}}" data-variation="inverted tiny" data-position="bottom center"> - <img src="{{AppendAvatarSize .Owner.RelAvatarLink 290}}" title="{{.Owner.Name}}"/> + <a class="profile-avatar image poping up" href="{{AppSubURL}}/user/settings/avatar" id="profile-avatar" data-content="{{.i18n.Tr "user.change_avatar"}}" data-variation="inverted tiny" data-position="bottom center"> + <img src="{{AppendAvatarSize .Owner.RelAvatarLink 287}}" title="{{.Owner.Name}}"/> </a> {{else}} - <span class="image"> - <img src="{{AppendAvatarSize .Owner.RelAvatarLink 290}}" title="{{.Owner.Name}}"/> + <span class="profile-avatar image"> + <img src="{{AppendAvatarSize .Owner.RelAvatarLink 287}}" title="{{.Owner.Name}}"/> </span> {{end}} <div class="content"> @@ -61,13 +61,23 @@ </li> {{end}} {{if and .IsLogged (ne .LoggedUserName .Owner.Name)}} - <li class="follow"> - {{if .LoggedUser.IsFollowing .Owner.ID}} - <a class="ui basic red button" href="{{.Link}}/action/unfollow?redirect_to={{$.Link}}"><i class="octicon octicon-person"></i> {{.i18n.Tr "user.unfollow"}}</a> - {{else}} - <a class="ui basic green button" href="{{.Link}}/action/follow?redirect_to={{$.Link}}"><i class="octicon octicon-person"></i> {{.i18n.Tr "user.follow"}}</a> - {{end}} - </li> + <li class="follow"> + {{if .LoggedUser.IsFollowing .Owner.ID}} + <form action="{{.Link}}/action/unfollow?redirect_to={{$.Link}}" method="POST"> + {{.CSRFTokenHTML}} + <button class="ui basic red button"> + <i class="octicon octicon-person"></i> {{.i18n.Tr "user.unfollow"}} + </button> + </form> + {{else}} + <form action="{{.Link}}/action/follow?redirect_to={{$.Link}}" method="POST"> + {{.CSRFTokenHTML}} + <button class="ui basic green button"> + <i class="octicon octicon-person"></i> {{.i18n.Tr "user.follow"}} + </button> + </form> + {{end}} + </li> {{end}} </ul> </div> |