Работа над ContentsPage

This commit is contained in:
Book Pauk
2020-11-13 18:47:11 +07:00
parent e095c3318b
commit bd1e5485d7
4 changed files with 143 additions and 9 deletions

View File

@@ -1,8 +1,67 @@
<template>
<Window width="600px" ref="window" @close="close">
<template slot="header">
Оглавление/закладки
</template>
<div class="bg-grey-3 row">
<q-tabs
v-model="selectedTab"
active-color="black"
active-bg-color="white"
indicator-color="white"
dense
no-caps
inline-label
class="no-mp bg-grey-4 text-grey-7"
>
<q-tab name="contents" icon="la la-list" label="Оглавление" />
<q-tab name="bookmarks" icon="la la-bookmark" label="Закладки" />
</q-tabs>
</div>
<div class="q-mb-sm"/>
<div class="tab-panel" v-show="selectedTab == 'contents'">
<div>
<div class="row" v-for="item in contents" :key="item.key">
<q-expansion-item v-if="item.list.length"
class="item"
expand-icon-toggle
switch-toggle-side
expand-icon="la la-arrow-circle-down"
>
<template slot="header">
<div class="row no-wrap clickable" style="width: 470px">
<div class="q-mr-sm col overflow-hidden column justify-center" v-html="item.label"></div>
<div class="column justify-center">{{ item.perc }}%</div>
</div>
</template>
<q-item class="subitem clickable" v-for="subitem in item.list" :key="subitem.key">
<div class="row no-wrap" style="margin-left: 55px; padding-left: 60px; width: 470px">
<div class="q-mr-sm col overflow-hidden column justify-center" v-html="subitem.label"></div>
<div class="column justify-center">{{ item.perc }}%</div>
</div>
</q-item>
</q-expansion-item>
<q-item v-else class="item clickable">
<div class="row no-wrap" style="margin-left: 55px; width: 470px">
<div class="q-mr-sm col overflow-hidden column justify-center" v-html="item.label"></div>
<div class="column justify-center">{{ item.perc }}%</div>
</div>
</q-item>
<q-separator />
</div>
</div>
</div>
<div class="tab-panel" v-show="selectedTab == 'bookmarks'">
<div>
</div>
</div>
</Window>
</template>
@@ -23,11 +82,42 @@ export default @Component({
},
})
class ContentsPage extends Vue {
selectedTab = 'contents';
contents = [];
created() {
}
init() {
init(currentBook, parsed) {
this.$refs.window.init();
const prepareLabel = (title) => {
let titleParts = title.split('<p>');
const textParts = titleParts.filter(v => v).map(v => v.replace(/(&nbsp;|<([^>]+)>)/ig, ''));
return textParts.join('<br>');
}
let i = 0;
const newContents = [];
parsed.contents.forEach((cont) => {
const label = prepareLabel(cont.title);
let j = 0;
const list = [];
cont.subtitles.forEach((sub) => {
const l = prepareLabel(sub.title);
const p = parsed.para[sub.paraIndex];
list.push({perc: (p.offset/parsed.textLength*100).toFixed(2), label: l, key: j});
j++;
});
const p = parsed.para[cont.paraIndex];
newContents.push({perc: (p.offset/parsed.textLength*100).toFixed(0), label, key: i, list});
i++;
});
this.contents = newContents;
}
close() {
@@ -45,4 +135,22 @@ class ContentsPage extends Vue {
</script>
<style scoped>
.tab-panel {
overflow-x: hidden;
overflow-y: auto;
font-size: 90%;
padding: 0 10px 0px 10px;
}
.clickable {
cursor: pointer;
}
.item:hover {
background-color: #f0f0f0;
}
.subitem:hover {
background-color: #e0e0e0;
}
</style>

View File

@@ -616,10 +616,14 @@ class Reader extends Vue {
contentsPageToggle() {
this.contentsPageActive = !this.contentsPageActive;
if (this.contentsPageActive) {
const page = this.$refs.page;
if (this.contentsPageActive && this.activePage == 'TextPage' && page.parsed) {
this.closeAllWindows();
this.$refs.contentsPage.init();
this.contentsPageActive = true;
this.$nextTick(() => {
this.$refs.contentsPage.init(this.mostRecentBook(), page.parsed);
});
} else {
this.contentsPageActive = false;
}

View File

@@ -53,9 +53,11 @@ export default class BookParser {
let dimPromises = [];
//оглавление
this.contents = [];//[{paraIndex: <number>, subtitles: [{paraIndex: <number>}, ... ]}, ... ]
let curTitle = {paraIndex: -1, subtitles: []};
let curSubtitle = {paraIndex: -1};
this.contents = [];//[{paraIndex: <number>, title: <string>, subtitles: [{paraIndex: <number>, title: <string>}, ... ]}, ... ]
let curTitle = {paraIndex: -1, title: '', subtitles: []};
let curSubtitle = {paraIndex: -1, title: ''};
let inTitle = false;
let inSubtitle = false;
let paraIndex = -1;
let paraOffset = 0;
@@ -124,6 +126,12 @@ export default class BookParser {
addIndex: (addIndex ? addIndex : 0),
};
if (inSubtitle) {
curSubtitle.title += '<p>';
} else if (inTitle) {
curTitle.title += '<p>';
}
para[paraIndex] = p;
paraOffset += p.length;
};
@@ -163,6 +171,13 @@ export default class BookParser {
p.length += len;
p.text += text;
if (inSubtitle) {
curSubtitle.title += text;
} else if (inTitle) {
curTitle.title += text;
}
para[paraIndex] = p;
paraOffset += p.length;
};
@@ -218,7 +233,8 @@ export default class BookParser {
bold = true;
center = true;
curTitle = {paraIndex, subtitles: []};
inTitle = true;
curTitle = {paraIndex, title: '', subtitles: []};
this.contents.push(curTitle);
}
@@ -247,7 +263,8 @@ export default class BookParser {
bold = true;
center = true;
curSubtitle = {paraIndex};
inSubtitle = true;
curSubtitle = {paraIndex, title: ''};
curTitle.subtitles.push(curSubtitle);
}
@@ -278,6 +295,7 @@ export default class BookParser {
isFirstTitlePara = false;
bold = false;
center = false;
inTitle = false;
}
if (tag == 'emphasis' || tag == 'strong') {
@@ -292,6 +310,7 @@ export default class BookParser {
isFirstTitlePara = false;
bold = false;
center = false;
inSubtitle = false;
}
if (tag == 'epigraph') {

View File

@@ -32,6 +32,8 @@ import {QPopupProxy} from 'quasar/src/components/popup-proxy';
import {QDialog} from 'quasar/src/components/dialog';
import {QChip} from 'quasar/src/components/chip';
import {QTree} from 'quasar/src/components/tree';
import {QExpansionItem} from 'quasar/src/components/expansion-item';
const components = {
//QLayout,
@@ -58,7 +60,8 @@ const components = {
QPopupProxy,
QDialog,
QChip,
QTree
QTree,
QExpansionItem,
};
//directives