read.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <template>
  2. <view class="color-bg" :style="{'background-color': read_setting_data.readMode==config.read_config.readMode.Bright?config.read_config.colorList[read_setting_data.colorBgIndex]:DarkBg,'height':book_text_list_view.length<=0?'100vh':'100%'}">
  3. <readPage class="content" ref="readPages" @touchstart="onStartClickView"
  4. @touchend="onEndClickView" @touchmove="hideSetting" v-for="(book_read_data_item,index) in book_text_list_view" :key="book_read_data_item.book_chapter_id"
  5. :text_content="book_read_data_item.book_content" :book_title="book_read_data_item.book_title">
  6. </readPage>
  7. <settingMenu ref="Menu" v-if="menuShow" @clickCatalog="onClickCatalog"
  8. @clickPreChapter="onClickPreChapter" @clickNextChapter="onClickNextChapter"
  9. @clickMode="onClickMode" @clickOpenSetting="onClickOpenSetting"
  10. @Close="closeMenu" @changeFontSize="onChangeFontSize" @changeBgColor="onChangeBgColor"
  11. @selectAutoBuy="onSelectAutoBuy" @clickKeep="onClickKeep">
  12. </settingMenu>
  13. <chapterCatalog v-if="showChapterList" :items="directoryList" :size="40" :remain="16"
  14. :scrollHeight="windowHeight*0.6" @clickChar="goToChapter" @Close="showChapterList=false">
  15. </chapterCatalog>
  16. </view>
  17. </template>
  18. <script setup lang="ts">
  19. import { onUnload } from '@dcloudio/uni-app'
  20. import { nextTick, ref, watch } from 'vue';
  21. import { book_item_data, book_read_data, chapter_item_data } from '../../data/data';
  22. import { tools } from '../../framework/tools';
  23. import { UserStatus } from '../../stores/userStatusManager';
  24. import { log } from '../../framework/log';
  25. import readPage from '../../components/read/readPage.vue'
  26. import settingMenu from '../../components/read/settingMenu.vue'
  27. import chapterCatalog from '../../components/read/chapterCatalog.vue'
  28. import {onPullDownRefresh,onReachBottom} from '@dcloudio/uni-app'
  29. import { ReadSetting } from '../../stores/readSetting';
  30. import { config } from '../../config/config';
  31. const {windowHeight,windowWidth} = uni.getSystemInfoSync()
  32. const readPages = ref(null)
  33. const Menu = ref(null)
  34. let book_data:book_item_data = UserStatus().getUserSelectBook()
  35. let directoryList:chapter_item_data[] = []
  36. let cur_read_chapter_index =ref(0)
  37. let start_read_chapter_id = book_data.start_read_chapter_id
  38. //设置属性
  39. let read_setting_data = ReadSetting().getReadSetting()
  40. let fontSize = config.read_config.fontSizeList[read_setting_data.fontSizeIndex]
  41. let bgColor = config.read_config.colorList[read_setting_data.colorBgIndex]
  42. // 页面销毁
  43. onUnload(()=>{
  44. tools.exitRead()
  45. })
  46. //设置属性end
  47. updateNavigation()
  48. if(book_data!=null&&start_read_chapter_id!=-1){
  49. initView()
  50. }
  51. let book_text_list_view = ref<Array<book_read_data>>([])
  52. let book_text_list_cache = ref<Map<number,book_read_data>>(new Map<number,book_read_data>())
  53. function initView(){
  54. tools.getChapterList(book_data.chapter_path,(chapter_ls)=>{
  55. directoryList = chapter_ls
  56. cur_read_chapter_index.value = tools.getCurChapterIndex(start_read_chapter_id,directoryList)
  57. draw(null)
  58. })
  59. }
  60. function draw(cb:Function,dir_is_down:boolean=true){
  61. let loading_view = (d:book_read_data)=>{
  62. book_data.start_read_chapter_id = d.book_chapter_id //记录开始阅读章节id
  63. cb && cb()
  64. nextTick(()=>{
  65. if(d!=null){
  66. if(dir_is_down){
  67. book_text_list_view.value.push(d)
  68. }else{
  69. book_text_list_view.value.unshift(d)
  70. }
  71. }
  72. })
  73. }
  74. if(cur_read_chapter_index.value<=directoryList.length&&cur_read_chapter_index.value>=0){
  75. let data = tools.getCurChapterData(cur_read_chapter_index.value,directoryList)
  76. if(data!=null){
  77. let cache_data = book_text_list_cache.value.get(data.id)
  78. if(cache_data!=null){
  79. loading_view(cache_data)
  80. }else{
  81. tools.getCurChapterTxt(book_data.base_path,data.id,fontSize*2,(text:string)=>{
  82. cache_data = new book_read_data()
  83. cache_data.book_content = text
  84. cache_data.book_chapter_id = data.id
  85. cache_data.book_title = tools.autoParagraphTitle(data.name,fontSize*4)
  86. book_text_list_cache.value.set(data.id,cache_data)
  87. loading_view(cache_data)
  88. })
  89. }
  90. }
  91. }else{
  92. log.Error("暂无可读取内容!")
  93. }
  94. }
  95. function down_dir_load(){
  96. cur_read_chapter_index.value+=1;
  97. draw(null)
  98. }
  99. function up_dir_load(){
  100. cur_read_chapter_index.value-=1;
  101. draw(null,false)
  102. }
  103. onPullDownRefresh( async () => {
  104. showTopLoadingStatus()
  105. uni.stopPullDownRefresh();
  106. })
  107. onReachBottom(async ()=>{
  108. showBottomLoadingStatus()
  109. })
  110. function showBottomLoadingStatus(){
  111. readPages.value.find((child,index)=>{
  112. if( index == (book_text_list_view.value.length-1) ){
  113. child.showBottomLoading()
  114. down_dir_load()
  115. }
  116. })
  117. }
  118. function showTopLoadingStatus(){
  119. readPages.value.find((child,index)=>{
  120. if( index == 0 ){
  121. child.showTopLoading()
  122. up_dir_load()
  123. }
  124. })
  125. }
  126. //设置相关
  127. let menuShow = ref(false)
  128. let startTouchY = ref(-1)
  129. let endTouchY = ref(-1)
  130. function onClickCatalog(){
  131. closeMenu()
  132. showChapterList.value = true
  133. }
  134. function hideChapterList(){
  135. showChapterList.value = false
  136. }
  137. function onClickOpenSetting(){
  138. console.log("点了设置")
  139. showSetting()
  140. }
  141. function onClickPreChapter(){
  142. goToChapter(tools.getPreChapterData(cur_read_chapter_index.value,directoryList))
  143. hideSetting()
  144. }
  145. function onClickNextChapter(){
  146. goToChapter(tools.getNextChapterData(cur_read_chapter_index.value,directoryList))
  147. hideSetting()
  148. }
  149. function onStartClickView(e){
  150. startTouchY.value = e.changedTouches[0].pageY
  151. }
  152. function onEndClickView(e){
  153. endTouchY.value = e.changedTouches[0].pageY
  154. if(Math.abs(endTouchY.value-startTouchY.value)<=5){
  155. startTouchY.value = -1
  156. showMenuView()
  157. }
  158. }
  159. function showMenuView(){
  160. menuShow.value = true
  161. }
  162. function hideAllTop(){
  163. }
  164. function showSetting(){
  165. Menu.value.showSettingFont()
  166. }
  167. function hideSetting(){
  168. startTouchY.value = -1
  169. menuShow.value = false
  170. hideChapterList()
  171. }
  172. function closeMenu(){
  173. hideSetting()
  174. }
  175. function onChangeFontSize(index:number){
  176. let new_index = -1;
  177. if(index>0){
  178. new_index = ReadSetting().data.fontSizeIndex + 1
  179. if(new_index>=config.read_config.fontSizeList.length){
  180. }else{
  181. ReadSetting().changeFontSize(new_index)
  182. }
  183. }else{
  184. new_index = ReadSetting().data.fontSizeIndex - 1
  185. if(new_index<0){
  186. }else{
  187. ReadSetting().changeFontSize(new_index)
  188. }
  189. }
  190. }
  191. function onChangeBgColor(index:number){
  192. ReadSetting().changeReadMode(config.read_config.readMode.Bright)
  193. ReadSetting().changeBgColor(index)
  194. }
  195. function onSelectAutoBuy(isAuto:boolean){
  196. ReadSetting().changeAutoBuyNextChapter(isAuto)
  197. }
  198. function onClickKeep(){
  199. log.Debug("收藏",book_data.book_name)
  200. }
  201. let DarkBg = ref(tools.getDbColorByMode(read_setting_data.readMode))
  202. function onClickMode(mode:number){
  203. ReadSetting().changeReadMode(mode)
  204. }
  205. watch(async () => ReadSetting().data.readMode, // 监听的数据源
  206. (newVal, oldVal) => {
  207. DarkBg.value = tools.getDbColorByMode(read_setting_data.readMode)
  208. updateNavigation()
  209. }
  210. );
  211. //设置end
  212. //章节列表 start
  213. let showChapterList = ref(false)
  214. function goToChapter(chapter_list_item_data:chapter_item_data){
  215. // console.log("想看",chapter_list_item_data)
  216. if(chapter_list_item_data!=null){
  217. cur_read_chapter_index.value = tools.getCurChapterIndex(chapter_list_item_data.id,directoryList)
  218. draw(()=>{
  219. book_text_list_view.value = []
  220. })
  221. hideChapterList()
  222. }else{
  223. log.Error('goToChapter error!',cur_read_chapter_index.value)
  224. }
  225. }
  226. watch(async () => ReadSetting().data.colorBgIndex, // 监听的数据源
  227. (newVal, oldVal) => {
  228. bgColor = config.read_config.colorList[read_setting_data.colorBgIndex]
  229. updateNavigation()
  230. }
  231. );
  232. function updateNavigation(){
  233. let showbgColor = bgColor
  234. if(read_setting_data.readMode==config.read_config.readMode.Dark){
  235. showbgColor = tools.getDbColorByMode(read_setting_data.readMode)
  236. }
  237. uni.setNavigationBarColor({
  238. frontColor: '#ffffff',
  239. backgroundColor: showbgColor,
  240. animation: {
  241. duration: 0,
  242. timingFunc: 'easeIn'
  243. }
  244. })
  245. }
  246. // function getCurChapterId(){
  247. // return tools.getCurChapterData(cur_read_chapter_index.value,directoryList).id
  248. // }
  249. </script>
  250. <style scoped lang="scss">
  251. .color-bg{
  252. // position: relative; /* 或者使用 fixed/absolute,根据需要调整 */
  253. width: 100vw;
  254. // height: 100vh; /* 视口高度 */
  255. // overflow: hidden; /* 隐藏超出容器的内容,如果需要的话 */
  256. // height: 100%;
  257. overflow-y: auto;
  258. }
  259. .content {
  260. /* 内容组件的样式 */
  261. position: relative; /* 相对于 page-container 定位 */
  262. z-index: 1; /* 确保内容在背景之上 */
  263. /* 其他样式... */
  264. }
  265. </style>