Эх сурвалжийг харах

Merge branch 'release/1.1.3'

Book Pauk 2 жил өмнө
parent
commit
1370bae4d6

+ 2 - 2
client/components/Reader/LibsPage/LibsPage.vue

@@ -34,8 +34,8 @@ class LibsPage {
         if (!this.mode)
             return;
 
-        //TODO: убрать второе условие в 24г
-        if (!this.libs || (this.mode === 'omnireader' && this.libs.mode !== this.mode)) {
+        //TODO: убрать условие с mode в 24г
+        if (!this.libs || !this.libs.groups || (this.mode === 'omnireader' && this.libs.mode !== this.mode)) {
             const defaults = rstore.getLibsDefaults(this.mode);
             this.commit('reader/setLibs', defaults);
         }

+ 113 - 97
client/components/Reader/Reader.vue

@@ -393,6 +393,9 @@ class Reader {
                 this.recentItemKeys = [];
                 //сохранение в удаленном хранилище
                 await this.$refs.serverStorage.saveRecent(itemKeys);
+
+                //periodicTasks
+                this.periodicTasks();//no await
             } catch (e) {
                 if (!this.offlineModeActive)
                     this.$root.notify.error(e.message);
@@ -442,26 +445,15 @@ class Reader {
             this.$refs.recentBooksPage.init();
         })();
 
-        //проверки обновлений читалки
+        //единственный запуск periodicTasks при инициализации
+        //дальнейшие запуски periodicTasks выполняются из debouncedSaveRecent
+        //т.е. только по действию пользователя
         (async() => {
+            await utils.sleep(15*1000);
             this.isFirstNeedUpdateNotify = true;
-            //вечный цикл, запрашиваем периодически конфиг для проверки выхода новой версии читалки
-            while (1) {// eslint-disable-line no-constant-condition
-                await this.checkNewVersionAvailable();
-                await utils.sleep(60*60*1000); //каждый час
-            }
-            //дальше хода нет
-        })();
 
-        //проверки обновлений книг
-        (async() => {
-            await utils.sleep(15*1000); //подождем неск. секунд перед первым запросом
-            //вечный цикл, запрашиваем периодически обновления
-            while (1) {// eslint-disable-line no-constant-condition
-                await this.checkBuc();
-                await utils.sleep(70*60*1000); //каждые 70 минут
-            }
-            //дальше хода нет
+            this.allowPeriodicTasks = true;
+            this.periodicTasks();//no await
         })();
     }
 
@@ -560,26 +552,56 @@ class Reader {
         }
     }
 
