Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6c9b700ed | ||
|
|
afa3fcb524 | ||
|
|
b9aeb648d6 | ||
|
|
5f5df1e5b7 | ||
|
|
ad885679e4 | ||
|
|
e002bebfbe | ||
|
|
a8a41e2b3d | ||
|
|
31940caa84 | ||
|
|
880334054e | ||
|
|
5f03ad5597 | ||
|
|
1efa3f055d | ||
|
|
8ccf11278b | ||
|
|
8a9e7ab4c3 | ||
|
|
c0fa7c0c51 | ||
|
|
022dfd4709 | ||
|
|
71e08aacc3 | ||
|
|
337eca87f2 |
@@ -11,7 +11,7 @@
|
|||||||
<el-tab-pane label="Клавиатура">
|
<el-tab-pane label="Клавиатура">
|
||||||
<HotkeysHelpPage></HotkeysHelpPage>
|
<HotkeysHelpPage></HotkeysHelpPage>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="Мышь/тачпад">
|
<el-tab-pane label="Мышь/тачскрин">
|
||||||
<MouseHelpPage></MouseHelpPage>
|
<MouseHelpPage></MouseHelpPage>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="История версий" name="releases">
|
<el-tab-pane label="История версий" name="releases">
|
||||||
|
|||||||
@@ -1,15 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<h4>Управление с помощью мыши/тачпада:</h4>
|
<h4>Управление с помощью мыши/тачскрина:</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>ЛКМ/ТАЧ</b> по экрану в одну из областей - активация действия:</li>
|
<li><b>ЛКМ/ТАЧ</b> по экрану в одну из областей - активация действия:</li>
|
||||||
<div class="click-map-page">
|
<div class="click-map-page">
|
||||||
<ClickMapPage ref="clickMapPage"></ClickMapPage>
|
<ClickMapPage ref="clickMapPage"></ClickMapPage>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<li><b>ПКМ</b> - показать/скрыть панель управления</li>
|
<li><b>ПКМ</b> - показать/скрыть панель управления</li>
|
||||||
<li><b>СКМ</b> - вкл./выкл. плавный скроллинг текста</li>
|
<li><b>СКМ</b> - вкл./выкл. плавный скроллинг текста</li>
|
||||||
|
<br>
|
||||||
|
<li>Жесты для тачскрина:</li>
|
||||||
|
<ul>
|
||||||
|
<li style="list-style-type: square">от центра вверх: на весь экран</li>
|
||||||
|
<li style="list-style-type: square">от центра вниз: плавный скроллинг</li>
|
||||||
|
<li style="list-style-type: square">от центра вправо: увеличить скорость скроллинга</li>
|
||||||
|
<li style="list-style-type: square">от центра влево: уменьшить скорость скроллинга</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
* Для управления с помощью мыши/тачпада необходимо установить галочку "Включить управление кликом" в настройках
|
* Для управления с помощью мыши/тачскрина необходимо установить галочку "Включить управление кликом" в настройках
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-show="clickControl" ref="layoutEvents" class="layout events" @mousedown.prevent.stop="onMouseDown" @mouseup.prevent.stop="onMouseUp"
|
<div v-show="clickControl" ref="layoutEvents" class="layout events" @mousedown.prevent.stop="onMouseDown" @mouseup.prevent.stop="onMouseUp"
|
||||||
@wheel.prevent.stop="onMouseWheel"
|
@wheel.prevent.stop="onMouseWheel"
|
||||||
@touchstart.stop="onTouchStart" @touchend.stop="onTouchEnd" @touchcancel.prevent.stop="onTouchCancel"
|
@touchstart.stop="onTouchStart" @touchend.stop="onTouchEnd" @touchmove.stop="onTouchMove" @touchcancel.prevent.stop="onTouchCancel"
|
||||||
oncontextmenu="return false;">
|
oncontextmenu="return false;">
|
||||||
<div v-show="showStatusBar" v-html="statusBarClickable" @mousedown.prevent.stop @touchstart.stop
|
<div v-show="showStatusBar" v-html="statusBarClickable" @mousedown.prevent.stop @touchstart.stop
|
||||||
@click.prevent.stop="onStatusBarClick"></div>
|
@click.prevent.stop="onStatusBarClick"></div>
|
||||||
@@ -877,6 +877,14 @@ class TextPage extends Vue {
|
|||||||
this.$emit('tool-bar-toggle');
|
this.$emit('tool-bar-toggle');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doScrollingToggle() {
|
||||||
|
this.$emit('scrolling-toggle');
|
||||||
|
}
|
||||||
|
|
||||||
|
doFullScreenToggle() {
|
||||||
|
this.$emit('full-screen-toogle');
|
||||||
|
}
|
||||||
|
|
||||||
async doFontSizeInc() {
|
async doFontSizeInc() {
|
||||||
if (!this.settingsChanging) {
|
if (!this.settingsChanging) {
|
||||||
this.settingsChanging = true;
|
this.settingsChanging = true;
|
||||||
@@ -968,7 +976,7 @@ class TextPage extends Vue {
|
|||||||
case 'Enter':
|
case 'Enter':
|
||||||
case 'Backquote'://`
|
case 'Backquote'://`
|
||||||
case 'KeyF':
|
case 'KeyF':
|
||||||
this.$emit('full-screen-toogle');
|
this.doFullScreenToggle();
|
||||||
break;
|
break;
|
||||||
case 'Tab':
|
case 'Tab':
|
||||||
case 'KeyQ':
|
case 'KeyQ':
|
||||||
@@ -1009,22 +1017,64 @@ class TextPage extends Vue {
|
|||||||
if (!this.$isMobileDevice)
|
if (!this.$isMobileDevice)
|
||||||
return;
|
return;
|
||||||
this.endClickRepeat();
|
this.endClickRepeat();
|
||||||
|
|
||||||
if (event.touches.length == 1) {
|
if (event.touches.length == 1) {
|
||||||
const touch = event.touches[0];
|
const touch = event.touches[0];
|
||||||
const rect = event.target.getBoundingClientRect();
|
const rect = event.target.getBoundingClientRect();
|
||||||
const x = touch.pageX - rect.left;
|
const x = touch.pageX - rect.left;
|
||||||
const y = touch.pageY - rect.top;
|
const y = touch.pageY - rect.top;
|
||||||
if (this.handleClick(x, y)) {
|
const hc = this.handleClick(x, y, new Set(['Menu']));
|
||||||
this.repDoing = true;
|
if (hc) {
|
||||||
this.debouncedStartClickRepeat(x, y);
|
if (hc != 'Menu') {
|
||||||
|
this.repDoing = true;
|
||||||
|
this.debouncedStartClickRepeat(x, y);
|
||||||
|
} else {
|
||||||
|
this.startTouch = {x, y};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTouchEnd() {
|
onTouchMove(event) {
|
||||||
|
if (this.startTouch) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTouchEnd(event) {
|
||||||
if (!this.$isMobileDevice)
|
if (!this.$isMobileDevice)
|
||||||
return;
|
return;
|
||||||
this.endClickRepeat();
|
this.endClickRepeat();
|
||||||
|
|
||||||
|
if (event.changedTouches.length == 1) {
|
||||||
|
const touch = event.changedTouches[0];
|
||||||
|
const rect = event.target.getBoundingClientRect();
|
||||||
|
const x = touch.pageX - rect.left;
|
||||||
|
const y = touch.pageY - rect.top;
|
||||||
|
if (this.startTouch) {
|
||||||
|
const dy = this.startTouch.y - y;
|
||||||
|
const dx = this.startTouch.x - x;
|
||||||
|
const moveDelta = 30;
|
||||||
|
const touchDelta = 15;
|
||||||
|
if (dy > 0 && Math.abs(dy) >= moveDelta && Math.abs(dy) > Math.abs(dx)) {
|
||||||
|
//движение вверх
|
||||||
|
this.doFullScreenToggle();
|
||||||
|
} else if (dy < 0 && Math.abs(dy) >= moveDelta && Math.abs(dy) > Math.abs(dx)) {
|
||||||
|
//движение вниз
|
||||||
|
this.doScrollingToggle();
|
||||||
|
} else if (dx > 0 && Math.abs(dx) >= moveDelta && Math.abs(dy) < Math.abs(dx)) {
|
||||||
|
//движение влево
|
||||||
|
this.doScrollingSpeedDown();
|
||||||
|
} else if (dx < 0 && Math.abs(dx) >= moveDelta && Math.abs(dy) < Math.abs(dx)) {
|
||||||
|
//движение вправо
|
||||||
|
this.doScrollingSpeedUp();
|
||||||
|
} else if (Math.abs(dy) < touchDelta && Math.abs(dx) < touchDelta) {
|
||||||
|
this.doToolBarToggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.startTouch = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTouchCancel() {
|
onTouchCancel() {
|
||||||
@@ -1038,12 +1088,13 @@ class TextPage extends Vue {
|
|||||||
return;
|
return;
|
||||||
this.endClickRepeat();
|
this.endClickRepeat();
|
||||||
if (event.button == 0) {
|
if (event.button == 0) {
|
||||||
if (this.handleClick(event.offsetX, event.offsetY)) {
|
const hc = this.handleClick(event.offsetX, event.offsetY);
|
||||||
|
if (hc && hc != 'Menu') {
|
||||||
this.repDoing = true;
|
this.repDoing = true;
|
||||||
this.debouncedStartClickRepeat(event.offsetX, event.offsetY);
|
this.debouncedStartClickRepeat(event.offsetX, event.offsetY);
|
||||||
}
|
}
|
||||||
} else if (event.button == 1) {
|
} else if (event.button == 1) {
|
||||||
this.$emit('scrolling-toggle');
|
this.doScrollingToggle();
|
||||||
} else if (event.button == 2) {
|
} else if (event.button == 2) {
|
||||||
this.doToolBarToggle();
|
this.doToolBarToggle();
|
||||||
}
|
}
|
||||||
@@ -1074,7 +1125,7 @@ class TextPage extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClick(pointX, pointY) {
|
getClickAction(pointX, pointY) {
|
||||||
const w = pointX/this.realWidth*100;
|
const w = pointX/this.realWidth*100;
|
||||||
const h = pointY/this.realHeight*100;
|
const h = pointY/this.realHeight*100;
|
||||||
|
|
||||||
@@ -1090,27 +1141,35 @@ class TextPage extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (action) {
|
return action;
|
||||||
case 'Down' ://Down
|
}
|
||||||
this.doDown();
|
|
||||||
break;
|
handleClick(pointX, pointY, exclude) {
|
||||||
case 'Up' ://Up
|
const action = this.getClickAction(pointX, pointY);
|
||||||
this.doUp();
|
|
||||||
break;
|
if (!exclude || !exclude.has(action)) {
|
||||||
case 'PgDown' ://PgDown
|
switch (action) {
|
||||||
this.doPageDown();
|
case 'Down' ://Down
|
||||||
break;
|
this.doDown();
|
||||||
case 'PgUp' ://PgUp
|
break;
|
||||||
this.doPageUp();
|
case 'Up' ://Up
|
||||||
break;
|
this.doUp();
|
||||||
case 'Menu' :
|
break;
|
||||||
this.doToolBarToggle();
|
case 'PgDown' ://PgDown
|
||||||
break;
|
this.doPageDown();
|
||||||
default :
|
break;
|
||||||
// Nothing
|
case 'PgUp' ://PgUp
|
||||||
|
this.doPageUp();
|
||||||
|
break;
|
||||||
|
case 'Menu' :
|
||||||
|
this.doToolBarToggle();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
// Nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (action && action != 'Menu');
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,21 @@
|
|||||||
export const versionHistory = [
|
export const versionHistory = [
|
||||||
|
{
|
||||||
|
showUntil: '2019-11-10',
|
||||||
|
header: '0.7.7 (2019-11-06)',
|
||||||
|
content:
|
||||||
|
`
|
||||||
|
<ul>
|
||||||
|
<li>добавлены следующие жесты для тачскрина (только при включенной опции "управление кликом"):</li>
|
||||||
|
<ul>
|
||||||
|
<li style="list-style-type: square">от центра вверх: на весь экран</li>
|
||||||
|
<li style="list-style-type: square">от центра вниз: плавный скроллинг</li>
|
||||||
|
<li style="list-style-type: square">от центра вправо: увеличить скорость скроллинга</li>
|
||||||
|
<li style="list-style-type: square">от центра влево: уменьшить скорость скроллинга</li>
|
||||||
|
</ul>
|
||||||
|
</ul>
|
||||||
|
`
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
showUntil: '2019-10-29',
|
showUntil: '2019-10-29',
|
||||||
header: '0.7.6 (2019-10-30)',
|
header: '0.7.6 (2019-10-30)',
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Liberama",
|
"name": "Liberama",
|
||||||
"version": "0.7.6",
|
"version": "0.7.7",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class AppLogger {
|
|||||||
loggerParams = [
|
loggerParams = [
|
||||||
{log: 'ConsoleLog'},
|
{log: 'ConsoleLog'},
|
||||||
{log: 'FileLog', fileName: `${config.logDir}/${config.name}.log`},
|
{log: 'FileLog', fileName: `${config.logDir}/${config.name}.log`},
|
||||||
|
{log: 'FileLog', fileName: `${config.logDir}/${config.name}.err.log`, exclude: [LM_OK, LM_INFO]},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ class FileDecompressor {
|
|||||||
|
|
||||||
async unZip(filename, outputDir) {
|
async unZip(filename, outputDir) {
|
||||||
const zip = new ZipStreamer();
|
const zip = new ZipStreamer();
|
||||||
return await await zip.unpack(filename, outputDir);
|
return await zip.unpack(filename, outputDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
unBz2(filename, outputDir) {
|
unBz2(filename, outputDir) {
|
||||||
|
|||||||
@@ -74,8 +74,7 @@ class ReaderWorker {
|
|||||||
try {
|
try {
|
||||||
decompFiles = await this.decomp.decompressNested(downloadedFilename, decompDir);
|
decompFiles = await this.decomp.decompressNested(downloadedFilename, decompDir);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (this.config.branch == 'development')
|
log(LM_ERR, e.stack);
|
||||||
console.error(e);
|
|
||||||
throw new Error('Ошибка распаковки');
|
throw new Error('Ошибка распаковки');
|
||||||
}
|
}
|
||||||
wState.set({progress: 100});
|
wState.set({progress: 100});
|
||||||
@@ -97,8 +96,7 @@ class ReaderWorker {
|
|||||||
wState.finish({path: `/tmp/${finishFilename}`});
|
wState.finish({path: `/tmp/${finishFilename}`});
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (this.config.branch == 'development')
|
log(LM_ERR, e.stack);
|
||||||
console.error(e);
|
|
||||||
wState.set({state: 'error', error: (errMes ? errMes : e.message)});
|
wState.set({state: 'error', error: (errMes ? errMes : e.message)});
|
||||||
} finally {
|
} finally {
|
||||||
//clean
|
//clean
|
||||||
@@ -137,7 +135,6 @@ class ReaderWorker {
|
|||||||
|
|
||||||
async periodicCleanDir(dir, maxSize, timeout) {
|
async periodicCleanDir(dir, maxSize, timeout) {
|
||||||
try {
|
try {
|
||||||
log(`Start clean dir: ${dir}, maxSize=${maxSize}`);
|
|
||||||
const list = await fs.readdir(dir);
|
const list = await fs.readdir(dir);
|
||||||
|
|
||||||
let size = 0;
|
let size = 0;
|
||||||
@@ -149,21 +146,20 @@ class ReaderWorker {
|
|||||||
files.push({name, stat});
|
files.push({name, stat});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log(`found ${files.length} files in dir ${dir}`);
|
log(`clean dir ${dir}, maxSize=${maxSize}, found ${files.length} files`);
|
||||||
|
|
||||||
files.sort((a, b) => a.stat.mtimeMs - b.stat.mtimeMs);
|
files.sort((a, b) => a.stat.mtimeMs - b.stat.mtimeMs);
|
||||||
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (i < files.length && size > maxSize) {
|
while (i < files.length && size > maxSize) {
|
||||||
const file = files[i];
|
const file = files[i];
|
||||||
log(`rm ${dir}/${file.name}`);
|
|
||||||
await fs.remove(`${dir}/${file.name}`);
|
await fs.remove(`${dir}/${file.name}`);
|
||||||
size -= file.stat.size;
|
size -= file.stat.size;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
log(`removed ${i} files`);
|
log(`removed ${i} files`);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
log(LM_ERR, e.message);
|
log(LM_ERR, e.stack);
|
||||||
} finally {
|
} finally {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.periodicCleanDir(dir, maxSize, timeout);
|
this.periodicCleanDir(dir, maxSize, timeout);
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ class ZipStreamer {
|
|||||||
entryCallback = (entryCallback ? entryCallback : () => {});
|
entryCallback = (entryCallback ? entryCallback : () => {});
|
||||||
const unzip = new unzipStream({file: zipFile});
|
const unzip = new unzipStream({file: zipFile});
|
||||||
|
|
||||||
|
unzip.on('error', reject);
|
||||||
|
|
||||||
let files = [];
|
let files = [];
|
||||||
unzip.on('extract', (en) => {
|
unzip.on('extract', (en) => {
|
||||||
const entry = {path: en.name, size: en.size, compressedSize: en.compressedSize};
|
const entry = {path: en.name, size: en.size, compressedSize: en.compressedSize};
|
||||||
|
|||||||
Reference in New Issue
Block a user