-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add reactions to issues/PR and comments #2856
Conversation
Seems good. Just a question to the team: Should it really look almost identical to GitHub's reactions? Or should it be different to don't look like a GitHub's copy? |
@andreynering reactions looks same also in other products (mattermost, discord etc) |
Yes, you're right. I think it's fine, then. |
As for these 6 reactions and their naming it just for being API compatible with github |
models/issue.go
Outdated
func (issue *Issue) GetReactionsByType() map[string]ReactionList { | ||
var reactions = make(map[string]ReactionList) | ||
for _, reaction := range issue.Reactions { | ||
list, ok := reactions[reaction.Type] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can simplify to reactions[reaction.Type] = append(reactions[reaction.Type], reaction)
Also in Comment.GetReactionsByType()
.
@@ -1350,6 +1350,40 @@ | |||
} | |||
} | |||
} | |||
.segment.reactions, .select-reaction { | |||
&.dropdown .menu { | |||
right: 0!important; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a CSS expert, but !important
is generally considered a bad practice. Are these necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sadly but it's needed as semantic UI is full of these :(
return | ||
} | ||
|
||
if ctx.HasError() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this if
block accomplish?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think yes but I will verify. It's to check if there is form validation error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still confused as to why this if
block is necessary
ID int64 `xorm:"pk autoincr"` | ||
Type string `xorm:"INDEX UNIQUE(s) NOT NULL"` | ||
IssueID int64 `xorm:"INDEX UNIQUE(s) NOT NULL"` | ||
CommentID int64 `xorm:"INDEX UNIQUE(s)"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Foreign key please? 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bkcsoft IIRC, xorm does not support foreign keys 😢
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And what also I don't quite like it inserts 0 values for IDs where it would normally should be null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would it ever insert 0
/null
? It would throw foreign key constrain
and that would be that 😛
@lafriks It's ready for review so that we can add it to v1.4? |
@lunny still WIP, will finish it this week |
@@ -22,6 +22,7 @@ | |||
{{end}} | |||
</div> | |||
{{end}} | |||
{{template "repo/issue/view_content/reactions" Dict "ctx" $ "ActionURL" (Printf "%s/issues/%d/comment/%d/reactions" $.RepoLink $.Issue.Index .ID) "Reactions" .GetReactionsByType }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't we just do {{template "repo/issue/view_content/reactions" .}}
like we do elsewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ethantkoenig because this template needs to be used in loop and loop variable needs to be passed to that template
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see. On another note, there aren't handlers for the :owner/:repo/issues/:index/comments/:id/reactions
route, so trying to add a reaction to a comment always results in a 404.
public/js/index.js
Outdated
$(container + '.select-reaction > .menu > .item').on('click', function(e){ | ||
e.preventDefault(); | ||
var url = $(this).closest('.select-reaction').data('action-url') | ||
+ '/' + ($(this).hasClass('is-active') ? 'unreact' : 'react'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is-active
class isn't used anywhere, so the action is always react
, and it's impossible to unreact.
{{range $key, $value := .Reactions}} | ||
<a class="ui label basic{{if $value.HasUser $.ctx.SignedUserID}} blue{{end}} has-emoji"> | ||
{{if eq $key "hooray"}} | ||
:tada: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no js handlers for clicking on these
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, unreacting is not yet implemented :)
@@ -22,6 +22,7 @@ | |||
{{end}} | |||
</div> | |||
{{end}} | |||
{{template "repo/issue/view_content/reactions" Dict "ctx" $ "ActionURL" (Printf "%s/issues/%d/comment/%d/reactions" $.RepoLink $.Issue.Index .ID) "Reactions" .GetReactionsByType }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see. On another note, there aren't handlers for the :owner/:repo/issues/:index/comments/:id/reactions
route, so trying to add a reaction to a comment always results in a 404.
@@ -19,6 +19,7 @@ | |||
<div class="ui top attached header"> | |||
<span class="text grey"><a {{if gt .Issue.Poster.ID 0}}href="{{.Issue.Poster.HomeLink}}"{{end}}>{{.Issue.Poster.Name}}</a> {{.i18n.Tr "repo.issues.commented_at" .Issue.HashTag $createdStr | Safe}}</span> | |||
<div class="ui right actions"> | |||
{{template "repo/issue/view_content/reactions" Dict "ctx" $ "ActionURL" (Printf "%s/issues/%d/reactions" $.RepoLink .Issue.Index) "Reactions" .GetReactionsByType }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.GetReactionsByType
is not defined in the current context, so .GetReactionsByType
will evaluate to nil.
In this case, it gets us what we want (we don't want to show the current reactions in the issue header, just the button for adding reactions, and the reactions template won't render the current reactions if Reactions
is nil), but this is confusing and non-obvious.
Can we make this more straightforward? My proposal would be to have two separate templates: one for displaying the current reaction, and another template for the button/pop-out to add new reactions. In the issue header, we would only use the second template, but in other places we would use both.
8133bce
to
23a2415
Compare
Ok, I think I have finished it now, so feel free to test and review it. |
@ethantkoenig I think have fixed all recommendations |
Codecov Report
@@ Coverage Diff @@
## master #2856 +/- ##
==========================================
- Coverage 33.43% 33.29% -0.15%
==========================================
Files 270 272 +2
Lines 39595 39939 +344
==========================================
+ Hits 13239 13297 +58
- Misses 24466 24741 +275
- Partials 1890 1901 +11
Continue to review full report at Codecov.
|
models/issue.go
Outdated
@@ -808,6 +835,15 @@ func (issue *Issue) ChangeAssignee(doer *User, assigneeID int64) (err error) { | |||
return nil | |||
} | |||
|
|||
// GetReactionsByType returns issue reactions grouped by type | |||
func (issue *Issue) GetReactionsByType() map[string]ReactionList { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe GetReactionsMap
or GetReactionsGroupByType
better name.
models/issue_comment.go
Outdated
} | ||
|
||
// GetReactionsByType returns comment reactions grouped by type | ||
func (c *Comment) GetReactionsByType() map[string]ReactionList { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe
func (reactions ReactionList) GroupByType() map[string]ReactionList {
var returns = make(map[string]ReactionList)
for _, reaction := range reactions {
returns[reaction.Type] = append(returns[reaction.Type], reaction)
}
return returns
}
And you can remove the above two methods.
And when click the reations, no request was sent to server. |
@lunny did you do Ctrl+f5 seems css&js was used from browser cache |
@lafriks need rebase |
77a3728
to
5460507
Compare
@ethantkoenig rebased and fixed your reported issues |
Lint error |
@lunny already fixed that but drone did not pick up latest commit correctly :( |
@lafriks You get a 500 if you view an issue that a deleted user reacted to. I think we need to delete all of a user's reactions when a user deletes his/her account. |
Hence foreign keys... |
762066c
to
285a810
Compare
@ethantkoenig @bkcsoft Added checks for deleted user and reaction deletion when deleting user |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One nit
models/issue_reaction.go
Outdated
// GetFirstUsers returns first 10 reacted user display names seperated by comma | ||
func (list ReactionList) GetFirstUsers() string { | ||
var buffer bytes.Buffer | ||
var rem = 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move to a named constant, since it is used multiple places?
8b76f5a
to
d2add53
Compare
@ethantkoenig moved that hardcoded limit to UI settings |
LGTM |
cc58235
to
d2add53
Compare
@ethantkoenig need your approval |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to approve 😛
@lafriks I don't mean to unnecessarily delay this PR, but it is too late to ask for tests? |
@ethantkoenig I will do them in other PR |
Screenshots:
For unauthorized users and tooltip to show reacted users:
