You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

JitsiKeyboardAvoidingView.js 2.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // @flow
  2. import { getDefaultHeaderHeight } from '@react-navigation/elements';
  3. import React, { useEffect, useState } from 'react';
  4. import {
  5. KeyboardAvoidingView,
  6. Platform,
  7. StatusBar
  8. } from 'react-native';
  9. import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context';
  10. import { StyleType } from '../../styles';
  11. type Props = {
  12. /**
  13. * The children component(s) of the Modal, to be rendered.
  14. */
  15. children: React$Node,
  16. /**
  17. * Additional style to be appended to the KeyboardAvoidingView content container.
  18. */
  19. contentContainerStyle?: StyleType,
  20. /**
  21. * Is a text input rendered at the bottom of the screen?
  22. */
  23. hasBottomTextInput: boolean,
  24. /**
  25. * Is the screen rendering a tab navigator?
  26. */
  27. hasTabNavigator: boolean,
  28. /**
  29. * Is the screen presented as a modal?
  30. */
  31. isModalPresentation: boolean,
  32. /**
  33. * Additional style to be appended to the KeyboardAvoidingView.
  34. */
  35. style?: StyleType
  36. }
  37. const JitsiKeyboardAvoidingView = (
  38. {
  39. children,
  40. contentContainerStyle,
  41. hasTabNavigator,
  42. hasBottomTextInput,
  43. isModalPresentation,
  44. style
  45. }: Props) => {
  46. const frame = useSafeAreaFrame();
  47. const insets = useSafeAreaInsets();
  48. const [ bottomPadding, setBottomPadding ] = useState(insets.bottom);
  49. const [ topPadding, setTopPadding ] = useState(insets.top);
  50. useEffect(() => {
  51. // This useEffect is needed because insets are undefined at first for some reason
  52. // https://github.com/th3rdwave/react-native-safe-area-context/issues/54
  53. setBottomPadding(insets.bottom);
  54. setTopPadding(insets.top);
  55. }, [ insets.bottom, insets.top ]);
  56. const headerHeight = getDefaultHeaderHeight(frame, isModalPresentation, topPadding);
  57. // Notch devices have in general a header height between 103 and 106px
  58. const topNotchDevice = headerHeight > 100;
  59. const deviceHeight = topNotchDevice ? headerHeight - 50 : headerHeight;
  60. const tabNavigatorPadding
  61. = hasTabNavigator ? deviceHeight : 0;
  62. const noNotchDevicePadding = bottomPadding || 10;
  63. const iosVerticalOffset
  64. = deviceHeight + noNotchDevicePadding + tabNavigatorPadding;
  65. const androidVerticalOffset = hasBottomTextInput
  66. ? deviceHeight + StatusBar.currentHeight : deviceHeight;
  67. return (
  68. <KeyboardAvoidingView
  69. behavior = { Platform.OS === 'ios' ? 'padding' : 'height' }
  70. contentContainerStyle = { contentContainerStyle }
  71. enabled = { true }
  72. keyboardVerticalOffset = {
  73. Platform.OS === 'ios'
  74. ? iosVerticalOffset
  75. : androidVerticalOffset
  76. }
  77. style = { style }>
  78. { children }
  79. </KeyboardAvoidingView>
  80. );
  81. };
  82. export default JitsiKeyboardAvoidingView;