diff --git a/README.md b/README.md index 7bafd07..eb574cd 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,13 @@ Options: "root": "/opds" }, + // страница для скачивания свежего релиза + "latestReleaseLink": "https://github.com/bookpauk/inpx-web/releases/latest", + + // api для проверки новой версии, + // пустая строка - отключить проверку выхода новых версий + "checkReleaseLink": "https://api.github.com/repos/bookpauk/inpx-web/releases/latest", + // настройки по умолчанию для веб-интерфейса // устанавливаются при первой загрузке страницы в браузере // дальнейшие изменения настроек с помощью веб-интерфейса уже сохраняются в самом браузере @@ -188,7 +195,8 @@ Options: "showDeleted": false, // показывать удаленные "abCacheEnabled": true, // кешировать запросы "langDefault": "", // язык по умолчанию (например "ru,en") - "showJson": false // показывать JSON (в расширенном поиске) + "showJson": false, // показывать JSON (в расширенном поиске) + "showNewReleaseAvailable": true // уведомлять о выходе новой версии } } ``` diff --git a/client/components/Search/Search.vue b/client/components/Search/Search.vue index d995ab9..90d71e9 100644 --- a/client/components/Search/Search.vue +++ b/client/components/Search/Search.vue @@ -3,6 +3,19 @@
+ +
+
+ Доступна новая версия {{ config.name }} v{{ config.latestVersion }} +
+ + Скачать + + + Отключить уведомление + +
+
@@ -504,6 +517,7 @@ class Search { limit = 20; extendedParams = false; showJson = false; + showNewReleaseAvailable = true; //stuff prevList = {}; @@ -555,6 +569,7 @@ class Search { mounted() { (async() => { + //для срабатывания watch.config await this.api.updateConfig(); //устанавливаем uiDefaults от сервера, если это необходимо @@ -604,6 +619,7 @@ class Search { this.abCacheEnabled = settings.abCacheEnabled; this.langDefault = settings.langDefault; this.showJson = settings.showJson; + this.showNewReleaseAvailable = settings.showNewReleaseAvailable; } recvMessage(d) { @@ -631,6 +647,10 @@ class Search { return this.$store.state.config; } + get newReleaseAvailable() { + return (this.config.latestVersion && this.config.version != this.config.latestVersion); + } + get recStruct() { if (this.config.dbConfig && this.config.dbConfig.inpxInfo.recStruct) return this.config.dbConfig.inpxInfo.recStruct; @@ -728,14 +748,19 @@ class Search { } openReleasePage() { - window.open('https://github.com/bookpauk/inpx-web/releases', '_blank'); + if (this.config.latestReleaseLink) + window.open(this.config.latestReleaseLink, '_blank'); } makeProjectName() { const collection = this.config.dbConfig.inpxInfo.collection.split('\n'); this.collection = collection[0].trim(); - this.projectName = `${this.config.name} v${this.config.webAppVersion}`; + let projectName = `${this.config.name} v${this.config.webAppVersion}`; + if (this.newReleaseAvailable) + projectName += `, доступно обновление: v${this.config.latestVersion}`; + + this.projectName = projectName; this.makeTitle(); } diff --git a/client/components/Search/SettingsDialog/SettingsDialog.vue b/client/components/Search/SettingsDialog/SettingsDialog.vue index 42e8074..f7bfbc3 100644 --- a/client/components/Search/SettingsDialog/SettingsDialog.vue +++ b/client/components/Search/SettingsDialog/SettingsDialog.vue @@ -19,6 +19,7 @@ />
+ @@ -85,6 +86,9 @@ const componentOptions = { abCacheEnabled(newValue) { this.commit('setSettings', {'abCacheEnabled': newValue}); }, + showNewReleaseAvailable(newValue) { + this.commit('setSettings', {'showNewReleaseAvailable': newValue}); + }, } }; class SettingsDialog { @@ -105,6 +109,7 @@ class SettingsDialog { showDates = true; showDeleted = false; abCacheEnabled = true; + showNewReleaseAvailable = true; limitOptions = [ {label: '10', value: 10}, @@ -125,6 +130,10 @@ class SettingsDialog { mounted() { } + get config() { + return this.$store.state.config; + } + get settings() { return this.$store.state.settings; } @@ -142,6 +151,7 @@ class SettingsDialog { this.showDates = settings.showDates; this.showDeleted = settings.showDeleted; this.abCacheEnabled = settings.abCacheEnabled; + this.showNewReleaseAvailable = settings.showNewReleaseAvailable; } okClick() { diff --git a/client/components/share/DivBtn.vue b/client/components/share/DivBtn.vue index fa4c841..f7583df 100644 --- a/client/components/share/DivBtn.vue +++ b/client/components/share/DivBtn.vue @@ -89,8 +89,10 @@ export default vueComponent(DivBtn); } .button-pressed { - margin-left: 2px; - margin-top: 2px; + margin-left: 1px; + margin-top: 1px; + margin-right: -1px; + margin-bottom: -1px; } .clickable { diff --git a/client/store/root.js b/client/store/root.js index 357d2c0..71082f7 100644 --- a/client/store/root.js +++ b/client/store/root.js @@ -21,6 +21,7 @@ const state = { abCacheEnabled: true, langDefault: '', showJson: false, + showNewReleaseAvailable: true, }, }; diff --git a/server/config/base.js b/server/config/base.js index c349dd0..2cf732b 100644 --- a/server/config/base.js +++ b/server/config/base.js @@ -6,6 +6,7 @@ const execDir = path.resolve(__dirname, '..'); module.exports = { branch: 'unknown', version: pckg.version, + latestVersion: '', name: pckg.name, execDir, @@ -19,7 +20,7 @@ module.exports = { loggingEnabled: true, //поправить в случае, если были критические изменения в DbCreator или InpxParser - //иначе будет рассинхронизация между сервером и клиентом на уровне БД + //иначе будет рассинхронизация по кешу между сервером и клиентом на уровне БД dbVersion: '11', dbCacheSize: 5, @@ -33,7 +34,7 @@ module.exports = { lowMemoryMode: false, fullOptimization: false, - webConfigParams: ['name', 'version', 'branch', 'bookReadLink', 'dbVersion', 'extendedSearch', 'uiDefaults'], + webConfigParams: ['name', 'version', 'latestVersion', 'branch', 'bookReadLink', 'dbVersion', 'extendedSearch', 'latestReleaseLink', 'uiDefaults'], allowRemoteLib: false, remoteLib: false, @@ -57,6 +58,10 @@ module.exports = { password: '', root: '/opds', }, + + latestReleaseLink: 'https://github.com/bookpauk/inpx-web/releases/latest', + checkReleaseLink: 'https://api.github.com/repos/bookpauk/inpx-web/releases/latest', + uiDefaults: { limit: 20, downloadAsZip: false, @@ -69,6 +74,7 @@ module.exports = { abCacheEnabled: true, langDefault: '', showJson: false, + showNewReleaseAvailable: true, }, }; diff --git a/server/config/index.js b/server/config/index.js index b6549a5..902eded 100644 --- a/server/config/index.js +++ b/server/config/index.js @@ -25,6 +25,8 @@ const propsToSave = [ 'remoteLib', 'server', 'opds', + 'latestReleaseLink', + 'checkReleaseLink', 'uiDefaults', ]; diff --git a/server/core/WebWorker.js b/server/core/WebWorker.js index 657d177..06c4bb8 100644 --- a/server/core/WebWorker.js +++ b/server/core/WebWorker.js @@ -10,6 +10,7 @@ const DbCreator = require('./DbCreator'); const DbSearcher = require('./DbSearcher'); const InpxHashCreator = require('./InpxHashCreator'); const RemoteLib = require('./RemoteLib');//singleton +const FileDownloader = require('./FileDownloader'); const asyncExit = new (require('./AsyncExit'))(); const log = new (require('./AppLogger'))().log;//singleton @@ -28,7 +29,8 @@ const stateToText = { [ssDbCreating]: 'Создание поисковой базы', }; -const cleanDirPeriod = 60*60*1000;//каждый час +const cleanDirInterval = 60*60*1000;//каждый час +const checkReleaseInterval = 2*60*60*1000;//каждые 2 часа //singleton let instance = null; @@ -67,6 +69,7 @@ class WebWorker { this.periodicCleanDir(dirConfig);//no await this.periodicCheckInpx();//no await + this.periodicCheckNewRelease();//no await instance = this; } @@ -638,7 +641,7 @@ class WebWorker { let lastCleanDirTime = 0; while (1) {// eslint-disable-line no-constant-condition //чистка папок - if (Date.now() - lastCleanDirTime >= cleanDirPeriod) { + if (Date.now() - lastCleanDirTime >= cleanDirInterval) { for (const config of dirConfig) { try { await this.cleanDir(config); @@ -690,6 +693,27 @@ class WebWorker { await utils.sleep(inpxCheckInterval*60*1000); } } + + async periodicCheckNewRelease() { + const checkReleaseLink = this.config.checkReleaseLink; + if (!checkReleaseLink) + return; + const down = new FileDownloader(1024*1024); + + while (1) {// eslint-disable-line no-constant-condition + try { + let release = await down.load(checkReleaseLink); + release = JSON.parse(release.toString()); + + if (release.tag_name) + this.config.latestVersion = release.tag_name; + } catch(e) { + log(LM_ERR, `periodicCheckNewRelease: ${e.message}`); + } + + await utils.sleep(checkReleaseInterval); + } + } } module.exports = WebWorker; \ No newline at end of file