Compare commits

..

8 Commits

9 changed files with 191 additions and 39 deletions

View File

@@ -0,0 +1,59 @@
<template>
<Window ref="window" width="600px" height="95%" @close="close">
<template slot="header">
Настроить закладки
</template>
</Window>
</template>
<script>
//-----------------------------------------------------------------------------
import Vue from 'vue';
import Component from 'vue-class-component';
import Window from '../../share/Window.vue';
const BookmarkSettingsProps = Vue.extend({
props: {
libs: Object,
}
});
export default @Component({
components: {
Window,
},
watch: {
libs: function() {
},
}
})
class BookmarkSettings extends BookmarkSettingsProps {
created() {
}
mounted() {
}
init() {
this.$refs.window.init();
}
close() {
this.$emit('close');
}
keyHook(event) {
if (event.type == 'keydown' && event.key == 'Escape') {
this.close();
return true;
}
return false;
}
}
//-----------------------------------------------------------------------------
</script>
<style scoped>
</style>

View File

@@ -23,8 +23,8 @@
<q-btn class="q-mr-xs" round dense color="blue" icon="la la-plus" @click.stop="addBookmark" size="12px"> <q-btn class="q-mr-xs" round dense color="blue" icon="la la-plus" @click.stop="addBookmark" size="12px">
<q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Добавить закладку</q-tooltip> <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Добавить закладку</q-tooltip>
</q-btn> </q-btn>
<q-btn round dense color="blue" icon="la la-bars" @click.stop="bookmarkSettings" size="12px" disabled> <q-btn round dense color="blue" icon="la la-bars" @click.stop="bookmarkSettings" size="12px" disabled>
<q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Настроить закладки (пока недоступно)</q-tooltip> <q-tooltip :delay="1500" anchor="bottom middle" content-style="font-size: 80%">Настроить закладки</q-tooltip>
</q-btn> </q-btn>
</template> </template>
<template v-slot:selected> <template v-slot:selected>
@@ -97,6 +97,7 @@
</template> </template>
</Dialog> </Dialog>
</div> </div>
<BookmarkSettings v-if="bookmarkSettingsActive" ref="bookmarkSettings" :libs="libs" @close="closeBookmarkSettings"></BookmarkSettings>
</Window> </Window>
</template> </template>
@@ -108,6 +109,8 @@ import _ from 'lodash';
import Window from '../share/Window.vue'; import Window from '../share/Window.vue';
import Dialog from '../share/Dialog.vue'; import Dialog from '../share/Dialog.vue';
import BookmarkSettings from './BookmarkSettings/BookmarkSettings.vue';
import rstore from '../../store/modules/reader'; import rstore from '../../store/modules/reader';
import * as utils from '../../share/utils'; import * as utils from '../../share/utils';
@@ -118,7 +121,8 @@ const proxySubst = {
export default @Component({ export default @Component({
components: { components: {
Window, Window,
Dialog Dialog,
BookmarkSettings
}, },
watch: { watch: {
libs: function() { libs: function() {
@@ -153,6 +157,8 @@ class ExternalLibs extends Vue {
bookmarkDesc = ''; bookmarkDesc = '';
defaultRootLink = ''; defaultRootLink = '';
bookmarkSettingsActive = false;
created() { created() {
this.$root.addKeyHook(this.keyHook); this.$root.addKeyHook(this.keyHook);
@@ -549,9 +555,6 @@ class ExternalLibs extends Vue {
this.addBookmarkVisible = false; this.addBookmarkVisible = false;
} }
bookmarkSettings() {
}
fullScreenToggle() { fullScreenToggle() {
this.fullScreenActive = !this.fullScreenActive; this.fullScreenActive = !this.fullScreenActive;
if (this.fullScreenActive) { if (this.fullScreenActive) {
@@ -584,14 +587,28 @@ class ExternalLibs extends Vue {
} }
} }
keyHook() { bookmarkSettings() {
this.bookmarkSettingsActive = true;
this.$nextTick(() => {
this.$refs.bookmarkSettings.init();
});
}
closeBookmarkSettings() {
this.bookmarkSettingsActive = false;
}
keyHook(event) {
if (this.$root.rootRoute() == '/external-libs') { if (this.$root.rootRoute() == '/external-libs') {
if (this.bookmarkSettingsActive && this.$refs.bookmarkSettings.keyHook(event))
return true;
if (this.$refs.dialogAddBookmark.active) if (this.$refs.dialogAddBookmark.active)
return false; return false;
if (event.type == 'keydown' && event.key == 'F4') { if (event.type == 'keydown' && event.key == 'F4') {
this.addBookmark() this.addBookmark();
return; return true;
} }
if (event.type == 'keydown' && event.key == 'Escape' && if (event.type == 'keydown' && event.key == 'Escape' &&
@@ -599,8 +616,8 @@ class ExternalLibs extends Vue {
(document.activeElement != this.$refs.selectedLink.$refs.target || !this.$refs.selectedLink.menu) (document.activeElement != this.$refs.selectedLink.$refs.target || !this.$refs.selectedLink.menu)
) { ) {
this.close(); this.close();
return true;
} }
return true;
} }
return false; return false;
} }

View File

@@ -331,6 +331,12 @@ class Reader extends Vue {
this.checkActivateDonateHelpPage(); this.checkActivateDonateHelpPage();
this.loading = false; this.loading = false;
//проверим состояние Settings, и обновим, если надо
const newSettings = rstore.addDefaultsToSettings(this.settings);
if (newSettings) {
this.commit('reader/setSettings', newSettings);
}
this.updateRoute(); this.updateRoute();
await this.showWhatsNew(); await this.showWhatsNew();

View File

@@ -505,7 +505,7 @@ class ServerStorage extends Vue {
const md = newRecentMod.data; const md = newRecentMod.data;
if (md.key && result[md.key]) if (md.key && result[md.key])
result[md.key] = utils.applyObjDiff(result[md.key], md.mod, true); result[md.key] = utils.applyObjDiff(result[md.key], md.mod, {isAddChanged: true});
if (!bookManager.loaded) { if (!bookManager.loaded) {
this.warning('Ожидание загрузки списка книг перед синхронизацией'); this.warning('Ожидание загрузки списка книг перед синхронизацией');
@@ -569,7 +569,7 @@ class ServerStorage extends Vue {
let applyMod = this.cachedRecentMod.data; let applyMod = this.cachedRecentMod.data;
if (applyMod && applyMod.key && newRecentPatch.data[applyMod.key]) if (applyMod && applyMod.key && newRecentPatch.data[applyMod.key])
newRecentPatch.data[applyMod.key] = utils.applyObjDiff(newRecentPatch.data[applyMod.key], applyMod.mod, true); newRecentPatch.data[applyMod.key] = utils.applyObjDiff(newRecentPatch.data[applyMod.key], applyMod.mod, {isAddChanged: true});
newRecentMod = {rev: this.cachedRecentMod.rev + 1, data: {}}; newRecentMod = {rev: this.cachedRecentMod.rev + 1, data: {}};
needSaveRecentPatch = true; needSaveRecentPatch = true;

View File

@@ -108,8 +108,10 @@ export default @Component({
}, },
vertShift: function(newValue) { vertShift: function(newValue) {
const font = (this.webFontName ? this.webFontName : this.fontName); const font = (this.webFontName ? this.webFontName : this.fontName);
this.fontShifts = Object.assign({}, this.fontShifts, {[font]: newValue}); if (this.fontShifts[font] != newValue) {
this.fontVertShift = newValue; this.fontShifts = Object.assign({}, this.fontShifts, {[font]: newValue});
this.fontVertShift = newValue;
}
}, },
fontName: function(newValue) { fontName: function(newValue) {
const font = (this.webFontName ? this.webFontName : newValue); const font = (this.webFontName ? this.webFontName : newValue);
@@ -185,10 +187,18 @@ class SettingsPage extends Vue {
settingsChanged() { settingsChanged() {
if (_.isEqual(this.form, this.settings)) if (_.isEqual(this.form, this.settings))
return; return;
this.form = Object.assign({}, this.settings); this.form = Object.assign({}, this.settings);
if (!this.unwatch)
this.unwatch = {};
for (let prop in rstore.settingDefaults) { for (let prop in rstore.settingDefaults) {
if (this.unwatch && this.unwatch[prop])
this.unwatch[prop]();
this[prop] = this.form[prop]; this[prop] = this.form[prop];
this.$watch(prop, (newValue) => {
this.unwatch[prop] = this.$watch(prop, (newValue) => {
this.form = Object.assign({}, this.form, {[prop]: newValue}); this.form = Object.assign({}, this.form, {[prop]: newValue});
}); });
} }

View File

@@ -32,7 +32,7 @@ const DialogProps = Vue.extend({
props: { props: {
value: Boolean, value: Boolean,
} }
}) });
export default @Component({ export default @Component({
}) })

View File

@@ -124,6 +124,7 @@ class Window extends Vue {
.main { .main {
background-color: transparent !important; background-color: transparent !important;
z-index: 50; z-index: 50;
overflow: hidden;
} }
.xyfit { .xyfit {

View File

@@ -130,20 +130,53 @@ export function getObjDiff(oldObj, newObj) {
} }
export function isObjDiff(diff) { export function isObjDiff(diff) {
return (_.isObject(diff) && diff.__isDiff); return (_.isObject(diff) && diff.__isDiff && diff.change && diff.add && diff.del);
} }
export function isEmptyObjDiff(diff) { export function isEmptyObjDiff(diff) {
return (!_.isObject(diff) || !diff.__isDiff || return (!isObjDiff(diff) ||
(!Object.keys(diff.change).length && !(Object.keys(diff.change).length ||
!Object.keys(diff.add).length && Object.keys(diff.add).length ||
!diff.del.length diff.del.length
) )
); );
} }
export function applyObjDiff(obj, diff, isAddChanged) { export function isEmptyObjDiffDeep(diff, opts = {}) {
const result = _.cloneDeep(obj); if (!isObjDiff(diff))
return true;
const {
isApplyChange = true,
isApplyAdd = true,
isApplyDel = true,
} = opts;
let notEmptyDeep = false;
const change = diff.change;
for (const key of Object.keys(change)) {
if (_.isObject(change[key]))
notEmptyDeep |= !isEmptyObjDiffDeep(change[key], opts);
else if (isApplyChange)
notEmptyDeep = true;
}
return !(
notEmptyDeep ||
(isApplyAdd && Object.keys(diff.add).length) ||
(isApplyDel && diff.del.length)
);
}
export function applyObjDiff(obj, diff, opts = {}) {
const {
isAddChanged = false,
isApplyChange = true,
isApplyAdd = true,
isApplyDel = true,
} = opts;
let result = _.cloneDeep(obj);
if (!diff.__isDiff) if (!diff.__isDiff)
return result; return result;
@@ -151,21 +184,28 @@ export function applyObjDiff(obj, diff, isAddChanged) {
for (const key of Object.keys(change)) { for (const key of Object.keys(change)) {
if (result.hasOwnProperty(key)) { if (result.hasOwnProperty(key)) {
if (_.isObject(change[key])) { if (_.isObject(change[key])) {
result[key] = applyObjDiff(result[key], change[key], isAddChanged); result[key] = applyObjDiff(result[key], change[key], opts);
} else { } else {
result[key] = _.cloneDeep(change[key]); if (isApplyChange)
result[key] = _.cloneDeep(change[key]);
} }
} else if (isAddChanged) { } else if (isAddChanged) {
result[key] = _.cloneDeep(change[key]); result[key] = _.cloneDeep(change[key]);
} }
} }
for (const key of Object.keys(diff.add)) { if (isApplyAdd) {
result[key] = _.cloneDeep(diff.add[key]); for (const key of Object.keys(diff.add)) {
result[key] = _.cloneDeep(diff.add[key]);
}
} }
for (const key of diff.del) { if (isApplyDel && diff.del.length) {
delete result[key]; for (const key of diff.del) {
delete result[key];
}
if (_.isArray(result))
result = result.filter(v => v);
} }
return result; return result;

View File

@@ -1,3 +1,5 @@
import * as utils from '../../share/utils';
const readerActions = { const readerActions = {
'help': 'Вызвать cправку', 'help': 'Вызвать cправку',
'loader': 'На страницу загрузки', 'loader': 'На страницу загрузки',
@@ -256,6 +258,25 @@ const settingDefaults = {
userHotKeys: {}, userHotKeys: {},
}; };
for (const font of fonts)
settingDefaults.fontShifts[font.name] = font.fontVertShift;
for (const font of webFonts)
settingDefaults.fontShifts[font.name] = font.fontVertShift;
for (const button of toolButtons)
settingDefaults.showToolButton[button.name] = button.show;
for (const hotKey of hotKeys)
settingDefaults.userHotKeys[hotKey.name] = hotKey.codes;
function addDefaultsToSettings(settings) {
const diff = utils.getObjDiff(settings, settingDefaults);
if (!utils.isEmptyObjDiffDeep(diff, {isApplyChange: false})) {
return utils.applyObjDiff(settings, diff, {isApplyChange: false});
}
return false;
}
const libsDefaults = { const libsDefaults = {
startLink: 'http://flibusta.is', startLink: 'http://flibusta.is',
comment: 'Флибуста | Книжное братство', comment: 'Флибуста | Книжное братство',
@@ -279,15 +300,6 @@ const libsDefaults = {
] ]
}; };
for (const font of fonts)
settingDefaults.fontShifts[font.name] = font.fontVertShift;
for (const font of webFonts)
settingDefaults.fontShifts[font.name] = font.fontVertShift;
for (const button of toolButtons)
settingDefaults.showToolButton[button.name] = button.show;
for (const hotKey of hotKeys)
settingDefaults.userHotKeys[hotKey.name] = hotKey.codes;
// initial state // initial state
const state = { const state = {
toolBarActive: true, toolBarActive: true,
@@ -341,7 +353,13 @@ const mutations = {
state.currentProfile = value; state.currentProfile = value;
}, },
setSettings(state, value) { setSettings(state, value) {
state.settings = Object.assign({}, state.settings, value); const newSettings = Object.assign({}, state.settings, value);
const added = addDefaultsToSettings(newSettings);
if (added) {
state.settings = added;
} else {
state.settings = newSettings;
}
}, },
setSettingsRev(state, value) { setSettingsRev(state, value) {
state.settingsRev = Object.assign({}, state.settingsRev, value); state.settingsRev = Object.assign({}, state.settingsRev, value);
@@ -361,6 +379,7 @@ export default {
fonts, fonts,
webFonts, webFonts,
settingDefaults, settingDefaults,
addDefaultsToSettings,
libsDefaults, libsDefaults,
namespaced: true, namespaced: true,