Добавлена возможность двигать окна, небольшое облагораживание отображения
This commit is contained in:
@@ -1,17 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="main" class="main" @click="close">
|
<Window @close="close">
|
||||||
<div class="mainWindow" @click.stop>
|
<template slot="header">
|
||||||
<Window @close="close">
|
Скопировать текст
|
||||||
<template slot="header">
|
</template>
|
||||||
Скопировать текст
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div ref="text" class="text" tabindex="-1">
|
<div ref="text" class="text" tabindex="-1">
|
||||||
<div v-html="text"></div>
|
<div v-html="text"></div>
|
||||||
</div>
|
|
||||||
</Window>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Window>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -109,23 +105,6 @@ class CopyTextPage extends Vue {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.main {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 40;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainWindow {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
|
|||||||
@@ -1,101 +1,97 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="main" class="main" @click="close">
|
<Window width="600px" ref="window" @close="close">
|
||||||
<div class="mainWindow" @click.stop>
|
<template slot="header">
|
||||||
<Window @close="close">
|
<span v-show="!loading">Последние {{tableData ? tableData.length : 0}} открытых книг</span>
|
||||||
<template slot="header">
|
<span v-show="loading"><i class="el-icon-loading" style="font-size: 25px"></i> <span style="position: relative; top: -4px">Список загружается</span></span>
|
||||||
<span v-show="!loading">Последние {{tableData ? tableData.length : 0}} открытых книг</span>
|
</template>
|
||||||
<span v-show="loading"><i class="el-icon-loading" style="font-size: 30px"></i> <span style="position: relative; top: -5px">Список загружается</span></span>
|
|
||||||
|
<el-table
|
||||||
|
:data="tableData"
|
||||||
|
style="width: 100%"
|
||||||
|
size="mini"
|
||||||
|
height="1px"
|
||||||
|
stripe
|
||||||
|
border
|
||||||
|
:default-sort = "{prop: 'touchDateTime', order: 'descending'}"
|
||||||
|
:header-cell-style = "headerCellStyle"
|
||||||
|
:row-key = "rowKey"
|
||||||
|
>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
type="index"
|
||||||
|
width="35px"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="touchDateTime"
|
||||||
|
min-width="90px"
|
||||||
|
sortable
|
||||||
|
>
|
||||||
|
<template slot="header" slot-scope="scope"><!-- eslint-disable-line vue/no-unused-vars -->
|
||||||
|
<span style="font-size: 90%">Время<br>просм.</span>
|
||||||
|
</template>
|
||||||
|
<template slot-scope="scope"><!-- eslint-disable-line vue/no-unused-vars -->
|
||||||
|
<div class="desc" @click="loadBook(scope.row.url)">
|
||||||
|
{{ scope.row.touchDate }}<br>
|
||||||
|
{{ scope.row.touchTime }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
>
|
||||||
|
<template slot="header" slot-scope="scope"><!-- eslint-disable-line vue/no-unused-vars -->
|
||||||
|
<!--el-input ref="input"
|
||||||
|
:value="search" @input="search = $event"
|
||||||
|
size="mini"
|
||||||
|
style="margin: 0; padding: 0; vertical-align: bottom; margin-top: 10px"
|
||||||
|
placeholder="Найти"/-->
|
||||||
|
<div class="el-input el-input--mini">
|
||||||
|
<input class="el-input__inner"
|
||||||
|
ref="input"
|
||||||
|
placeholder="Найти"
|
||||||
|
style="margin: 0; vertical-align: bottom; margin-top: 20px; padding: 0 10px 0 10px"
|
||||||
|
:value="search" @input="search = $event.target.value"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table
|
<el-table-column
|
||||||
:data="tableData"
|
min-width="300px"
|
||||||
style="width: 100%"
|
|
||||||
size="mini"
|
|
||||||
height="1px"
|
|
||||||
stripe
|
|
||||||
border
|
|
||||||
:default-sort = "{prop: 'touchDateTime', order: 'descending'}"
|
|
||||||
:header-cell-style = "headerCellStyle"
|
|
||||||
:row-key = "rowKey"
|
|
||||||
>
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<div class="desc" @click="loadBook(scope.row.url)">
|
||||||
|
<span style="color: green">{{ scope.row.desc.author }}</span><br>
|
||||||
|
<span>{{ scope.row.desc.title }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
type="index"
|
min-width="100px"
|
||||||
width="35px"
|
>
|
||||||
>
|
<template slot-scope="scope">
|
||||||
</el-table-column>
|
<a v-show="isUrl(scope.row.url)" :href="scope.row.url" target="_blank">Оригинал</a><br>
|
||||||
<el-table-column
|
<a :href="scope.row.path" :download="getFileNameFromPath(scope.row.path)">Скачать FB2</a>
|
||||||
prop="touchDateTime"
|
</template>
|
||||||
min-width="90px"
|
</el-table-column>
|
||||||
sortable
|
|
||||||
>
|
|
||||||
<template slot="header" slot-scope="scope"><!-- eslint-disable-line vue/no-unused-vars -->
|
|
||||||
<span style="font-size: 90%">Время<br>просм.</span>
|
|
||||||
</template>
|
|
||||||
<template slot-scope="scope"><!-- eslint-disable-line vue/no-unused-vars -->
|
|
||||||
<div class="desc" @click="loadBook(scope.row.url)">
|
|
||||||
{{ scope.row.touchDate }}<br>
|
|
||||||
{{ scope.row.touchTime }}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
>
|
width="60px"
|
||||||
<template slot="header" slot-scope="scope"><!-- eslint-disable-line vue/no-unused-vars -->
|
>
|
||||||
<!--el-input ref="input"
|
<template slot-scope="scope">
|
||||||
:value="search" @input="search = $event"
|
<el-button
|
||||||
size="mini"
|
size="mini"
|
||||||
style="margin: 0; padding: 0; vertical-align: bottom; margin-top: 10px"
|
style="width: 30px; padding: 7px 0 7px 0; margin-left: 4px"
|
||||||
placeholder="Найти"/-->
|
@click="handleDel(scope.row.key)"><i class="el-icon-close"></i>
|
||||||
<div class="el-input el-input--mini">
|
</el-button>
|
||||||
<input class="el-input__inner"
|
</template>
|
||||||
ref="input"
|
</el-table-column>
|
||||||
placeholder="Найти"
|
|
||||||
style="margin: 0; padding: 0; vertical-align: bottom; margin-top: 20px; padding: 0 10px 0 10px"
|
|
||||||
:value="search" @input="search = $event.target.value"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<el-table-column
|
</el-table-column>
|
||||||
min-width="300px"
|
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<div class="desc" @click="loadBook(scope.row.url)">
|
|
||||||
<span style="color: green">{{ scope.row.desc.author }}</span><br>
|
|
||||||
<span>{{ scope.row.desc.title }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column
|
</el-table>
|
||||||
min-width="100px"
|
</Window>
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<a v-show="isUrl(scope.row.url)" :href="scope.row.url" target="_blank">Оригинал</a><br>
|
|
||||||
<a :href="scope.row.path" :download="getFileNameFromPath(scope.row.path)">Скачать FB2</a>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column
|
|
||||||
width="60px"
|
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<el-button
|
|
||||||
size="mini"
|
|
||||||
style="width: 30px; padding: 7px 0 7px 0; margin-left: 4px"
|
|
||||||
@click="handleDel(scope.row.key)"><i class="el-icon-close"></i>
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
</el-table>
|
|
||||||
</Window>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -128,6 +124,8 @@ class RecentBooksPage extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
this.$refs.window.init();
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
//this.$refs.input.focus();
|
//this.$refs.input.focus();
|
||||||
});
|
});
|
||||||
@@ -315,21 +313,6 @@ class RecentBooksPage extends Vue {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.main {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 50;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainWindow {
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.desc {
|
.desc {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -870,7 +870,6 @@ class SettingsPage extends Vue {
|
|||||||
.mainWindow {
|
.mainWindow {
|
||||||
height: 70%;
|
height: 70%;
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
|
|||||||
@@ -131,7 +131,6 @@ class TextPage extends Vue {
|
|||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
this.$root.$on('resize', () => {this.$nextTick(this.onResize)});
|
this.$root.$on('resize', () => {this.$nextTick(this.onResize)});
|
||||||
this.mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -1007,7 +1006,7 @@ class TextPage extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onTouchStart(event) {
|
onTouchStart(event) {
|
||||||
if (!this.mobile)
|
if (!this.$isMobileDevice)
|
||||||
return;
|
return;
|
||||||
this.endClickRepeat();
|
this.endClickRepeat();
|
||||||
if (event.touches.length == 1) {
|
if (event.touches.length == 1) {
|
||||||
@@ -1023,19 +1022,19 @@ class TextPage extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onTouchEnd() {
|
onTouchEnd() {
|
||||||
if (!this.mobile)
|
if (!this.$isMobileDevice)
|
||||||
return;
|
return;
|
||||||
this.endClickRepeat();
|
this.endClickRepeat();
|
||||||
}
|
}
|
||||||
|
|
||||||
onTouchCancel() {
|
onTouchCancel() {
|
||||||
if (!this.mobile)
|
if (!this.$isMobileDevice)
|
||||||
return;
|
return;
|
||||||
this.endClickRepeat();
|
this.endClickRepeat();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseDown(event) {
|
onMouseDown(event) {
|
||||||
if (this.mobile)
|
if (this.$isMobileDevice)
|
||||||
return;
|
return;
|
||||||
this.endClickRepeat();
|
this.endClickRepeat();
|
||||||
if (event.button == 0) {
|
if (event.button == 0) {
|
||||||
@@ -1051,13 +1050,13 @@ class TextPage extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMouseUp() {
|
onMouseUp() {
|
||||||
if (this.mobile)
|
if (this.$isMobileDevice)
|
||||||
return;
|
return;
|
||||||
this.endClickRepeat();
|
this.endClickRepeat();
|
||||||
}
|
}
|
||||||
|
|
||||||
onMouseWheel(event) {
|
onMouseWheel(event) {
|
||||||
if (this.mobile)
|
if (this.$isMobileDevice)
|
||||||
return;
|
return;
|
||||||
if (event.deltaY > 0) {
|
if (event.deltaY > 0) {
|
||||||
this.doDown();
|
this.doDown();
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="window">
|
<div ref="main" class="main" @click="close" @mouseup.prevent.stop="onMouseUp" @mousemove.prevent.stop="onMouseMove">
|
||||||
<div class="header">
|
<div ref="windowBox" class="windowBox" @click.stop>
|
||||||
<span class="header-text"><slot name="header"></slot></span>
|
<div class="window">
|
||||||
<span class="close-button" @click="close"><i class="el-icon-close"></i></span>
|
<div ref="header" class="header" @mousedown.prevent.stop="onMouseDown"
|
||||||
|
@touchstart.stop="onTouchStart" @touchend.stop="onTouchEnd" @touchmove.stop="onTouchMove">
|
||||||
|
<span class="header-text"><slot name="header"></slot></span>
|
||||||
|
<span class="close-button" @mousedown.stop @click="close"><i class="el-icon-close"></i></span>
|
||||||
|
</div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<slot></slot>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -14,17 +19,112 @@ import Vue from 'vue';
|
|||||||
import Component from 'vue-class-component';
|
import Component from 'vue-class-component';
|
||||||
|
|
||||||
export default @Component({
|
export default @Component({
|
||||||
|
props: {
|
||||||
|
height: { type: String, default: '100%' },
|
||||||
|
width: { type: String, default: '100%' },
|
||||||
|
}
|
||||||
})
|
})
|
||||||
class Window extends Vue {
|
class Window extends Vue {
|
||||||
close() {
|
init() {
|
||||||
this.$emit('close');
|
this.$nextTick(() => {
|
||||||
|
this.$refs.windowBox.style.height = this.height;
|
||||||
|
this.$refs.windowBox.style.width = this.width;
|
||||||
|
|
||||||
|
const left = (this.$refs.main.offsetWidth - this.$refs.windowBox.offsetWidth)/2;
|
||||||
|
const top = (this.$refs.main.offsetHeight - this.$refs.windowBox.offsetHeight)/2;
|
||||||
|
this.$refs.windowBox.style.left = (left > 0 ? left : 0) + 'px';
|
||||||
|
this.$refs.windowBox.style.top = (top > 0 ? top : 0) + 'px';
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMouseDown(event) {
|
||||||
|
if (this.$isMobileDevice)
|
||||||
|
return;
|
||||||
|
if (event.button == 0) {
|
||||||
|
this.$refs.header.style.cursor = 'move';
|
||||||
|
this.startX = event.screenX;
|
||||||
|
this.startY = event.screenY;
|
||||||
|
this.moving = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseUp(event) {
|
||||||
|
if (event.button == 0) {
|
||||||
|
this.$refs.header.style.cursor = 'default';
|
||||||
|
this.moving = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseMove(event) {
|
||||||
|
if (this.moving) {
|
||||||
|
const deltaX = event.screenX - this.startX;
|
||||||
|
const deltaY = event.screenY - this.startY;
|
||||||
|
this.startX = event.screenX;
|
||||||
|
this.startY = event.screenY;
|
||||||
|
|
||||||
|
this.$refs.windowBox.style.left = (this.$refs.windowBox.offsetLeft + deltaX) + 'px';
|
||||||
|
this.$refs.windowBox.style.top = (this.$refs.windowBox.offsetTop + deltaY) + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTouchStart(event) {
|
||||||
|
if (!this.$isMobileDevice)
|
||||||
|
return;
|
||||||
|
if (event.touches.length == 1) {
|
||||||
|
const touch = event.touches[0];
|
||||||
|
this.$refs.header.style.cursor = 'move';
|
||||||
|
this.startX = touch.screenX;
|
||||||
|
this.startY = touch.screenY;
|
||||||
|
this.moving = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTouchMove(event) {
|
||||||
|
if (!this.$isMobileDevice)
|
||||||
|
return;
|
||||||
|
if (event.touches.length == 1 && this.moving) {
|
||||||
|
const touch = event.touches[0];
|
||||||
|
const deltaX = touch.screenX - this.startX;
|
||||||
|
const deltaY = touch.screenY - this.startY;
|
||||||
|
this.startX = touch.screenX;
|
||||||
|
this.startY = touch.screenY;
|
||||||
|
|
||||||
|
this.$refs.windowBox.style.left = (this.$refs.windowBox.offsetLeft + deltaX) + 'px';
|
||||||
|
this.$refs.windowBox.style.top = (this.$refs.windowBox.offsetTop + deltaY) + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTouchEnd() {
|
||||||
|
if (!this.$isMobileDevice)
|
||||||
|
return;
|
||||||
|
this.$refs.header.style.cursor = 'default';
|
||||||
|
this.moving = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
close() {
|
||||||
|
if (!this.moving)
|
||||||
|
this.$emit('close');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.main {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.windowBox {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.window {
|
.window {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -39,9 +139,9 @@ class Window extends Vue {
|
|||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
background-color: #e5e7ea;
|
background-color: #59B04F;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 40px;
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-text {
|
.header-text {
|
||||||
@@ -54,8 +154,12 @@ class Window extends Vue {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 40px;
|
width: 30px;
|
||||||
height: 40px;
|
height: 30px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.close-button:hover {
|
||||||
|
background-color: #69C05F;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -6,6 +6,7 @@ import './element';
|
|||||||
|
|
||||||
import App from './components/App.vue';
|
import App from './components/App.vue';
|
||||||
//Vue.config.productionTip = false;
|
//Vue.config.productionTip = false;
|
||||||
|
Vue.prototype.$isMobileDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent);
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
router,
|
router,
|
||||||
|
|||||||
Reference in New Issue
Block a user