ModalPortal.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /**
  2. * ModalPortal
  3. * @邠心vbe on 2022/02/28
  4. */
  5. import React, { Component } from 'react';
  6. import { StyleSheet, View } from 'react-native';
  7. import Modal from 'react-native-modal';
  8. let modal
  9. export default class ModalPortal extends Component {
  10. constructor(props) {
  11. super(props);
  12. this.state = {
  13. showDialog: false,
  14. showLoading: false,
  15. showIOSLoading: false,
  16. children: <></>,
  17. loadChildren: <></>,
  18. loadMessage: "...",
  19. };
  20. modal = this;
  21. this.isHide = true;
  22. this.onBack = undefined;
  23. }
  24. static show(children, onBack) {
  25. return modal.show(children, onBack);
  26. }
  27. static showLoading(children) {
  28. return modal.showLoading(children);
  29. }
  30. static dismiss() {
  31. modal.dismiss();
  32. }
  33. static dismissLoading() {
  34. modal.dismissLoading();
  35. }
  36. static dismissAll() {
  37. modal.dismissAll();
  38. }
  39. static isShowing() {
  40. return modal.isShowing();
  41. }
  42. show(children, onBack=undefined) {
  43. if (isIOS) {
  44. if (!this.isHide) {
  45. setTimeout(() => {
  46. this.show(children);
  47. }, 500);
  48. return;
  49. }
  50. this.setState({
  51. showDialog: true,
  52. children: children,
  53. }, () => {
  54. this.onModalShow();
  55. })
  56. } else {
  57. this.setState({
  58. showDialog: true,
  59. children: children
  60. })
  61. this.onBack = onBack;
  62. }
  63. }
  64. showLoading(children) {
  65. if (isIOS) {
  66. //console.log("showIOSLoading", children)
  67. this.setState({
  68. loadChildren: children,
  69. showIOSLoading: true
  70. })
  71. } else {
  72. this.setState({
  73. showLoading: true,
  74. loadChildren: children
  75. });
  76. }
  77. }
  78. dismiss() {
  79. this.setState({
  80. showDialog: false
  81. })
  82. this.onBack = undefined;
  83. }
  84. dismissLoading() {
  85. if (isIOS) {
  86. this.setState({
  87. showIOSLoading: false
  88. })
  89. } else {
  90. this.setState({
  91. showLoading: false
  92. })
  93. }
  94. }
  95. dismissAll() {
  96. this.setState({
  97. showDialog: false,
  98. showLoading: false,
  99. showIOSLoading: false
  100. })
  101. }
  102. isShowing() {
  103. //console.log("[ModalPortal] isShowing", this.state.showDialog);
  104. return this.state.showDialog;
  105. }
  106. onBackPress() {
  107. if (this.onBack) {
  108. this.onBack();
  109. return;
  110. }
  111. if (this.state.showLoading) {
  112. this.dismissLoading();
  113. } else if (this.state.showDialog) {
  114. this.dismiss();
  115. }
  116. }
  117. onModalShow() {
  118. //console.log('onModalShow', this.isHide);
  119. this.isHide = false;
  120. }
  121. onModalHide() {
  122. //console.log('onModalHide', this.isHide);
  123. this.isHide = true;
  124. }
  125. render() {
  126. return (
  127. <>
  128. <Modal
  129. style={{margin: 0, zIndex: 900}}
  130. isVisible={this.state.showDialog}
  131. deviceHeight={$height + statusHeight}
  132. avoidKeyboard={true}
  133. animationIn={"fadeIn"}
  134. animationOut={"fadeOut"}
  135. useNativeDriver={true}
  136. statusBarTranslucent={true}
  137. onBackButtonPress={() => this.onBackPress()}
  138. onModalHide={() => this.onModalHide()}>
  139. {this.state.children}
  140. </Modal>
  141. <Modal
  142. style={{margin: 0, zIndex: 901}}
  143. isVisible={this.state.showLoading}
  144. deviceHeight={$height + statusHeight}
  145. animationIn="fadeIn"
  146. animationOut="fadeOut"
  147. useNativeDriver={true}
  148. animationInTiming={80}
  149. animationOutTiming={100}
  150. statusBarTranslucent={true}
  151. onBackButtonPress={() => this.onBackPress()}>
  152. {this.state.loadChildren}
  153. </Modal>
  154. { this.state.showIOSLoading &&
  155. <View style={styles.iosLoadingView}>
  156. {this.state.loadChildren}
  157. </View>
  158. }
  159. </>
  160. );
  161. }
  162. }
  163. const styles = StyleSheet.create({
  164. iosLoadingView: {
  165. top: 0,
  166. left: 0,
  167. right: 0,
  168. bottom: 0,
  169. zIndex: 500,
  170. alignItems: 'center',
  171. position: 'absolute',
  172. justifyContent: 'center',
  173. backgroundColor: 'rgba(0,0,0,.7)'
  174. }
  175. })