Album.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. import { jumpPage } from "@/features/trackTimeDuration/hooks/Common";
  2. import { getAlbums, getAlbumsStat } from "@/services/health";
  3. import { View, Text, Image, ScrollView } from "@tarojs/components";
  4. import { useEffect, useState } from "react";
  5. import './Album.scss'
  6. import '@/features/health/History.scss'
  7. import NewHeader, { NewHeaderType } from "@/_health/components/new_header";
  8. import { rpxToPx } from "@/utils/tools";
  9. import NewButton, { NewButtonType } from "@/_health/base/new_button";
  10. import { MainColorType } from "@/context/themes/color";
  11. import { getThemeColor } from "@/features/health/hooks/health_hooks";
  12. import dayjs from "dayjs";
  13. import Taro from "@tarojs/taro";
  14. import StickyDateList from "@/_health/components/sticky_date_list";
  15. import ListFooter from "@/_health/components/list_footer";
  16. import CoverList from "@/_health/components/cover_list";
  17. import { TimeFormatter } from "@/utils/time_format";
  18. import { useTranslation } from "react-i18next";
  19. import RightArrowRow from "@/_health/components/right_arrow_row";
  20. import NoRecord from "@/_health/components/no_record";
  21. let myScrollTop = 0
  22. export default function Album() {
  23. const [medias, setMedias] = useState<any>([])
  24. const [window, setWindow] = useState('')
  25. const [stat, setStat] = useState<any>(null)
  26. const [isPulling, setIsPulling] = useState(false)
  27. const [itemLayouts, setItemLayouts] = useState<any>([])
  28. const [showDate, setShowDate] = useState(false)
  29. const [date, setDate] = useState('')
  30. const [page, setPage] = useState(1)
  31. const [total, setTotal] = useState(0)
  32. const [loading, setLoading] = useState(false)
  33. const [loaded, setLoaded] = useState(false)
  34. const { t } = useTranslation()
  35. useEffect(() => {
  36. getAlbumsData('')
  37. Taro.setNavigationBarTitle({
  38. title: t('health.photos')
  39. })
  40. }, [])
  41. useEffect(() => {
  42. if (medias.length > 0) {
  43. setTimeout(() => {
  44. measureItemLayouts()
  45. }, 500)
  46. }
  47. }, [medias])
  48. function more() {
  49. if (loading) return;
  50. if (total == medias.length) return;
  51. var index = page;
  52. index++;
  53. setPage(index)
  54. getAlbumsData(window, index)
  55. }
  56. function getAlbumsData(str, index = 1) {
  57. // setIsPulling(true)
  58. setLoading(true)
  59. getAlbums({
  60. page: index,
  61. limit: 10,
  62. window: str
  63. }).then(res => {
  64. if (index == 1) {
  65. setMedias((res as any).data)
  66. setTotal((res as any).total)
  67. }
  68. else {
  69. setMedias([...medias, ...(res as any).data])
  70. }
  71. setIsPulling(false)
  72. setLoading(false)
  73. setLoaded(true)
  74. }).catch(e => {
  75. setLoading(false)
  76. })
  77. getAlbumsStat().then(res => {
  78. setStat(res)
  79. })
  80. }
  81. // function historyMonth(index, preIndex) {
  82. // var showDate = false;
  83. // var dateStr = ''
  84. // if (index == 0) {
  85. // var currentDate = (medias[index].date + '').substring(0, 6)
  86. // var now = dayjs().format('YYYYMM')
  87. // showDate = true
  88. // dateStr = currentDate.substring(0, 4) + '年' + currentDate.substring(4, 6) + '月'
  89. // }
  90. // else {
  91. // var currentDate = (medias[index].date + '').substring(0, 6)
  92. // var now = (medias[index - 1].date + '').substring(0, 6)
  93. // if (currentDate != now) {
  94. // showDate = true
  95. // // dateStr = currentDate
  96. // dateStr = currentDate.substring(0, 4) + '年' + currentDate.substring(4, 6) + '月'
  97. // }
  98. // }
  99. // if (showDate) {
  100. // return <View className="history_year_month h30 g01">{dateStr}</View>
  101. // }
  102. // return <View />
  103. // }
  104. function measureItemLayouts() {
  105. const query = Taro.createSelectorQuery()
  106. medias.forEach((item, index) => {
  107. query.select(`#history-${index}`).boundingClientRect()
  108. });
  109. query.exec((res) => {
  110. var layouts: any = []
  111. res.forEach((rect, index) => {
  112. if (rect) {
  113. layouts[index] = rect.top + myScrollTop
  114. }
  115. });
  116. setItemLayouts(layouts)
  117. })
  118. }
  119. function onScroll(e) {
  120. var top = e.detail.scrollTop
  121. myScrollTop = top
  122. // if (e.detail.scrollTop > 60) {
  123. // Taro.setNavigationBarTitle({
  124. // title: t('health.photos')
  125. // })
  126. // }
  127. // else {
  128. // Taro.setNavigationBarTitle({
  129. // title: ''
  130. // })
  131. // }
  132. if (itemLayouts.length > 0) {
  133. var i = -1
  134. var date = ''
  135. medias.forEach((item, index) => {
  136. if (top >= itemLayouts[index] - 50) {
  137. i = index
  138. var currentDate = (medias[index].date + '').substring(0, 6)
  139. date = currentDate.substring(0, 4) + '年' + currentDate.substring(4, 6) + '月'
  140. }
  141. })
  142. setShowDate(i != -1)
  143. setDate(date)
  144. }
  145. else {
  146. setShowDate(false)
  147. setDate('')
  148. }
  149. }
  150. function historyYear(index) {
  151. var showDate = false;
  152. var dateStr2: any = ''
  153. if (index == 0) {
  154. var currentDate = global.language == 'en' ? dayjs(medias[index].timestamp).format('YYYY') : dayjs(medias[index].timestamp).format('YYYY年')
  155. var now = global.language == 'en' ? dayjs().format('YYYY') : dayjs().format('YYYY年')
  156. if (currentDate != now) {
  157. showDate = true
  158. dateStr2 = currentDate
  159. }
  160. }
  161. else {
  162. var currentDate = global.language == 'en' ? dayjs(medias[index].timestamp).format('YYYY') : dayjs(medias[index].timestamp).format('YYYY年')
  163. var now = global.language == 'en' ? dayjs(medias[index - 1].timestamp).format('YYYY') : dayjs(medias[index - 1].timestamp).format('YYYY年')
  164. if (currentDate != now) {
  165. showDate = true
  166. dateStr2 = currentDate
  167. }
  168. }
  169. if (showDate) {
  170. return <View className="history_year_month h42 bold">{dateStr2}</View>
  171. }
  172. return <View />
  173. }
  174. function historyDate(item, index) {
  175. if (index == 0) {
  176. if (global.language == 'zh' && TimeFormatter.isToday(item.timestamp)) {
  177. return '今天'
  178. }
  179. if (global.language == 'zh' && TimeFormatter.isYesterday(item.timestamp)) {
  180. return '昨天'
  181. }
  182. return dayjs(item.timestamp).format('DD')
  183. }
  184. if (dayjs(item.timestamp).format('MM-DD') ==
  185. dayjs(medias[index - 1].timestamp).format('MM-DD')) {
  186. return ''
  187. }
  188. if (global.language == 'zh' && TimeFormatter.isToday(item.timestamp)) {
  189. return '今天'
  190. }
  191. if (global.language == 'zh' && TimeFormatter.isYesterday(item.timestamp)) {
  192. return '昨天'
  193. }
  194. return dayjs(item.timestamp).format('DD')
  195. }
  196. function historyMonth(item, index) {
  197. if (index == 0) {
  198. if (global.language == 'zh' && TimeFormatter.isToday(item.timestamp)) {
  199. return ''
  200. }
  201. if (global.language == 'zh' && TimeFormatter.isYesterday(item.timestamp)) {
  202. return ''
  203. }
  204. return dayjs(item.timestamp).format('MMM')
  205. }
  206. if (dayjs(item.timestamp).format('MM-DD') ==
  207. dayjs(medias[index - 1].timestamp).format('MM-DD')) {
  208. return ''
  209. }
  210. if (global.language == 'zh' && TimeFormatter.isToday(item.timestamp)) {
  211. return ''
  212. }
  213. if (global.language == 'zh' && TimeFormatter.isYesterday(item.timestamp)) {
  214. return ''
  215. }
  216. return dayjs(item.timestamp).format('MMM')
  217. }
  218. return <StickyDateList onRefresherRefresh={() => {
  219. setIsPulling(true)
  220. setPage(1)
  221. getAlbumsData(window, 1)
  222. }} isPulling={isPulling}
  223. onScroll={onScroll}
  224. showDate={showDate}
  225. date={date}
  226. loadMore={more}
  227. >
  228. <View style={{ display: 'flex', flexDirection: 'column' }}>
  229. {/* <NewHeader type={NewHeaderType.left} title={t('health.photos')} /> */}
  230. {/* {stat && <ScrollView style={{ width: rpxToPx(750), flexDirection: 'row', display: 'flex', height: rpxToPx(72) }} scrollX enableFlex showScrollbar={false}>
  231. <View style={{ width: rpxToPx(40), flexShrink: 0 }} />
  232. <NewButton type={NewButtonType.img} onClick={() => {
  233. setWindow('')
  234. getAlbumsData('')
  235. }}>
  236. <View className="streak_toolbar_btn"
  237. style={{ backgroundColor: window == '' ? '#B2B2B21A' : 'transparent' }}
  238. >
  239. <Text className={window == '' ? 'bold h30' : 'h30'}
  240. style={{ color: window == '' ? '#000' : MainColorType.g01, marginRight: 5 }}>全部 </Text>
  241. <Text className="h20" style={{ color: window == '' ? '#000' : MainColorType.g01 }}>{stat.total}</Text>
  242. </View>
  243. </NewButton>
  244. {
  245. stat.items.map((item, index) => {
  246. return <View key={index}>
  247. <NewButton type={NewButtonType.img} onClick={() => {
  248. setWindow(item.window)
  249. getAlbumsData(item.window)
  250. }}>
  251. <View className="streak_toolbar_btn"
  252. style={{ backgroundColor: window == item.window ? getThemeColor(item.window) + '1A' : 'transparent' }}
  253. >
  254. <Text className={window == item.window ? 'bold h30' : 'h30'}
  255. style={{ color: window == item.window ? getThemeColor(item.window) : MainColorType.g01, marginRight: 5 }}>{item.window} </Text>
  256. <Text className="h20" style={{ color: window == item.window ? getThemeColor(item.window) : MainColorType.g01 }}>{' ' + item.image_count}</Text>
  257. </View>
  258. </NewButton>
  259. </View>
  260. })
  261. }
  262. <View style={{ width: rpxToPx(40), flexShrink: 0 }} />
  263. </ScrollView>} */}
  264. {/* <View style={{ height: rpxToPx(36) }} /> */}
  265. {/* <View className="photo_wall" onClick={() => {
  266. jumpPage('/pages/account/PhotoWall?window=' + window)
  267. }}>
  268. <View style={{ flex: 1 }} />
  269. <Text className="photo_wall_text">Photo Wall</Text>
  270. <Image className="photo_wall_arrow" src={require('@assets/_health/arrow2.png')} />
  271. <View className="album_line" />
  272. </View> */}
  273. <RightArrowRow title={t('health.photo_wall')} height={rpxToPx(184)} onClick={() => {
  274. jumpPage('/pages/account/PhotoWall?window=' + window)
  275. }} />
  276. <View style={{
  277. backgroundColor: '#fff',
  278. minHeight: '100vh'
  279. }}>
  280. {
  281. medias.map((item, index) => {
  282. return <View key={index} id={`history-${index}`} style={{ display: 'flex', flexDirection: 'column', paddingTop: rpxToPx(6), backgroundColor: '#fff' }}>
  283. {
  284. historyYear(index)
  285. }
  286. <View className="history_item2" style={{ paddingRight: rpxToPx(30) }}>
  287. <View className="cell_date" >
  288. <View className="h42 bold" style={{ lineHeight: rpxToPx(60) + 'px' }}>{historyDate(item, index)}</View>
  289. <View className="h24 bold" style={{ marginLeft: rpxToPx(6), marginTop: rpxToPx(13), lineHeight: rpxToPx(47) + 'px' }}>{historyMonth(item, index)}</View>
  290. </View>
  291. {/* <Text className="cell_date">{(item.date + '').substring(6, 9)}</Text> */}
  292. <View style={{ display: 'flex', flex: 1 }}>
  293. <CoverList
  294. imgs={item.images}
  295. count={item.images.length}
  296. />
  297. {/* <View className="media" style={{ marginRight: item.images.length == 4 ? 80 : 0 }}>
  298. {
  299. item.images.map((photo, i) => {
  300. return <Image onClick={() => {
  301. Taro.previewImage({
  302. current: photo,
  303. urls: item.images
  304. })
  305. }} mode="aspectFill" src={photo} key={i * 900} className="media_item" />
  306. })
  307. }
  308. </View> */}
  309. </View>
  310. {/* <View className="border_footer_line" /> */}
  311. </View>
  312. </View>
  313. })
  314. }
  315. {
  316. medias.length > 0 && <View style={{ height: rpxToPx(40), flexShrink: 0, backgroundColor: '#fff' }} />
  317. }
  318. <ListFooter noMore={(medias.length > 0) && (total == medias.length)} />
  319. {
  320. loaded && medias.length == 0 && <NoRecord />
  321. }
  322. </View>
  323. </View>
  324. </StickyDateList>
  325. }