Files
nuttyreading-html/pages/eBook/2/contentSetting.vue
@fawn-nine f8e1a3015b 1
2023-03-03 12:11:23 +08:00

462 lines
10 KiB
Vue

<template>
<view>
<view class="fixed menu" v-show="menuFlag" @touchend="hide">
<cus-navbar :style="{boxShadow: `0 2rpx 8rpx ${textColor}29`}" :bgColor="bgColor" :titleColor="textColor">
<block slot="right">
<text class="iconfont icon-gengduo" @tap.stop.prevent="moreHandle"></text>
</block>
</cus-navbar>
<view class="bottom"
:style="{backgroundColor:bgColor,color:textColor,boxShadow: `0 -2rpx 8rpx ${textColor}29`}">
<view class="item" @touchend.prevent.stop="catalogHandle">
<text class="iconfont icon-caidan1"></text>
<text>目录</text>
</view>
<view class="item" @touchend.prevent.stop="darkHandle">
<text class="iconfont" :class="isDark?'icon-rijian':'icon-yejian'"></text>
<text>{{isDark?'日间':'夜间'}}</text>
</view>
<view class="item" @touchend.prevent.stop="cacheHandle">
<text v-if="!isCacheing" class="iconfont icon-xiazai"></text>
<text v-else>{{curCaches.length}}/{{chapterData.length}}</text>
<text>{{curCaches.length!==chapterData.length?'缓存':'已缓存'}}</text>
</view>
<view class="item" @touchend.prevent.stop="settingHandle">
<text class="iconfont icon-shezhi"></text>
<text>设置</text>
</view>
</view>
<!-- 听书 -->
<view v-if="!settingFlag" class="listen" :style="{color:bgColor}" @touchend.prevent.stop="listenHandle">
</view>
<!-- 设置 -->
<view class="setting" v-show="settingFlag"
:style="{backgroundColor:bgColor,color:textColor,boxShadow: `0 -2rpx 8rpx ${textColor}29`}"
@touchend.stop>
<view class="line">
<view class="title">字号</view>
<cus-button data-str="-" bgColor="rgba(0,0,0,.1)" :textColor="textColor" width="60px"
fontSize="14px" :disabled="fontSize<=minFontSize" :border="false" @click="changeFontSize(-2)">A
</cus-button>
<view style="margin: 0 8px;">{{fontSize}}</view>
<cus-button data-str="+" bgColor="rgba(0,0,0,.1)" :textColor="textColor" width="60px"
fontSize="14px" :disabled="fontSize>=maxFontSize" :border="false" @click="changeFontSize(2)">A
</cus-button>
</view>
<view class="line">
<view class="title">背景</view>
<cus-button class="background" v-for="(item,index) in bgColorList" :key="index" :bgColor="item"
:border="index===colorType" @click="changeBackground(index)">
</cus-button>
</view>
<view class="line">
<view class="title">翻页</view>
<cus-button v-for="(item,index) in turnTypeList" :key="index" :bgColor="bgColor" :border="true"
:textColor="textColor" width="60px" :hairLine="index!==turnType" @click="changeTurnType(index)">
{{item}}
</cus-button>
</view>
</view>
</view>
<!-- 侧边目录 -->
<view class="fixed catalog" v-show="catalogFlag">
<view class="mask" @tap="catalogFlag=false"></view>
<view class="catalog-content" :style="{backgroundColor:bgColor,color:textColor}">
<view class="order iconfont" :class="descFlag?'icon-paixu1':'icon-paixu'"
@touchend.prevent.stop="sortHandle">
</view>
<scroll-view class="scroll-view" scroll-y="true" :scroll-into-view="'siv'+sivId">
<view :class="{'reverse':descFlag}">
<view class="item" :id="'siv'+index"
:class="{'text-gray':curCaches.includes(item.index),'text-red':chapterIndex===index}"
v-for="(item,index) in chapterData" :key="item.index" @tap="clickCatalog(index)">
<view class="chapter-name">{{item.title}}</view>
<view v-if="curCaches.includes(item.index)">已缓存</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</template>
<script>
import {
mapGetters,
mapMutations
}
from 'vuex'
export default {
return: {
// 背景色
bgColor: {
type: String,
default: '#cdeeda'
},
// 字体颜色
textColor: {
type: String,
default: '#000'
},
// 夜间模式背景色
darkBgColor: {
type: String,
default: '#000000'
},
// 夜间模式字体颜色
darkTextColor: {
type: String,
default: '#666666'
},
// 是否是夜间模式
isDark: {
type: Boolean,
default: false
},
// 字体大小
fontSize: {
type: Number,
default: 16
},
// 背景颜色列表
bgColorList: {
type: Array,
default: []
},
// 字体颜色列表
textColorList: {
type: Array,
default: []
},
// 翻页方式列表
turnTypeList: {
type: Array,
default: []
},
// 颜色类别,对应颜色列表的下标
colorType: {
type: Number,
default: 0
},
// 翻页方式类别,对应翻页方式列表的下标
turnType: {
type: Number,
default: 0
},
// 章节列表
chapterData: {
type: Array,
default: []
},
// 当前章节的下标
chapterIndex: {
type: Number,
default: 0
},
},
data() {
return {
menuFlag: false, // 控制菜单的显隐
settingFlag: false, // 控制设置的显隐
minFontSize: 15,
maxFontSize: 40,
catalogFlag: false, // 控制目录的显隐
descFlag: false, // 是否倒序排序
sivId: null, // 打开目录时跳转至位置
curCaches: [], // 缓存的章节id
isCacheing: false, // 是否缓存中
}
},
computed: {
...mapGetters({
setting: 'get_setting',
curSource: 'get_curSource',
}),
},
watch: {
curCaches: {
handler(nVal, oVal) {
if (nVal.length === this.chapterData.length) {
this.isCacheing = false
}
},
deep: true,
immediate: true
}
},
methods: {
...mapMutations(['set_setting']),
// 显示操作菜单
async show() {
this.menuFlag = true
if (this.chapterData && this.chapterData.length > 0) {
// 从缓存获取信息
// bookChapterCache
let bcc = await this.$fileReader(`_bcc_${this.curSource.value}_${this.chapterData[0].id}`)
this.curCaches = JSON.parse(bcc || '[]')
}
},
hide() {
this.menuFlag = false
this.settingFlag = false
this.$emit('whenHide')
},
// 章节目录的显示
catalogHandle() {
this.catalogFlag = true
this.settingFlag = false
this.hide()
this.$nextTick(function() {
this.sivId = this.chapterIndex === 0 ? 0 : this.chapterIndex - 5
})
},
// 夜间/日间
darkHandle() {
this.$emit('updateProps', [
['isDark', !this.isDark],
])
this.changeBackground(this.colorType, !this.isDark)
},
// 缓存
async cacheHandle() {
if (this.isCacheing) {
return
}
if (this.curCaches.length === this.chapterData.length) {
return
}
this.isCacheing = true
for (let chapter of this.chapterData) {
if (this.curCaches.includes(chapter.index)) {
continue
}
await this.doBookContent(chapter)
}
this.isCacheing = false
},
async doBookContent(params, num = 0) {
if (num === 20) {
return false
}
let res = await this.$store.dispatch('getBookContent', params)
if (res) {
this.curCaches.push(params.index)
return true
} else {
num += 1
await this.doBookContent(params, num)
}
},
// 设置
settingHandle() {
this.settingFlag = !this.settingFlag
},
// 听书
listenHandle() {
this.$emit('listenHandle')
},
changeFontSize(num) {
this.$emit('updateProps', [
['fontSize', this.fontSize + num],
])
this.$emit('updatePage')
},
changeBackground(index, isDark) {
if (isDark) {
this.$emit('updateProps', [
['bgColor', this.darkBgColor],
['textColor', this.darkTextColor]
])
} else {
this.$emit('updateProps', [
['bgColor', this.bgColorList[index], true],
['textColor', this.textColorList[index], true],
['colorType', index],
])
}
},
changeTurnType(index) {
this.$emit('updateProps', [
['turnType', index],
])
},
// 点击某一章节目录
async clickCatalog(index) {
this.catalogFlag = false
this.sivId = index
this.$emit('updateCatalog', index)
},
// 排序
sortHandle() {
this.descFlag = !this.descFlag
},
moreHandle() {
this.$emit('moreHandle')
},
}
}
</script>
<style lang="scss">
.fixed {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: transparent;
z-index: 1024;
}
.menu {
.bottom {
position: absolute;
width: 100%;
height: 80px;
bottom: 0;
display: flex;
justify-content: space-around;
align-items: center;
font-size: 11px;
.item {
width: 100%;
height: 80px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.iconfont {
font-size: 21px;
}
text {
line-height: 21px;
}
}
}
.setting {
position: absolute;
bottom: 80px;
width: 100%;
padding: 20px 0;
background-color: rgba($color: #000000, $alpha: 0.8);
font-size: 11px;
.line {
padding: 0 40rpx;
display: flex;
justify-content: flex-start;
align-items: center;
.title {
margin-right: 40rpx;
}
.background+.background {
margin-left: 30px;
}
}
.line+.line {
padding-top: 24px;
}
}
}
.catalog {
width: 600rpx;
.mask {
position: fixed;
width: 100%;
height: 100%;
background-color: #000000;
opacity: 0.5;
}
.catalog-content {
position: absolute;
width: 100%;
height: 100%;
padding-top: var(--status-bar-height);
.order {
position: sticky;
top: 0;
padding: 32rpx 40rpx;
text-align: right;
font-size: 50rpx;
line-height: 56rpx;
}
.scroll-view {
height: calc(100% - 120rpx);
box-sizing: border-box;
opacity: 1;
.item {
padding: 0 10px;
height: 36px;
line-height: 36px;
font-size: 12px;
white-space: nowrap;
overflow: hidden;
display: flex;
justify-content: space-between;
align-items: center;
.chapter-name {
width: 480rpx;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
}
.listen {
position: fixed;
bottom: 120px;
right: 20px;
width: 60px;
height: 60px;
line-height: 60px;
border-radius: 50%;
background-color: #6b6b6b;
text-align: center;
font-size: 30px;
z-index: 999;
}
.reverse {
display: flex;
flex-direction: column-reverse;
}
.text-gray {
color: #999999;
}
.text-red {
color: #ff0000;
}
</style>