HistoryItem.tsx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import formatMilliseconds from "@/utils/format_time";
  2. import { View, Text, Image } from "@tarojs/components";
  3. import './History.scss'
  4. import Taro from "@tarojs/taro";
  5. import dayjs from "dayjs";
  6. import { useSelector } from "react-redux";
  7. import { getThemeColor } from "./hooks/health_hooks";
  8. import Rings, { RingCommon, BgRing, TargetRing, CurrentDot } from "@/features/trackTimeDuration/components/Rings";
  9. import { MainColorType } from "@/context/themes/color";
  10. import { durationArc, startArc } from "./util";
  11. import { IconMore } from "@/components/basic/Icons";
  12. import showActionSheet from "@/components/basic/ActionSheet";
  13. import { makeDone } from "@/services/health";
  14. export default function HistoryItem(props: {
  15. data: any,
  16. preData: any,
  17. index: number,
  18. onClick: Function,
  19. isArchived?: boolean,
  20. refresh?: Function,
  21. mode: string,
  22. fast_type?: string
  23. }) {
  24. const health = useSelector((state: any) => state.health);
  25. let showActionSheetWithOptions;
  26. function preview(obj) {
  27. var list: any = []
  28. props.data.events.map((item) => {
  29. item.moment.media.map((media) => {
  30. list.push(media.url)
  31. })
  32. })
  33. Taro.previewImage({
  34. current: obj.url,
  35. urls: list
  36. })
  37. }
  38. //npm install react-native-text-size
  39. function getTitle(item) {
  40. if (item.title) return item.title
  41. if (item.moment) {
  42. return item.moment.title
  43. }
  44. // if (health.mode == 'FAST') {
  45. // return '开始断食'
  46. // }
  47. // else if (health.mode == 'SLEEP') {
  48. // return '开始睡眠'
  49. // }
  50. return ''
  51. }
  52. function ring() {
  53. const common: RingCommon = {
  54. useCase: 'ChooseScenario',
  55. radius: 10,
  56. lineWidth: 3,
  57. isFast: true,
  58. status: 'WAIT_FOR_START'
  59. }
  60. const bgRing: BgRing = {
  61. color: MainColorType.ringBg
  62. }
  63. const realRing = {
  64. hideBg: true,
  65. color: props.mode == 'FAST,SLEEP'?getThemeColor('FAST'):getThemeColor(health.mode),
  66. startArc: startArc(props.data.window_range.start_timestamp),
  67. durationArc: durationArc(props.data.window_range.start_timestamp, props.data.window_range.end_timestamp)
  68. }
  69. const canvasId = props.mode == 'FAST,SLEEP'?'history_fast_sleep' + props.index:'history_' + props.index
  70. return <Rings common={common} bgRing={bgRing} realRing={realRing} canvasId={canvasId} />
  71. }
  72. function ring2() {
  73. const common: RingCommon = {
  74. useCase: 'ChooseScenario',
  75. radius: 10,
  76. lineWidth: 3,
  77. isFast: true,
  78. status: 'WAIT_FOR_START'
  79. }
  80. const bgRing: BgRing = {
  81. color: MainColorType.ringBg
  82. }
  83. const realRing = {
  84. hideBg: true,
  85. color: getThemeColor('SLEEP'),
  86. startArc: startArc(props.data.events[1].time.timestamp),
  87. durationArc: durationArc(props.data.events[1].time.timestamp, props.data.events[2].time.timestamp)
  88. }
  89. const canvasId = 'history2_props_mode' + props.index
  90. return <Rings common={common} bgRing={bgRing} realRing={realRing} canvasId={canvasId} />
  91. }
  92. function mediaCount() {
  93. let count = 0;
  94. props.data.events.map((item) => {
  95. if (item.moment) {
  96. item.moment.media.map((obj, j) => {
  97. count++;
  98. })
  99. }
  100. })
  101. return count;
  102. }
  103. function historyDate() {
  104. if (!props.preData) {
  105. return dayjs(props.data.window_range.start_timestamp).format('D')
  106. }
  107. if (dayjs(props.data.window_range.start_timestamp).format('D') ==
  108. dayjs(props.preData.window_range.start_timestamp).format('D')) {
  109. return ''
  110. }
  111. return dayjs(props.data.window_range.start_timestamp).format('D')
  112. }
  113. return <View className="history_item2">
  114. <View className="history_date">{historyDate()}</View>
  115. <View className="history_content">
  116. <View style={{ display: 'flex', flexDirection: 'column' }}>
  117. {
  118. props.data.events.map((item, index) => {
  119. return <Text key={index}>
  120. <Text className="history_item_title">{item.time && dayjs(item.time.timestamp).format('HH:mm')} {getTitle(item)} </Text>
  121. {
  122. item.moments && item.moments.map((moment, i) => {
  123. return <Text className="history_item_desc" key={i * 1000}>{moment.description}</Text>
  124. })
  125. }
  126. </Text>
  127. })
  128. }
  129. </View>
  130. <View className="media" style={{ marginTop: mediaCount() > 0 ? 9 : -10, marginRight: mediaCount() == 4 ? 80 : 0 }}>
  131. {
  132. props.data.events.map((item) => {
  133. if (item.moments) {
  134. return item.moments.map(moment => {
  135. return moment.media.map((obj, j) => {
  136. return <Image className="media_item" mode="aspectFill" onClick={() => preview(obj)} src={obj.url} key={j * 10} />
  137. })
  138. })
  139. }
  140. })
  141. }
  142. </View>
  143. <View className="history_duration_bg">
  144. {
  145. props.fast_type != 'LF' && ring()
  146. }
  147. {
  148. props.data.window_range.end_timestamp && <Text className="history_item_duration">{formatMilliseconds(props.data.window_range.end_timestamp - props.data.window_range.start_timestamp)}</Text>
  149. }
  150. </View>
  151. {
  152. props.mode == 'FAST,SLEEP' && props.data.events.length>2 && <View className="history_duration_bg" style={{marginTop:0}}>
  153. {
  154. props.fast_type != 'LF' && ring2()
  155. }
  156. {
  157. props.data.window_range.end_timestamp && <Text className="history_item_duration">{formatMilliseconds(props.data.events[2].time.timestamp - props.data.events[1].time.timestamp)}</Text>
  158. }
  159. </View>
  160. }
  161. {
  162. props.isArchived && <View className="history_archived_row">
  163. <View className="history_archived" onClick={(e) => {
  164. if (process.env.TARO_ENV == 'weapp') {
  165. e.stopPropagation()
  166. }
  167. showActionSheet({
  168. showActionSheetWithOptions: showActionSheetWithOptions,
  169. title: 'Oprate Title',
  170. itemList: ['标记完成', '补记'],
  171. success: (res) => {
  172. // tapActionSheet(res)
  173. switch (res) {
  174. case 1:
  175. break;
  176. case 0:
  177. makeDone(props.data.window_id).then(res => {
  178. global.refreshWindow()
  179. global.refreshHistory()
  180. if (props.refresh)
  181. props.refresh()
  182. })
  183. break;
  184. }
  185. }
  186. });
  187. }}>
  188. <IconMore width={17} color="#b2b2b2" />
  189. </View>
  190. </View>
  191. }
  192. </View>
  193. <View className="seperate_light_line" />
  194. </View>
  195. }