LogBoxInspectorSourceMapStatus.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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 Animated from '../../Animated/src/Animated';
  12. import Easing from '../../Animated/src/Easing';
  13. import * as React from 'react';
  14. import StyleSheet from '../../StyleSheet/StyleSheet';
  15. import Text from '../../Text/Text';
  16. import LogBoxButton from './LogBoxButton';
  17. import * as LogBoxStyle from './LogBoxStyle';
  18. import type {PressEvent} from '../../Types/CoreEventTypes';
  19. type Props = $ReadOnly<{|
  20. onPress?: ?(event: PressEvent) => void,
  21. status: 'COMPLETE' | 'FAILED' | 'NONE' | 'PENDING',
  22. |}>;
  23. function LogBoxInspectorSourceMapStatus(props: Props): React.Node {
  24. const [state, setState] = React.useState({
  25. animation: null,
  26. rotate: null,
  27. });
  28. React.useEffect(() => {
  29. if (props.status === 'PENDING') {
  30. if (state.animation == null) {
  31. const animated = new Animated.Value(0);
  32. const animation = Animated.loop(
  33. Animated.timing(animated, {
  34. duration: 2000,
  35. easing: Easing.linear,
  36. toValue: 1,
  37. useNativeDriver: true,
  38. }),
  39. );
  40. setState({
  41. animation,
  42. rotate: animated.interpolate({
  43. inputRange: [0, 1],
  44. /* $FlowFixMe(>=0.38.0) - Flow error detected during the deployment
  45. * of v0.38.0. To see the error, remove this comment and run flow
  46. */
  47. outputRange: ['0deg', '360deg'],
  48. }),
  49. });
  50. animation.start();
  51. }
  52. } else {
  53. if (state.animation != null) {
  54. state.animation.stop();
  55. setState({
  56. animation: null,
  57. rotate: null,
  58. });
  59. }
  60. }
  61. return () => {
  62. if (state.animation != null) {
  63. state.animation.stop();
  64. }
  65. };
  66. }, [props.status, state.animation]);
  67. let image;
  68. let color;
  69. switch (props.status) {
  70. case 'FAILED':
  71. image = require('./LogBoxImages/alert-triangle.png');
  72. color = LogBoxStyle.getErrorColor(1);
  73. break;
  74. case 'PENDING':
  75. image = require('./LogBoxImages/loader.png');
  76. color = LogBoxStyle.getWarningColor(1);
  77. break;
  78. }
  79. if (props.status === 'COMPLETE' || image == null) {
  80. return null;
  81. }
  82. return (
  83. <LogBoxButton
  84. backgroundColor={{
  85. default: 'transparent',
  86. pressed: LogBoxStyle.getBackgroundColor(1),
  87. }}
  88. hitSlop={{bottom: 8, left: 8, right: 8, top: 8}}
  89. onPress={props.onPress}
  90. style={styles.root}>
  91. <Animated.Image
  92. source={image}
  93. style={[
  94. styles.image,
  95. {tintColor: color},
  96. state.rotate == null || props.status !== 'PENDING'
  97. ? null
  98. : {transform: [{rotate: state.rotate}]},
  99. ]}
  100. />
  101. <Text style={[styles.text, {color}]}>Source Map</Text>
  102. </LogBoxButton>
  103. );
  104. }
  105. const styles = StyleSheet.create({
  106. root: {
  107. alignItems: 'center',
  108. borderRadius: 12,
  109. flexDirection: 'row',
  110. height: 24,
  111. paddingHorizontal: 8,
  112. },
  113. image: {
  114. height: 14,
  115. width: 16,
  116. marginEnd: 4,
  117. tintColor: LogBoxStyle.getTextColor(0.4),
  118. },
  119. text: {
  120. fontSize: 12,
  121. includeFontPadding: false,
  122. lineHeight: 16,
  123. },
  124. });
  125. export default LogBoxInspectorSourceMapStatus;