-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Refactor comment message rendering #25524
Conversation
Here is my thought so far... I think the refactoring makes it clear between text and attachment fragment, but I also think the current code is good enough to handle both in one code even though the strikethrough style is currently useless for an attachment (I say currently to anticipate in the future where we can send attachment and text in one action). App/src/pages/home/report/ReportActionItemFragment.js Lines 121 to 128 in 03cf0b1
So, if we ignore the refactoring, I see what we did here is moving the But with the above concern, I still think it's best to put the style at the View that wraps the fragments. All of my concerns above are actually trying to be future-proof though, so let me know what you think. btw, here is my improved solution (from what I proposed in my draft PR) that I could think of
|
I don't agree. This whole situation is getting a bit embarrassing, because we, as a team, are struggling to add a goddamn 8px margin over an attachment miniature. We two tried to fix that and we failed again. So, no, I don't think that suggests that the surrounding code is good enough.
Again, we're struggling to be present-proof, so I don't think we have the comfort of becoming so future-proof. Also, I feel that this whole "message as a list of fragments" model is more a kind of legacy and poor modeling than a preparation for a single message with multiple attachments. If we assumed that all combinations of message fragments are valid, we should check if the first fragment is an attachment, by the way, and then add a margin on top of the whole message (still making assumptions about what will be rendered a bit far from that point, though). Finally, in the worst case, if the backend actually served a message with multiple attachment I think that this whole thing already took too much time, so I really would like to at least leave the surrounding code (which I now consider the actual root cause of the whole mess) in better shape... |
I think I agree to just focus on what we have now instead of trying to think too far ahead. I believe the refactor will make it easier to make any changes to a specific type of fragment (either attachment or text). So, should I go ahead now updating my PR with this refactor? EDIT: but I think I will keep the |
4d7e721
to
852fedc
Compare
|
00dbc0c
to
22acd8c
Compare
There are some serious issues on |
...so the logic for rendering attachments is clearly separated from the logic for rendering textual comments. This fixes Expensify#25415
22acd8c
to
5d914f1
Compare
Lint is failing |
Damn, it should be the last one. Fixed. |
I will resume the work on Monday (checklist, testing, etc.), sorry for the extra delay |
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 tested as many cases as possible. Hopefully there wouldn't be any minor regressions after this refactor 🙏
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 love the direction this is going!
|
||
const containsOnlyEmojis = EmojiUtils.containsOnlyEmojis(text); | ||
|
||
return ( |
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 is the difference between what is rendered here and what is rendered in RenderCommentHTML
? It feels like all the stuff here should also be in its own 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.
What is the difference between what is rendered here and what is rendered in RenderCommentHTML?
Uh, here we render a bunch of text, and there we render HTML? 😁
It feels like all the stuff here should also be in its own component.
It's already extracted from ReportActionItemFragment.js (you can check the red diff).
RenderCommentHTML
was extracted because it is used at least twice. A pragmatic thing.
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 changes! Just leaving a small review and saying the changes look more or less fine to me as far as I understood them.
feedback: I see there is a lot of moving of components around - this made it a bit hard for me to tell which is the change that fixes the bug. The reusable part looks to be the RenderCommentHTML
(which seems fine).
I would be interested in seeing a version of this PR that fixes the bug only without additional refactoring. We gain a lot from fixing the bug and less from moving things around.
I would also request that in the future we also please update the description of the issue to clearly explain what we are trying to achieve. That way, new reviewers can quickly catch up on the context.
...so the logic for rendering attachments is clearly separated from the logic for rendering textual comments
I didn't get much from this tbh.
Hope these thoughts find you well 🙇
case 'COMMENT': { | ||
const {html, text} = props.fragment; | ||
const isPendingDelete = props.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && props.network.isOffline; |
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.
question: Can you remind us we are removing the props.network.isOffline
here?
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 treat is as removing the old variable completely and adding a new one with a similar name.
If you track the usages, everything is still behaving as it previously was.
A crucial place: https://github.com/Expensify/App/pull/25524/files#r1387825465
return <RenderHTML html={props.source === 'email' ? `<email-comment>${htmlWithTag}</email-comment>` : `<comment>${htmlWithTag}</comment>`} />; | ||
if (isFragmentAttachment) { | ||
return ( | ||
<AttachmentCommentFragment |
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.
NAB/IMO, I think it doesn't need it's own component as it is not used anywhere else and the component we created looks very simple.
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 created it for symmetry. I agree that it's not strictly needed, but do you think it needs to be removed now? It can grow if New Expensify goes more into a fat client architecture direction.
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.
If it was me reviewing the proposal I would personally say to not bother with this so we can move forward.
I did find this:
But that doesn't really instruct us on when it's appropriate to create a new component.
Our style guide doesn't say much on this so the ideal thing would be to hash out what the best practice should be and then pop the outcome in the style guide so people can put their bias aside.
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 much of a checklist/style guide person (I appreciate automated code formatters, though!), so let me know what can we do to resolve this thread in the context of this PR
If we were forced to add a new checkbox or something similar, I would vote for:
If there's nothing wrong with a chunk of PR code being reviewed, and there's no confidence that any alternative would be apparently or measurably better, it should be left as-is
</Text> | ||
</> | ||
)} | ||
</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.
noting/nab: this looks logically equivalent as far as I can tell, but let us know if there is a material change to look out for here.
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.
It's meant to be exactly equivalent beside the bugfix! Technically, in the old code, a lot of text-related code was also applied to attachments, but it was a no-op (as there's no text in an attachment image).
@@ -84,7 +83,7 @@ function ReportActionItemMessage(props) { | |||
}; | |||
|
|||
return ( | |||
<View style={[styles.chatItemMessage, !props.displayAsGroup && isAttachment ? styles.mt2 : {}, ...props.style]}> | |||
<View style={[styles.chatItemMessage, ...props.style]}> |
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.
confirming: So, I see we no longer need this because we are handling it inside ReportActionFragment
. But not sure exactly why this is being moved to that view. Is this the bug fix part?
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 you meant:
because we are handling it inside
AttachmentCommentFragment
Yes, this is the fix part. This margin is explicitly meant for the attachment presentation (think: an actual displayed attachment image), but because of various conditions, when the message is deleted, the booleans here can be true, while deeper inside, we take a rendering path that doesn't actually display the attachment image. Hence the "jump".
In the new suggested structure, things are more clearly separated, so it's quite obvious that a margin meant for attachment can be displayed if-and-only-if we display an actual attachment image.
<TextCommentFragment | ||
source={props.source} | ||
fragment={fragment} | ||
styleAsDeleted={isPendingDelete && props.network.isOffline} |
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.
@marcaaron ☝️
Going OOO this week so removing myself as a blocker here.
@cubuspl42 please fix lint. |
Done |
Do we need any more reviews on this or is it OK to merge? I see lots of people as assigned reviewers :D |
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 your help in reviewing this @tgolen 👍
Not waiting on @marcaaron as he's ooo. |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to production by https://github.com/mountiny in version: 1.4.0-3 🚀
|
|
||
function TextCommentFragment(props) { | ||
const {fragment, styleAsDeleted} = props; | ||
const {html, text} = fragment; |
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.
Might be related: When there is a mention and emoji the backend only sending emoji itself on text
and it is getting treated as only emoji and enlarged in chat causing UI problems. #50306
...so the logic for rendering attachments is clearly separated from the logic for rendering textual comments.
Details
Fixing a regression caused by #24539, which was solving #24216.
Fixed Issues
$ #25415
PROPOSAL:
Tests
Same as QA Steps
Offline tests
QA Steps
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodWaiting for Copy
label for a copy review on the original GH to get the correct copy.STYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)/** comment above it */
this
are necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);
ifthis.submit
is never passed to a component event handler likeonClick
)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Web
fix-name-jump-web.mp4
Mobile Web - Chrome
fix-name-jump-android-web-compressed.mp4
Mobile Web - Safari
fix-name-jump-ios-web.mp4
Desktop
iOS
fix-name-jump-ios.mp4
Android
fix-name-jump-android-compressed.mp4