diff --git a/client/api/reader.js b/client/api/reader.js index 4e7a99da..b8081bd8 100644 --- a/client/api/reader.js +++ b/client/api/reader.js @@ -5,11 +5,11 @@ import {Buffer} from 'safe-buffer'; import * as utils from '../share/utils'; const api = axios.create({ - baseURL: '/api/reader' + baseURL: '/api/reader' }); const workerApi = axios.create({ - baseURL: '/api/worker' + baseURL: '/api/worker' }); class Reader { diff --git a/client/components/Reader/HelpPage/DonateHelpPage/DonateHelpPage.vue b/client/components/Reader/HelpPage/DonateHelpPage/DonateHelpPage.vue index 9b7bdc14..637ce6e7 100644 --- a/client/components/Reader/HelpPage/DonateHelpPage/DonateHelpPage.vue +++ b/client/components/Reader/HelpPage/DonateHelpPage/DonateHelpPage.vue @@ -53,11 +53,10 @@ class DonateHelpPage extends Vue { async copyAddress(address, prefix) { const result = await copyTextToClipboard(address); - const msg = (result ? `${prefix}-адрес ${address} успешно скопирован в буфер обмена` : 'Копирование не удалось'); if (result) - this.$notify.success({message: msg}); + this.$notify.success({message: `${prefix}-адрес ${address} успешно скопирован в буфер обмена`}); else - this.$notify.error({message: msg}); + this.$notify.error({message: 'Копирование не удалось'}); } } //----------------------------------------------------------------------------- diff --git a/client/components/Reader/HelpPage/HelpPage.vue b/client/components/Reader/HelpPage/HelpPage.vue index e3273813..98d6aafb 100644 --- a/client/components/Reader/HelpPage/HelpPage.vue +++ b/client/components/Reader/HelpPage/HelpPage.vue @@ -16,6 +16,9 @@ + + + @@ -36,6 +39,7 @@ import CommonHelpPage from './CommonHelpPage/CommonHelpPage.vue'; import HotkeysHelpPage from './HotkeysHelpPage/HotkeysHelpPage.vue'; import MouseHelpPage from './MouseHelpPage/MouseHelpPage.vue'; import DonateHelpPage from './DonateHelpPage/DonateHelpPage.vue'; +import VersionHistoryPage from './VersionHistoryPage/VersionHistoryPage.vue'; export default @Component({ components: { @@ -44,6 +48,7 @@ export default @Component({ HotkeysHelpPage, MouseHelpPage, DonateHelpPage, + VersionHistoryPage, }, }) class HelpPage extends Vue { @@ -57,6 +62,10 @@ class HelpPage extends Vue { this.selectedTab = 'donate'; } + activateVersionHistoryHelpPage() { + this.selectedTab = 'releases'; + } + keyHook(event) { if (event.type == 'keydown' && (event.code == 'Escape')) { this.close(); diff --git a/client/components/Reader/HelpPage/VersionHistoryPage/VersionHistoryPage.vue b/client/components/Reader/HelpPage/VersionHistoryPage/VersionHistoryPage.vue new file mode 100644 index 00000000..3b42f24e --- /dev/null +++ b/client/components/Reader/HelpPage/VersionHistoryPage/VersionHistoryPage.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/client/components/Reader/LoaderPage/LoaderPage.vue b/client/components/Reader/LoaderPage/LoaderPage.vue index 3f2bedfb..160d792c 100644 --- a/client/components/Reader/LoaderPage/LoaderPage.vue +++ b/client/components/Reader/LoaderPage/LoaderPage.vue @@ -18,6 +18,10 @@ Загрузить файл с диска
+ + Из буфера обмена + +
Комментарии @@ -26,6 +30,8 @@ Помочь проекту {{ version }} + + @@ -33,12 +39,17 @@ //----------------------------------------------------------------------------- import Vue from 'vue'; import Component from 'vue-class-component'; +import PasteTextPage from './PasteTextPage/PasteTextPage.vue'; export default @Component({ + components: { + PasteTextPage, + }, }) class LoaderPage extends Vue { bookUrl = null; loadPercent = 0; + pasteTextActive = false; created() { this.commit = this.$store.commit; @@ -83,12 +94,27 @@ class LoaderPage extends Vue { } loadFile() { - const file = this.$refs.file.files[0]; + const file = this.$refs.file.files[0]; this.$refs.file.value = ''; if (file) this.$emit('load-file', {file}); } + loadBufferClick() { + this.pasteTextToggle(); + } + + loadBuffer(opts) { + if (opts.buffer.length) { + const file = new File([opts.buffer], 'dummyName-PasteFromClipboard'); + this.$emit('load-file', {file}); + } + } + + pasteTextToggle() { + this.pasteTextActive = !this.pasteTextActive; + } + openHelp() { this.$emit('help-toggle'); } @@ -102,6 +128,10 @@ class LoaderPage extends Vue { } keyHook(event) { + if (this.pasteTextActive) { + return this.$refs.pasteTextPage.keyHook(event); + } + //недостатки сторонних ui const input = this.$refs.input.$refs.input; if (document.activeElement === input && event.type == 'keydown' && event.code == 'Enter') { diff --git a/client/components/Reader/LoaderPage/PasteTextPage/PasteTextPage.vue b/client/components/Reader/LoaderPage/PasteTextPage/PasteTextPage.vue new file mode 100644 index 00000000..b17fcd05 --- /dev/null +++ b/client/components/Reader/LoaderPage/PasteTextPage/PasteTextPage.vue @@ -0,0 +1,133 @@ + + + + + diff --git a/client/components/Reader/Reader.vue b/client/components/Reader/Reader.vue index bbef9b77..b0caaf99 100644 --- a/client/components/Reader/Reader.vue +++ b/client/components/Reader/Reader.vue @@ -7,35 +7,35 @@
- + - +
- + - + - + - + - + - +
- +
@@ -68,13 +68,27 @@ @start-text-search="startTextSearch" @stop-text-search="stopTextSearch"> - + + + +
+ + Посмотреть историю версий + + Больше не показывать + +
+ + @@ -101,6 +115,7 @@ import ServerStorage from './ServerStorage/ServerStorage.vue'; import bookManager from './share/bookManager'; import readerApi from '../../api/reader'; import * as utils from '../../share/utils'; +import {versionHistory} from './versionHistory'; export default @Component({ components: { @@ -167,11 +182,15 @@ class Reader extends Vue { allowUrlParamBookPos = false; showRefreshIcon = true; mostRecentBookReactive = null; + showToolButton = {}; actionList = []; actionCur = -1; hidden = false; + whatsNewVisible = false; + whatsNewContent = ''; + created() { this.loading = true; this.commit = this.$store.commit; @@ -223,14 +242,17 @@ class Reader extends Vue { if (this.$root.rootRoute == '/reader') { if (this.routeParamUrl) { - await this.loadBook({url: this.routeParamUrl, bookPos: this.routeParamPos}); + await this.loadBook({url: this.routeParamUrl, bookPos: this.routeParamPos, force: this.routeParamRefresh}); } else { this.loaderActive = true; } } this.checkSetStorageAccessKey(); + this.checkActivateDonateHelpPage(); this.loading = false; + + await this.showWhatsNew(); })(); } @@ -241,6 +263,8 @@ class Reader extends Vue { this.showClickMapPage = settings.showClickMapPage; this.clickControl = settings.clickControl; this.blinkCachedLoad = settings.blinkCachedLoad; + this.showWhatsNewDialog = settings.showWhatsNewDialog; + this.showToolButton = settings.showToolButton; } checkSetStorageAccessKey() { @@ -257,6 +281,56 @@ class Reader extends Vue { } } + checkActivateDonateHelpPage() { + const q = this.$route.query; + + if (q['donate']) { + this.$router.replace(`/reader`); + this.helpToggle(); + this.$nextTick(() => { + this.$refs.helpPage.activateDonateHelpPage(); + }); + } + } + + checkBookPosPercent() { + const q = this.$route.query; + if (q['__pp']) { + let pp = q['__pp']; + if (pp) { + pp = parseFloat(pp) || 0; + const recent = this.mostRecentBook(); + (async() => { + await utils.sleep(100); + this.bookPos = Math.floor(recent.textLength*pp/100); + })(); + } + } + } + + async showWhatsNew() { + await utils.sleep(2000); + + const whatsNew = versionHistory[0]; + if (this.showWhatsNewDialog && + whatsNew.showUntil >= utils.formatDate(new Date(), 'coDate') && + whatsNew.header != this.whatsNewContentHash) { + this.whatsNewContent = 'Версия ' + whatsNew.header + whatsNew.content; + this.whatsNewVisible = true; + } + } + + openVersionHistory() { + this.whatsNewVisible = false; + this.versionHistoryToggle(); + } + + whatsNewDisable() { + this.whatsNewVisible = false; + const whatsNew = versionHistory[0]; + this.commit('reader/setWhatsNewContentHash', whatsNew.header); + } + get routeParamPos() { let result = undefined; const q = this.$route.query; @@ -293,6 +367,11 @@ class Reader extends Vue { return decodeURIComponent(result); } + get routeParamRefresh() { + const q = this.$route.query; + return !!q['__refresh']; + } + bookPosChanged(event) { if (event.bookPosSeen !== undefined) this.bookPosSeen = event.bookPosSeen; @@ -353,6 +432,10 @@ class Reader extends Vue { return this.$store.state.reader.settings; } + get whatsNewContentHash() { + return this.$store.state.reader.whatsNewContentHash; + } + addAction(pos) { let a = this.actionList; if (!a.length || a[a.length - 1] != pos) { @@ -523,6 +606,15 @@ class Reader extends Vue { } } + versionHistoryToggle() { + this.helpToggle(); + if (this.helpActive) { + this.$nextTick(() => { + this.$refs.helpPage.activateVersionHistoryHelpPage(); + }); + } + } + refreshBook() { if (this.mostRecentBook()) { this.loadBook({url: this.mostRecentBook().url, force: true}); @@ -708,7 +800,7 @@ class Reader extends Vue { this.progressActive = true; - await this.$nextTick() + await this.$nextTick(); const progress = this.$refs.page; @@ -743,6 +835,7 @@ class Reader extends Vue { progress.hide(); this.progressActive = false; this.blinkCachedLoadMessage(); + this.checkBookPosPercent(); await this.activateClickMapPage(); return; } @@ -791,6 +884,7 @@ class Reader extends Vue { } else this.stopBlink = true; + this.checkBookPosPercent(); await this.activateClickMapPage(); } catch (e) { progress.hide(); this.progressActive = false; @@ -1010,4 +1104,10 @@ i { .clear { color: rgba(0,0,0,0); } - \ No newline at end of file + +.clickable { + color: blue; + text-decoration: underline; + cursor: pointer; +} + diff --git a/client/components/Reader/SettingsPage/SettingsPage.vue b/client/components/Reader/SettingsPage/SettingsPage.vue index 67ee8932..a2d3af99 100644 --- a/client/components/Reader/SettingsPage/SettingsPage.vue +++ b/client/components/Reader/SettingsPage/SettingsPage.vue @@ -106,6 +106,7 @@ + @@ -345,6 +346,28 @@ + + + +
Показывать кнопки панели
+ + + {{item.text}} + +
+
+ + + + +
Управление
+ + + Включить управление кликом + +
+
+ @@ -380,14 +403,12 @@ - + - - Включить управление кликом - +
Подсказки, уведомления
@@ -406,7 +427,7 @@ Предупреждать о загрузке из кэша - +