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

Edit Comments #2320

Merged
merged 35 commits into from
May 11, 2021
Merged

Edit Comments #2320

merged 35 commits into from
May 11, 2021

Conversation

yuwenmemon
Copy link
Contributor

@yuwenmemon yuwenmemon commented Apr 9, 2021

Pullerbearing (@MariaHCD)
cc @roryabraham

Details

Give users the ability to edit their comments!

Fixed Issues

Fixes https://github.com/Expensify/Expensify/issues/147482
Fixes https://github.com/Expensify/Expensify/issues/162717

Tests/QA

  1. Open up a chat
  2. On Web/Desktop, click the pencil button that shows when you hover over a chat message of your own. On Mobile, long tap a message of your own
  3. Make sure that the comment shows up inside of the text input with the "Cancel" and "Save" buttons underneath
  4. Edit the comment, click "Cancel" make sure that the original comment still shows
  5. Edit the comment, click "Save" make sure that the comment shows as what you've edited it to become, with (edited) showing up next to the comment now

  1. Hover over a comment that is not your own, make sure that no "pencil" edit icon shows up and that you cannot edit that comment

Tested On

  • [ x ] Web
  • [ x ] Mobile Web
  • [ x ] Desktop
  • [ x ] iOS
  • Android

Screenshots

Web

Kapture 2021-04-30 at 15 53 18

Mobile Web

Kapture 2021-04-30 at 16 01 52

Desktop

Kapture 2021-04-30 at 16 31 52

iOS

Kapture 2021-04-30 at 16 35 25

Android

I can't get the Android emulator to run without slowing my machine to a crawl so animations, so here are some stills:
Screen Shot 2021-04-30 at 4 48 57 PM
Screen Shot 2021-04-30 at 4 49 23 PM
Screen Shot 2021-04-30 at 4 49 52 PM

@yuwenmemon yuwenmemon requested a review from a team as a code owner April 9, 2021 07:09
@MelvinBot MelvinBot requested review from MariaHCD and removed request for a team April 9, 2021 07:10
src/components/PopoverWithMeasuredContent.js Outdated Show resolved Hide resolved
src/pages/home/report/ReportActionContextMenu.js Outdated Show resolved Hide resolved
src/libs/actions/Report.js Outdated Show resolved Hide resolved
src/pages/home/report/ReportActionItem.js Outdated Show resolved Hide resolved
src/pages/home/report/ReportActionItemMessageEdit.js Outdated Show resolved Hide resolved
src/pages/home/report/ReportActionItemMessageEdit.js Outdated Show resolved Hide resolved
style={[styles.textInput, styles.flex0]}
/>
<View style={[styles.flexRow, styles.mt1]}>
<TouchableOpacity style={[styles.button, styles.mr2]}>
Copy link
Contributor

Choose a reason for hiding this comment

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

As stated in this thread, I would prefer to see something like this:

<Pressable
    onPress={this.deleteDraft}
    style={({hovered, pressed}) => [
        styles.button,
        styles.mr2,
        getButtonBackgroundColorStyle(getButtonState(hovered, pressed)),
    ]}
/>

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, I see you switched to Pressable but didn't use the style callback w/ getButtonBackgroundColorStyle(getButtonState(hovered, pressed))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We might need @Expensify/design's help to think around 2 things:

  1. The normal button hover color is the same as the hover color for the comment:
  2. There is a greenHover color, however, what should we use for greenPressed?
    Kapture 2021-05-06 at 10 05 45

Or perhaps better yet, do we need button styles for hover for the edit comment buttons?

Cancel
</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.buttonSuccess]}>
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, but you would just have to create something like getButtonSuccessBackgroundColorStyle

<Pressable
    onPress={this.deleteDraft}
    style={({hovered, pressed}) => [
        styles.button,
        styles.mr2,
        getButtonSuccessBackgroundColorStyle(getButtonState(hovered, pressed)),
    ]}
/>

Copy link
Contributor

Choose a reason for hiding this comment

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

Same here

</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.buttonSuccess]}>
<Text style={[styles.buttonText, styles.buttonSuccessText]} onPress={this.publishDraft}>
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here with the onPress given to the Text

@@ -896,6 +896,29 @@ NetworkConnection.onReconnect(() => {
fetchAll(false);
});

function editReportComment(reportID, reportAction, htmlForNewComment) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing a method doc here

@@ -896,6 +896,29 @@ NetworkConnection.onReconnect(() => {
fetchAll(false);
});

