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

Use 'SafeAreaView' through the app #3067

Closed
wants to merge 10 commits into from

Conversation

borisyankov
Copy link
Contributor

@borisyankov borisyankov commented Oct 21, 2018

Based on #2702 (as it changes internally how it uses SafeAreaView)

@borisyankov
Copy link
Contributor Author

Rebased and updated.
Now going over all the changes another time and double-checking everything works fine and nothing is missing.

@borisyankov borisyankov force-pushed the safe-area-view branch 2 times, most recently from 51c9934 to cac146d Compare May 29, 2019 20:58
@borisyankov borisyankov changed the title WIP: SafeAreaView Use 'SafeAreaView' through the app May 29, 2019
@borisyankov borisyankov force-pushed the safe-area-view branch 2 times, most recently from f182c24 to 4ab0806 Compare May 29, 2019 21:20
@gnprice
Copy link
Member

gnprice commented Jun 4, 2019

P1 because it fixes #3066 .

@gnprice gnprice removed the blocked on other work To come back to after another related PR, or some other task. label Aug 12, 2019
@gnprice
Copy link
Member

gnprice commented Aug 12, 2019

We're now on react-navigation v2 (see #3573), so this is unblocked!

@gnprice
Copy link
Member

gnprice commented Aug 12, 2019

Just rebased this branch. (Across over a year's changes!)

Makes sure our main tabs are aligned properly with the edges of the screen on iOS.

More about how safe areas work on iOS:
https://developer.apple.com/documentation/uikit/uiview/positioning_content_relative_to_the_safe_area

About the React Native-specific component:
https://facebook.github.io/react-native/docs/safeareaview
Instead of using `react-native-safe-area` and getting the inset
values from the `session` state, use `SafeAreaView` witch is a
component coming with React Native.
Fixes zulip#3066

Previous approach almost worked correctly, but there was one
case it didn't - when the keyboard did pop on an iPhone, the
bottom space was sill there, though it shouldn't, as the keyboard
is located over the `Home Indicator`.
All 'screen'-type components need a `SafeAreaView` to make sure
the offsets from the edges are correct. This makes sure we do
that fot the `ChatScreen` component.
We no longer need `react-native-safe-area` so stop using it to
track the changes to the safe area insets (we are using `SafeAreaView`)
We no longer track `safeAreaInsets` data so remove i from the reducer.
No longer used and needed. Remove completely from the codebase.
Now, completely unused, remove the 'react-native-safe-area' package.
@chrisbobbe
Copy link
Contributor

chrisbobbe commented Sep 23, 2020

Just rebased across another year's changes; I came across this while looking at #4267.

There are a few issues with this branch that will need to be resolved. I tested with an iPhone XR simulator.

  • Things break if, on a single screen, we use a SafeAreaView and a ZulipStatusBar while the ZulipStatusBar still sets its own height. (There ends up being an overlarge gap at the top.) But the commits that add SafeAreaView and the commit that removes the ZulipStatusBar's height are separate. They're not that large, so they could probably be reasonably combined into one commit.
  • The status bar's background color isn't always correct (see, in particular, the chat screen).
  • Tapping the image in the lightbox is supposed to make the header and the footer slide away completely; now, they just retreat into the unsafe area (top and bottom) but are still quite visible. This is one lingering case where it would be good to be able to grab the safe-area insets—an ability that vanishes in this current PR branch. But we might end up substantially reworking the lightbox; see Replace outdated react-native-photo-view library. #4217.

@chrisbobbe
Copy link
Contributor

Also, it's worth noting that React Navigation has its own docs that go through how to handle safe areas—in a way that doesn't (at least doesn't directly) use the SafeAreaView component from React Native: https://reactnavigation.org/docs/4.x/handling-iphonex/.

chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this pull request Sep 23, 2020
Even though we've been passing the `hidden` prop for the lightbox's
ZulipStatusBar since the beginning (3f8ad4a), evidently it
sometimes still appears. I don't have a clear answer for why, but I
suspect it might have to do with a particular subtlety in
react-navigation. From their docs [1]:

"""
If you're using a tab or drawer navigator, it's a bit more complex
because all of the screens in the navigator might be rendered at
once and kept rendered - that means that the last `StatusBar` config
you set will be used (likely on the final tab of your tab navigator,
not what the user is seeing).
"""

We do use a tab navigator (`MainTabs`), so this isn't implausible on
its face.

When the status bar appears, it's been causing zulip#4267: the close
button appears behind the status bar.

The `ZulipStatusBar` component has been conscripted into doing part
of the work of React Native's [2], or React Navigation's [3],
`SafeAreaView` component, which we haven't started using yet. (zulip#3067
is open for using it all over the app.) In particular, as long as
the `hidden` prop is true, a `View` with the height of the top inset
of the safe area (wrapping the status bar) prevents the rest of the
screen's content from "unsafely" rendering in that area.

When this screen's `ZulipStatusBar` has its `hidden` prop passed as
`true`, however, it doesn't defend the safe-area view at the top,
whether or not a status bar is actually showing. That's because the
wrapping `View` gets its height set to zero in the `hidden` case.

So, without answering why a status bar might actually be showing
when we tell it not to, remove the wrapping `View`'s height
difference between `hidden` being true and false, conceding that
`ZulipStatusBar` should be the defender of the top safe area, and in
particular that it should still do so when it's been marked as
`hidden`. At least until we move on the sweeping changes of zulip#3067.

Also, we've got a sliding animation for the header, and the distance
it needs to travel has increased by the height of the safe area. So,
account for that by adding `safeAreaInsets.top` to `NAVBAR_SIZE` in
the appropriate place. (Without that addition, the header just
retreats into the top inset instead of leaving the screen entirely.)

[1] https://reactnavigation.org/docs/4.x/status-bar/#tabs-and-drawer
[2] https://reactnative.dev/docs/0.62/safeareaview
[3] https://reactnavigation.org/docs/4.x/handling-iphonex/

Fixes: zulip#4267
chrisbobbe added a commit to chrisbobbe/zulip-mobile that referenced this pull request Sep 23, 2020
Even though we've been passing the `hidden` prop for the lightbox's
ZulipStatusBar since the beginning (3f8ad4a), evidently it
sometimes still appears. I don't have a clear answer for why, but I
suspect it might have to do with a particular subtlety in
react-navigation. From their docs [1]:

"""
If you're using a tab or drawer navigator, it's a bit more complex
because all of the screens in the navigator might be rendered at
once and kept rendered - that means that the last `StatusBar` config
you set will be used (likely on the final tab of your tab navigator,
not what the user is seeing).
"""

We do use a tab navigator (`MainTabs`), so this isn't implausible on
its face.

When the status bar appears, it's been causing zulip#4267: the close
button appears behind the status bar.

The `ZulipStatusBar` component has been conscripted into doing part
of the work of React Native's [2], or React Navigation's [3],
`SafeAreaView` component, which we haven't started using yet. (zulip#3067
is open for using it all over the app.) In particular, as long as
the `hidden` prop is true, a `View` with the height of the top inset
of the safe area (wrapping the status bar) prevents the rest of the
screen's content from "unsafely" rendering in that area.

