OpenTime.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /* eslint-disable prefer-const */
  2. /* eslint-disable no-underscore-dangle */
  3. import React from "react";
  4. import { StyleSheet, LayoutAnimation, Platform, UIManager } from "react-native";
  5. import { range, convert2Digit } from "beeshell/dist/common/utils";
  6. import {
  7. CheckBox,
  8. Layout,
  9. Modal,
  10. Button,
  11. Card,
  12. Text,
  13. MenuItem,
  14. Icon,
  15. SelectItem,
  16. } from "@ui-kitten/components";
  17. import { Scrollpicker } from "beeshell";
  18. import { useModel } from "flooks";
  19. import moment from "moment";
  20. import OpenTimeUtil from "../Utils/OpenTimeUtil";
  21. if (Platform.OS === "android") {
  22. if (UIManager.setLayoutAnimationEnabledExperimental) {
  23. UIManager.setLayoutAnimationEnabledExperimental(true);
  24. }
  25. }
  26. const styles = StyleSheet.create({
  27. checkBoxAll: {
  28. paddingVertical: 10,
  29. },
  30. checkBoxItem: {
  31. paddingVertical: 2,
  32. paddingHorizontal: 10,
  33. },
  34. time: {
  35. // width: 100,
  36. // height: 300,
  37. },
  38. backdrop: {
  39. backgroundColor: "rgba(0, 0, 0, 0.5)",
  40. },
  41. btnList: {
  42. flexDirection: "row",
  43. justifyContent: "space-between",
  44. paddingTop: 15,
  45. },
  46. hideHeight: {
  47. height: 0,
  48. borderWidth: 0,
  49. },
  50. btn: {
  51. flex: 1,
  52. minWidth: 50,
  53. },
  54. });
  55. const ForwardIcon = props => <Icon {...props} name="arrow-ios-forward" />;
  56. const titleText = (props, title, value) => (
  57. <Text {...props} category="s1" numberOfLines={1} ellipsizeMode="tail">
  58. {title}
  59. <Text category="c1" style={{ paddingLeft: 10 }}>
  60. {value}
  61. </Text>
  62. </Text>
  63. );
  64. export default function OpenTime({
  65. open,
  66. submit,
  67. cancelEvent,
  68. openModal,
  69. week,
  70. startTime,
  71. endTime,
  72. }) {
  73. const {
  74. MONDAY,
  75. TUESDAY,
  76. WEDNESDAY,
  77. THURSDAY,
  78. FRIDAY,
  79. SATURDAY,
  80. SUNDAY,
  81. every,
  82. confirm,
  83. cancel,
  84. start,
  85. end,
  86. hour,
  87. min,
  88. weekName,
  89. weekWords,
  90. } = useModel("wordsModel");
  91. const weeks = [
  92. {
  93. key: "MONDAY",
  94. label: MONDAY,
  95. },
  96. {
  97. key: "TUESDAY",
  98. label: TUESDAY,
  99. },
  100. {
  101. key: "WEDNESDAY",
  102. label: WEDNESDAY,
  103. },
  104. {
  105. key: "THURSDAY",
  106. label: THURSDAY,
  107. },
  108. {
  109. key: "FRIDAY",
  110. label: FRIDAY,
  111. },
  112. {
  113. key: "SATURDAY",
  114. label: SATURDAY,
  115. },
  116. {
  117. key: "SUNDAY",
  118. label: SUNDAY,
  119. },
  120. ];
  121. const [checkList, changeChecked] = React.useState([]);
  122. const listItems = weeks.map((item, index) => (
  123. <CheckBox
  124. style={styles.checkBoxItem}
  125. key={index}
  126. checked={checkList.includes(item.key)}
  127. onChange={checked => {
  128. const _checkList = [...checkList];
  129. if (checked) {
  130. _checkList.push(item.key);
  131. } else {
  132. _checkList.splice(_checkList.indexOf(item.key), 1);
  133. }
  134. changeChecked(_checkList);
  135. }}
  136. >
  137. {item.label}
  138. </CheckBox>
  139. ));
  140. const list = React.useMemo(() => {
  141. const hourSum = 24;
  142. const minuteSum = 60;
  143. const hours = range(hourSum / 1).map(item => {
  144. item = convert2Digit(item * 1);
  145. return {
  146. label: `${item} ${hour}`,
  147. value: item,
  148. };
  149. });
  150. const minutes = range(minuteSum / 10).map(item => {
  151. item = convert2Digit(item * 10);
  152. return {
  153. label: `${item} ${min}`,
  154. value: item,
  155. };
  156. });
  157. return [hours, minutes];
  158. }, [open]);
  159. const [time1, setTime1] = React.useState([8, 0]);
  160. const [time2, setTime2] = React.useState([20, 0]);
  161. const [showTime1, changeShowTime1] = React.useState(true);
  162. const [showTime2, changeShowTime2] = React.useState(false);
  163. const [showWeek, changeShowWeek] = React.useState(false);
  164. const allChecked = React.useMemo(() => {
  165. if (weeks.length === checkList.length) {
  166. return true;
  167. }
  168. return false;
  169. }, [weeks, checkList]);
  170. const indeterminate = React.useMemo(() => {
  171. if (!allChecked && checkList.length > 0) {
  172. return true;
  173. }
  174. return false;
  175. }, [allChecked, checkList]);
  176. const canSubmit = React.useMemo(() => {
  177. if (time1.length === 2 && time2.length === 2 && checkList.length > 0) {
  178. return true;
  179. }
  180. return false;
  181. }, [time1, time2, checkList]);
  182. const time1Str = React.useMemo(() => {
  183. if (time1.length === 2) {
  184. const str = `${time1[0]}:${time1[1] * 10}`;
  185. return moment(str, "H:m").format("HH:mm");
  186. }
  187. return "";
  188. }, [time1]);
  189. const time2Str = React.useMemo(() => {
  190. if (time2.length === 2) {
  191. const str = `${time2[0]}:${time2[1] * 10}`;
  192. return moment(str, "H:m").format("HH:mm");
  193. }
  194. return "";
  195. }, [time2]);
  196. const weekStr = React.useMemo(() => {
  197. if (allChecked) {
  198. return every;
  199. }
  200. const _weeks = weeks.filter(item => {
  201. return checkList.includes(item.key);
  202. });
  203. return _weeks
  204. .map(item => {
  205. return item.label;
  206. })
  207. .join(",");
  208. }, []);
  209. const [showName, setShowName] = React.useState([" ", ""]);
  210. React.useEffect(() => {
  211. if (week && endTime && startTime) {
  212. let _openTimeUtil = new OpenTimeUtil(startTime, endTime, week, weekWords);
  213. setShowName([_openTimeUtil.getTimeStr(), _openTimeUtil.getWeekStr()]);
  214. }
  215. }, [week, endTime, startTime]);
  216. function hideElseShow(key) {
  217. changeShowTime1(key === 1);
  218. changeShowTime2(key === 2);
  219. changeShowWeek(key === 3);
  220. LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
  221. }
  222. return (
  223. <>
  224. <SelectItem
  225. appearance="form"
  226. style={{ flex: 1, height: 32 }}
  227. accessoryRight={ForwardIcon}
  228. title={props => titleText(props, showName[0], showName[1])}
  229. onPress={openModal}
  230. />
  231. <Modal
  232. visible={open && list.length > 0}
  233. backdropStyle={styles.backdrop}
  234. onBackdropPress={cancelEvent}
  235. >
  236. <Card disabled appearance="modalCrad" style={{ width: 242 }}>
  237. <Layout>
  238. <MenuItem
  239. appearance="cardContent"
  240. title={props => titleText(props, start, time1Str)}
  241. accessoryRight={ForwardIcon}
  242. onPress={() => {
  243. hideElseShow(1);
  244. }}
  245. />
  246. </Layout>
  247. <Card
  248. disabled
  249. appearance="modalCrad"
  250. style={[{ width: 222 }, showTime1 ? {} : styles.hideHeight]}
  251. >
  252. <Scrollpicker
  253. key="time1"
  254. list={list}
  255. proportion={[1, 1]}
  256. offsetCount={1}
  257. value={time1}
  258. onChange={(index, value) => {
  259. const _time1 = [...time1];
  260. _time1[index] = value;
  261. setTime1(_time1);
  262. }}
  263. />
  264. </Card>
  265. <Layout>
  266. <MenuItem
  267. appearance="cardContent"
  268. title={props => titleText(props, end, time2Str)}
  269. accessoryRight={ForwardIcon}
  270. onPress={() => {
  271. hideElseShow(2);
  272. }}
  273. />
  274. </Layout>
  275. <Card
  276. disabled
  277. appearance="modalCrad"
  278. style={[{ width: 222 }, showTime2 ? {} : styles.hideHeight]}
  279. >
  280. <Scrollpicker
  281. key="time2"
  282. list={list}
  283. proportion={[1, 1]}
  284. offsetCount={1}
  285. value={time2}
  286. onChange={(index, value) => {
  287. const _time2 = [...time2];
  288. _time2[index] = value;
  289. setTime2(_time2);
  290. }}
  291. />
  292. </Card>
  293. <Layout>
  294. <MenuItem
  295. appearance="cardContent"
  296. title={props => titleText(props, weekName, weekStr)}
  297. accessoryRight={ForwardIcon}
  298. onPress={() => {
  299. hideElseShow(3);
  300. }}
  301. />
  302. </Layout>
  303. <Card
  304. appearance="modalCrad"
  305. style={[showWeek ? {} : styles.hideHeight]}
  306. >
  307. <CheckBox
  308. style={styles.checkBoxAll}
  309. checked={allChecked}
  310. indeterminate={indeterminate}
  311. onChange={checked => {
  312. changeChecked(
  313. checked
  314. ? weeks.map(item => {
  315. return item.key;
  316. })
  317. : []
  318. );
  319. }}
  320. >
  321. {every}
  322. </CheckBox>
  323. {listItems}
  324. </Card>
  325. <Layout style={styles.btnList}>
  326. <Button
  327. style={styles.btn}
  328. appearance="outline"
  329. status="info"
  330. onPress={cancelEvent}
  331. >
  332. {cancel}
  333. </Button>
  334. <Button
  335. style={[styles.btn, { marginLeft: 10 }]}
  336. disabled={!canSubmit}
  337. onPress={() => {
  338. submit(time1Str, time2Str, checkList);
  339. setShowName([`${time1Str}~${time2Str}`, weekStr]);
  340. }}
  341. >
  342. {confirm}
  343. </Button>
  344. </Layout>
  345. </Card>
  346. </Modal>
  347. </>
  348. );
  349. }