Forráskód Böngészése

Add upload, change URL, fix fullscreen, bump deps, tweaks

Mike L 2 napja
szülő
commit
6fe6c47bbc

+ 1 - 1
app.js

@@ -17,7 +17,7 @@ app.set('view engine', 'pug');
 // uncomment after placing your favicon in /public
 app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
 app.use(logger('dev'));
-app.use(bodyParser.json());
+app.use(bodyParser.json({ limit: '512mb' }));
 app.use(bodyParser.urlencoded({ extended: false }));
 app.use(cookieParser());
 app.use(express.static(path.join(__dirname, 'public')));

+ 1 - 3
config.js

@@ -11,8 +11,6 @@ module.exports = {
 	field_lists: 'naives',
 	// 1小时内单个IP可获取最多临时链接数
 	rate_limit: 500,
-	// 是否显示首页中的作死文本 eg.「☭赵」
-	isZhao: false,
 	// 用于匹配GUID的正则
-	reg_guid: /[?a-zA-Z0-9]{8}-[?a-zA-Z0-9]{4}-[?a-zA-Z0-9]{4}-[?a-zA-Z0-9]{4}-[?a-zA-Z0-9]{12}$/,
+	reg_guid: /(?<=\/)[a-zA-Z0-9]{8}$/,
 }

BIN
dump.rdb


+ 2 - 2
lib/tools.js

@@ -1,5 +1,5 @@
 var redis = require("redis");
