Dialog.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. /**
  2. * Dialog
  3. * @邠心vbe on 2021/02/20
  4. */
  5. import React from 'react';
  6. import * as Progress from 'react-native-progress';
  7. import {Pressable, StyleSheet, Text, View, Image} from 'react-native';
  8. import Toast from 'react-native-root-toast';
  9. import utils from '../utils/utils';
  10. import ModalPortal from './ModalPortal';
  11. import Button from './Button';
  12. const maxDef = isIOS ? 480 : 540;
  13. var _maxWidth = isIOS ? $vw(75) : $vw(87);
  14. const maxWidth = _maxWidth > maxDef ? maxDef: _maxWidth;
  15. const BUTTON_OK = 'ok';
  16. const BUTTON_CANCEL = 'cancel';
  17. export const getDialogWidth = () => {
  18. return maxWidth;
  19. }
  20. /**
  21. * 显示一个弹窗
  22. * @param {*} props 参数{title, message, ok, cancel, showCancel, callback(button)}
  23. */
  24. const showDialog = (props) => {
  25. var param = {
  26. align: props.align || 'left',
  27. title: props.title || '',
  28. message: props.message || '',
  29. ok: props.ok || 'OK',
  30. cancel: props.cancel || 'CANCEL',
  31. showCancel: props.showCancel != undefined ? props.showCancel : true,
  32. callback: props.callback
  33. }
  34. ModalPortal.show((
  35. isIOS ? <IOSDialog {...param}/>
  36. : <AndroidDialog {...param}/>
  37. ));
  38. }
  39. /**
  40. * 显示一个只有确认按钮的弹窗
  41. * @param {}} message 消息
  42. * @param {*} ok 按钮文字
  43. * @param {*} back callback(btn)
  44. */
  45. const showResultDialog = (message, ok, back) => {
  46. var param = {
  47. title: isIOS ? message : '',
  48. message: !isIOS ? message : '',
  49. showCancel: false,
  50. ok: ok || 'I Known',
  51. callback: back
  52. }
  53. showDialog(param);
  54. }
  55. const showProgressDialog = (message='Loading...') => {
  56. //message = message ?? 'Waiting...';
  57. ModalPortal.showLoading((
  58. isIOS ? <IOSProgress message={message}/>
  59. : <AndroidProgress message={message}/>
  60. ));
  61. }
  62. const dismissDialog = () => {
  63. ModalPortal.dismiss();
  64. }
  65. const dismissLoading = () => {
  66. ModalPortal.dismissLoading();
  67. }
  68. const dismissAll = () => {
  69. ModalPortal.dismissAll();
  70. }
  71. const IOSDialog = (props) => {
  72. return (
  73. <View style={iosStyle.modalDialog}>
  74. { props.title != '' &&
  75. <Text style={iosStyle.modalTitle}>{props.title}</Text>
  76. }
  77. { props.message != '' &&
  78. <Text style={[
  79. iosStyle.message,
  80. {
  81. textAlign: props.align
  82. }
  83. ]}>
  84. {props.message}
  85. </Text>
  86. }
  87. <View style={iosStyle.modalFooter}>
  88. <Button
  89. text={props.ok}
  90. style={iosStyle.btnGroup}
  91. viewStyle={iosStyle.btnView}
  92. textStyle={iosStyle.btnConfirm}
  93. onClick={() => {
  94. dismissDialog();
  95. if (props.callback) {
  96. props.callback(BUTTON_OK);
  97. }
  98. }}/>
  99. { props.showCancel &&
  100. <Button
  101. text={props.cancel}
  102. style={[iosStyle.btnGroup, iosStyle.btnRight]}
  103. viewStyle={iosStyle.btnView}
  104. textStyle={iosStyle.btnText}
  105. onClick={() => {
  106. dismissDialog();
  107. if (props.callback) {
  108. props.callback(BUTTON_CANCEL);
  109. }
  110. }}/>
  111. }
  112. </View>
  113. </View>
  114. );
  115. }
  116. const AndroidDialog = (props) => {
  117. return (
  118. <View style={andStyles.modalDialog}>
  119. { props.title != '' &&
  120. <Text style={andStyles.title}>
  121. {props.title}
  122. </Text>
  123. }
  124. { props.message != '' &&
  125. <Text style={[
  126. andStyles.message,
  127. {
  128. textAlign: props.align
  129. }
  130. ]}>
  131. {props.message}
  132. </Text>
  133. }
  134. <View style={andStyles.modalFooter}>
  135. { props.showCancel &&
  136. <AndroidButton
  137. title={props.cancel}
  138. onPress={() => {
  139. dismissDialog();
  140. if (props.callback) {
  141. props.callback(BUTTON_CANCEL);
  142. }
  143. }}
  144. />
  145. }
  146. <AndroidButton
  147. title={props.ok}
  148. onPress={() => {
  149. dismissDialog();
  150. if (props.callback) {
  151. props.callback(BUTTON_OK);
  152. }
  153. }}
  154. />
  155. </View>
  156. </View>
  157. )
  158. }
  159. const AndroidButton = ({title, onPress}) => {
  160. return (
  161. <View style={andStyles.modalButton}>
  162. <Pressable
  163. style={andStyles.modalPress}
  164. android_ripple={ripple}
  165. onPress={onPress}>
  166. <Text style={andStyles.modalBtnText}>{title}</Text>
  167. </Pressable>
  168. </View>
  169. );
  170. }
  171. const IOSProgress = (props) => {
  172. return (
  173. <View style={iosStyle.modalProgress}>
  174. <Image
  175. style={iosStyle.loadingIcon}
  176. source={require('../images/icon/loading.gif')}/>
  177. <Text
  178. style={iosStyle.proMessage}
  179. onPress={() => {
  180. dismissLoading();
  181. }}>{props.message}</Text>
  182. </View>
  183. );
  184. }
  185. const AndroidProgress = (props) => {
  186. return (
  187. <View style={andStyles.progressDialog}>
  188. <View style={andStyles.progressView}>
  189. <View style={{
  190. width: 48,
  191. height: 48
  192. }}>
  193. <Progress.CircleSnail
  194. size={48}
  195. duration={667}
  196. thickness={4}
  197. color={[colorAccent]}
  198. direction={'clockwise'}
  199. spinDuration={2000}/>
  200. </View>
  201. <Text
  202. style={andStyles.proMessage}
  203. onPress={() => {
  204. dismissLoading();
  205. }}>{props.message}</Text>
  206. </View>
  207. </View>
  208. );
  209. }
  210. const iosStyle = StyleSheet.create({
  211. modalDialog: {
  212. width: maxWidth,
  213. marginLeft: 'auto',
  214. marginRight: 'auto',
  215. borderRadius: 12,
  216. overflow: 'hidden',
  217. backgroundColor: 'white'
  218. },
  219. modalProgress: {
  220. width: 180,
  221. overflow: 'hidden',
  222. alignItems: 'center',
  223. marginLeft: 'auto',
  224. marginRight: 'auto',
  225. borderRadius: 12,
  226. backgroundColor: 'white'
  227. },
  228. loadingIcon: {
  229. width: 80,
  230. height: 80,
  231. transform: [{scale: 1.3}]
  232. },
  233. title: {
  234. paddingTop: 18,
  235. paddingLeft: 16,
  236. paddingRight: 16,
  237. paddingBottom: 16
  238. },
  239. modalTitle: {
  240. color: '#111',
  241. fontSize: 18,
  242. paddingTop: 18,
  243. paddingLeft: 10,
  244. paddingRight: 10,
  245. fontWeight: 'bold',
  246. textAlign: 'center',
  247. },
  248. message: {
  249. color: '#333',
  250. fontSize: 14,
  251. paddingTop: 4,
  252. paddingLeft: 20,
  253. paddingRight: 20
  254. },
  255. proMessage: {
  256. color: '#555',
  257. fontSize: 15,
  258. marginTop: -4,
  259. paddingBottom: 14
  260. },
  261. modalFooter: {
  262. width: maxWidth,
  263. marginTop: 18,
  264. borderTopWidth: 1,
  265. borderTopColor: '#EFF1F1',
  266. flexDirection: 'row'
  267. },
  268. btnGroup: {
  269. flex: 1,
  270. borderRadius: 0,
  271. backgroundColor: 'white'
  272. },
  273. btnRight: {
  274. borderLeftWidth: 1,
  275. borderLeftColor: '#EFF1F1'
  276. },
  277. btnView: {
  278. flex: 1,
  279. height: 45,
  280. alignItems: 'center',
  281. justifyContent: 'center'
  282. },
  283. btnText: {
  284. color: '#064FE1',
  285. fontSize: 14,
  286. textAlign: 'center'
  287. },
  288. btnConfirm: {
  289. color: '#064FE1',
  290. fontSize: 14,
  291. fontWeight: 'bold'
  292. }
  293. })
  294. const andStyles = StyleSheet.create({
  295. modalDialog: {
  296. width: maxWidth,
  297. zIndex: 100,
  298. paddingTop: 16,
  299. paddingLeft: 20,
  300. paddingRight: 20,
  301. paddingBottom: 8,
  302. borderRadius: 3,
  303. marginLeft: 'auto',
  304. marginRight: 'auto',
  305. backgroundColor: 'white'
  306. },
  307. progressDialog: {
  308. width: maxWidth,
  309. zIndex: 100,
  310. paddingTop: 16,
  311. paddingLeft: 24,
  312. paddingRight: 24,
  313. paddingBottom: 16,
  314. borderRadius: 3,
  315. marginLeft: 'auto',
  316. marginRight: 'auto',
  317. backgroundColor: 'white'
  318. },
  319. title: {
  320. color: '#000',
  321. paddingBottom: 8,
  322. fontSize: 18
  323. },
  324. message: {
  325. color: '#333',
  326. fontSize: 14,
  327. paddingBottom: 8,
  328. },
  329. proMessage: {
  330. flex: 1,
  331. color: '#333',
  332. fontSize: 15,
  333. paddingLeft: 24
  334. },
  335. modalFooter: {
  336. paddingTop: 8,
  337. alignItems: 'center',
  338. flexDirection: 'row',
  339. justifyContent: 'flex-end'
  340. },
  341. modalButton: {
  342. marginLeft: 8,
  343. borderRadius: 3,
  344. overflow: 'hidden'
  345. },
  346. modalPress: {
  347. padding: 8
  348. },
  349. modalBtnText: {
  350. fontSize: 14,
  351. color: colorPrimaryDark
  352. },
  353. progressView: {
  354. alignItems: 'center',
  355. flexDirection: 'row'
  356. }
  357. });
  358. export default Dialog = {
  359. BUTTON_OK: BUTTON_OK,
  360. BUTTON_CANCEL: BUTTON_CANCEL,
  361. showDialog: showDialog,
  362. dismissAll: dismissAll,
  363. dismissDialog: dismissDialog,
  364. dismissLoading: dismissLoading,
  365. showResultDialog: showResultDialog,
  366. showProgressDialog: showProgressDialog,
  367. modalProps: {
  368. avoidKeyboard: true,
  369. animationIn: "fadeIn",
  370. animationOut: "fadeOut",
  371. propagateSwipe: true,
  372. useNativeDriver: true,
  373. hideModalContentWhileAnimating: true
  374. }
  375. }
  376. //Toast显示位置
  377. const toastPosition = isIOS ? 0 : -70;
  378. export const InitSomething = () => {
  379. global.dialogId = undefined;
  380. global.EndView = () => <View style={ui.end}/>
  381. global.toastShort = (msg) => {
  382. if (utils.isNotEmpty(msg)) {
  383. if (typeof msg !== 'string')
  384. msg = '' + msg;
  385. Toast.show(msg, {
  386. duration: Toast.durations.SHORT,
  387. position: toastPosition,
  388. shadow: false,
  389. opacity: 0.85,
  390. textStyle: {
  391. fontSize: 14
  392. },
  393. backgroundColor: '#222222',
  394. containerStyle: {
  395. paddingLeft: 16,
  396. paddingRight: 16,
  397. borderRadius: 50,
  398. maxHeight: $vh(80)
  399. }
  400. });
  401. }
  402. }
  403. global.toastLong = (msg) => {
  404. if (utils.isNotEmpty(msg)) {
  405. if (typeof msg !== 'string')
  406. msg = '' + msg;
  407. Toast.show(msg, {
  408. duration: Toast.durations.LONG,
  409. position: toastPosition,
  410. shadow: false,
  411. opacity: 0.85,
  412. textStyle: {
  413. fontSize: 14
  414. },
  415. backgroundColor: '#222222',
  416. containerStyle: {
  417. paddingLeft: 16,
  418. paddingRight: 16,
  419. borderRadius: 50,
  420. maxHeight: $vh(80)
  421. }
  422. });
  423. }
  424. }
  425. }