-    async checkNewVersionAvailable() {
-        if (!this.checkingNewVersion && this.showNeedUpdateNotify) {
-            this.checkingNewVersion = true;
-            try {
-                await utils.sleep(15*1000); //подождем 15 секунд, чтобы прогрузился ServiceWorker при выходе новой версии
-                const config = await miscApi.loadConfig();
-                this.commit('config/setConfig', config);
+    async periodicTasks() {
+        if (!this.allowPeriodicTasks || this.doingPeriodicTasks)
+            return;
 
-                let againMes = '';
-                if (this.isFirstNeedUpdateNotify) {
-                    againMes = ' еще один раз';
+        this.doingPeriodicTasks = true;
+        try {
+            if (!this.taskList) {
+                const taskArr = [
+                    [this.checkNewVersionAvailable, 60], //проверки обновлений читалки, каждый час
+                    [this.checkBuc, 70], //проверки обновлений книг, каждые 70 минут
+                ];
+
+                this.taskList = [];
+                for (const task of taskArr) {
+                    const [method, period] = task;
+                    this.taskList.push({method, period, lastRunTime: 0});
                 }
+            }
+
+            for (const task of this.taskList) {
+                if (Date.now() - task.lastRunTime >= task.period*60*1000) {
+                    try {
+                        //console.log('task run', task.method.name);
+                        await task.method();
+                    } catch (e) {
+                        console.error(e);
+                    }
+                    task.lastRunTime = Date.now();
+                }
+            }
+        } catch (e) {
+            console.error(e);
+        } finally {
+            this.doingPeriodicTasks = false;
+        }
+    }
+
+    async checkNewVersionAvailable() {
+        if (this.showNeedUpdateNotify) {
+            const config = await miscApi.loadConfig();
+            this.commit('config/setConfig', config);
+
+            let againMes = '';
+            if (this.isFirstNeedUpdateNotify) {
+                againMes = ' еще один раз';
+            }
+
+            if (this.version != this.clientVersion)
+                this.$root.notify.info(`Вышла новая версия (v${this.version}) читалки.<br>Пожалуйста, обновите страницу${againMes}.`, 'Обновление');
 
-                if (this.version != this.clientVersion)
-                    this.$root.notify.info(`Вышла новая версия (v${this.version}) читалки.<br>Пожалуйста, обновите страницу${againMes}.`, 'Обновление');
-            } catch(e) {
-                console.error(e);
-            } finally {
-                this.checkingNewVersion = false;
-            }        
             this.isFirstNeedUpdateNotify = false;
         }
     }
@@ -588,82 +610,78 @@ class Reader {
         if (!this.bothBucEnabled)
             return;
 
-        try {
-            const sorted = bookManager.getSortedRecent();
-
-            //выберем все кандидиаты на обновление
-            const updateUrls = new Set();
-            for (const book of sorted) {
-                if (!book.deleted && book.checkBuc && book.url && book.url.indexOf('disk://') !== 0)
-                    updateUrls.add(book.url);
-            }
+        const sorted = bookManager.getSortedRecent();
 
-            //теперь по кусочкам запросим сервер
-            const arr = Array.from(updateUrls);
-            const bucSize = {};
-            const chunkSize = 100;
-            for (let i = 0; i < arr.length; i += chunkSize) {
-                const chunk = arr.slice(i, i + chunkSize);
+        //выберем все кандидиаты на обновление
+        const updateUrls = new Set();
+        for (const book of sorted) {
+            if (!book.deleted && book.checkBuc && book.url && book.url.indexOf('disk://') !== 0)
+                updateUrls.add(book.url);
+        }
 
-                const data = await readerApi.checkBuc(chunk);
+        //теперь по кусочкам запросим сервер
+        const arr = Array.from(updateUrls);
+        const bucSize = {};
+        const chunkSize = 100;
+        for (let i = 0; i < arr.length; i += chunkSize) {
+            const chunk = arr.slice(i, i + chunkSize);
 
-                for (const item of data) {
-                    bucSize[item.id] = item.size;
-                }
+            const data = await readerApi.checkBuc(chunk);
 
-                await utils.sleep(1000);//чтобы не ддосить сервер
+            for (const item of data) {
+                bucSize[item.id] = item.size;
             }
 
-            const checkSetTime = {};
-            //проставим новые размеры у книг
-            for (const book of sorted) {
-                if (book.deleted)
-                    continue;
-                
-                //размер 0 считаем отсутствующим
-                if (book.url && bucSize[book.url] && bucSize[book.url] !== book.bucSize) {
-                    book.bucSize = bucSize[book.url];
-                    await bookManager.recentSetItem(book);
-                }
+            await utils.sleep(1000);//чтобы не ддосить сервер
+        }
 
-                //подготовка к следующему шагу, ищем книгу по url с максимальной датой установки checkBucTime/loadTime
-                //от этой даты будем потом отсчитывать bucCancelDays
-                if (updateUrls.has(book.url)) {
-                    let rec = checkSetTime[book.url] || {time: 0, loadTime: 0};
+        const checkSetTime = {};
+        //проставим новые размеры у книг
+        for (const book of sorted) {
+            if (book.deleted)
+                continue;
+            
+            //размер 0 считаем отсутствующим
+            if (book.url && bucSize[book.url] && bucSize[book.url] !== book.bucSize) {
+                book.bucSize = bucSize[book.url];
+                await bookManager.recentSetItem(book);
+            }
 
-                    const time = (book.checkBucTime ? book.checkBucTime : (rec.loadTime || 0));
-                    if (time > rec.time || (time == rec.time && (book.loadTime > rec.loadTime)))
-                        rec = {time, loadTime: book.loadTime, key: book.key};
+            //подготовка к следующему шагу, ищем книгу по url с максимальной датой установки checkBucTime/loadTime
+            //от этой даты будем потом отсчитывать bucCancelDays
+            if (updateUrls.has(book.url)) {
+                let rec = checkSetTime[book.url] || {time: 0, loadTime: 0};
 
-                    checkSetTime[book.url] = rec;
-                }
+                const time = (book.checkBucTime ? book.checkBucTime : (rec.loadTime || 0));
+                if (time > rec.time || (time == rec.time && (book.loadTime > rec.loadTime)))
+                    rec = {time, loadTime: book.loadTime, key: book.key};
+
+                checkSetTime[book.url] = rec;
             }
+        }
 
-            //bucCancelEnabled и bucCancelDays
-            //снимем флаг checkBuc у необновлявшихся bucCancelDays
-            if (this.bucCancelEnabled) {
-                for (const rec of Object.values(checkSetTime)) {
-                    if (rec.time && Date.now() - rec.time > this.bucCancelDays*24*3600*1000) {
-                        const book = await bookManager.getRecentBook({key: rec.key});
-                        const needBookUpdate = 
-                            book.checkBuc
-                            && book.bucSize
-                            && utils.hasProp(book, 'downloadSize')
-                            && book.bucSize !== book.downloadSize
-                            && (book.bucSize - book.downloadSize >= this.bucSizeDiff)
-                        ;
-
-                        if (book && !needBookUpdate) {
-                            await bookManager.setCheckBuc(book, undefined);//!!!
-                        }
+        //bucCancelEnabled и bucCancelDays
+        //снимем флаг checkBuc у необновлявшихся bucCancelDays
+        if (this.bucCancelEnabled) {
+            for (const rec of Object.values(checkSetTime)) {
+                if (rec.time && Date.now() - rec.time > this.bucCancelDays*24*3600*1000) {
+                    const book = await bookManager.getRecentBook({key: rec.key});
+                    const needBookUpdate = 
+                        book.checkBuc
+                        && book.bucSize
+                        && utils.hasProp(book, 'downloadSize')
+                        && book.bucSize !== book.downloadSize
+                        && (book.bucSize - book.downloadSize >= this.bucSizeDiff)
+                    ;
+
+                    if (book && !needBookUpdate) {
+                        await bookManager.setCheckBuc(book, undefined);//!!!
                     }
                 }
             }
-
-            await this.$refs.recentBooksPage.updateTableData();
-        } catch (e) {
-            console.error(e);
         }
+
+        await this.$refs.recentBooksPage.updateTableData();
     }
 
     updateCountChanged(event) {
@@ -1409,8 +1427,6 @@ class Reader {
             if (!this.showHelpOnErrorIfNeeded(url)) {
                 this.$root.stdDialog.alert(e.message, 'Ошибка', {color: 'negative'});
             }
-        } finally {
-            this.checkNewVersionAvailable();
         }
     }
 

+ 16 - 2
client/components/Reader/ServerStorage/ServerStorage.vue

@@ -22,10 +22,12 @@ const ssCacheStore = localForage.createInstance({
 const componentOptions = {
     watch: {
         serverSyncEnabled: function() {
-            this.serverSyncEnabledChanged();
+            if (this.inited)
+                this.serverSyncEnabledChanged();
         },
         serverStorageKey: function() {
-            this.serverStorageKeyChanged(true);
+            if (this.inited)
+                this.serverStorageKeyChanged(true);
         },
         settings: function() {
             this.debouncedSaveSettings();
@@ -85,6 +87,13 @@ class ServerStorage {
             if (!this.cachedRecentMod)
                 await this.cleanCachedRecent('cachedRecentMod');
 
+            //подстраховка хранения ключа, восстановим из IndexedDB при проблемах в localStorage
+            if (!this.serverStorageKey) {
+                const key = await ssCacheStore.getItem('storageKey');
+                if (key)
+                    this.commit('reader/setServerStorageKey', key);
+            }
+
             if (!this.serverStorageKey) {
                 //генерируем новый ключ
                 await this.generateNewServerStorageKey();
@@ -123,6 +132,7 @@ class ServerStorage {
     async generateNewServerStorageKey() {
         const key = utils.toBase58(utils.randomArray(32));
         this.commit('reader/setServerStorageKey', key);
+        //дождемся serverStorageKeyChanged, событие по watch не работает при this.inited == false
         await this.serverStorageKeyChanged(true);
     }
 
@@ -141,6 +151,10 @@ class ServerStorage {
     async serverStorageKeyChanged(force) {
         if (this.prevServerStorageKey != this.serverStorageKey) {
             this.prevServerStorageKey = this.serverStorageKey;
+
+            //сохраним ключ также в IndexedDB, чтобы была возможность восстановить при проблемах с localStorage
+            await ssCacheStore.setItem('storageKey', this.serverStorageKey);
+
             this.hashedStorageKey = utils.toBase58(cryptoUtils.sha256(this.serverStorageKey));
             this.keyInited = true;
 

+ 46 - 44
client/components/Reader/share/BookParser.js

@@ -438,61 +438,63 @@ export default class BookParser {
         };
 
         const onEndNode = (elemName) => {// eslint-disable-line no-unused-vars
-            if (tag == elemName) {
-                if (tag == 'binary') {
-                    binaryId = '';
+            tag = elemName;
+
+            if (tag == 'binary') {
+                binaryId = '';
+            }
+        
+            if (path.indexOf('/fictionbook/body') == 0) {
+                if (tag == 'title') {
+                    isFirstTitlePara = false;
+                    bold = false;
+                    center = false;
+                    inTitle = false;
                 }
-            
-                if (path.indexOf('/fictionbook/body') == 0) {
-                    if (tag == 'title') {
-                        isFirstTitlePara = false;
-                        bold = false;
-                        center = false;
-                        inTitle = false;
-                    }
 
-                    if (tag == 'section') {
-                        sectionLevel--;
-                    }
+                if (tag == 'section') {
+                    sectionLevel--;
+                }
 
-                    if (tag == 'emphasis' || tag == 'strong' || tag == 'sup' || tag == 'sub') {
-                        growParagraph(`</${tag}>`, 0);
-                    }
+                if (tag == 'emphasis' || tag == 'strong' || tag == 'sup' || tag == 'sub') {
+                    growParagraph(`</${tag}>`, 0);
+                }
 
-                    if (tag == 'p') {
-                        inPara = false;
-                    }
+                if (tag == 'p') {
+                    inPara = false;
+                }
 
-                    if (tag == 'subtitle') {
-                        isFirstTitlePara = false;
-                        bold = false;
-                        center = false;
-                        inSubtitle = false;
-                    }
+                if (tag == 'subtitle') {
+                    isFirstTitlePara = false;
+                    bold = false;
+                    center = false;
+                    inSubtitle = false;
+                }
 
-                    if (tag == 'epigraph' || tag == 'annotation') {
-                        italic = false;
-                        space -= 1;
-                        newParagraph();
-                    }
+                if (tag == 'epigraph' || tag == 'annotation') {
+                    italic = false;
+                    space -= 1;
+                    newParagraph();
+                }
 
-                    if (tag == 'stanza') {
-                        newParagraph();
-                    }
+                if (tag == 'stanza') {
+                    newParagraph();
+                }
 
-                    if (tag == 'text-author') {
-                        bold = false;
-                        space -= 1;
-                    }
+                if (tag == 'text-author') {
+                    bold = false;
+                    space -= 1;
                 }
+            }
 
-                path = path.substr(0, path.length - tag.length - 1);
-                let i = path.lastIndexOf('/');
-                if (i >= 0) {
-                    tag = path.substr(i + 1);
-                } else {
+            let i = path.lastIndexOf(tag);
+            if (i >= 0) {
+                path = path.substring(0, i - 1);
+                i = path.lastIndexOf('/');
+                if (i >= 0)
+                    tag = path.substring(i + 1);
+                else
                     tag = path;
-                }
             }
         };
 

+ 13 - 0
client/components/Reader/versionHistory.js

@@ -1,4 +1,17 @@
 export const versionHistory = [
+{
+    version: '1.1.3',
+    releaseDate: '2023-02-06',
+    showUntil: '2023-02-05',
+    content:
+`
+<ul>
+    <li>исправление багов</li>
+</ul>
+
+`
+},
+
 {
     version: '1.1.2',
     releaseDate: '2023-01-22',

+ 1 - 1
client/store/modules/reader.js

@@ -325,7 +325,7 @@ const state = {
     currentProfile: '',
     settings: _.cloneDeep(settingDefaults),
     settingsRev: {},
-    libs: false,
+    libs: {},
     libsRev: 0,
 };
 

+ 2 - 2
package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "liberama",
-  "version": "1.1.2",
+  "version": "1.1.3",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "liberama",
-      "version": "1.1.2",
+      "version": "1.1.3",
       "hasInstallScript": true,
       "license": "CC0-1.0",
       "dependencies": {

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "liberama",
-  "version": "1.1.2",
+  "version": "1.1.3",
   "author": "Book Pauk <bookpauk@gmail.com>",
   "license": "CC0-1.0",
   "repository": "bookpauk/liberama",