-var uuidv4 = require('uuid').v4;
+var randomstring = require('random-string-gen');
 
 /**
  * Redis存档的Hash消息管理工具
@@ -49,7 +49,7 @@ module.exports = function(conf)
 	 * @return {[type]}            [description]
 	 */
 	this.getUniID = (callback) => {
-		var guid = uuidv4();
+		var guid = randomstring(8);
 		this.exists(guid, (exists) => {
 			// 如果存在则递归重新获取,直到获取到不重复的GUID并返回
 			exists ? this.getUniID(callback) : callback(guid);

+ 3 - 3
package.json

@@ -1,6 +1,6 @@
 {
   "name": "naiveboom",
-  "version": "1.1.2",
+  "version": "2.0.0",
   "license": "MIT License",
   "private": true,
   "scripts": {
@@ -14,9 +14,9 @@
     "express-rate-limit": "^2.14.2",
     "morgan": "^1.11.0",
     "pug": "^3.0.4",
+    "random-string-gen": "^1.1.4",
     "redis": "^4.7.1",
     "serve-favicon": "~2.4.5",
-    "util": "^0.10.3",
-    "uuid": "^11.1.1"
+    "util": "^0.10.3"
   }
 }

BIN
public/images/zhao.png


+ 37 - 4
public/javascripts/a.js

@@ -17,31 +17,64 @@ modal = new Vue({
 
 Vue.component('vue-easymde', VueEasyMDE.VueEasyMDE)
 
+var blobMap = {}
+
 app = new Vue({
 	el: '#app',
 	data: {
 		text: null,
 		enurl: null,
+		copyicon: 'fa-clone',
 		easyMDEOpts: {
+			maxHeight: '47vh',
+			onToggleFullScreen: function() { $('.navbar').toggle(); },
 			sideBySideFullscreen: false,
+			spellChecker: false,
 			renderingConfig: { codeSyntaxHighlighting: true },
+			uploadImage: true,
+			imageUploadFunction: function(file, onSuccess, onError) {
+				var url = URL.createObjectURL(file);
+				var reader = new FileReader();
+				reader.onerror = onError;
+				reader.onload = function() {
+					blobMap[url] = reader.result;
+					var prefix = '[' + file.name + ']';
+					if (file.type.startsWith('image')) {
+						prefix = '!' + prefix;
+					}
+					var test = new RegExp('\\[(.+)(' + file.name + ')?\\]\\(blob:.*?\\1\\)');
+					app.text = app.text.replace(test, prefix + '(' + url + ')');
+				};
+				onSuccess(url);
+				reader.readAsDataURL(file);
+			},
 		},
 	},
 	methods: {
+		copyTempURL: function() {
+			navigator.clipboard.writeText(app.enurl).then(function() {
+				app.copyicon = 'fa-check';
+				setTimeout(function() {
+					app.copyicon = 'fa-clone';
+				}, 3000);
+			})
+		},
 		getTempURL: function() {
 			$('#enurl').loading({
 				message: '加载中...',
 				onStop: function(loading) {
-				    loading.overlay.fadeOut(650)
-				  }
+					loading.overlay.fadeOut(650);
+				}
 			});
 			axios.post('/api/get-temp', {
-				text: app.text
+				text: app.text.replace(/\]\((blob:[^)]*)\)/g, function(_, blobURL) {
+					return '](' + blobMap[blobURL] + ')';
+				})
 			}).then(function(response) {
 				$('#enurl').loading('stop');
 				var data = response.data;
 				if (data.status == 1) {
-					var newURL = window.location.protocol + '//' + window.location.host + window.location.pathname;
+					var newURL = location.protocol + '//' + location.host + location.pathname;
 					app.enurl = newURL + data.guid;
 				} else {
 					throw 'failure to get the tmp url!';

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 0 - 1
public/javascripts/axios.min.js


+ 46 - 6
public/javascripts/view.js

@@ -1,5 +1,27 @@
+function replaceDataURLFrom(text) {
+	var blobMap = {};
+	var promises = [];
+	var test = /\]\((data:.*?)\)/g
+	for (var match = test.exec(text); match; match = test.exec(text)) {
+		promises.push(
+			fetch(match[1]).then(function(res) {
+				return Promise.all([res.url, res.blob()]);
+			}).then(function([dataURL, blob]) {
+				blobMap[dataURL] = URL.createObjectURL(blob);
+			})
+		);
+	};
+	return Promise.all(promises).then(function() {
+		return text.replace(test, function(_, dataURL) {
+			return '](' + blobMap[dataURL] + ')';
+		});
+	});
+}
+
 Vue.component('vue-easymde', VueEasyMDE.VueEasyMDE)
 
+var origText;
+
 // 查看消息需要用到的JS
 app = new Vue({
 	el: '#app',
@@ -7,22 +29,40 @@ app = new Vue({
 		status: -1,
 		text: null,
 		easyMDEOpts: {
-			toolbar: ['preview'],
+			maxHeight: '70vh',
+			onToggleFullScreen: function() { $('.navbar').toggle(); },
+			spellChecker: false,
+			toolbar: [
+				{
+					name: 'copy no-disable',
+					action: function() {
+						if (!origText) return;
+						navigator.clipboard.writeText(origText);
+					},
+					className: 'fa fa-clipboard',
+					title: 'Copy to clipboard',
+				},
+				'preview',
+				'fullscreen',
+			],
 			renderingConfig: { codeSyntaxHighlighting: true },
 		},
 	},
 	mounted: function() {
 		// 从URL获取GUID,然后透过POST获取消息
-		var guid = reg_guid.exec(window.location.href)[0];
+		var guid = reg_guid.exec(location.href)[0];
 		axios.post('/api/get-msg', {
 			guid: guid
-		}).then(function (response) {
+		}).then(function(response) {
 			var data = response.data;
 			app.status = data.status;
-			app.text = data.text;
-		}).catch(function (error) {
+			if (app.status !== 1) return null;
+			origText = data.text;
+			return replaceDataURLFrom(data.text);
+		}).then(function(text) {
+			app.text = text;
+		}).catch(function(error) {
 			throw error;
-			alert('发生错误!')
 		});
 	},
 	watch: {

+ 7 - 2
public/stylesheets/style.css

@@ -14,7 +14,8 @@ p.tips{ line-height: 1.8em; }
 .fade-enter-active, .fade-leave-active {
   transition: opacity .5s;
 }
-.fade-enter, .fade-leave-to
+
+.fade-enter, .fade-leave-to {
   opacity: 0;
 }
 
@@ -24,4 +25,8 @@ p.tips{ line-height: 1.8em; }
 
 #tg { top: 1vw; left: 1vw; width: 1px; display: block; position: absolute; background: gray; transition: all 2s ease-in; opacity: 0; }
 
-#enurl { transition: all .3s ease-in; margin: 3px 0; display: inline-block; color: #02B875; border: 1px solid; border-radius: .859em; padding: 8px 15px; margin-top: 9px; border-radius: .5; }
+#enurl { transition: all .3s ease-in; margin: 3px 0; display: inline-block; color: #02B875; border: 1px solid; border-radius: .5em; padding: 8px 15px; margin-top: 9px; }
+
+#enurl .btn { margin: -.5rem -.5rem -.25rem -.125rem; padding: 0 .5rem; color: gray; border: 0; }
+
+#enurl .fa-check { color: #02B875; }

+ 1 - 1
routes/apis.js

@@ -31,7 +31,7 @@ router.post('/get-temp', apiLimiter, function(req, res, next) {
  */
 router.post('/get-msg', function(req, res) {
 	var guid = req.body.guid;
-	console.log("GUID", guid);
+	console.log('GUID', guid);
 	mtool.exists(guid, (exists) => {
 		var rep = {status: 0, text: null};
 		if (exists) {

+ 1 - 1
routes/index.js

@@ -5,7 +5,7 @@ var mtool = new (require('../lib/tools.js'))(conf);// 消息操作工具
 
 /* GET home page. */
 router.get('/', function(req, res, next) {
-  res.render('index', { title: 'Naiveboom - 比较安全', isZhao: conf.isZhao});
+  res.render('index', { title: 'Naiveboom - 比较安全' });
 });
 
 /**

+ 19 - 15
views/index.pug

@@ -2,19 +2,23 @@ extends layout
 block content
     include imports.pug
     <div id='app'>
-        <div class="row">
+        <div class='row'>
             <div class='col-md-10 col-xs-12 col-sm-12'>
                 <p> <p class='lead'>无需注册的阅后即焚</p>在下面的框框里输入一些内容
                 | <br>然后点一下「去产生」按钮,你就会得到一个长的网址
                 | <br>将这个网址发给你的朋友,他只能看一次
                 | 内容就会 <b>永远消失</b>! </p>
                 <vue-easymde v-model='text' :options='easyMDEOpts'></vue-easymde>
-                <button :disabled='!text' v-on:click='getTempURL' class="btn btn-primary getbtn">去产生</button>
+                <button :disabled='!text' v-on:click='getTempURL' class='btn btn-primary getbtn'>去产生</button>
 
-                <transition name="fade">
-                    <p v-if="enurl">
+                <transition name='fade'>
+                    <p v-if='enurl'>
                         |可以把这个网址分享给你的朋友:
-                        <span id='enurl'>{{ enurl }}</span>
+                        | <span id='enurl'>
+                        | {{ enurl }}
+                        | <button v-on:click='copyTempURL' class='btn btn-sm'>
+                        |   <i class='fa' :class='copyicon'></i>
+                        | </button></span>
                     </p>
                 </transition>
                 hr
@@ -30,19 +34,19 @@ block content
     </div>
     //- modal
     <div id='modal'>
-        <div id='mmodal' class="modal">
-          <div class="modal-dialog" role="document">
-            <div class="modal-content">
-              <div class="modal-header">
-                <h5 class="modal-title">{{ title }}</h5>
-                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
-                  <span aria-hidden="true">&times;</span>
+        <div id='mmodal' class='modal'>
+          <div class='modal-dialog' role='document'>
+            <div class='modal-content'>
+              <div class='modal-header'>
+                <h5 class='modal-title'>{{ title }}</h5>
+                <button type='button' class='close' data-dismiss='modal' aria-label='Close'>
+                  <span aria-hidden='true'>&times;</span>
                 </button>
               </div>
-              <div class="modal-body" v-html='msg'>
+              <div class='modal-body' v-html='msg'>
               </div>
-              <div class="modal-footer">
-                <button type="button" class="btn btn-primary" data-dismiss="modal">关闭</button>
+              <div class='modal-footer'>
+                <button type='button' class='btn btn-primary' data-dismiss='modal'>关闭</button>
               </div>
             </div>
           </div>

+ 19 - 19
views/layout.pug

@@ -2,41 +2,41 @@ doctype html
 html
   head
     title= title
-    link(rel='stylesheet', href='https://cdn.bootcss.com/bootswatch/4.0.0/litera/bootstrap.min.css')
-    script(src='https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js')
-    script(src='https://cdn.bootcss.com/bootstrap/4.0.0/js/bootstrap.min.js')
+    link(rel='stylesheet', href='https://cdn.jsdelivr.net/npm/bootstrap@4/dist/css/bootstrap.min.css')
+    script(src='https://cdn.jsdelivr.net/npm/jquery@3.5/dist/jquery.min.js')
+    script(src='https://cdn.jsdelivr.net/npm/bootstrap@4/dist/js/bootstrap.bundle.min.js')
     script(src='https://cdn.jsdelivr.net/npm/vue@2')
-    script(src='/javascripts/axios.min.js')
+    script(src='https://cdn.jsdelivr.net/npm/axios@0')
     script(src='/javascripts/jquery.loading.min.js')
 
     link(rel='stylesheet', href='/stylesheets/style.css')
     link(rel='stylesheet', href='/stylesheets/jquery.loading.min.css')
     meta(content='width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0' name='viewport')
   body
-    <div class="navbar navbar-expand-lg fixed-top navbar-light bg-light" style="">
-          <div class="container">
-            <a href="/" class="navbar-brand">naiveBoom</a>
-            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation" style="">
-              <span class="navbar-toggler-icon"></span>
+    <div class='navbar navbar-expand-lg fixed-top navbar-light bg-light'>
+          <div class='container'>
+            <a href='/' class='navbar-brand'>naiveBoom</a>
+            <button class='navbar-toggler' type='button' data-toggle='collapse' data-target='#navbarResponsive' aria-controls='navbarResponsive' aria-expanded='false' aria-label='Toggle navigation' style=''>
+              <span class='navbar-toggler-icon'></span>
             </button>
-            <div class="collapse navbar-collapse" id="navbarResponsive">
-              <ul class="navbar-nav">
-                <li class="nav-item">
-                  <a class="nav-link" target='_blank' href="https://github.com/kchown/naiveboom">GitHub</a>
+            <div class='collapse navbar-collapse' id='navbarResponsive'>
+              <ul class='navbar-nav'>
+                <li class='nav-item'>
+                  <a class='nav-link' target='_blank' href='https://github.com/kchown/naiveboom'>GitHub</a>
                 </li>
-                <li class="nav-item">
-                  <a class="nav-link" target='_blank' href="https://kch.host">Blog</a>
+                <li class='nav-item'>
+                  <a class='nav-link' target='_blank' href='https://kch.host'>Blog</a>
                 </li>
               </ul>
             </div>
           </div>
     </div>
-    <div class="container maincontent">
+    <div class='container maincontent'>
       <noscript>
-        <div class="alert alert-dismissible alert-danger">
-          <button type="button" class="close" data-dismiss="alert">&times;</button>
+        <div class='alert alert-dismissible alert-danger'>
+          <button type='button' class='close' data-dismiss='alert'>&times;</button>
           <strong>上帝啊!</strong> 您禁用了JavaScript,请开启它 <br> 如果您禁止使用JavaScript,将无法使用我们的服务!
-          <a href="http://www.chiefgroup.com.hk/temp/chiefeasy/how-to-enable-javascript.html" target='_blank' class="alert-link">查看如何开启Cookie</a>
+          <a href='http://www.chiefgroup.com.hk/temp/chiefeasy/how-to-enable-javascript.html' target='_blank' class='alert-link'>查看如何开启Cookie</a>
         </div>
       </noscript>
       block content

+ 2 - 2
views/look.pug

@@ -3,14 +3,14 @@ block content
 	include imports.pug
 	#app
 		<div v-if='status==1' class='col-md-10 col-xs-12 col-sm-12'>
-			<vue-easymde ref="preview" :value='text' :options='easyMDEOpts'></vue-easymde>
+			<vue-easymde ref='preview' :value='text' :options='easyMDEOpts'></vue-easymde>
 		</div>
 		<div v-else-if='status==0'>
 		h6 啊喔😯,你查看的内容已经不见了...
 		p.tips
 			| 这是因为这个网址已经被看过一次了,被看过一次的内容就会自动消失
 			| <br>对,这就是人们常说的 <b>阅后即焚!</b>
-		a(href="/") 我也要生成一个!
+		a(href='/') 我也要生成一个!
 		</div>
 		<div v-else>
 		p#warning 正在获取...

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott