Skip to content
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

#2821 add up arrow to edit feature #3157

Merged

Conversation

dklymenk
Copy link
Contributor

@dklymenk dklymenk commented May 26, 2021

Details

In addition to solution described in my original proposal, code in this PR should be faster because it doesn't loop over all messages to filter the ones where user is the author, but instead it loops over the list in reverse order and stops on the first matching result.

Please note that this feature is not present on native apps, the same way the shortcut for sending message (Enter/Return key) is not working on native apps.

Fixed Issues

Fixes #2821

Tests / QA Steps

Web and Desktop:

  1. Open a chat where you already have at least one message sent. (Or write a message if you don't have one)
  2. While message box is focused, press ArrowUp.
  3. The edit box for your last message should appear.

Android and iOS:

  1. Since the feature is not present on native, make sure basic chatting functionality is not broken.

Tested On

  • Web
  • Mobile Web
  • Desktop
  • iOS
  • Android

Screenshots

Web

2021-05-26.09-57-07.mp4

Mobile Web

Simulator.Screen.Recording.-.iPhone.11.-.2021-05-26.at.10.27.42.mp4

Desktop

Screen.Recording.2021-05-26.at.10.33.13.mov

iOS

Android

@dklymenk dklymenk marked this pull request as ready for review May 26, 2021 07:40
@dklymenk dklymenk requested a review from a team as a code owner May 26, 2021 07:40
@MelvinBot MelvinBot requested review from thienlnam and removed request for a team May 26, 2021 07:41
@roryabraham roryabraham self-requested a review May 26, 2021 16:28
roryabraham
roryabraham previously approved these changes May 26, 2021
Copy link
Contributor

@roryabraham roryabraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this is looking great and testing well!

src/pages/home/report/ReportActionCompose.js Outdated Show resolved Hide resolved
@roryabraham
Copy link
Contributor

All yours @thienlnam

Comment on lines 259 to 260
Object.keys(this.props.reportActions).reverse(),
key => this.props.reportActions[key].actorEmail === this.props.session.email,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this the correct way to do it. You should sort by the sequenceNumber.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see that report actions are being sorted by sequenceNumber here:
https://github.com/Expensify/Expensify.cash/blob/9f305176681385f2aa80f43de06fc6dffa7f0b83/src/pages/home/report/ReportActionsView.js#L243-L255

Is this a requirement, however? In my local storage for any ReportActions_<report_id> sequenceNumber always matches the key of a report action.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean? This code just loops though the reportActions backwards and finds the first one where the actor email is the current user.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Objects keys are not sequential. so keys' order could be discrete.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the keys in my localstorage are ordered and identical to sequenceNumber. If one can't trust this order, I think running sortBy on entire object for every action trigger would not be very efficient. It would be better to have some storage for sorted list shared with ReportActionsView.js in that case.

@parasharrajat
Copy link
Member

@roryabraham I noticed one thing may be not related to this issue. We can see the edit action on IOU actions but not edit box open for them and this PR will try to follow the same when user will press the UP Arrow.

@roryabraham
Copy link
Contributor

roryabraham commented May 26, 2021

@parasharrajat Thanks for reviewing! Good point about not filtering out IOU actions!

Check out these lines from the DeleteComment pull request. It implements a function (reused for edit comment and delete comment) called canEdit that determines if the user should be able to edit that action.

So what we should do is:

  1. Also return false in that function if the reportAction is an IOU action
  2. Move that function to a separate library so it can be imported and used here.

@dklymenk
Copy link
Contributor Author

Ok, I see.

I do the check for reportActionID, that's enough to avoid editing the newly created message, but I see the need to have a separate function for that since it's such a widely used check.

So I create a new file src/libs/canEdit.js with default export? Or add a function to some existing one?

Also since that PR is not merged yet, I can't really "move" the function to separate library, so i'll just add a function and won't touch the original implementation.

@parasharrajat
Copy link
Member

I think reportUtils.js will be a good place to use and you can suggest that function on the Delete comment PR.

@roryabraham
Copy link
Contributor

roryabraham commented May 26, 2021

Agreed, in this PR we can just add a function to reportUtils.js called canEditReportAction, then import it and use it both in the ReportActionContextMenu and here in the ReportActionCompose

@dklymenk
Copy link
Contributor Author

Updated the PR with change regarding the new function.

I also took the liberty of adding the isReportMessageAttachment call to the new canEditReportAction function as well.

Copy link
Contributor

@roryabraham roryabraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two other suggestions:

  1. I noticed that you didn't import & use your new function in ReportActionContextMenu here. Let's do that to DRY this up.
  2. Instead of using withOnyx and passing in the sessionEmail as a parameter to the canEditReportAction function, you could instead use Onyx.connect directly in reportUtils to keep a local reference to the current user's email. That way we have one Onyx subscription to the SESSION key instead of 2+

function canEditReportAction(reportAction, sessionEmail) {
return reportAction.actorEmail === sessionEmail
&& reportAction.reportActionID
&& reportAction.actionName !== 'IOU'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
&& reportAction.actionName !== 'IOU'
&& reportAction.actionName === 'ADDCOMMENT'

Also, you could optionally add a const to CONST.js called REPORT_ACTION.ACTION_TYPES so that we're not using a string literal here.

@roryabraham
Copy link
Contributor

roryabraham commented May 26, 2021

Here's an example of what I mean by using Onyx.connect directly in the library function instead of using withOnyx in the React code.

…se Onyx.connect directly in reportUtils + add CONST.REPORT_ACTION + check for ADDCOMMENT
@dklymenk
Copy link
Contributor Author

I've applied requested changes. @roryabraham, please check. Thank you.

@dklymenk dklymenk requested a review from roryabraham May 28, 2021 16:39
src/CONST.js Outdated
@@ -47,6 +47,7 @@ const CONST = {
TYPE: {
CHAT: 'chat',
IOU: 'iou',
ADDCOMMENT: 'ADDCOMMENT',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've created REPORT.TYPE.ADDCOMMENT here, but we want REPORT.ACTION.TYPE.ADDCOMMENT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, fixed

@dklymenk dklymenk requested a review from roryabraham May 28, 2021 17:50
@dklymenk
Copy link
Contributor Author

Copy link
Contributor

@roryabraham roryabraham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was broken after your last merge. To fix it, I think you'll need to:

  1. Remove the canEdit member function from ReportActionContextMenu (including from the constructor)
  2. Replace it's current usage in the shouldShow for deleteComment with () => canEditReportAction(this.props.reportAction)

Please be careful to retest locally before each new request for review, especially if you had to resolve merge conflicts.

src/libs/reportUtils.js Show resolved Hide resolved
this.canEdit()
&& !isReportMessageAttachment(this.getActionText())
),
shouldShow: canEditReportAction(this.props.reportAction),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
shouldShow: canEditReportAction(this.props.reportAction),
shouldShow: () => canEditReportAction(this.props.reportAction),

@dklymenk
Copy link
Contributor Author

My bad on this one. For some reason I did not think that conflict resolution would break stuff.

Applied your suggestions. Thanks.

@dklymenk dklymenk requested a review from roryabraham May 29, 2021 17:01
@roryabraham
Copy link
Contributor

@dklymenk Sorry, there are more merge conflicts now 😞

@dklymenk
Copy link
Contributor Author

@roryabraham

Resolved the conflict. Tested. Everything should be ok.

@roryabraham
Copy link
Contributor

looks good and tests well 👍

@roryabraham
Copy link
Contributor

@thienlnam All yours for the merge after E2E tests are done 👍

@roryabraham
Copy link
Contributor

Since Jack approved a previous version of this pull request, and I think this might resolve this deploy blocker, I'm going to go ahead and merge this.

@isagoico
Copy link

isagoico commented Jun 1, 2021

@dklymenk We found this issue in mWeb

mWeb - Up arrow not enabled for edit feature

Expected Result

The edit box for your last message should appear.

Actual Result

Arrow up is disabled and unable to select by tapping

Action Performed

  1. Launch the url and login
  2. Open a chat where you already have at least one message sent. (Or write a message if you don't have one)
  3. While message box is focused, press ArrowUp.

Platform

mWeb ✔️

Notes/images/video

Bug5094951_Up_arrow.mp4

@roryabraham
Copy link
Contributor

No need to block deploys on this @isagoico, but @dklymenk let's get this fixed with a follow-up PR. You showed a video of it working, so this hopefully should be pretty simple.

@dklymenk
Copy link
Contributor Author

dklymenk commented Jun 2, 2021

@isagoico Those "arrow keys" on your video are grayed out(inactive,disabled). Tapping them doesn't provide any feedback to user nor does it send any events to browser.

Moreover, those are not actually arrow keys. A quick online search told me, that they behave more like Tab and Shit+Tab to jump between inputs on a form.
Here is a demo (note that buttons become enabled when there is an action available):

Simulator_Screen_Recording_iPhone_11_2021_06_02_at_08_33_10.mp4

I used https://www.w3schools.com/html/tryit.asp?filename=tryhtml_form_submit, but any form with proper html should do the trick.

Now I don't have a real iPhone, and to my understanding you cannot install apps from app store on a simulator, so if you can install some third-party full 5 row keyboard from store, try with that and it won't work, I'll try to get my hands on one to fix the issue.

@roryabraham The video I showed for mobile web is from Chromium dev tools responsive mode iPhone simulator and I pressed an Up Arrow on my actual laptop keyboard there, but to demonstrate that it actually works on real phone, I have shot a few videos: one with third-party keyboard from F-Droid and one with actual physical keyboard connected via usb-c dongle:

video_2021-06-02_09-11-59.mp4
test.mp4

Hopefully, this clears up the confusion and the issue can be closed again. Thanks.

EDIT: I meant "the HOLD for payment can be added back", and not "the issue can be closed again".

EDIT2: Corrected the origin of demo mWeb video in the first post of the PR.

@iwiznia
Copy link
Contributor

iwiznia commented Jun 2, 2021

I agree with @dklymenk

@roryabraham
Copy link
Contributor

Thanks @dklymenk!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants