layout.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import { View, Text, ScrollView } from "@tarojs/components";
  2. import './layout.scss'
  3. import { NaviBarTitleShowType, TemplateType } from "@/utils/types";
  4. import { useEffect, useRef, useState } from "react";
  5. import Taro, { usePageScroll } from "@tarojs/taro";
  6. import { rpxToPx } from "@/utils/tools";
  7. let useNavigation;
  8. let GradientText
  9. let RefreshControl;
  10. let ScrollViewRN;
  11. if (process.env.TARO_ENV == 'rn') {
  12. ScrollViewRN = require("react-native").ScrollView
  13. RefreshControl = require("react-native").RefreshControl
  14. GradientText = require('@/components/basic/GradientText').default
  15. useNavigation = require("@react-navigation/native").useNavigation
  16. }
  17. export default function Layout(props: {
  18. children: React.ReactNode,
  19. type: TemplateType,
  20. refresh?: Function,
  21. more?: Function,
  22. triggered?: boolean,
  23. title?: string,
  24. titleColor?: string,
  25. header?: React.ReactNode,
  26. secondPage?: boolean,
  27. isFastSleepTheme?: boolean,
  28. titleShowStyle: NaviBarTitleShowType,
  29. showPullToRefresh?: boolean,
  30. // ref?: any
  31. }) {
  32. const { children, type, triggered } = props;
  33. const [isRefreshing, setIsRefreshing] = useState(false)
  34. const scrollRef = useRef(null);
  35. const [scrollTop, setScrollTop] = useState(0)
  36. const [showTitle, setShowTitle] = useState(props.titleShowStyle == NaviBarTitleShowType.alwayShow)
  37. let navigation;
  38. if (useNavigation) {
  39. navigation = useNavigation()
  40. }
  41. useEffect(() => {
  42. Taro.setNavigationBarTitle({
  43. title: showTitle ? props.title ? props.title : '' : ''
  44. })
  45. if (navigation) {
  46. navigation.setOptions({
  47. headerTitle: showTitle ? props.title ? props.title : '' : '',
  48. });
  49. }
  50. // setTimeout(() => {
  51. // if (process.env.TARO_ENV == 'rn') {
  52. // setScrollTop(100)
  53. // // debugger
  54. // // (scrollRef.current as any).scrollToOffset(100,true)
  55. // }
  56. // }, 8000)
  57. }, [showTitle, props.title])
  58. function onRefresh() {
  59. if (props.refresh) {
  60. props.refresh()
  61. }
  62. setIsRefreshing(true)
  63. setTimeout(() => {
  64. setIsRefreshing(false)
  65. }, 1000)
  66. }
  67. function onScroll(e) {
  68. if (props.titleShowStyle == NaviBarTitleShowType.scrollToShow) {
  69. if (e.nativeEvent){
  70. const {contentOffset} = e.nativeEvent
  71. if (contentOffset.y > 70) {
  72. setShowTitle(true)
  73. }
  74. else {
  75. setShowTitle(false)
  76. }
  77. }
  78. else {
  79. if (e.detail.scrollTop > 70) {
  80. setShowTitle(true)
  81. }
  82. else {
  83. setShowTitle(false)
  84. }
  85. }
  86. }
  87. if (e.nativeEvent){
  88. const { contentSize, contentOffset, layoutMeasurement } = e.nativeEvent;
  89. const isAtTheBottom =
  90. contentSize.height - contentOffset.y <= layoutMeasurement.height;
  91. if (isAtTheBottom && props.more){
  92. props.more()
  93. }
  94. }
  95. }
  96. usePageScroll((e) => {
  97. if (props.titleShowStyle == NaviBarTitleShowType.scrollToShow) {
  98. if (e.scrollTop > 70) {
  99. setShowTitle(true)
  100. }
  101. else {
  102. setShowTitle(false)
  103. }
  104. }
  105. })
  106. function fastSleepTitle() {
  107. if (process.env.TARO_ENV == 'rn') {
  108. return <GradientText style={{
  109. fontSize: props.secondPage ? rpxToPx(56) : rpxToPx(72),
  110. fontWeight: 'bold',
  111. marginLeft: rpxToPx(46),
  112. marginTop: rpxToPx(24),
  113. marginBottom: rpxToPx(24)
  114. }}>{props.title}</GradientText>
  115. }
  116. return <Text className='layout_title fast_sleep_text'
  117. style={{
  118. fontSize: props.secondPage ? rpxToPx(56) : rpxToPx(72)
  119. }}
  120. >{props.title}</Text>
  121. }
  122. function pageDetail() {
  123. return <View>
  124. {
  125. props.title && <View className="layout_title_view" style={{ backgroundColor: global.isDebug ? 'red' : 'transparent' }}>
  126. {
  127. props.isFastSleepTheme ? fastSleepTitle() :
  128. <Text className='layout_title'
  129. style={{
  130. color: props.titleColor ? props.titleColor : '#fff',
  131. fontSize: props.secondPage ? rpxToPx(56) : rpxToPx(72)
  132. }}
  133. >{props.title}</Text>
  134. }
  135. </View>
  136. }
  137. {
  138. children
  139. }
  140. <View style={{ height: 0 }} />
  141. </View>
  142. }
  143. switch (type) {
  144. case TemplateType.flex:
  145. return <View className='flex'>
  146. {/* <View className="flex-expand" /> */}
  147. {
  148. process.env.TARO_ENV == 'weapp' ? pageDetail() :
  149. <ScrollViewRN scrollEventThrottle={400} style={{ minHeight: Taro.getSystemInfoSync().screenHeight }} onScroll={onScroll} showsVerticalScrollIndicator={false}>
  150. {
  151. pageDetail()
  152. }
  153. <View style={{ height: 200 }} />
  154. </ScrollViewRN>
  155. }
  156. </View>
  157. case TemplateType.customHeader:
  158. if (process.env.TARO_ENV == 'rn') {
  159. return <ScrollViewRN onScroll={onScroll}
  160. ref={scrollRef}
  161. scrollEventThrottle={400}
  162. // scrollTop={scrollTop}
  163. // scrollWithAnimation
  164. style={{ minHeight: Taro.getSystemInfoSync().screenHeight }}
  165. refreshControl={
  166. props.showPullToRefresh ? <RefreshControl
  167. tintColor='white'
  168. colors={['white']} // 设置刷新指示器的颜色为白色
  169. progressBackgroundColor="white" // 设置刷新指示器的背景颜色为白色
  170. refreshing={isRefreshing}
  171. onRefresh={onRefresh}
  172. /> : null
  173. }
  174. showsVerticalScrollIndicator={false}>
  175. <View className='flex'>
  176. {
  177. props.header
  178. }
  179. {children}
  180. <View style={{ height: 200 }} />
  181. </View>
  182. </ScrollViewRN>
  183. }
  184. return <View className='flex'>
  185. {/* <View className="flex-expand" /> */}
  186. {
  187. props.header
  188. }
  189. {children}
  190. <View style={{ height: 50 }} />
  191. </View>
  192. }
  193. return <View />
  194. }