function editReportComment(reportID, reportAction, htmlForNewComment) {
// Optimistically update the report action with the new message
const sequenceNumber = reportAction.sequenceNumber;
Copy link
Contributor

Choose a reason for hiding this comment

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

I was just reviewing @sketchydroide's delete comment PR, and I thought the way he approached this syntactically was a bit cleaner (and has better error handling):

function editReportComment(reportID, reportAction, htmlForNewComment) {
    // Optimistically update Onyx
    actionToMerge = {}'
    const oldMessage = {...reportAction.message};
    actionToMerge[reportAction.sequenceNumber] = {
        ...reportAction,
        message: [
            {
                type: 'COMMENT',
                html: htmlForNewComment,
                text: htmlForNewComment.replace(/<[^>]*>?/gm, ''),
            },
        ],
    };
    
    Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, actionToMerge);
    
    // Make the API request
    API.Report_EditComment({
        reportID,
        reportActionID: reportAction.reportActionID,
        reportComment: htmlForNewComment,
    })
        .catch(() => {
            // If it fails, reset Onyx
            actionToMerge[reportAction.sequenceNumber] = {
                ...reportAction,
                message: oldMessage,
            };

            Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, reportActionsToMerge);
        });
}

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 like the error handling, but I actually find my way to be less confusing. Maybe that's just because I wrote it so I'm familiar with it, but it's a little more clear what's exactly is being edited.

@yuwenmemon yuwenmemon changed the title [WIP] Edit Comments Edit Comments Apr 30, 2021
@yuwenmemon
Copy link
Contributor Author

HEYO! I am removing this WIP! Please take a look! 🙇

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.

Okay, this seems to be working well, with the known exception that the ReportActionItemMessageEdit doesn't immediately gain focus when opened from the Popover version of the ReportActionContextMenu. @yuwenmemon is going to create a follow-up issue for that and make it external.

@yuwenmemon yuwenmemon merged commit 66186d1 into main May 11, 2021
@yuwenmemon yuwenmemon deleted the yuwen-editComments branch May 11, 2021 00:43
@OSBotify
Copy link
Contributor

🚀 Deployed to staging in version: 1.0.41-7🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@isagoico isagoico added the DeployBlockerCash This issue or pull request should block deployment label May 11, 2021
@isagoico
Copy link

Blue screen displayed when trying to edit message.

Expected Result

A context menu should show up

Actual Result

Screen becomes blue after long tap on message

Action Performed

  1. Open https://staging.expensify.cash/
  2. Login with existing account
  3. Open any chat
  4. Long tap a message of your own

Platform

iOS ✔️

Notes/images/Video

Bug5063742_RPReplay_Final1620758969.mp4

@roryabraham
Copy link
Contributor

@isagoico This could happen before this PR, can you create a separate issue?

@isagoico
Copy link

Tester was unable to reproduce the same blue screen in prod but it seems really similar to this issue #2705. Should I include the new info there? or just create a separate issue?

@roryabraham
Copy link
Contributor

Okay, yeah good idea to just add it in there

@isagoico
Copy link

Perfect, will remove the deploy blocker label then

@isagoico isagoico removed the DeployBlockerCash This issue or pull request should block deployment label May 11, 2021
@OSBotify
Copy link
Contributor

🚀 Deployed to production in version: 1.0.44-0🚀

platform result
🤖 android 🤖 failure ❌
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@mananjadhav
Copy link
Collaborator

I am tagging this PR to highlight an issue fixed here. All conditions in ternary expressions or left-hand operands on conditional renders, should be boolean. This PR is one of the PRs that uses conditional render with string operands, hence I am tagging it here for the contributors to check.

We've also updated the item in the checklist with this PR to avoid this issue in the future.

*/
deleteDraft() {
saveReportActionDraft(this.props.reportID, this.props.action.reportActionID, '');
toggleReportActionComposeView(true, this.props.isSmallScreenWidth);
Copy link
Contributor

Choose a reason for hiding this comment

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

This caused a regression (case 2). If we delete any comment the main composer will show up, even if we are deleting a non-focused message.

What we had to do is to add a condition where we show the main composer only if we are deleting the currently focused message.

super(props);
this.updateDraft = this.updateDraft.bind(this);
this.deleteDraft = this.deleteDraft.bind(this);
this.debouncedSaveDraft = _.debounce(this.debouncedSaveDraft.bind(this), 1000, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

Coming from #38483.
We can clear the side effects like this debounce when the component unmounts.
No one could have imagined that there would be multiple instances of this component at the same time. 😂

style={[styles.textInput, styles.flex0]}
onFocus={() => {
scrollToIndex({animated: true, index: this.props.index}, true);
toggleReportActionComposeView(false);
Copy link
Contributor

Choose a reason for hiding this comment

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

Since scrolling and toggling of the composer could result in a race condition due to animations, it is better to wait for the animations to complete before scrolling. This caused an issue #40767 where the composer box is partially hidden.

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

Successfully merging this pull request may close these issues.

9 participants