When this screen's `ZulipStatusBar` has its `hidden` prop passed as
`true`, however, it doesn't defend the safe-area view at the top,
whether or not a status bar is actually showing. That's because the
wrapping `View` gets its height set to zero in the `hidden` case.

So, without answering why a status bar might actually be showing
when we tell it not to, remove the wrapping `View`'s height
difference between `hidden` being true and false, conceding that
`ZulipStatusBar` should be the defender of the top safe area, and in
particular that it should still do so when it's been marked as
`hidden`. At least until we make the sweeping changes of zulip#3067.

Also, we've got a sliding animation for the header, and the distance
it needs to travel has increased by the height of the safe area. So,
account for that by adding `safeAreaInsets.top` to `NAVBAR_SIZE` in
the appropriate place. (Without that addition, the header just
retreats into the top inset instead of leaving the screen entirely.)

There are no other places where we pass `hidden` as `true` for
`ZulipStatusBar`, so changing its behavior in that situation
shouldn't have any nasty side effects.

[1] https://reactnavigation.org/docs/4.x/status-bar/#tabs-and-drawer
[2] https://reactnative.dev/docs/0.62/safeareaview
[3] https://reactnavigation.org/docs/4.x/handling-iphonex/

Fixes: zulip#4267
@chrisbobbe
Copy link
Contributor

This has been superseded by our current plan for #3066. Currently, we have #4683 open for part of that.

@chrisbobbe chrisbobbe closed this Jun 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants