-
Notifications
You must be signed in to change notification settings - Fork 787
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
feat(comments): allow editing and deleting issue comments #327
feat(comments): allow editing and deleting issue comments #327
Conversation
const isActionButtonVisible = | ||
comment.user && | ||
authUser.login === comment.user.login && | ||
!Object.prototype.hasOwnProperty.call(comment, 'repository_url'); |
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.
For what this check?
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.
Because the description of the issue it is also a commentListItem, so I only show the button if is a comment and when is an issue description it has this field (repository_url), does that make sense?
I think I could extract this !Object.prototype.hasOwnProperty.call(comment, 'repository_url');
for a function for readability, what do you think?
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.
Still kind of unsure why we need this. Do we need to check for the repository_url
field at all?
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.
Also I notice that my initial issue post doesn't seem to allow me to edit:
Not sure if this is where you've set that to happen, but I think it would make sense to show the ActionSheet but only allow for editing for the first issue comment and not deleting. Happy to defer this if you feel like taking care of this in a separate PR however :)
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 using repository_url
for distinguishing between issue description and issue comment, only issue description has this field like I said before I think is better extract that for a method in order to improve the "understanding".
About editing the description, you are completely right, I didn't realize this possibility, I will take care of that in this PR. 😄
|
||
<View style={styles.dateContainer}> | ||
<Text style={styles.date}> | ||
{moment(comment.created_at).fromNow()} | ||
</Text> | ||
</View> | ||
|
||
{isActionButtonVisible && ( | ||
<View style={styles.iconContainer}> |
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.
Let's for greater clarity, rename the class to something like actionButtonIconContainer
?
src/issue/issue.reducer.js
Outdated
@@ -17,6 +19,8 @@ const initialState = { | |||
isMerged: false, | |||
isPendingComments: false, | |||
isPostingComment: false, | |||
isDeletingComment: false, | |||
isEditingIssueComment: false, |
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 better just isEditingComment
?
src/issue/screens/issue.screen.js
Outdated
const repoName = repository.name; | ||
const owner = repository.owner.login; | ||
|
||
this.props.deleteIssueCommentByDispatch(id, owner, repoName); |
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 do not know for sure, but it makes sense to define the variable id
, if it will be used once, I mean what maybe just pass comment.id
?
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.
yeah, you are completely right! 😄
@@ -248,6 +248,12 @@ export const en = { | |||
areYouSurePrompt: 'Are you sure?', | |||
applyLabelTitle: 'Apply a label to this issue', | |||
}, | |||
comment: { |
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.
Please duplicate these all new keys into the remaining language files.
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.
Should I try to translate? or I add the text in English?
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.
Generally not, although if you know any language and can translate, it would be good, but if not, then it is enough to duplicate it in English, otherwise there will be errors (because new keys will not be in the remaining languages)
src/issue/screens/issue.screen.js
Outdated
isPendingIssue || | ||
isDeletingComment | ||
); | ||
const showLoadingContainer = isPendingComments || isPendingIssue; |
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.
Since this variable contains a boolean value, it can be renamed to isShowLoadingContainer
?
<ViewContainer> | ||
{isEditingIssueComment && <LoadingModal />} | ||
<ScrollView> | ||
{repository.full_name && ( |
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 do you think, besides the name of the repository, can show the title issue?
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.
Sounds good to me
return (dispatch, getState) => { | ||
const accessToken = getState().auth.accessToken; | ||
|
||
dispatch({ type: DELETE_ISSUE_COMMENT.PENDING }); |
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 know this is not in the scope of this PR but what do you think about using redux-actions
instead? We can reduce boilerplate significantly.
You can find and example in this PR #187
If you're not feeling ok with it, that's fine too!
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, that's pretty amazing, I really like this approach! But to be honest, I think this should be done in a separated PR, I think is better just refactor the whole issue.action.js instead only this particular part, just for keeping the cohesion of the file.
What do you think about? 😄
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.
Completely agree!
Thanks!!!
I completely agree! Thanks!!
…On Wed, Sep 13, 2017 at 6:42 PM Jouderian Nobre Junior < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/issue/issue.action.js
<#327 (comment)>:
> @@ -117,6 +121,56 @@ export const postIssueComment = (body, owner, repoName, issueNum) => {
};
};
+export const deleteIssueComment = (issueCommentId, owner, repoName) => {
+ return (dispatch, getState) => {
+ const accessToken = getState().auth.accessToken;
+
+ dispatch({ type: DELETE_ISSUE_COMMENT.PENDING });
Oh, that's pretty amazing, I really like this approach! But to be honest,
I think this should be done in a separated PR, I think is better just
refactor the whole issue.action.js instead only this particular part, just
for keeping the cohesion of the file.
What do you think about? 😄
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#327 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAcYUqKp-g6MwfuwQTHAaadZxv1SeJGBks5siGhtgaJpZM4PVczh>
.
|
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 awesome! One thing I think might be improved visually is taking away the ...
and replacing it with a long touch. In other words, instead of using up a lot of space with the ellipsis, just use a long tap to bring up the deletion menu.
@andrewda yeah, that can be done. To be honest like much this approach because we are maybe "hiding" some features from the user, but I'm not against this approach 😄 I would love to get more opinions about, any thoughts @lex111 @alejandronanez @housseindjirdeh? |
@lex111 I did most of all improvements, could you take a look? 😄 |
@jouderianjr now everything is ok 👌 As still a variant with actions, you can look at this https://github.com/AidenMontgomery/react-native-swiping-row |
Cool, So, now we have basically 3 options :) Which one you guys would prefer? |
src/issue/screens/issue.screen.js
Outdated
@@ -240,6 +266,8 @@ class Issue extends Component { | |||
<CommentListItem | |||
comment={item} | |||
onLinkPress={node => this.onLinkPress(node)} | |||
onDeletePress={comment => this.deleteComment(comment)} | |||
onEditPress={comment => this.editComment(comment)} |
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 we can write shorter as onDeletePress={this.deleteComment}
. Maybe another pr is required if you guys(@lex111, @jouderianjr) agree with it.
Of course, there are so many places like this. And it doesn't matter.
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.
Yeah, I agree with you, I do prefer the shorter version, I just tried to follow the file pattern, but I also agree in do another PR for that, should be better change all the file.
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.
Yeah I've used arrow syntax within render callbacks throughout the app. Leveraging onDeletePress={this.deleteComment}
is better and I think I'll dedicate some time to do that throughout the app
@lex111 😲 Swiping is a really good idea! |
Cool, 2 votes 😄 I'll implement with swipe action |
@andrewda I've implemented with long press click. Could you take a look? |
@jouderianjr it's a pity, but there is no way to disable swipe on the screen issue? |
I'm having the same issue with TabNavigation swipe that prevents scrolling horizontally in webviews on Android (Readme.md is displayed in webview in #326) I would love to have the TabNavigation swipe disabled all together in the app. I personally find this type of navigation confusing, especially when you know that you can have the Issue screen (for example) displayed in all 4 tabs at the same time.. |
I think disabling the swipe only in a few screens not intuitive. We could disable for the whole tab navigation, is just set |
Man thank you all so so much for thinking this through. So some thoughts:
If they both don't seem to coexist together, then we'll have to forego swipe I'm afraid. However, I think this is definitely something we should explore if we can.
Let me know what you folks think 💬 |
@housseindjirdeh Cool! The swipe feature really improves the UX, I will do more tests in order to add that for the app 😄 |
@housseindjirdeh This screenshot is not from the actual gitpoint app 😂 It's from music app?! |
Haha @vitalkanev I know 😂 😂 It was the first app I can think of (Spotify) that had a really nice swipe feature to remove and add songs to your library. Just wanted to show how even though I can still navigate from swiping the left side of the screen, the swipe still works well in the context of each item. Probably should have explained why I threw that |
And thank you @jouderianjr, please keep us posted. If it turns out to not be the smoothest experience, more than happy to use the simpler approach 💃 |
- Add translation keys for each language. - Show issue name in edit-issue-comment.screen. - Code style minor improvements
- Move action button to bottom. - Add long press to open action menu.
db91839
to
7c92872
Compare
Unfortunately, the swipe feature is not possible because of how the tabNavigation is implemented :/ I've updated the code with @housseindjirdeh suggestions, we have long press and the icon button in the bottom What do you think guys? 😄 Ps. I've attached an incomplete gif haha, The problem happens when we try swipe left from right, because the tabNavigation swipe its global :/ |
/> | ||
</TouchableOpacity> | ||
)} | ||
<TouchableWithoutFeedback onLongPress={this.showMenu}> |
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 use TouchableOpacity
better to show feedback?
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.
yeah, looks better!
Hey guys, don't forget my PR 🙉 @housseindjirdeh @andrewda |
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 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 great @jouderianjr, tested it again and again and editing/deleting work so smoothly. Thank you for this, it's sooo needed in the app.
Just left a few comments here and there for a few things I noticed. Honestly, the majority are minor and I'm happy to help you through each one :)
EditIssueComment: { | ||
screen: EditIssueCommentScreen, | ||
navigationOptions: ({ navigation }) => ({ | ||
title: navigation.state.params.title, |
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.
🎉
@@ -87,6 +89,10 @@ const styles = StyleSheet.create({ | |||
commentRegular: { | |||
...regularFont, | |||
}, | |||
actionButtonIconContainer: { | |||
alignItems: 'flex-end', | |||
justifyContent: 'center', |
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.
Looks slightly squeezed bottom right, just added a padding: 5
testing on my machine and I think it looks better with that :)
const isActionButtonVisible = | ||
comment.user && | ||
authUser.login === comment.user.login && | ||
!Object.prototype.hasOwnProperty.call(comment, 'repository_url'); |
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.
Still kind of unsure why we need this. Do we need to check for the repository_url
field at all?
source={{ | ||
uri: comment.user.avatar_url, | ||
}} | ||
<TouchableOpacity onLongPress={this.showMenu}> |
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.
Initially agreed that TouchableOpacity
makes sense here, but playing around with on my simulator I'm not sure if we should have this:
Notice how just tapping it while scrolling still shows the opacity change although no action fires until it's actually long pressed. I think this will better as a TouchableWithoutFeedback
so we don't get a prompt at all but onLongPress still shows an actionsheet
<Icon | ||
color={colors.grey} | ||
size={20} | ||
name={'ellipsis-h'} |
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.
🎉
{isEditingComment && <LoadingModal />} | ||
<ScrollView> | ||
{repository.full_name && ( | ||
<ListItem |
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.
Feels kinda out of place to have this ListItem
here, I think we can remove this to be honest (the user can easily see the back navigation step with the issue number)
<SectionList | ||
title={translate('issue.newIssue.issueComment', language)} | ||
> | ||
<TextInput |
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 great stuff. The only think I'm noticing is that with super long comments, this TextInput
is massive
That blocks the ScrollView
scroll capability and hides the the submit button. We'll need to have a fixed height for this input field (or a max height if that's possible - will be better if we can)
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.
src/issue/screens/issue.screen.js
Outdated
@@ -240,6 +266,8 @@ class Issue extends Component { | |||
<CommentListItem | |||
comment={item} | |||
onLinkPress={node => this.onLinkPress(node)} | |||
onDeletePress={comment => this.deleteComment(comment)} | |||
onEditPress={comment => this.editComment(comment)} |
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.
Yeah I've used arrow syntax within render callbacks throughout the app. Leveraging onDeletePress={this.deleteComment}
is better and I think I'll dedicate some time to do that throughout the app
const isActionButtonVisible = | ||
comment.user && | ||
authUser.login === comment.user.login && | ||
!Object.prototype.hasOwnProperty.call(comment, 'repository_url'); |
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.
Also I notice that my initial issue post doesn't seem to allow me to edit:
Not sure if this is where you've set that to happen, but I think it would make sense to show the ActionSheet but only allow for editing for the first issue comment and not deleting. Happy to defer this if you feel like taking care of this in a separate PR however :)
Hey @housseindjirdeh I set a fixed height to the TextInput, I don't know if that is the best approach :/ Any thoughts about that? Also, about the "edit issue description" feature I realize that is better handled with that in another PR because I think should be another screen, because we can edit the issue title and the title description, so I think this could be done on the same screen. |
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 maxHeight
might be a better option 🤔
Don't worry, I can submit a commit for that since it's so minor. All in all it looks amazing mate, more than happy to defer editing the title on a separate PR :)
`/notifications?participating=${participating}&all=${all}`, | ||
accessToken | ||
); | ||
|
||
export const fetchMarkNotificationAsRead = (notificationID, accessToken) => |
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.
@housseindjirdeh these were deleted by mistake
Closes #24
Before
After
Thanks in advance :)