Closed kavimuru closed 1 year ago
Triggered auto assignment to @sophiepintoraetz (Bug
), see https://stackoverflow.com/c/expensify/questions/14418 for more details.
Platforms
in OP are ✅)Came in over the weekend, will look into this tomorow.
Android
iOS
Triggered auto assignment to @danieldoglas (Engineering
), see https://stackoverflow.com/c/expensify/questions/4319 for more details.
Seems similar to https://github.com/Expensify/App/issues/15195
Thanks @sophiepintoraetz . This one can be external, so adding the label.
Job added to Upwork: https://www.upwork.com/jobs/~015c356c51bf928ca6
Current assignee @sophiepintoraetz is eligible for the External assigner, not assigning anyone new.
Triggered auto assignment to Contributor-plus team member for initial proposal review - @0xmiroslav (External
)
Current assignee @danieldoglas is eligible for the External assigner, not assigning anyone new.
There is an extra space above code
text and it's noticeable when we highlight it.
On native, we are using WrappedText
component to render code block. Inside of it, we wrap the text with 2 views.
The outer view height is 20, while the inner view is 18 with top
value is 4 (on iOS, the inner view height is 16). The height difference and the addition of the top
is the culprit of this issue.
I think the reason we are doing that is to align the code block text well with other text. Here is the comparison.
With top | Without top |
---|---|
To solve this, we can apply a bottom padding to InlineCodeBlock
(native). 4 for iOS, 6 for Android. We need to apply different value because iOS codeWordStyle
height is 16 while Android is 18. Or we can set both height to 18, so both padding will be 6.
Following.
Inline code block is not in the middle of the hovered report item
The root cause of this problem is rendering of View
inside Text
to display the code
tag on native platforms. I'll try to demonstrate the problem here with a small (unrelated) code sample.
Consider the following code:
<Text>
<Text>Hello world</Text>
<Text>
<View>
<Text>This </Text>
</View>
<View>
<Text>is </Text>
</View>
<View>
<Text>a </Text>
</View>
<View>
<Text>test </Text>
</View>
</Text>
</Text>
When this is run on a RN app, it looks like the following:
It is clearly noticeable that the items wrapped in the second text container are higher than the items in the first container. This is exactly what is happening in our app as well. To make the text
and code
elements inline, we're resorting to the addition of a top
property to the code
element in order to bring it down. This can be seen here:
This addition is what results in a illusion of extra padding at the top of the message.
After removing this property, here is how it looks.
To prove that we are rendering View
inside of Text
, we can check the contentModel of different tags in the transientRenderEngine
library. As seen from the link above, by default, code
tag uses Textual
content model which gets translated to a Text
wrapper element. We're also defining a customer renderer for code
tag which can be seen here. This custom renderer is translating each word into a View
component. Since the contentModel
of code
tag is defined as Textual
and we're rendering a View
inside it, this is where the problem lies. This can be further confirmed by looking at the React Component Tree of one such render.
Because we're using a View
inside of a Text
, this forces us to use the top
property on the word container which in turn causes this issue. We should not use View
inside of a Text
element. To make this work, we have to change the contentModel
of code
tag to block
. This can be done by adding following here:
code: defaultHTMLElementModels.code.extend({
contentModel: HTMLContentModel.block,
}),
Next, we need to make sure that we set flexDirection: 'row', flexWrap: 'wrap'
of the comment
tag wrapper here.
We then need to remove TDefaultRenderer
for the code
tag here. This is because we don't want our words to be wrapped inside a View
(which is then wrapped inside another comment
View).
In the same component, we also have to replace {props.defaultRendererProps.tnode.data}
with {props.defaultRendererProps.tnode.domNode.children[0].data}
. We have to do the same replacement for the web version of this file.
Finally, we also need to remove the hacky styles here and here that we added in order to make View
work inside Text
.
This is how it looks after the changes mentioned above are applied:
Once these changes are applied, here is how the component tree looks like:
None
@0xmiroslav can you please check both proposals?
The outer view height is 20, while the inner view is 18 with top value is 4 (on iOS, the inner view height is 16). The height difference and the addition of the top is the culprit of this issue.
@bernhardoj can you please explain the reason why inner view height is set differently between android and iOS? And what is inner view height on web?
@allroundexperts thanks for your deep research. I agree with your root cause analysis. It's known issue that View inside Text doesn't work correctly on native and that's why hacky styles are added. I also confirmed that this is not only android issue but also iOS.
But I still have concerns about your solution, while I like the idea of removing hacky top paddings per platform.
Because we're using a View inside of a Text, this forces us to use the top property on the word container which in turn causes this issue. We should not use View inside of a Text element. To make this work, we have to change the contentModel of code tag to block
Can you please explain why block
will work? Is there any documentation in upstream repo?
Btw, after updating this, code block never shows for me. Am I missing anything?
We then need to remove TDefaultRenderer for the code tag here. This is because we don't want our words to be wrapped inside a View (which is then wrapped inside another comment View).
You mean to remove TDefaultRenderer wrapper completely?
@allroundexperts thanks for your deep research. I agree with your root cause analysis. It's known issue that View inside Text doesn't work correctly on native and that's why hacky styles are added. I also confirmed that this is not only android issue but also iOS.
But I still have concerns about your solution, while I like the idea of removing hacky top paddings per platform.
Because we're using a View inside of a Text, this forces us to use the top property on the word container which in turn causes this issue. We should not use View inside of a Text element. To make this work, we have to change the contentModel of code tag to block
Can you please explain why
block
will work? Is there any documentation in upstream repo? Btw, after updating this, code block never shows for me. Am I missing anything?We then need to remove TDefaultRenderer for the code tag here. This is because we don't want our words to be wrapped inside a View (which is then wrapped inside another comment View).
You mean to remove TDefaultRenderer wrapper completely?
@0xmiroslav A block content model results in the element being rendered as a View
instead of Text
. This will fix the root cause of the issue. That's why we need to change it.
Yes, we have to remove TDefaultRenderer
wrapper completely on native. The reason why its not showing up is because I missed a step in the proposal. In the same component, you also have to replace {props.defaultRendererProps.tnode.data}
with {props.defaultRendererProps.tnode.domNode.children[0].data}
. I've also updated my proposal and added this step. Apologies for the inconvenience this might have caused you.
Please let me know if there is anything else that is of a concern to you.
@0xmiroslav You can also read the docs about the Transient render engine that we use here: https://meliorence.github.io/react-native-render-html/docs/architecture
I think this will provide you of more context of my proposal.
Incorrect top for single backtick message which displays it not in the center for native
It seems incorrect top and height are given for the codeWordStyle
native files which aren't set them in the center.
For IOS instead of top 4
set it to 2
which will add height of 16 and keeps 2
at the bottom which makes the message to the center(need to set considering 20px
of the parent div).
https://github.com/Expensify/App/blob/4d3390b156fcb59e694b0c21193bd699b276bafd/src/styles/codeStyles/index.ios.js#L6-L9
For android do the same setup where either change height to 16
and top to 2
or keep the height to 18
with the change of top to 1
. (Currently its 4
from the top and height is 18 which sums to 22 and that might be the cause of wrong placement)
https://github.com/Expensify/App/blob/4d3390b156fcb59e694b0c21193bd699b276bafd/src/styles/codeStyles/index.android.js#L5-L8
@0xmiroslav I think the inner view height number is "cherry-picked" to prevent the text getting cut off. On Android, setting the height to 16 will make the text cut off.
Edit 1: I just checked on iOS to make sure how it looks with height of 16 and looks like it is also getting cut off, and easily noticeable with an emoji inside the code block because of the fixed line height.
android:
ios:
On web, we don't define the height. But looking at the element, the height is 16. The 0.8 is the border width.
I'm guessing the initial height set on iOS and Android is taken from web, and then adjusted ~on Android~ to allow the text fully visible.
By the way, there is an existing issue related to the code block which will change the height and top property here. I think we need to wait for it to be merged and adjust the padding bottom based on the new value set.
Great insight @allroundexperts. That would be great if we can remove the style workaround. However, after trying your proposal, the text style is not applied to the text inside code block. The code block text size should be smaller (13). Also, after changing the content model of code to block, the text is empty on web as shown below
Maybe because the content model is not textual, the text style is lost? 🤔
code: defaultHTMLElementModels.code.extend({ contentModel: HTMLContentModel.block, }),
@bernhardoj Thanks for pointing this out. I forgot to mention that we have to do the same replacement props.defaultRendererProps.tnode.domNode.children[0].data
on web version of the InlineCodeBlock
component as well. I have updated the proposal to include this.
In the same [component](https://github.com/allroundexperts/Expensify/blob/cd58bc8ff8e99a5ba61c1f6c0e18b68382753d92/src/components/InlineCodeBlock/index.js#L15), we also have to replace {props.defaultRendererProps.tnode.data} with {props.defaultRendererProps.tnode.domNode.children[0].data}. We have to do the same replacement for the web version of this [file](https://github.com/allroundexperts/Expensify/blob/660e3892f8a8deace5e24497148a174ee8dde251/src/components/InlineCodeBlock/index.js#L15).
I'll check why text styles aren't being applied.
@danieldoglas @sophiepintoraetz @0xmiroslav this issue was created 2 weeks ago. Are we close to approving a proposal? If not, what's blocking us from getting this issue assigned? Don't hesitate to create a thread in #expensify-open-source to align faster in real time. Thanks!
Another update here. I did some more in depth research about my approach above. It seems like it does not wrap the text correctly. Check the image below for example.
As it can be seen, the text does not wrap correctly after the code block. It only comes to the same line as code block if the length of subsequent text is able to fit into the remaining space after code block.
I think that the reason why we added a custom renderer for code
block on native platforms is that the default implementation does not allow for adding borders to the code block. We can only add a background colour. Thus, to make it look like the same as on web, we resorted to this custom renderer.
I was then curious on how Slack is solving this issue. It turns out, Slack goes with native implementation of a code block on its Android and iOS apps. For any inline code block, it just sets a background colour without any borders. I have attached a screenshot of a sample code block in Slack both on Android and on web app. The difference is clear enough I think.
There might not be a bullet proof solution to solve this issue using custom renderer (Adjusting line heights and paddings might solve this temporarily but IMO something else will come up in the future). I've asked in this thread about what people think of discarding this whole approach of custom renderer for code block and just going with the native implementation (without border). Please do write your opinions in that thread as well.
I found this issue that will add native support for code block to a Text
component which probably will fix this issue too. Looks like that issue is going to be resolved soon, so I think we can hold this one until the PR for that issue is merged because this issue is just a minor visual thing.
@bernhardoj This is still a work around. No? Like in that PR, I can see the line heights being tweaked.
Although I haven't tested it fully yet so not sure if this fixes the bug in this ticket.
thanks for connecting that issue here @bernhardoj . I'll put this on hold while we wait for it.
We're still holding.
Still holding
Still holding on https://github.com/Expensify/App/issues/4733
Bumped the CME for that issue. Still holding.
CME is back from holiday
Still holding.
Still holding.
Still holding.
Still holding
Following the new guidelines for external issues, removing myself from this until we have approved proposals.
The user is reaching out again regarding the issue.
📣 @erikagail-binag! 📣 Hey, it seems we don’t have your contributor details yet! You'll only have to do this once, and this is how we'll hire you on Upwork. Please follow these steps:
Contributor details
Your Expensify account email: <REPLACE EMAIL HERE>
Upwork Profile Link: <REPLACE LINK HERE>
Still holding.
OG issue is in review!
Original linked issue has been closed to work on a more holistic solution - so will likely fold this issue into that one and pay out the reporting bonus here.
Thought on this, and this does not seem to be something we will fix for the mean time. If this does get resolved, we can reference this issue for the original reporter. But going to close for now.
If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
Action Performed:
Hello world
Expected Result:
The selected area should have the same padding from the top and the bottom from the border
Actual Result:
top has some extra margin than bottom space
Workaround:
unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Version Number: 1.2.69-2 Reproducible in staging?: y Reproducible in production?: y If this was caught during regression testing, add the test name, ID and link from TestRail: Email or phone of affected tester (no customers): Logs: https://stackoverflow.com/c/expensify/questions/4856 Notes/Photos/Videos:
https://user-images.githubusercontent.com/43996225/218231342-7a8fbeb6-d5b1-42a1-988a-21afae85348d.mp4
Expensify/Expensify Issue URL: Issue reported by: @jayeshmangwani Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1675802761130049 View all open jobs on GitHub
Upwork Automation - Do Not Edit