diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index aa580e6a5..8d11cfc29 100644 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -149,6 +149,9 @@ SHOW_USER_EMAIL = true DEFAULT_THEME = gitea ; All available themes. Allow users select personalized themes regardless of the value of `DEFAULT_THEME`. THEMES = gitea,arc-green +; All available reactions. Allow users react with different emoji's +: For the whole list look at https://gitea.com/gitea/gitea.com/issues/8 +REACTIONS = +1, -1, laugh, hooray, confused, heart, rocket, eyes ; Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used. DEFAULT_SHOW_FULL_NAME = false ; Whether to search within description at repository search on explore page. diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 9fdcd2c82..4fc8511b8 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -118,6 +118,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. - `DEFAULT_THEME`: **gitea**: \[gitea, arc-green\]: Set the default theme for the Gitea install. - `THEMES`: **gitea,arc-green**: All available themes. Allow users select personalized themes regardless of the value of `DEFAULT_THEME`. +- `REACTIONS`: All available reactions. Allow users react with different emoji's. - `DEFAULT_SHOW_FULL_NAME`: **false**: Whether the full name of the users should be shown where possible. If the full name isn't set, the username will be used. - `SEARCH_REPO_DESCRIPTION`: **true**: Whether to search within description at repository search on explore page. - `USE_SERVICE_WORKER`: **true**: Whether to enable a Service Worker to cache frontend assets. diff --git a/docs/content/doc/advanced/customizing-gitea.en-us.md b/docs/content/doc/advanced/customizing-gitea.en-us.md index 362f4fb25..7c66991f6 100644 --- a/docs/content/doc/advanced/customizing-gitea.en-us.md +++ b/docs/content/doc/advanced/customizing-gitea.en-us.md @@ -161,6 +161,15 @@ Locales may change between versions, so keeping track of your customized locales To add a custom Readme, add a markdown formatted file (without an `.md` extension) to `custom/options/readme` +### Reactions + +To change reaction emoji's you can set allowed reactions at app.ini +``` +[ui] +REACTIONS = +1, -1, laugh, confused, heart, hooray, eyes +``` +A full list of supported emoji's is at [emoji list](https://gitea.com/gitea/gitea.com/issues/8) + ## Customizing the look of Gitea As of version 1.6.0 Gitea has built-in themes. The two built-in themes are, the default theme `gitea`, and a dark theme `arc-green`. To change the look of your Gitea install change the value of `DEFAULT_THEME` in the [ui](https://docs.gitea.io/en-us/config-cheat-sheet/#ui-ui) section of `app.ini` to another one of the available options. diff --git a/integrations/issue_test.go b/integrations/issue_test.go index 5a4b75b75..d46e35a94 100644 --- a/integrations/issue_test.go +++ b/integrations/issue_test.go @@ -194,6 +194,32 @@ func TestIssueCommentClose(t *testing.T) { assert.Equal(t, "Description", val) } +func TestIssueReaction(t *testing.T) { + defer prepareTestEnv(t)() + session := loginUser(t, "user2") + issueURL := testNewIssue(t, session, "user2", "repo1", "Title", "Description") + + req := NewRequest(t, "GET", issueURL) + resp := session.MakeRequest(t, req, http.StatusOK) + htmlDoc := NewHTMLParser(t, resp.Body) + + req = NewRequestWithValues(t, "POST", path.Join(issueURL, "/reactions/react"), map[string]string{ + "_csrf": htmlDoc.GetCSRF(), + "content": "8ball", + }) + session.MakeRequest(t, req, http.StatusInternalServerError) + req = NewRequestWithValues(t, "POST", path.Join(issueURL, "/reactions/react"), map[string]string{ + "_csrf": htmlDoc.GetCSRF(), + "content": "eyes", + }) + session.MakeRequest(t, req, http.StatusOK) + req = NewRequestWithValues(t, "POST", path.Join(issueURL, "/reactions/unreact"), map[string]string{ + "_csrf": htmlDoc.GetCSRF(), + "content": "eyes", + }) + session.MakeRequest(t, req, http.StatusOK) +} + func TestIssueCrossReference(t *testing.T) { defer prepareTestEnv(t)() diff --git a/modules/auth/repo_form.go b/modules/auth/repo_form.go index 1c873f2ea..e3f6410c3 100644 --- a/modules/auth/repo_form.go +++ b/modules/auth/repo_form.go @@ -347,7 +347,7 @@ func (f *CreateCommentForm) Validate(ctx *macaron.Context, errs binding.Errors) // ReactionForm form for adding and removing reaction type ReactionForm struct { - Content string `binding:"Required;In(+1,-1,laugh,confused,heart,hooray)"` + Content string `binding:"Required"` } // Validate validates the fields diff --git a/modules/setting/setting.go b/modules/setting/setting.go index f2112f59f..a97ab9467 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -169,6 +169,7 @@ var ( DefaultShowFullName bool DefaultTheme string Themes []string + Reactions []string SearchRepoDescription bool UseServiceWorker bool @@ -198,6 +199,7 @@ var ( MaxDisplayFileSize: 8388608, DefaultTheme: `gitea`, Themes: []string{`gitea`, `arc-green`}, + Reactions: []string{`+1`, `-1`, `laugh`, `hooray`, `confused`, `heart`, `rocket`, `eyes`}, Admin: struct { UserPagingNum int RepoPagingNum int diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 739370da6..a2f4022a7 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -673,6 +673,7 @@ func ViewIssue(ctx *context.Context) { } } ctx.Data["IssueWatch"] = iw + ctx.Data["AllowedReactions"] = setting.UI.Reactions issue.RenderedContent = string(markdown.Render([]byte(issue.Content), ctx.Repo.RepoLink, ctx.Repo.Repository.ComposeMetas())) @@ -1447,6 +1448,12 @@ func ChangeIssueReaction(ctx *context.Context, form auth.ReactionForm) { switch ctx.Params(":action") { case "react": + if !util.IsStringInSlice(form.Content, setting.UI.Reactions) { + err := fmt.Errorf("ChangeIssueReaction: '%s' is not an allowed reaction", form.Content) + ctx.ServerError(err.Error(), err) + return + } + reaction, err := models.CreateIssueReaction(ctx.User, issue, form.Content) if err != nil { log.Info("CreateIssueReaction: %s", err) @@ -1542,6 +1549,12 @@ func ChangeCommentReaction(ctx *context.Context, form auth.ReactionForm) { switch ctx.Params(":action") { case "react": + if !util.IsStringInSlice(form.Content, setting.UI.Reactions) { + err := fmt.Errorf("ChangeIssueReaction: '%s' is not an allowed reaction", form.Content) + ctx.ServerError(err.Error(), err) + return + } + reaction, err := models.CreateCommentReaction(ctx.User, comment.Issue, comment, form.Content) if err != nil { log.Info("CreateCommentReaction: %s", err) diff --git a/routers/repo/pull.go b/routers/repo/pull.go index 0ff077b46..78406de8a 100644 --- a/routers/repo/pull.go +++ b/routers/repo/pull.go @@ -422,6 +422,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *models.Issue) *git.Compare ctx.Data["NumCommits"] = compareInfo.Commits.Len() ctx.Data["NumFiles"] = compareInfo.NumFiles + ctx.Data["AllowedReactions"] = setting.UI.Reactions return compareInfo } diff --git a/templates/repo/diff/comments.tmpl b/templates/repo/diff/comments.tmpl index cc62f19a3..d86cf4077 100644 --- a/templates/repo/diff/comments.tmpl +++ b/templates/repo/diff/comments.tmpl @@ -38,7 +38,7 @@ {{$reactions := .Reactions.GroupByType}} {{if $reactions}}