import React, { useState, useEffect, useRef } from 'react'; import { View, Text, ScrollView } from '@tarojs/components'; import { observer, inject } from 'mobx-react'; import './index.less'; import TopNavBar from '@src/components/TopNavBar/index'; import Taro from '@tarojs/taro'; import BookConfigPuP from '@src/components/bookConfigPup'; import { BookStore } from '@src/store/book'; import useApi from '@src/Hook/useApi'; import { getReadLog, setReadLog } from '@src/utils/loginSto'; interface Config { size: 'pre_15' | 'pre_17' | 'pre_19' | 'pre_21' | 'pre_23' | 'pre_25' | 'pre_27' | 'pre_29' | any; off_on: boolean; bg: 'bg_b' | 'bg_h' | 'bg_l' | 'bg_hh'; lh: 'lh_72' | 'lh_84' | 'lh_96'; } type PageStateProps = { store: { bookStore: BookStore, indexStore, appInfoStore } }; interface BookArticleProps extends PageStateProps { } const BookArticle: React.FC = ({ store }) => { const [isLoad, setIsLoad] = useState(false) const { bookStore, indexStore, appInfoStore } = store const { openBookData } = bookStore const [bookConfig, setBookConfig] = useState({ size: 'pre_21', off_on: true, bg: 'bg_b', lh: 'lh_72' }); const [pup, setPup] = useState(false); const { getBookContent,readingBook } = useApi(appInfoStore) const [currentScrollId, setCurrentScrollId] = useState(''); const newReadLogIdRef = useRef(""); const readLogInterval = useRef() // 页面显示的操作请求 useEffect(() => { // ComponentDidMount try { Taro.getStorage({ key: 'bookConfig', success: (res) => { setBookConfig(JSON.parse(res.data)); }, fail: () => { setConfig({ size: 'pre_21', off_on: true, bg: 'bg_b', lh: 'lh_72' }); } }); } catch (e) { console.error('Error loading book config:', e); } //假如存在阅读记录获取对应章节的条数 let readLogId = getReadLog(openBookData?.bookId) getBookContent({ pageNum: 1, pageSize: readLogId ? Number(readLogId?.split('-')[1]) : 2 }).then(res => { //继续阅读时跳转到上次阅读的段落 console.log("上次阅读到readLogId", readLogId) setCurrentScrollId(readLogId) }) }, []); // 页面卸载的操作 useEffect(() => { reportRead() return () => { console.log("卸载", newReadLogIdRef.current); openBookData && setReadLog({ [openBookData.bookId]: newReadLogIdRef.current })//离开时存放当前位置 clearInterval(readLogInterval.current)//清除上报心跳 }; }, []) // 这里可以填写上报逻辑 const reportRead = () => { console.log("上报", newReadLogIdRef.current) openBookData && setReadLog({ [openBookData.bookId]: newReadLogIdRef.current }) if(readLogInterval.current){ clearInterval(readLogInterval.current) } // 定时上报心跳 readLogInterval.current = setInterval(() => { readingBook(bookStore.readId) console.log("上报阅读心跳",newReadLogIdRef.current,bookStore.readId) }, 3000); }; //设置配置 const setConfig = (data: Config) => { if (data) { setBookConfig(data); Taro.setStorage({ key: 'bookConfig', data: JSON.stringify(data), success: (res: any) => { console.log('添加bookConfig===>成功!', res); }, fail: (err) => { console.log('添加bookConfig===>失败', err); } }); // 控制自义定头部背景 store.bookStore.setData({ bookConfig: data }); } }; /**计算字体 */ const setSize = (parms: number) => { let num = bookConfig.size.split('_'); if (num[1] && parms) { setConfig({ ...bookConfig, size: num[0] + '_' + (Number(num[1]) + 2) }); } else { setConfig({ ...bookConfig, size: num[0] + '_' + (Number(num[1]) - 2) }); } }; /**设置背景 */ const setBg = (bg: 'bg_b' | 'bg_h' | 'bg_l' | 'bg_hh') => { setConfig({ ...bookConfig, bg }); if (!bookConfig.off_on) { setOff(bg); } }; /**设置行高*/ const setLh = (lh: 'lh_72' | 'lh_84' | 'lh_96') => { setConfig({ ...bookConfig, lh }); }; /**关灯 */ const setOff = (bg?: 'bg_b' | 'bg_h' | 'bg_l' | 'bg_hh') => { const newOffOn = !bookConfig.off_on; const newConfig = bg ? { ...bookConfig, bg, off_on: newOffOn } : { ...bookConfig, off_on: newOffOn }; setConfig(newConfig); Taro.setNavigationBarColor({ frontColor: newOffOn ? '#000000' : '#ffffff', backgroundColor: newOffOn ? '#fff' : '#111111' }); }; /**菜单 */ const togglePup = () => { setPup(!pup); }; //设置setNavigationBarColor useEffect(() => { Taro.setNavigationBarColor({ frontColor: bookConfig.off_on ? '#000000' : '#ffffff', backgroundColor: bookConfig.off_on ? '#fff' : '#111' }); }, [bookConfig.off_on]); const onLoad = async () => { if (openBookData?.contentData) { let { size, current, total, records } = openBookData.contentData if (records.length < total) { console.log("加载") setIsLoad(true) await getBookContent({ pageNum: 1, pageSize: size + 2 }).then(res => { setIsLoad(false) }) } else { Taro.showToast({ title: '没有更多了~~', duration: 1000, icon: 'none' }) } } } // 计算阅读的位置,存放以备下次阅读的时候跳转到对应位置 const handleScroll = () => { const query = Taro.createSelectorQuery(); query.selectAll('.shrot-text').boundingClientRect(); // 选择所有子元素 query.selectViewport().scrollOffset(); // 获取视口的滚动位置 query.exec(res => { const items = res[0]; // 子元素的位置信息 const scrollTop = res[1].scrollTop + indexStore.navHeight; // 视口的滚动距离 // 遍历所有子元素,判断哪个子元素在可视区域 for (let item of items) { if (item.top <= scrollTop && item.bottom >= scrollTop) { if (openBookData?.bookId) { newReadLogIdRef.current = item.id//存放当前可视的段落ID } break; } } }); }; const { size, bg, off_on, lh } = bookConfig; return ( {/* 顶部设置 */} { size !== 'pre_15' && setSize(0) }} className={!off_on ? size === 'pre_15' ? 'cl_e5' : '' : size === 'pre_15' ? 'cl_d6' : ''} >字小 { size !== 'pre_29' && setSize(1) }} className={!off_on ? size === 'pre_29' ? 'cl_e5' : '' : size === 'pre_29' ? 'cl_d6' : ''} >字大 { setOff() }}>{off_on ? '关灯' : '开灯'} {isLoad && 菜单} {/* 正文内容 */} { openBookData?.contentData?.records?.map(item => { let arr = item.paragraphInfo.content?.match(/[^\n]*\n?/g); return { arr?.map((str, index) => { // let strArr = str?.match(/[^。]*。/g) return { str } }) } }) } {/* 设置弹窗 */} {pup && } {/* 底部下来加载 */} {/* { isLoad && } */} ); }; export default inject('store')(observer(TopNavBar(BookArticle, { isToBack: true, isReloadBook: true })));