This commit is contained in:
Jesse-Ma
2022-07-29 15:21:20 +08:00
parent deb1fbe49d
commit 732907c3b6
22 changed files with 592 additions and 415 deletions

View File

@@ -58,121 +58,78 @@
.layout-footer-center {
display: none;
}
}
}
</style>
<style>
.ivu-btn-text:focus {
margin-top: -3px;
box-shadow: none !important;
}
</style>
<template>
<div class="layout">
<Layout>
<Affix :offset-top="0">
<Header class="header">
<Row>
<Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 22, offset: 1 }" :md="{ span: 20, offset: 2 }"
:lg="{ span: 18, offset: 3 }" :xl="{ span: 16, offset: 4 }" :xxl="{ span: 16, offset: 4 }">
<Affix :offset-top="0">
<div style="background: white;width:100%;height:40px;">
<img style="height:40px;float:left;" alt="refresh flagnote" src="/static/favicon.png">
<div style="float:left;width:auto;">
<Button-group size="large">
<Button aria-label="publish" type="error" :loading="loading"
style="margin-left:5px; border-radius: 0px;font-size: 24px;" @click="submitNote()"
icon="md-cloud-upload"></Button>
<Button aria-label="download text" v-show="model.showDownloadText" type="error"
style="margin-left:5px; border-radius: 0px; font-size: 22px;" @click="downLoadText()"
icon="md-download"></Button>
<Header class="header">
<div>
<Row>
<Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 22, offset: 1 }" :md="{ span: 20, offset: 2 }"
:lg="{ span: 18, offset: 3 }" :xl="{ span: 16, offset: 4 }" :xxl="{ span: 16, offset: 4 }">
</Button-group>
<div id="textToTop" v-on:click="toTop()" :class="[toTopState?'showBlock':'hideBlock']"
style="width: 100%;height: 20px;position: absolute;top: 35px;"><div style="display:inline-block;cursor: pointer;padding:2px;"><Icon type="ios-arrow-up" size="28" color="#ed4014"/></div></div>
<div style="background: white;width:100%;height:40px;">
<img style="height:40px;float:left;" src="favicon.png">
<div style="float:left;width:auto;">
<Button-group size="large">
<Button type="error" :loading="loading" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
@click="submitNote()" icon="md-cloud-upload"></Button>
<Button v-show="model.showDownloadText" type="error"
style="margin-left:5px; border-radius: 0px; font-size: 22px;"
@click="downLoadText()" icon="md-download"></Button>
</Button-group>
</div>
</div>
<div style="float:right;width:auto;">
<Button-group size="large">
<Button type="error" style="margin-left:0px; border-radius: 0px;font-size: 24px;"
@click="createNote()" icon="md-add"></Button>
<Button type="error" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
@click="showDeleteModel()" icon="md-trash"></Button>
</Button-group>
</div>
<div style="float:right;width:auto;">
<Button-group size="large">
<!--
<Button v-show="!show" type="error" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
@click="showNote()" icon="md-eye"></Button>
<Button v-show="show" type="error" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
@click="hideNote()" icon="md-eye-off"></Button>
-->
</Button-group>
</div>
<!--
<div style="float:right;width:auto;">
<Button-group size="default">
<Button type="error" @click="unLockNote()" icon="md-eye"></Button>
<Button type="error" @click="lockNote()" icon="md-eye-off"></Button>
<Button type="error" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
@click="dropNote()" icon="md-trash"></Button> </Button-group>
<Button-group size="large">
<Button aria-label="to top" v-show="toTopState" type="text"
style="margin-left:0px; border-radius: 0px; font-size: 28px;color:red;line-height: 20px;"
@click="toTop()" icon="ios-arrow-up" ghost></Button>
<Button aria-label="create note" type="error"
style="margin-left:10px; border-radius: 0px;font-size: 24px;" @click="createNote()"
icon="md-add"></Button>
<Button aria-label="delete note" type="error"
style="margin-left:5px; border-radius: 0px;font-size: 24px;" @click="showDeleteModel()"
icon="md-trash"></Button>
</Button-group>
</div>
-->
<!--
<div style="width:auto;float:right;font-size: 24px;">
<Button-group vertical size="large" style="position:absolute;right;0px;top:0px;">
<Button type="error" style="border-radius: 0px;font-size: 24px;" icon="md-add"
@click="showExt = true"></Button>
<Button type="error" v-show="showExt" style="border-radius: 0px;font-size: 24px;"
icon="md-cloud-upload"></Button>
<Button type="error" v-show="showExt" style="border-radius: 0px;font-size: 24px;"
icon="logo-googleplus"></Button>
<Button type="error" v-show="showExt" style="border-radius: 0px;font-size: 24px;"
icon="logo-tumblr"></Button>
</Button-group>
</div>
-->
</div>
</div>
</Affix>
</Col>
</Row>
</Header>
</Col>
</Row>
</div>
</Header>
</Affix>
<Content class="content">
<div style="min-height: 650px;">
<Row>
@@ -183,11 +140,7 @@
<div id="wrapper" style="border-left: 0px solid #FF3366;">
<Input element-id="noteText" type="textarea" :border="false" v-model="noteForm.text"
:autosize="{ minRows: 30, maxRows: 20480 }" placeholder="Enter something..." v-on:input="log"
@on-keydown="down"/>
</div>
<div>
@on-keydown="down" />
</div>
</Form>
</Card>
@@ -212,13 +165,14 @@
<p>Content of dialog</p>
</Modal>
<Modal v-model="model.showDelete" width="330" footer-hide class-name="fnmodal" :styles="{ borderRadius: 0 }">
<Modal v-model="model.showDelete" width="330" footer-hide class-name="fnmodal" :styles="{ borderRadius: 0 }">
<p style="text-align: center;font-size:medium ;margin-bottom: 20px;">
{{$t("message.askTodelete")}}
{{ $t("message.askTodelete") }}
</p>
<p style="text-align: center;">
<Button type="error" :loading="model.deleting" style="border-radius: 0px;"
@click="dropNote()" >{{$t("button.yes")}}</Button>
<Button type="error" :loading="model.deleting" style="border-radius: 0px;" @click="dropNote()">{{
$t("button.yes")
}}</Button>
</p>
</Modal>
@@ -265,46 +219,58 @@ export default {
locking: 0,
commited: 0
},
model:{
model: {
showDelete: false,
deleting: false,
showDownloadText: false,
},
toTopState : false,
toTopState: false,
}
},
created() {
this.model.showDownloadText = !isWeixin();
// read $route
this.noteForm.key = this.$route.params.name;
let keyMeta = this.$route.meta.keyMeta;
//ipad chrome url not redirect
let path = location.pathname;
if ("/" == path) {
history.pushState('', '', '/' + this.noteForm.key);
}
//wx does not show downloadText
this.model.showDownloadText = !isWeixin();
// let noteMeta = this.$route.meta.noteMeta;
let storeKey = getStoreKey(this.noteForm.key);
this.secret.storeKey = storeKey;
// first edit
if (keyMeta) {
this.state.lock = 0;
this.secret.cipher = keyMeta.cipher;
this.secret.currentTime = keyMeta.currentTime;
// key init Time
this.noteForm.initTime = keyMeta.currentTime;
storage.local.setText(storeKey + '.text', "0|" + this.secret.cipher + "|0|" + this.secret.currentTime + "|");
storage.session.setObject(storeKey + '.keyMeta', null);
storage.local.dynamicClear(this.secret.currentTime);
// clear
storage.local.dynamicClear();
//if local less 1m ,then deep clear,let local greater than 2m
// if (storage.local.getAvailableSize < 1 * 1024 * 1024) {
// storage.local.dynamicDeepClear(this.secret.currentTime, storeKey);
// }
storage.local.setText(storeKey + '.text', "0|" + this.secret.cipher + "|0|" + this.noteForm.initTime + "|");
} else {
// second edit
let storeText = storage.local.getText(storeKey + '.text');
let starray = storeText.split('|');
this.state.lock = parseInt(starray[0]);
this.secret.cipher = starray[1];
this.noteForm.initTime = parseInt(starray[3]);
// this.secret.currentTime = noteMeta.currentTime;
// storage.local.dynamicClear(this.secret.currentTime);
}
//TODO: password lock
if (this.state.lock == 1) {
this.show = false;
this.noteForm.text = "*****lock*****";
@@ -313,34 +279,9 @@ export default {
this.loadText();
}
this.bindCtrlAllEvent();
this.bindEvent();
let that = this;
window.onscroll = function () {
//变量scrollTop是滚动条滚动时距离顶部的距离
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
// //变量windowHeight是可视区的高度
// var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
// //变量scrollHeight是滚动条的总高度
// var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
//滚动条到底部的条件
if (scrollTop >= 20) {
//写后台加载数据的函数
//console.log("距顶部" + scrollTop + "可视区高度" + windowHeight + "滚动条总高度" + scrollHeight);
that.toTopState = true;
} else {
//toTop.style.setProperty("display", "none")
that.toTopState = false;
}
}
this.bindToTopEvent();
@@ -349,6 +290,20 @@ export default {
},
mounted() {
const myObserver = new ResizeObserver(entries => {
// iterate over the entries, do something.
entries.forEach(entry => {
let affix = document.querySelector('.ivu-affix');
if (affix) {
affix.setAttribute("style", "top: 0px; width: " + entry.contentRect.width + "px;");
}
});
});
const someOtherEl = document.querySelector('#wrapper');
myObserver.observe(someOtherEl);
},
updated() {
},
@@ -359,8 +314,13 @@ export default {
computed: {},
watch: {},
methods: {
toTop(){
window.scrollTo(0, 0);
toTop() {
window.scrollTo(0, 0);
let elent = document.querySelector('#noteText');
elent.selectionStart = 0;
elent.selectionEnd = 0;
elent.focus();
},
showInput() {
this.showPassword = true;
@@ -377,16 +337,15 @@ export default {
cancel() {
},
downLoadText(){
var blob = new Blob([this.noteForm.text], {type: "application/octet-stream;charset=utf-8"});
saveAs(blob, this.noteForm.key+".txt");
downLoadText() {
var blob = new Blob([this.noteForm.text], { type: "application/octet-stream;charset=utf-8" });
saveAs(blob, this.noteForm.key + ".txt");
},
loadText() {
let secretKey = getSecretKey(this.noteForm.key);
let storeText = storage.local.getText(this.secret.storeKey + '.text');
if (null != storeText && '' != storeText) {
let starray = storeText.split('|');
let lock = parseInt(starray[0]);
@@ -395,12 +354,11 @@ export default {
return;
}
//let cipher = storeText.substring(2,34)
storeText = starray[4];
if (storeText.length > 0) {
storeText = unzip(storeText);
let secretKey = getSecretKey(this.noteForm.key);
let plainText = aesDecrypt(storeText, secretKey);
if (plainText.startsWith("FLAGNOTE#")) {
this.noteForm.text = plainText.substring(9);
@@ -421,9 +379,10 @@ export default {
},
down(event) {
if (event.keyCode == 9) {
let start = event.currentTarget.selectionStart, end = event.currentTarget.selectionEnd;
let start = event.currentTarget.selectionStart;
let end = event.currentTarget.selectionEnd;
let text = event.currentTarget.value;
let tab = ' ';//\t
let tab = '\t';//\t
text = text.substr(0, start) + tab + text.substr(start);
event.currentTarget.value = text;
event.currentTarget.selectionStart = start + tab.length;
@@ -435,21 +394,14 @@ export default {
this.noteForm.text = event.currentTarget.value;
setStoreText(this.noteForm, this.secret);
// html2canvas(document.body).then(function (canvas) {
// canvas;
// //document.body.appendChild(canvas);
// });
} else if (event.ctrlKey && (event.which == 13)) {
//save
let that = this;
this.save().then(res => {
if (res) {
let storeText = storage.local.getText(that.secret.storeKey + '.text');
let starray = storeText.split("|");
storage.local.setText(that.secret.storeKey + '.text', starray[0] + '|' + starray[1] + '|1|'+ starray[3] +'|' + starray[4]);
storage.local.setText(that.secret.storeKey + '.text', starray[0] + '|' + starray[1] + '|1|' + starray[3] + '|' + starray[4]);
location.reload();
}
});
@@ -473,7 +425,7 @@ export default {
if (res) {
let storeText = storage.local.getText(that.secret.storeKey + '.text');
let starray = storeText.split("|");
storage.local.setText(that.secret.storeKey + '.text', starray[0] + '|' + starray[1] + '|1|'+ starray[3] +'|' + starray[4]);
storage.local.setText(that.secret.storeKey + '.text', starray[0] + '|' + starray[1] + '|1|' + starray[3] + '|' + starray[4]);
location.reload();
this.state.locking = 0;
}
@@ -588,7 +540,20 @@ export default {
location.reload();
},
bindEvent() {
bindToTopEvent() {
let that = this;
window.onscroll = function () {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop >= 20) {
that.toTopState = true;
} else {
that.toTopState = false;
}
//document.getElementsByClassName("ivu-affix")[0]
}
},
bindCtrlAllEvent() {
if (document.body.createTextRange) {
Jquery(document).keydown(function (e) {
if ((e.ctrlKey || e.metaKey) && e.keyCode == 65) {