Работа над BookInfoDialog

This commit is contained in:
Book Pauk
2022-11-10 17:17:56 +07:00
parent 81d8b476a5
commit 391fb3aa70
3 changed files with 177 additions and 25 deletions

View File

@@ -9,9 +9,57 @@
</template>
<div ref="box" class="fit column q-mt-xs overflow-auto no-wrap" style="padding: 0px 10px 10px 10px;">
<div class="row" style="height: 300px">
<div style="height: 300px">
<img v-if="coverSrc" :src="coverSrc" style="height: 100%;" />
<div class="text-green-10">
{{ bookAuthor }}
</div>
<div>
<b>{{ book.title }}</b>
</div>
<div class="row q-mt-sm no-wrap">
<div class="column justify-center" style="height: 300px; width: 200px;">
<img v-if="coverSrc" :src="coverSrc" class="fit row justify-center items-center" style="object-fit: contain" @error="coverSrc = ''" />
<div v-if="!coverSrc" class="fit row justify-center items-center text-grey-5" style="border: 1px solid #ccc; font-size: 300%">
<i>{{ book.ext }}</i>
</div>
</div>
<div class="col column q-ml-sm" style="min-width: 300px; border: 1px solid #ccc">
<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="bg-grey-4 text-grey-7"
>
<q-tab name="fb2" label="Fb2 инфо" />
<q-tab name="inpx" label="Inpx инфо" />
</q-tabs>
</div>
<div class="overflow-auto full-width" style="height: 262px">
<div v-for="item in info" :key="item.name">
<div class="row q-ml-sm q-mt-sm items-center">
<div class="text-blue" style="font-size: 90%">
{{ item.label }}
</div>
<div class="col q-mx-xs" style="height: 0px; border-top: 1px solid #ccc" />
</div>
<div v-for="subItem in item.value" :key="subItem.name" class="row q-ml-md">
<div style="width: 110px">
{{ subItem.label }}
</div>
<div class="q-ml-sm">
{{ subItem.value }}
</div>
</div>
</div>
</div>
</div>
</div>
@@ -40,13 +88,12 @@ const componentOptions = {
watch: {
modelValue(newValue) {
this.dialogVisible = newValue;
if (newValue)
this.init();
},
dialogVisible(newValue) {
this.$emit('update:modelValue', newValue);
},
bookInfo() {
this.parseBookInfo();
}
}
};
class BookInfoDialog {
@@ -57,28 +104,125 @@ class BookInfoDialog {
};
dialogVisible = false;
selectedTab = 'fb2';
//info props
coverSrc = '';
annotation = '';
info = [];
fb2 = [];
book = {};
created() {
this.commit = this.$store.commit;
this.parseBookInfo();
}
mounted() {
}
parseBookInfo() {
const bookInfo = this.bookInfo;
const parser = new Fb2Parser();
init() {
//defaults
this.coverSrc = '';
this.annotation = '';
this.info = [];
this.fb2 = [];
this.book = {};
this.parseBookInfo();
}
get bookAuthor() {
if (this.book.author) {
let a = this.book.author.split(',');
return a.slice(0, 3).join(', ') + (a.length > 3 ? ' и др.' : '');
}
return '';
}
get inpx() {
const mapping = [
{name: 'fileInfo', label: 'Информация о файле', value: [
{name: 'folder', label: 'Папка'},
{name: 'file', label: 'Файл'},
{name: 'size', label: 'Размер'},
{name: 'date', label: 'Добавлен'},
]},
];
/*
{name: 'author', label: 'Автор(ы)'},
{name: 'bookTitle', label: 'Название'},
{name: 'sequenceName', label: 'Серия'},
{name: 'sequenceNum', label: 'Номер в серии'},
{name: 'genre', label: 'Жанр'},
{name: 'date', label: 'Дата'},
{name: 'lang', label: 'Язык книги'},
{name: 'srcLang', label: 'Язык оригинала'},
{name: 'translator', label: 'Переводчик(и)'},
{name: 'keywords', label: 'Ключевые слова'},
{"author":"Грант Максвелл",
"genre":"det_hard",
"title":"Tower of Death",
"series":"The Shadow[a]",
"serno":53,
"file":"641310",
"size":420422,
"libid":"641310",
"del":0,
"ext":"fb2",
"date":"2021-11-04",
"insno":181,
"folder":"f.fb2-641019-643928.zip",
"lang":"en",
"librate":0,
"keywords":"Hard-Boiled, Pulp Fiction,det",
*/
const valueToString = (value, nodePath) => {//eslint-disable-line no-unused-vars
if (typeof(value) === 'string') {
return value;
}
return value;
};
let result = [];
for (const item of mapping) {
const itemOut = {name: item.name, label: item.label, value: []};
for (const subItem of item.value) {
const subItemOut = {
name: subItem.name,
label: subItem.label,
value: valueToString(this.book[subItem.name], `${item.name}/${subItem.name}`)
};
if (subItemOut.value)
itemOut.value.push(subItemOut);
}
if (itemOut.value.length)
result.push(itemOut);
}
return result;
}
get info() {
let result = [];
switch (this.selectedTab) {
case 'fb2':
return this.fb2;
case 'inpx':
return this.inpx;
}
return result;
}
parseBookInfo() {
const bookInfo = this.bookInfo;
const parser = new Fb2Parser();
//cover
if (bookInfo.cover)
@@ -86,10 +230,10 @@ class BookInfoDialog {
//fb2
if (bookInfo.fb2) {
this.info = parser.bookInfoList(bookInfo.fb2);
this.fb2 = parser.bookInfoList(bookInfo.fb2);
const infoObj = parser.bookInfo(bookInfo.fb2);
if (infoObj) {
if (infoObj.titleInfo) {
let ann = infoObj.titleInfo.annotationHtml;
if (ann) {
ann = ann.replace(/<p>/g, `<p class="p-annotation">`);
@@ -97,6 +241,10 @@ class BookInfoDialog {
}
}
}
//book
if (bookInfo.book)
this.book = bookInfo.book;
}
okClick() {

View File

@@ -17,7 +17,7 @@ import {QBtn} from 'quasar/src/components/btn';
import {QBtnToggle} from 'quasar/src/components/btn-toggle';
import {QIcon} from 'quasar/src/components/icon';
//import {QSlider} from 'quasar/src/components/slider';
//import {QTabs, QTab} from 'quasar/src/components/tabs';
import {QTabs, QTab} from 'quasar/src/components/tabs';
//import {QTabPanels, QTabPanel} from 'quasar/src/components/tab-panels';
//import {QSeparator} from 'quasar/src/components/separator';
//import {QList} from 'quasar/src/components/item';
@@ -52,7 +52,7 @@ const components = {
QBtnToggle,
QIcon,
//QSlider,
//QTabs, QTab,
QTabs, QTab,
//QTabPanels, QTabPanel,
//QSeparator,
//QList,

View File

@@ -79,10 +79,10 @@ class Fb2Parser extends XmlParser {
info.translator = parseAuthors('translator');
const seqAttrs = titleInfo.attrs('sequence') || new Map();
info.sequenceName = seqAttrs.get('name') || null;
info.sequenceNum = seqAttrs.get('number') || null;
info.sequenceLang = seqAttrs.get('xml:lang') || null;
const seqAttrs = titleInfo.attrs('sequence') || {};
info.sequenceName = seqAttrs['name'] || null;
info.sequenceNum = seqAttrs['number'] || null;
info.sequenceLang = seqAttrs['xml:lang'] || null;
result.titleInfo = info;
}
@@ -141,12 +141,16 @@ class Fb2Parser extends XmlParser {
continue;
for (const subItem of item.value) {
if (info[subItem.name] !== null)
itemOut.value.push({
if (info[subItem.name] !== null) {
const subItemOut = {
name: subItem.name,
label: subItem.label,
value: valueToString(info[subItem.name])
});
value: valueToString(info[subItem.name], `${item.name}/${subItem.name}`)
};
if (subItemOut.value)
itemOut.value.push(subItemOut);
}
}
if (itemOut.value.length)