Dialog.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  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.modalTitle}>{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. paddingTop: 18,
  237. paddingLeft: 16,
  238. paddingRight: 16,
  239. paddingBottom: 16
  240. },
  241. modalTitle: {
  242. color: '#111',
  243. fontSize: 18,
  244. paddingTop: 18,
  245. paddingLeft: 10,
  246. paddingRight: 10,
  247. fontWeight: 'bold',
  248. textAlign: 'center',
  249. },
  250. message: {
  251. color: textPrimary,
  252. fontSize: 14,
  253. paddingTop: 4,
  254. paddingLeft: 20,
  255. paddingRight: 20
  256. },
  257. proMessage: {
  258. color: '#555',
  259. fontSize: 15,
  260. marginTop: -4,
  261. paddingBottom: 14
  262. },
  263. modalFooter: {
  264. width: maxWidth,
  265. marginTop: 18,
  266. borderTopWidth: 1,
  267. borderTopColor: '#EFF1F1',
  268. flexDirection: 'row'
  269. },
  270. btnGroup: {
  271. flex: 1,
  272. borderRadius: 0,
  273. backgroundColor: colorLight
  274. },
  275. btnRight: {
  276. borderLeftWidth: 1,
  277. borderLeftColor: '#EFF1F1'
  278. },
  279. btnView: {
  280. flex: 1,
  281. height: 45,
  282. alignItems: 'center',
  283. justifyContent: 'center'
  284. },
  285. btnText: {
  286. color: '#064FE1',
  287. fontSize: 14,
  288. textAlign: 'center'
  289. },
  290. btnConfirm: {
  291. color: '#064FE1',
  292. fontSize: 14,
  293. fontWeight: 'bold'
  294. }
  295. })
  296. const andStyles = StyleSheet.create({
  297. modalDialog: {
  298. width: maxWidth,
  299. zIndex: 100,
  300. paddingTop: 16,
  301. paddingLeft: 20,
  302. paddingRight: 20,
  303. paddingBottom: 8,
  304. borderRadius: 3,
  305. marginLeft: 'auto',
  306. marginRight: 'auto',
  307. backgroundColor: colorLight
  308. },
  309. progressDialog: {
  310. width: maxWidth,
  311. zIndex: 100,
  312. paddingTop: 16,
  313. paddingLeft: 24,
  314. paddingRight: 24,
  315. paddingBottom: 16,
  316. borderRadius: 3,
  317. marginLeft: 'auto',
  318. marginRight: 'auto',
  319. backgroundColor: colorLight
  320. },
  321. title: {
  322. color: '#000',
  323. paddingBottom: 8,
  324. fontSize: 18
  325. },
  326. message: {
  327. color: textPrimary,
  328. fontSize: 14,
  329. paddingBottom: 8,
  330. },
  331. proMessage: {
  332. flex: 1,
  333. color: textPrimary,
  334. fontSize: 15,
  335. paddingLeft: 24
  336. },
  337. modalFooter: {
  338. paddingTop: 8,
  339. alignItems: 'center',
  340. flexDirection: 'row',
  341. justifyContent: 'flex-end'
  342. },
  343. modalButton: {
  344. marginLeft: 8,
  345. borderRadius: 3,
  346. overflow: 'hidden'
  347. },
  348. modalPress: {
  349. padding: 8
  350. },
  351. modalBtnText: {
  352. fontSize: 14,
  353. color: colorPrimary
  354. },
  355. progressView: {
  356. alignItems: 'center',
  357. flexDirection: 'row'
  358. },
  359. endView: {
  360. paddingTop: 16
  361. },
  362. halfView: {
  363. paddingTop: 8
  364. }
  365. });
  366. export default Dialog = {
  367. BUTTON_OK: BUTTON_OK,
  368. BUTTON_CANCEL: BUTTON_CANCEL,
  369. isShowing: ModalPortal.isShowing,
  370. showDialog: showDialog,
  371. dismissAll: dismissAll,
  372. dismissDialog: dismissDialog,
  373. dismissLoading: dismissLoading,
  374. showResultDialog: showResultDialog,
  375. showProgressDialog: showProgressDialog,
  376. modalProps: {
  377. avoidKeyboard: true,
  378. animationIn: "fadeIn",
  379. animationOut: "fadeOut",
  380. propagateSwipe: true,
  381. useNativeDriver: true,
  382. hideModalContentWhileAnimating: true
  383. },
  384. styles: andStyles,
  385. IOSProgress: IOSProgress
  386. }
  387. //Toast显示位置
  388. const toastPosition = isIOS ? 0 : -70;
  389. const getStringMessage = (msg) => {
  390. if (typeof msg == 'object') {
  391. if (msg.err) {
  392. return "" + msg.err;
  393. } else if (msg.msg) {
  394. return "" + msg.msg;
  395. } else if (msg.message) {
  396. return "" + msg.message;
  397. } else {
  398. return JSON.stringify(msg);
  399. }
  400. } else {
  401. return "" + msg;
  402. }
  403. }
  404. export const InitSomething = () => {
  405. global.dialogId = undefined;
  406. global.EndView = ({half=false}) => (
  407. half
  408. ? <View style={andStyles.halfView}/>
  409. : <View style={andStyles.endView}/>
  410. )
  411. global.toastShort = (msg) => {
  412. if (typeof msg !== 'string')
  413. msg = getStringMessage(msg);
  414. if (utils.isNotEmpty(msg)) {
  415. Toast.show(msg, {
  416. duration: Toast.durations.SHORT,
  417. position: toastPosition,
  418. shadow: false,
  419. opacity: 0.85,
  420. textStyle: {
  421. fontSize: 14,
  422. lineHeight: 18
  423. },
  424. backgroundColor: '#222222',
  425. containerStyle: {
  426. paddingLeft: 16,
  427. paddingRight: 16,
  428. borderRadius: 50,
  429. maxHeight: $vh(80)
  430. }
  431. });
  432. }
  433. }
  434. global.toastLong = (msg) => {
  435. if (typeof msg !== 'string')
  436. msg = getStringMessage(msg);
  437. if (utils.isNotEmpty(msg)) {
  438. Toast.show(msg, {
  439. duration: Toast.durations.LONG,
  440. position: toastPosition,
  441. shadow: false,
  442. opacity: 0.85,
  443. textStyle: {
  444. fontSize: 14
  445. },
  446. backgroundColor: '#222222',
  447. containerStyle: {
  448. paddingLeft: 16,
  449. paddingRight: 16,
  450. borderRadius: 50,
  451. maxHeight: $vh(80)
  452. }
  453. });
  454. }
  455. }
  456. }