Добавление отображения обложки (coverpage) в окне загруженных файлов
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import axios from 'axios';
|
||||
import * as utils from '../share/utils';
|
||||
import * as cryptoUtils from '../share/cryptoUtils';
|
||||
import wsc from './webSocketConnection';
|
||||
|
||||
const api = axios.create({
|
||||
@@ -225,8 +226,20 @@ class Reader {
|
||||
return response;
|
||||
}
|
||||
|
||||
async uploadFileBuf(buf) {
|
||||
const response = await wsc.message(await wsc.send({action: 'upload-file-buf', buf}));
|
||||
async uploadFileBuf(buf, urlCallback) {
|
||||
const key = utils.toHex(cryptoUtils.sha256(buf));
|
||||
const url = `disk://${key}`;
|
||||
|
||||
if (urlCallback)
|
||||
urlCallback(url);
|
||||
|
||||
let response;
|
||||
try {
|
||||
await axios.head(`/upload/${key}`, {headers: {'Cache-Control': 'no-cache'}});
|
||||
response = await wsc.message(await wsc.send({action: 'upload-file-touch', url}));
|
||||
} catch (e) {
|
||||
response = await wsc.message(await wsc.send({action: 'upload-file-buf', buf}));
|
||||
}
|
||||
|
||||
if (response.error)
|
||||
throw new Error(response.error);
|
||||
|
||||
@@ -194,6 +194,7 @@ import ReaderDialogs from './ReaderDialogs/ReaderDialogs.vue';
|
||||
|
||||
import bookManager from './share/bookManager';
|
||||
import wallpaperStorage from './share/wallpaperStorage';
|
||||
import coversStorage from './share/coversStorage';
|
||||
import dynamicCss from '../../share/dynamicCss';
|
||||
|
||||
import rstore from '../../store/modules/reader';
|
||||
@@ -366,6 +367,8 @@ class Reader {
|
||||
mounted() {
|
||||
(async() => {
|
||||
await wallpaperStorage.init();
|
||||
await coversStorage.init();
|
||||
|
||||
await bookManager.init(this.settings);
|
||||
bookManager.addEventListener(this.bookManagerEvent);
|
||||
|
||||
|
||||
@@ -106,7 +106,8 @@
|
||||
|
||||
<div class="row-part column justify-center items-stretch" style="width: 80px">
|
||||
<div class="col row justify-center items-center clickable" @click="loadBook(item)">
|
||||
<q-icon name="la la-book" size="40px" style="color: #dddddd" />
|
||||
<div v-show="isLoadedCover(item.coverPageUrl)" v-html="getCoverHtml(item.coverPageUrl)" />
|
||||
<q-icon v-show="!isLoadedCover(item.coverPageUrl)" name="la la-book" size="40px" style="color: #dddddd" />
|
||||
</div>
|
||||
|
||||
<div v-show="!showSameBook && item.group && item.group.length > 0" class="row justify-center" style="font-size: 70%">
|
||||
@@ -213,6 +214,7 @@ import LockQueue from '../../../share/LockQueue';
|
||||
import Window from '../../share/Window.vue';
|
||||
import bookManager from '../share/bookManager';
|
||||
import readerApi from '../../../api/reader';
|
||||
import coversStorage from '../share/coversStorage';
|
||||
|
||||
const componentOptions = {
|
||||
components: {
|
||||
@@ -240,6 +242,8 @@ class RecentBooksPage {
|
||||
showSameBook = false;
|
||||
archive = false;
|
||||
|
||||
covers = {};
|
||||
|
||||
created() {
|
||||
this.commit = this.$store.commit;
|
||||
|
||||
@@ -337,6 +341,7 @@ class RecentBooksPage {
|
||||
active: (activeBook.key == book.key),
|
||||
activeParent: false,
|
||||
inGroup: false,
|
||||
coverPageUrl: book.coverPageUrl,
|
||||
|
||||
//для сортировки
|
||||
loadTimeRaw,
|
||||
@@ -654,6 +659,43 @@ class RecentBooksPage {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
makeCoverHtml(data) {
|
||||
return `<img src="${data}" style="height: 100%; width: 100%; object-fit: contain" />`;
|
||||
}
|
||||
|
||||
isLoadedCover(coverPageUrl) {
|
||||
if (!coverPageUrl)
|
||||
return false;
|
||||
|
||||
let loadedCover = this.covers[coverPageUrl];
|
||||
if (!loadedCover) {
|
||||
(async() => {
|
||||
//сначала заглянем в storage
|
||||
let data = await coversStorage.getData(coverPageUrl);
|
||||
if (data) {
|
||||
this.covers[coverPageUrl] = this.makeCoverHtml(data);
|
||||
} else {//иначе идем на сервер
|
||||
try {
|
||||
data = await readerApi.getUploadedFileBuf(coverPageUrl);
|
||||
await coversStorage.setData(coverPageUrl, data);
|
||||
this.covers[coverPageUrl] = this.makeCoverHtml(data);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
return (loadedCover != undefined);
|
||||
}
|
||||
|
||||
getCoverHtml(coverPageUrl) {
|
||||
if (coverPageUrl && this.covers[coverPageUrl])
|
||||
return this.covers[coverPageUrl];
|
||||
else
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export default vueComponent(RecentBooksPage);
|
||||
|
||||
@@ -85,6 +85,7 @@ export default class BookParser {
|
||||
let binaryId = '';
|
||||
let binaryType = '';
|
||||
let dimPromises = [];
|
||||
this.coverPageId = '';
|
||||
|
||||
//оглавление
|
||||
this.contents = [];
|
||||
@@ -289,7 +290,7 @@ export default class BookParser {
|
||||
const href = attrs.href.value;
|
||||
const alt = (attrs.alt && attrs.alt.value ? attrs.alt.value : '');
|
||||
const {id, local} = this.imageHrefToId(href);
|
||||
if (href[0] == '#') {//local
|
||||
if (local) {//local
|
||||
imageNum++;
|
||||
|
||||
if (inPara && !this.sets.showInlineImagesInCenter && !center)
|
||||
@@ -301,6 +302,11 @@ export default class BookParser {
|
||||
|
||||
if (inPara && this.sets.showInlineImagesInCenter)
|
||||
newParagraph();
|
||||
|
||||
//coverpage
|
||||
if (path == '/fictionbook/description/title-info/coverpage/image') {
|
||||
this.coverPageId = id;
|
||||
}
|
||||
} else {//external
|
||||
imageNum++;
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@ import localForage from 'localforage';
|
||||
import path from 'path-browserify';
|
||||
import _ from 'lodash';
|
||||
|
||||
import * as utils from '../../../share/utils';
|
||||
import BookParser from './BookParser';
|
||||
import readerApi from '../../../api/reader';
|
||||
import * as utils from '../../../share/utils';
|
||||
|
||||
const maxDataSize = 500*1024*1024;//compressed bytes
|
||||
const maxRecentLength = 5000;
|
||||
@@ -345,9 +346,27 @@ class BookManager {
|
||||
const parsed = new BookParser(this.settings);
|
||||
|
||||
const parsedMeta = await parsed.parse(data, callback);
|
||||
|
||||
//cover page
|
||||
let coverPageUrl = '';
|
||||
if (parsed.coverPageId && parsed.binary[parsed.coverPageId]) {
|
||||
const bin = parsed.binary[parsed.coverPageId];
|
||||
const dataUrl = await utils.resizeImage(`data:${bin.type};base64,${bin.data}`);
|
||||
|
||||
//отправим dataUrl на сервер в /upload
|
||||
try {
|
||||
await readerApi.uploadFileBuf(dataUrl, (url) => {
|
||||
coverPageUrl = url;
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
const result = Object.assign({}, meta, parsedMeta, {
|
||||
length: data.length,
|
||||
textLength: parsed.textLength,
|
||||
coverPageUrl,
|
||||
parsed
|
||||
});
|
||||
|
||||
|
||||
@@ -363,4 +363,8 @@ export function getBookTitle(fb2) {
|
||||
]).join(' - ');
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function resizeImage(dataUrl) {
|
||||
return dataUrl;
|
||||
}
|
||||
Reference in New Issue
Block a user