LogBoxNotification.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @flow strict-local
  8. * @format
  9. */
  10. 'use strict';
  11. import * as React from 'react';
  12. import Image from '../../Image/Image';
  13. import StyleSheet from '../../StyleSheet/StyleSheet';
  14. import Text from '../../Text/Text';
  15. import View from '../../Components/View/View';
  16. import LogBoxButton from './LogBoxButton';
  17. import * as LogBoxStyle from './LogBoxStyle';
  18. import LogBoxLog from '../Data/LogBoxLog';
  19. import LogBoxMessage from './LogBoxMessage';
  20. import * as LogBoxData from '../Data/LogBoxData';
  21. type Props = $ReadOnly<{|
  22. log: LogBoxLog,
  23. totalLogCount: number,
  24. level: 'warn' | 'error',
  25. onPressOpen: () => void,
  26. onPressDismiss: () => void,
  27. |}>;
  28. function LogBoxLogNotification(props: Props): React.Node {
  29. const {totalLogCount, level, log} = props;
  30. // Eagerly symbolicate so the stack is available when pressing to inspect.
  31. React.useEffect(() => {
  32. LogBoxData.symbolicateLogLazy(log);
  33. }, [log]);
  34. return (
  35. <View style={toastStyles.container}>
  36. <LogBoxButton
  37. onPress={props.onPressOpen}
  38. style={toastStyles.press}
  39. backgroundColor={{
  40. default: LogBoxStyle.getBackgroundColor(1),
  41. pressed: LogBoxStyle.getBackgroundColor(0.9),
  42. }}>
  43. <View style={toastStyles.content}>
  44. <CountBadge count={totalLogCount} level={level} />
  45. <Message message={log.message} />
  46. <DismissButton onPress={props.onPressDismiss} />
  47. </View>
  48. </LogBoxButton>
  49. </View>
  50. );
  51. }
  52. function CountBadge(props) {
  53. return (
  54. <View style={countStyles.outside}>
  55. {/* $FlowFixMe(>=0.114.0) This suppression was added when fixing the type
  56. * of `StyleSheet.create`. Remove this comment to see the error. */}
  57. <View style={[countStyles.inside, countStyles[props.level]]}>
  58. <Text style={countStyles.text}>
  59. {props.count <= 1 ? '!' : props.count}
  60. </Text>
  61. </View>
  62. </View>
  63. );
  64. }
  65. function Message(props) {
  66. return (
  67. <View style={messageStyles.container}>
  68. <Text numberOfLines={1} style={messageStyles.text}>
  69. {props.message && (
  70. <LogBoxMessage
  71. plaintext
  72. message={props.message}
  73. style={messageStyles.substitutionText}
  74. />
  75. )}
  76. </Text>
  77. </View>
  78. );
  79. }
  80. function DismissButton(props) {
  81. return (
  82. <View style={dismissStyles.container}>
  83. <LogBoxButton
  84. backgroundColor={{
  85. default: LogBoxStyle.getTextColor(0.3),
  86. pressed: LogBoxStyle.getTextColor(0.5),
  87. }}
  88. hitSlop={{
  89. top: 12,
  90. right: 10,
  91. bottom: 12,
  92. left: 10,
  93. }}
  94. onPress={props.onPress}
  95. style={dismissStyles.press}>
  96. <Image
  97. source={require('./LogBoxImages/close.png')}
  98. style={dismissStyles.image}
  99. />
  100. </LogBoxButton>
  101. </View>
  102. );
  103. }
  104. const countStyles = StyleSheet.create({
  105. warn: {
  106. backgroundColor: LogBoxStyle.getWarningColor(1),
  107. },
  108. error: {
  109. backgroundColor: LogBoxStyle.getErrorColor(1),
  110. },
  111. log: {
  112. backgroundColor: LogBoxStyle.getLogColor(1),
  113. },
  114. outside: {
  115. padding: 2,
  116. borderRadius: 25,
  117. backgroundColor: '#fff',
  118. marginRight: 8,
  119. },
  120. inside: {
  121. minWidth: 18,
  122. paddingLeft: 4,
  123. paddingRight: 4,
  124. borderRadius: 25,
  125. fontWeight: '600',
  126. },
  127. text: {
  128. color: LogBoxStyle.getTextColor(1),
  129. fontSize: 14,
  130. lineHeight: 18,
  131. textAlign: 'center',
  132. fontWeight: '600',
  133. textShadowColor: LogBoxStyle.getBackgroundColor(0.4),
  134. textShadowOffset: {width: 0, height: 0},
  135. textShadowRadius: 3,
  136. },
  137. });
  138. const messageStyles = StyleSheet.create({
  139. container: {
  140. alignSelf: 'stretch',
  141. flexGrow: 1,
  142. flexShrink: 1,
  143. flexBasis: 'auto',
  144. borderLeftColor: LogBoxStyle.getTextColor(0.2),
  145. borderLeftWidth: 1,
  146. paddingLeft: 8,
  147. },
  148. text: {
  149. color: LogBoxStyle.getTextColor(1),
  150. flex: 1,
  151. fontSize: 14,
  152. lineHeight: 22,
  153. },
  154. substitutionText: {
  155. color: LogBoxStyle.getTextColor(0.6),
  156. },
  157. });
  158. const dismissStyles = StyleSheet.create({
  159. container: {
  160. alignSelf: 'center',
  161. flexDirection: 'row',
  162. flexGrow: 0,
  163. flexShrink: 0,
  164. flexBasis: 'auto',
  165. marginLeft: 5,
  166. },
  167. press: {
  168. height: 20,
  169. width: 20,
  170. borderRadius: 25,
  171. alignSelf: 'flex-end',
  172. alignItems: 'center',
  173. justifyContent: 'center',
  174. },
  175. image: {
  176. height: 8,
  177. width: 8,
  178. tintColor: LogBoxStyle.getBackgroundColor(1),
  179. },
  180. });
  181. const toastStyles = StyleSheet.create({
  182. container: {
  183. height: 48,
  184. position: 'relative',
  185. width: '100%',
  186. justifyContent: 'center',
  187. marginTop: 0.5,
  188. backgroundColor: LogBoxStyle.getTextColor(1),
  189. },
  190. press: {
  191. height: 48,
  192. position: 'relative',
  193. width: '100%',
  194. justifyContent: 'center',
  195. marginTop: 0.5,
  196. paddingHorizontal: 12,
  197. },
  198. content: {
  199. alignItems: 'flex-start',
  200. flexDirection: 'row',
  201. borderRadius: 8,
  202. flexGrow: 0,
  203. flexShrink: 0,
  204. flexBasis: 'auto',
  205. },
  206. });
  207. export default LogBoxLogNotification;