Dialog.js 10 KB

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