ModalPortal.js 3.8 KB

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