123d9b48创建于 2024年10月15日历史提交
<template>
  <div
    :class="{ 'cata-wrapper': true, visible: popCataVisible }"
    :style="popupTheme"
  >
    <div class="title">目录</div>
    <virtual-list
      style="height: 300px; overflow: auto"
      :class="{ night: isNight, day: !isNight }"
      ref="virtualListRef"
      data-key="index"
      wrap-class="data-wrapper"
      item-class="cata"
      :data-sources="virtualListdata"
      :data-component="CatalogItem"
      :estimate-size="40"
      :extra-props="{ gotoChapter, currentChapterIndex }"
    />
  </div>
</template>

<script setup lang="ts">
import VirtualList from 'vue3-virtual-scroll-list'
import settings from '../config/themeConfig'
import '../assets/fonts/popfont.css'
import CatalogItem from './CatalogItem.vue'
import type { BookChapter } from '@/book'

const store = useBookStore()

const { catalog, popCataVisible, miniInterface } = storeToRefs(store)

//主题
const isNight = computed(() => store.theme)
const theme = computed(() => store.theme)
const popupTheme = computed(() => {
  return {
    background: settings.themes[theme.value].popup,
  }
})

//虚拟列表 数据源
const virtualListdata = computed(() => {
  const catalogValue = catalog.value
  if (miniInterface.value) return catalogValue

  // pc端 virtualListIitem有2个章节
  const length = Math.ceil(catalogValue.length / 2)
  const virtualListDataSource = new Array<{
    index: number
    catas: BookChapter[]
  }>(length)

  let i = 0
  while (i < length) {
    virtualListDataSource[i] = {
      index: i,
      catas: catalogValue.slice(2 * i, 2 * i + 2),
    }
    i++
  }
  return virtualListDataSource
})

//打开目录 计算当前章节对应的虚拟列表位置
const virtualListRef = ref()
const currentChapterIndex = computed({
  get: () => store.readingBook.chapterIndex,
  set: value => (store.readingBook.chapterIndex = value),
})
const virtualListIndex = computed(() => {
  const index = currentChapterIndex.value
  if (miniInterface.value) return index
  // pc端 virtualListIitem有2个章节
  return Math.floor(index / 2)
})
onUpdated(() => {
  // dom更新触发ResizeObserver,更新虚拟列表内部的sizes Map
  if (!popCataVisible.value) return
  virtualListRef.value.scrollToIndex(virtualListIndex.value)
})

// 点击加载对应章节内容
const emit = defineEmits(['getContent'])
const gotoChapter = (chapter: BookChapter) => {
  const chapterIndex = catalog.value.indexOf(chapter)
  currentChapterIndex.value = chapterIndex
  store.setPopCataVisible(false)
  store.setContentLoading(true)
  store.saveBookProgress()
  emit('getContent', chapterIndex)
}
</script>

<style lang="scss" scoped>
.cata-wrapper {
  margin: -16px;
  padding: 18px 0 24px 25px;

  /* background: #ede7da url('../assets/imgs/themes/popup_1.png') repeat; */
  .title {
    font-size: 18px;
    font-weight: 400;
    font-family: FZZCYSK;
    margin: 0 0 20px 0;
    color: #ed4259;
    width: fit-content;
    border-bottom: 1px solid #ed4259;
  }
  :deep(.data-wrapper) {
    .cata {
      /*width: 50%;*/
      height: 40px;
      cursor: pointer;
      font:
        16px / 40px PingFangSC-Regular,
        HelveticaNeue-Light,
        'Helvetica Neue Light',
        'Microsoft YaHei',
        sans-serif;
    }
  }

  .night {
    :deep(.cata) {
      border-bottom: 1px solid #666;
    }
  }

  .day {
    :deep(.cata) {
      border-bottom: 1px solid #f2f2f2;
    }
  }
}
</style>