-
-
Notifications
You must be signed in to change notification settings - Fork 643
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
Implemented editing message #402
Conversation
Automated message from Dropbox CLA bot @kunall17, it looks like you've already signed the Dropbox CLA. Thanks! |
src/message/MessageContainer.js
Outdated
const { auth, message, pushRoute, popRoute } = this.props; | ||
if (isSentByYou(auth, message)) { | ||
pushRoute(''); | ||
fetchRawMessage(auth, message.id, (res) => { |
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.
We do use async/await and not callbacks.
It should be in the form of:
const res = await fetchRawMessage(auth, message.id);
Right arrow in the modal title bar is not a standard UI for iOS/Android. But, in that specific case, I think we want to implement it as Slack does: the compose box becomes filled with the message text, and then the icon for send optionally might change (or not). |
The slack one looks really cool, i'll implement something like that! |
@borisyankov updated the branch, |
6f58e81
to
4ad47b0
Compare
@borisyankov Updated the PR! |
Cool. It works reasonably well right now, I'll do a more thorough review of the code itself. We might also want to add a cancel button. We should discuss it. |
And we should either add a progress bar for the update, or do optimistic UI update which @nashvail worked on for the Reactions. We'll need to discuss that too. |
src/api/editMessage.js
Outdated
@@ -0,0 +1,15 @@ | |||
import { apiPatch } from './apiFetch'; |
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.
Would the name of the actual API call be 'updateMessage'?
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 reason is that 'edit' is more of a continuous action while update sound more like a command. Makes sense?
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, makes sense
src/api/editMessage.js
Outdated
{ | ||
content | ||
}, | ||
res => res, |
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.
Use this to return a more concrete field if only one is relevant which likely is the case.
Maybe res.content
or even res.content.raw_content
?
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 result is not being used anywhere, I'll remove it
src/common/Icons.js
Outdated
@@ -17,5 +17,6 @@ export const IconStream = (props) => <FontAwesomeIcon name="hashtag" {...props} | |||
export const IconPrivate = (props) => <FontAwesomeIcon name="lock" {...props} />; | |||
export const IconPrivateChat = (props) => <IoniconsIcon name="md-text" {...props} />; | |||
export const IconDownArrow = (props) => <IoniconsIcon name="md-arrow-down" {...props} />; | |||
export const IconEdit = (props) => <MaterialIcon name="done" {...props} />; |
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 'IconOK' or 'IconDone' ?
src/utils/message.js
Outdated
@@ -51,3 +51,6 @@ export const shouldBeMuted = (msg, narrow, subscriptions, mutes = []): boolean = | |||
|
|||
return mutes.some(x => x[0] === msg.display_recipient && x[1] === msg.subject); | |||
}; | |||
|
|||
export const isSentByYou = (message, auth): boolean => | |||
auth.email === message.sender_email; |
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 an overkill to extract that to a function?
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.
Would have suggested isSentBySelf
as a name, but am suggesting to inline the logic.
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'll inline the logic!
src/message/messageActionSheet.js
Outdated
const isSentByYouAndNarrowed = (message, auth, narrow) => | ||
isSentByYou(message, auth) && !isHomeNarrow(narrow); | ||
|
||
const actionSheetButtons = [ |
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.
Nice, I was thinking to add exactly that, but decided not to for now. Still like it a lot ;)
src/message/MessageList.js
Outdated
@@ -17,6 +17,11 @@ const styles = StyleSheet.create({ | |||
export default class MessageList extends React.PureComponent { | |||
autoScrollToBottom = false; | |||
|
|||
constructor(props) { | |||
super(); | |||
this.state = { actionSheetButtons: ['', ''] }; |
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.
We should use state
sparingly.
I don't like the API of this action-sheet component at all. It almost forces us to use state, but it is not a good approach.
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, note that any state change does a new render. In this case, it is likely not a perf issue, but still annoys me :)
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.
But here only once the state is changed, so no issues there.
Even I don't like the static way of using the actionsheets I saw there is an issue related to this in their library github page as well.
@@ -21,16 +21,17 @@ const styles = StyleSheet.create({ | |||
}, | |||
}); | |||
|
|||
export default class SendButton extends React.Component { | |||
export default class SubmitButton extends React.Component { |
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.
Do we really want to rename the button?
'submit form' vs 'send message'
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, Send Button suggest's its being only used to send the message, but submit suggest's it's being used to complete a process (send or edit)
src/compose/ComposeText.js
Outdated
|
||
handleEdit = async () => { | ||
const { auth, editMessage, cancelEditMessage } = this.props; | ||
if (editMessage.content.raw_content === this.state.text) { |
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.
Just do a return.
I don't think there is a single person that cares for the error.
This is too much of a 'developer' thinking ;)
src/compose/ComposeText.js
Outdated
try { | ||
await patchMessage(auth, this.state.text, editMessage.id); | ||
} catch (err) { | ||
this.showErrorAlert(err.message, 'Error Occurred'); |
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.
We need a better error message.
If it is a general error I suggest 'Failed to edit message' or 'Error while updating message'.
src/compose/ComposeText.js
Outdated
title, | ||
message, | ||
[{ text: 'OK', onPress: () => {} }], | ||
{ 'cancelable': true } // eslint-disable-line spellcheck/spell-checker |
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.
Add cancelable
to the dictionary?
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, almost forgot had modified it earlier!
Overall, the PR looks quite good. 👍 |
Updated the PR |
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/compose/ComposeText.js
Outdated
@@ -71,6 +82,29 @@ class ComposeText extends React.Component { | |||
}); | |||
} | |||
|
|||
showErrorAlert = (message, 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.
I think we can extract this from here.
we can create a common alert file (in common
) which will be helpful in future.
src/compose/ComposeText.js
Outdated
autocomplete: false, | ||
contentHeight: MIN_HEIGHT, | ||
}; | ||
} | ||
|
||
componentWillReceiveProps(nextProps) { | ||
if (nextProps.editMessage !== this.props.editMessage) { | ||
this.setState({ |
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.
we can pop keyboard here this.textInput.focus();
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.
Indeed. Testing on a real device makes it more obvious.
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.
Thanks for the suggestions @vishwesh3 :) 👍
Heads up @kunall17, we just merged some commits (latest: d7cfbe5) that conflict with the changes your made in this pull request! You can review this repository's recent commits to see where the conflicts occur. Please rebase your feature branch against the |
fdd9358
to
b47c353
Compare
Updated, b47c353 adds a new library to prevent the editMessage key to be persisted in the storage hence preventing those bugs, currently I have used a library which people suggested in the redux-persist repo! |
f88c5e0
to
af5a8ed
Compare
Heads up @kunall17, we just merged some commits (latest: 74b3cb3) that conflict with the changes your made in this pull request! You can review this repository's recent commits to see where the conflicts occur. Please rebase your feature branch against the |
Rebased |
2a7a922
to
318b8f7
Compare
Heads up @kunall17, we just merged some commits that conflict with the changes your made in this pull request! You can review this repository's recent commits to see where the conflicts occur. Please rebase your feature branch against the |
Heads up @kunall17, we just merged some commits that conflict with the changes your made in this pull request! You can review this repository's recent commits to see where the conflicts occur. Please rebase your feature branch against the |
I'll do another round of code reviews, before you do the rebase again 😄 |
package.json
Outdated
@@ -58,6 +58,8 @@ | |||
"redux-action-buffer": "^1.1.0", | |||
"redux-logger": "^3.0.1", | |||
"redux-persist": "^4.8.2", | |||
"redux-persist-transform-filter": "^0.0.10", | |||
"redux-persist-transform-immutable": "^4.1.0", |
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.
We do not currently use Immutable.js are you sure we need this?
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.
redux-persist-transform-immutable is redundant will remove it, don't remember how it got here!
@@ -0,0 +1,15 @@ | |||
import { apiPatch } from './apiFetch'; |
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.
You can get this file merged in, before the whole PR.
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.
Lets keep this file in this, as it has been reviewed. I'll make the api calls in another PR from next time!
The main thing about this PR that should be improved is how it handles the state of a message being edited.
|
title, | ||
message, | ||
[{ text: 'OK', onPress: () => {} }], | ||
{ 'cancelable': true } |
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 ampersands around cancellable
?
I don't think cancellable: true is correct, as an error message should not have a cancel option.
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.
cancelable is for the when the user presses outside the alert box, so if a user presses outside of the alert then it can be dismissed!
@@ -0,0 +1,10 @@ | |||
import { Alert } from 'react-native'; |
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 can also be merged separately, before the full PR is ready.
I didn't used state's for this because we need to have the editMessage object in the store as the Title component need's this and this is a read only object, so no need to throw this into state. I'll move the objects to |
I meant to rename the 'app' reducer to a 'session' reducer, not sure if you are confused or that you understood me. |
Yeah i know about the blacklist, but in the current implementation I had to throw away an object from a reducer hence I had to use this library, so i'll save the object in the app reducer hence we can avoid this library |
7360308
to
ebb247b
Compare
Done |
Heads up @kunall17, we just merged some commits that conflict with the changes your made in this pull request! You can review this repository's recent commits to see where the conflicts occur. Please rebase your feature branch against the |
Heads up @kunall17, we just merged some commits that conflict with the changes your made in this pull request! You can review this repository's recent commits to see where the conflicts occur. Please rebase your feature branch against the |
@borisyankov Rebased! |
Another epic-length PR merged :) |
Currently I used onLongPress, ideally this should be place in a menu (ActionSheet for IOS) hence when #378 will be completed i'll create an option there in 04cd5f4 :)