OpenTime.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /* eslint-disable no-underscore-dangle */
  2. import React from "react";
  3. import {
  4. StyleSheet,
  5. LayoutAnimation,
  6. Platform,
  7. UIManager,
  8. } from "react-native";
  9. import { range, convert2Digit } from "beeshell/dist/common/utils";
  10. import {
  11. CheckBox,
  12. Layout,
  13. Modal,
  14. Button,
  15. Card,
  16. Text,
  17. MenuItem,
  18. Icon,
  19. SelectItem,
  20. } from "@ui-kitten/components";
  21. import { Scrollpicker } from "beeshell";
  22. import { useModel } from "flooks";
  23. import moment from "moment";
  24. if (Platform.OS === "android") {
  25. if (UIManager.setLayoutAnimationEnabledExperimental) {
  26. UIManager.setLayoutAnimationEnabledExperimental(true);
  27. }
  28. }
  29. const styles = StyleSheet.create({
  30. checkBoxAll: {
  31. paddingVertical: 10,
  32. },
  33. checkBoxItem: {
  34. paddingVertical: 2,
  35. paddingHorizontal: 10,
  36. },
  37. time: {
  38. // width: 100,
  39. // height: 300,
  40. },
  41. backdrop: {
  42. backgroundColor: "rgba(0, 0, 0, 0.5)",
  43. },
  44. btnList: {
  45. flexDirection: "row",
  46. justifyContent: "space-between",
  47. paddingTop: 15,
  48. },
  49. hideHeight: {
  50. height: 0,
  51. borderWidth: 0,
  52. },
  53. btn: {
  54. flex: 1,
  55. minWidth: 50,
  56. },
  57. });
  58. const ForwardIcon = (props) => <Icon {...props} name='arrow-ios-forward' />;
  59. const titleText = (props, title, value) => (
  60. <Text {...props} category='s1' numberOfLines={1} ellipsizeMode='tail'>
  61. {title}
  62. <Text category='c1' style={{ paddingLeft: 10 }}>
  63. {value}
  64. </Text>
  65. </Text>
  66. );
  67. export default function OpenTime({
  68. open,
  69. submit,
  70. cancelEvent,
  71. openModal,
  72. defaultValue,
  73. }) {
  74. const {
  75. MONDAY,
  76. TUESDAY,
  77. WEDNESDAY,
  78. THURSDAY,
  79. FRIDAY,
  80. SATURDAY,
  81. SUNDAY,
  82. every,
  83. confirm,
  84. cancel,
  85. start,
  86. end,
  87. hour,
  88. min,
  89. weekName,
  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 (defaultValue && defaultValue.length > 0) {
  212. setShowName(defaultValue);
  213. }
  214. }, [defaultValue]);
  215. function hideElseShow(key) {
  216. changeShowTime1(key === 1);
  217. changeShowTime2(key === 2);
  218. changeShowWeek(key === 3);
  219. LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
  220. }
  221. return (
  222. <>
  223. <SelectItem
  224. appearance='form'
  225. style={{ flex: 1, height: 32 }}
  226. accessoryRight={ForwardIcon}
  227. title={(props) => titleText(props, showName[0], showName[1])}
  228. onPress={openModal}
  229. />
  230. <Modal
  231. visible={open && list.length > 0}
  232. backdropStyle={styles.backdrop}
  233. onBackdropPress={cancelEvent}
  234. >
  235. <Card
  236. disabled
  237. appearance='modalCrad'
  238. style={{ width: 242 }}
  239. >
  240. <Layout>
  241. <MenuItem
  242. appearance='cardContent'
  243. title={(props) => titleText(props, start, time1Str)}
  244. accessoryRight={ForwardIcon}
  245. onPress={() => {
  246. hideElseShow(1);
  247. }}
  248. />
  249. </Layout>
  250. <Card
  251. disabled
  252. appearance='modalCrad'
  253. style={[
  254. { width: 222 },
  255. showTime1 ? {} : styles.hideHeight,
  256. ]}
  257. >
  258. <Scrollpicker
  259. key='time1'
  260. list={list}
  261. proportion={[1, 1]}
  262. offsetCount={1}
  263. value={time1}
  264. onChange={(index, value) => {
  265. const _time1 = [...time1];
  266. _time1[index] = value;
  267. setTime1(_time1);
  268. }}
  269. />
  270. </Card>
  271. <Layout>
  272. <MenuItem
  273. appearance='cardContent'
  274. title={(props) => titleText(props, end, time2Str)}
  275. accessoryRight={ForwardIcon}
  276. onPress={() => {
  277. hideElseShow(2);
  278. }}
  279. />
  280. </Layout>
  281. <Card
  282. disabled
  283. appearance='modalCrad'
  284. style={[
  285. { width: 222 },
  286. showTime2 ? {} : styles.hideHeight,
  287. ]}
  288. >
  289. <Scrollpicker
  290. key='time2'
  291. list={list}
  292. proportion={[1, 1]}
  293. offsetCount={1}
  294. value={time2}
  295. onChange={(index, value) => {
  296. const _time2 = [...time2];
  297. _time2[index] = value;
  298. setTime2(_time2);
  299. }}
  300. />
  301. </Card>
  302. <Layout>
  303. <MenuItem
  304. appearance='cardContent'
  305. title={(props) =>
  306. titleText(props, weekName, weekStr)}
  307. accessoryRight={ForwardIcon}
  308. onPress={() => {
  309. hideElseShow(3);
  310. }}
  311. />
  312. </Layout>
  313. <Card
  314. appearance='modalCrad'
  315. style={[showWeek ? {} : styles.hideHeight]}
  316. >
  317. <CheckBox
  318. style={styles.checkBoxAll}
  319. checked={allChecked}
  320. indeterminate={indeterminate}
  321. onChange={(checked) => {
  322. changeChecked(
  323. checked
  324. ? weeks.map((item) => {
  325. return item.key;
  326. })
  327. : []
  328. );
  329. }}
  330. >
  331. {every}
  332. </CheckBox>
  333. {listItems}
  334. </Card>
  335. <Layout style={styles.btnList}>
  336. <Button
  337. style={styles.btn}
  338. appearance='outline'
  339. status='info'
  340. onPress={cancelEvent}
  341. >
  342. {cancel}
  343. </Button>
  344. <Button
  345. style={[styles.btn, { marginLeft: 10 }]}
  346. disabled={!canSubmit}
  347. onPress={() => {
  348. submit(time1Str, time2Str, checkList);
  349. setShowName([
  350. `${time1Str }~${ time2Str}`,
  351. weekStr,
  352. ]);
  353. }}
  354. >
  355. {confirm}
  356. </Button>
  357. </Layout>
  358. </Card>
  359. </Modal>
  360. </>
  361. );
  362. }