This commit is contained in:
Jesse-Ma
2022-07-21 18:51:30 +08:00
parent 0bdd2eea5c
commit deb1fbe49d
22 changed files with 26943 additions and 346 deletions

View File

@@ -15,6 +15,7 @@
}
.content {
background: #dddddd;
}
@@ -30,10 +31,6 @@
text-align: center;
}
.ivu-card-bordered {
border: 0px solid #dcdee2;
border-color: #e8eaec;
@@ -41,58 +38,54 @@
.noteKey {
color: red;
font-weight: bold;
font-size: 18px;
font-family: "Bitstream Vera Sans Mono", Consolas, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei"
.fnmodal {
align-items: center;
justify-content: center;
}
@media print {
@page {
size: portrait;
margin: 20px;
}
body {
margin: 0.8cm;
background-color: #ffffff;
}
.header {
display: none;
}
.layout-footer-center {
display: none;
}
}
</style>
<style>
#noteText {
color: black;
padding: 15px;
vertical-align: top;
width: 100%;
height: auto;
background: white;
min-width: 200px;
border-radius: 0px;
overflow-y: auto;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
/*min-height: 400px;*/
font-size: 14px;
}
#noteText::selection {
background: firebrick;
color: white;
}
#noteText::-moz-selection {
background: firebrick;
color: white;
}
#noteText br::selection {
background: firebrick;
color: white;
}
#noteText br::-moz-selection {
background: firebrick;
color: white;
.ivu-modal-content {
border-radius: 0px !important;
}
button span {
font-size: 18px;
margin-left: -1px !important;
margin-bottom: 5px;
}
</style>
<template>
<div class="layout" onkeydown="keydown">
<div class="layout">
<Layout>
<Affix :offset-top="0">
@@ -102,8 +95,12 @@ button span {
<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 }">
<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;">
@@ -112,7 +109,17 @@ button span {
<Button type="error"
style="margin-left:5px; border-radius: 0px;font-size: 24px; font-family: Arial, sans-serif"
icon="md-cloud-done">{{ this.noteForm.ttlDesc }}</Button>
@click="showShareModel()" icon="md-cloud-done">{{ noteForm.ttlDesc }}</Button>
<!--
<Button type="error"
style="margin-left:5px; border-radius: 0px; font-size: 22px;"
@click="downLoadImage()" icon="md-download">.png</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>
@@ -124,7 +131,7 @@ button span {
<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="dropNote()" icon="md-trash"></Button>
@click="showDeleteModel()" icon="md-trash"></Button>
</Button-group>
</div>
@@ -157,6 +164,7 @@ button span {
</Row>
</div>
</Header>
</Affix>
<Content class="content">
<div style="min-height: 650px;">
@@ -166,10 +174,7 @@ button span {
<Card :padding="0">
<div style="border-left: 0px solid #FF3366;">
<div id="noteText" style="text-align: left;min-height: 650px;" class="monoFt"
v-html="this.noteForm.escapeText">
view2
</div>
v-html="noteForm.escapeText"></div>
</div>
</Card>
</Col>
@@ -178,12 +183,36 @@ button span {
</Content>
<Footer class="layout-footer-center">2022 &copy; flagnote.com</Footer>
</Layout>
<Modal v-model="model.showShare" width="330" footer-hide class-name="qrmodal" :styles="{ borderRadius: 0 }">
<p style="text-align: center;">
<canvas id="qrimg" class=""></canvas>
</p>
<p style="text-align: center;">
<span id="tag-copy" class="noteUrl" :data-clipboard-text="noteForm.noteUrl" data-clipboard-action="copy">{{
noteForm.noteUrl
}}</span>
</p>
</Modal>
<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")}}
</p>
<p style="text-align: center;">
<Button type="error" :loading="model.delete" style="border-radius: 0px;" @click="dropNote()">{{$t("button.yes")}}</Button>
</p>
</Modal>
</div>
</template>
<script>
@@ -194,6 +223,11 @@ import { getSecretKey, getStoreKey } from "@/api/lock";
import { deleteNote } from "@/api/note";
import storage from "@/libs/storage";
import { getEscapeText } from "@/libs/noteStorage";
import QRCode from "qrcode";
import Clipboard from "clipboard";
import { saveAs } from 'file-saver';
import { isWeixin } from "@/libs/utils";
// import html2canvas from 'html2canvas';
export default {
name: 'ViewNote',
@@ -203,6 +237,7 @@ export default {
return {
noteForm: {
url: '',
noteUrl: '',
text: '',
escapeText: '',
key: '',
@@ -215,36 +250,122 @@ export default {
storeKey: '',
secretKey: '',
cipher: '',
currentTime: '',
},
state: {
lock: 0,
locking: 0,
initTime: null,
initTtl: null,
commited: 0
}
commited: 0,
},
model: {
showDelete: false,
showShare: false,
deleting: false,
showDownloadText: true,
},
toTopState: false,
}
},
created() {
this.model.showDownloadText = !isWeixin();
let noteMeta = this.$route.meta.noteMeta;
this.noteForm.key = this.$route.params.name;
this.noteForm.noteUrl = "https://flagnote.com/" + this.noteForm.key;
let storeKey = getStoreKey(this.noteForm.key);
this.secret.storeKey = storeKey;
let noteMeta = storage.session.getObject(storeKey + '.noteMeta');
if (noteMeta) {
this.state.lock = noteMeta.lock;
this.state.initTime = new Date().getTime();
this.state.initTtl = noteMeta.ttl;
this.secret.cipher = noteMeta.cipher;
this.secret.currentTime = noteMeta.currentTime;
this.secret.cipher = "00000000000000000000000000000000";//noteMeta.cipher; //读者有没有值可配置
this.noteForm.md5 = noteMeta.md5;
this.noteForm.ttl = noteMeta.ttl;
this.startClock();
this.startClock();
this.loadText();
storage.local.dynamicClear(this.secret.currentTime);
}
this.bindEvent();
var clipboard = new Clipboard("#tag-copy")
let that = this;
clipboard.on('success', function () {
//console.log("url copied")
//that.$Message.success({content:'url copied',duration: 10,closable:true});
that.$Message.success({ content: 'url copied' });
});
clipboard.on('error', function () {
that.$Message.error('not allow to copy');
});
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.bindEvent();
},
methods: {
downLoadText() {
var blob = new Blob([this.noteForm.text], { type: "application/octet-stream;charset=utf-8" });
saveAs(blob, this.noteForm.key + ".txt");
},
downLoadImage() {
//let that = this;
//html2canvas(document.getElementById("noteText")).then(function(canvas) {
// var canvas = document.getElementById("my-canvas");
//canvas.toBlob(function(blob) {
// saveAs(blob, that.noteForm.key+".png");
// });
// alert(canvas)
// document.body.appendChild(canvas);
//});
},
toTop() {
window.scrollTo(0, 0);
this.downLoadImage();
},
startClock() {
let that = this;
window.setInterval(function () {
@@ -268,7 +389,6 @@ export default {
if (that.noteForm.ttl <= 0) {
storage.local.delete(that.secret.storeKey + '.text');
storage.session.delete(that.secret.storeKey + '.keyMeta');
location.reload();
}
}, 1000)
@@ -282,37 +402,66 @@ export default {
createNote() {
window.open("/");
},
showShareModel() {
this.model.showShare = true;
let qrimg = document.getElementById("qrimg");
let qrurl = "https://flagnote.com/" + this.noteForm.key;
var opts = {
errorCorrectionLevel: 'Q',
type: 'image/jpeg',
quality: 0.9,
height: 192,
width: 192,
margin: 1,
color: {
dark: "#ed4014",
light: "#FFFFFF"
}
}
QRCode.toCanvas(qrimg, qrurl, opts)
},
showDeleteModel() {
this.model.showDelete = true;
},
dropNote() {
this.model.deleting = true;
let that = this;
deleteNote(this.noteForm.key).then(res => {
if (res) {
storage.local.delete(this.secret.storeKey + '.text');
storage.session.delete(this.secret.storeKey + '.keyMeta');
storage.local.delete(that.secret.storeKey + '.text');
storage.session.delete(that.secret.storeKey + '.keyMeta');
location.reload();
} else {
that.model.deleting = false;
}
});
},
loadText() {
let password;
if (this.noteForm.lock == 1) {
password = "123456"
password = "FLAGNOTE"; //默认密码
}
if (!password) {
password = "";
}
let secretKey = getSecretKey(this.secret.cipher, password);
let secretKey = getSecretKey(this.noteForm.key, password);
let storeText = storage.local.getText(this.secret.storeKey + '.text');
if (!storeText || md5(storeText.substring(35)) != this.noteForm.md5) {
if (!storeText || (md5(storeText.substring(51)) != this.noteForm.md5)) {
let note = this.getNote(this.noteForm.key);
storeText = this.noteForm.lock + '|' + this.secret.cipher + '|' + note.text;
storeText = this.noteForm.lock + '|' + this.secret.cipher + '|1|' + this.noteForm.currentTime + '|' + note.text;
storage.local.setText(this.secret.storeKey + '.text', storeText);
} else {
var starray = storeText.split('|');
storage.local.setText(this.secret.storeKey + '.text', starray[0] + "|" + starray[1] + "|1|" + starray[3] + "|" + starray[4]);
}
if (storeText) {
storeText = unzip(storeText.substring(35));
storeText = unzip(storeText.split('|')[4]);
let plainText = aesDecrypt(storeText, secretKey);
if (plainText.startsWith("FLAGNOTE#")) {
this.noteForm.text = plainText.substring(9);