Добавлена возможность двигать окна, небольшое облагораживание отображения

This commit is contained in:
Book Pauk
2019-08-28 16:48:16 +07:00
parent bdb5d90b1d
commit 682a044f32
6 changed files with 217 additions and 152 deletions

View File

@@ -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;

View File

@@ -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;
} }

View File

@@ -870,7 +870,6 @@ class SettingsPage extends Vue {
.mainWindow { .mainWindow {
height: 70%; height: 70%;
display: flex; display: flex;
position: relative;
} }
.text { .text {

View File

@@ -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();

View File

@@ -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>

View File

@@ -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,