Insert Image + alignment
This commit is contained in:
parent
c0be18a8d8
commit
86524e83bb
6
agent.js
6
agent.js
@ -53,6 +53,7 @@ var path = require('path');
|
|||||||
var cron = require('cron').CronJob;
|
var cron = require('cron').CronJob;
|
||||||
var readChunk = require('read-chunk');
|
var readChunk = require('read-chunk');
|
||||||
var fileType = require('file-type');
|
var fileType = require('file-type');
|
||||||
|
var farmhash = require('farmhash');
|
||||||
|
|
||||||
global.ws = require('socket.io-client')('http://localhost:' + appconfig.wsPort, { reconnectionAttempts: 10 });
|
global.ws = require('socket.io-client')('http://localhost:' + appconfig.wsPort, { reconnectionAttempts: 10 });
|
||||||
|
|
||||||
@ -177,6 +178,7 @@ var job = new cron({
|
|||||||
return Promise.map(fList, (f) => {
|
return Promise.map(fList, (f) => {
|
||||||
let fPath = path.join(fldPath, f);
|
let fPath = path.join(fldPath, f);
|
||||||
let fPathObj = path.parse(fPath);
|
let fPathObj = path.parse(fPath);
|
||||||
|
let fUid = farmhash.fingerprint32(fldName + '/' + f);
|
||||||
|
|
||||||
return fs.statAsync(fPath)
|
return fs.statAsync(fPath)
|
||||||
.then((s) => {
|
.then((s) => {
|
||||||
@ -193,10 +195,11 @@ var job = new cron({
|
|||||||
if(_.includes(['image/png', 'image/jpeg', 'image/gif', 'image/webp'], mimeInfo.mime)) {
|
if(_.includes(['image/png', 'image/jpeg', 'image/gif', 'image/webp'], mimeInfo.mime)) {
|
||||||
return lcdata.getImageMetadata(fPath).then((mData) => {
|
return lcdata.getImageMetadata(fPath).then((mData) => {
|
||||||
|
|
||||||
let cacheThumbnailPath = path.parse(path.join(dataPath, 'thumbs', fldName, fPathObj.name + '.png'));
|
let cacheThumbnailPath = path.parse(path.join(dataPath, 'thumbs', fUid + '.png'));
|
||||||
let cacheThumbnailPathStr = path.format(cacheThumbnailPath);
|
let cacheThumbnailPathStr = path.format(cacheThumbnailPath);
|
||||||
|
|
||||||
mData = _.pick(mData, ['format', 'width', 'height', 'density', 'hasAlpha', 'orientation']);
|
mData = _.pick(mData, ['format', 'width', 'height', 'density', 'hasAlpha', 'orientation']);
|
||||||
|
mData.uid = fUid;
|
||||||
mData.category = 'image';
|
mData.category = 'image';
|
||||||
mData.mime = mimeInfo.mime;
|
mData.mime = mimeInfo.mime;
|
||||||
mData.folder = fldName;
|
mData.folder = fldName;
|
||||||
@ -227,6 +230,7 @@ var job = new cron({
|
|||||||
// Other Files
|
// Other Files
|
||||||
|
|
||||||
allFiles.push({
|
allFiles.push({
|
||||||
|
uid: fUid,
|
||||||
category: 'file',
|
category: 'file',
|
||||||
mime: mimeInfo.mime,
|
mime: mimeInfo.mime,
|
||||||
folder: fldName,
|
folder: fldName,
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -6,8 +6,12 @@ let vueImage = new Vue({
|
|||||||
isLoadingText: '',
|
isLoadingText: '',
|
||||||
newFolderName: '',
|
newFolderName: '',
|
||||||
newFolderShow: false,
|
newFolderShow: false,
|
||||||
|
fetchFromUrlURL: '',
|
||||||
|
fetchFromUrlShow: false,
|
||||||
folders: [],
|
folders: [],
|
||||||
currentFolder: '',
|
currentFolder: '',
|
||||||
|
currentImage: '',
|
||||||
|
currentAlign: 'left',
|
||||||
images: []
|
images: []
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -20,12 +24,45 @@ let vueImage = new Vue({
|
|||||||
mdeModalOpenState = false;
|
mdeModalOpenState = false;
|
||||||
$('#modal-editor-image').slideUp();
|
$('#modal-editor-image').slideUp();
|
||||||
},
|
},
|
||||||
|
insertImage: (ev) => {
|
||||||
|
|
||||||
|
if(mde.codemirror.doc.somethingSelected()) {
|
||||||
|
mde.codemirror.execCommand('singleSelection');
|
||||||
|
}
|
||||||
|
|
||||||
|
let selImage = _.find(vueImage.images, ['uid', vueImage.currentImage]);
|
||||||
|
selImage.normalizedPath = (selImage.folder === '') ? selImage.filename : selImage.folder + '/' + selImage.filename;
|
||||||
|
selImage.titleGuess = _.startCase(selImage.basename);
|
||||||
|
|
||||||
|
let imageText = '';
|
||||||
|
switch(vueImage.currentAlign) {
|
||||||
|
case 'center':
|
||||||
|
imageText += '{.align-center}';
|
||||||
|
break;
|
||||||
|
case 'right':
|
||||||
|
imageText += '{.align-right}';
|
||||||
|
break;
|
||||||
|
case 'logo':
|
||||||
|
imageText += '{.pagelogo}';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mde.codemirror.doc.replaceSelection(imageText);
|
||||||
|
vueImage.cancel();
|
||||||
|
|
||||||
|
},
|
||||||
newFolder: (ev) => {
|
newFolder: (ev) => {
|
||||||
vueImage.newFolderShow = true;
|
vueImage.newFolderShow = true;
|
||||||
},
|
},
|
||||||
newFolderDiscard: (ev) => {
|
newFolderDiscard: (ev) => {
|
||||||
vueImage.newFolderShow = false;
|
vueImage.newFolderShow = false;
|
||||||
},
|
},
|
||||||
|
fetchFromUrl: (ev) => {
|
||||||
|
vueImage.fetchFromUrlShow = true;
|
||||||
|
},
|
||||||
|
fetchFromUrlDiscard: (ev) => {
|
||||||
|
vueImage.fetchFromUrlShow = false;
|
||||||
|
},
|
||||||
selectFolder: (fldName) => {
|
selectFolder: (fldName) => {
|
||||||
vueImage.currentFolder = fldName;
|
vueImage.currentFolder = fldName;
|
||||||
vueImage.loadImages();
|
vueImage.loadImages();
|
||||||
@ -34,6 +71,7 @@ let vueImage = new Vue({
|
|||||||
vueImage.isLoading = true;
|
vueImage.isLoading = true;
|
||||||
vueImage.isLoadingText = 'Fetching folders list...';
|
vueImage.isLoadingText = 'Fetching folders list...';
|
||||||
vueImage.currentFolder = '';
|
vueImage.currentFolder = '';
|
||||||
|
vueImage.currentImage = '';
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
socket.emit('uploadsGetFolders', { }, (data) => {
|
socket.emit('uploadsGetFolders', { }, (data) => {
|
||||||
vueImage.folders = data;
|
vueImage.folders = data;
|
||||||
@ -46,13 +84,16 @@ let vueImage = new Vue({
|
|||||||
vueImage.isLoadingText = 'Fetching images...';
|
vueImage.isLoadingText = 'Fetching images...';
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
socket.emit('uploadsGetImages', { folder: vueImage.currentFolder }, (data) => {
|
socket.emit('uploadsGetImages', { folder: vueImage.currentFolder }, (data) => {
|
||||||
vueImage.images = _.map(data, (f) => {
|
vueImage.images = data;
|
||||||
f.thumbpath = (f.folder === '') ? f.basename + '.png' : _.join([ f.folder, f.basename + '.png' ], '/');
|
|
||||||
return f;
|
|
||||||
});
|
|
||||||
vueImage.isLoading = false;
|
vueImage.isLoading = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
selectImage: (imageId) => {
|
||||||
|
vueImage.currentImage = imageId;
|
||||||
|
},
|
||||||
|
selectAlignment: (align) => {
|
||||||
|
vueImage.currentAlign = align;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -8,6 +8,10 @@ if($('#mk-editor').length === 1) {
|
|||||||
let mdeModalOpenState = false;
|
let mdeModalOpenState = false;
|
||||||
let mdeCurrentEditor = null;
|
let mdeCurrentEditor = null;
|
||||||
|
|
||||||
|
Vue.filter('filesize', (v) => {
|
||||||
|
return _.toUpper(filesize(v));
|
||||||
|
})
|
||||||
|
|
||||||
//=include editor-image.js
|
//=include editor-image.js
|
||||||
//=include editor-codeblock.js
|
//=include editor-codeblock.js
|
||||||
|
|
||||||
|
@ -65,6 +65,99 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.editor-modal-imagechoices {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: flex-start;
|
||||||
|
max-height: 450px;
|
||||||
|
overflow: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
> figure {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #FAFAFA;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
width: 160px;
|
||||||
|
min-height: 205px;
|
||||||
|
margin: 0 5px 10px 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
transition: background-color 0.4s ease;
|
||||||
|
|
||||||
|
> img {
|
||||||
|
border: 1px solid #DDD;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 2px;
|
||||||
|
background-color: #FFF;
|
||||||
|
margin: 0 0 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> span {
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
> strong {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
display: block;
|
||||||
|
width: 150px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
background-color: $primary;
|
||||||
|
color: #FFF;
|
||||||
|
|
||||||
|
> img {
|
||||||
|
border-color: darken($primary, 10%);
|
||||||
|
}
|
||||||
|
|
||||||
|
> span > strong {
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-modal-imagealign {
|
||||||
|
|
||||||
|
.control > span {
|
||||||
|
letter-spacing: 1px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #aeb1b5;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .is-grouped {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button > .icon {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-modal-folderlist {
|
||||||
|
height: 358px;
|
||||||
|
overflow: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.CodeMirror {
|
.CodeMirror {
|
||||||
border-left: none;
|
border-left: none;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
|
@ -5,7 +5,7 @@ var router = express.Router();
|
|||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
|
||||||
var validPathRe = new RegExp("^([a-z0-9\\/-]+\\.[a-z0-9]+)$");
|
var validPathRe = new RegExp("^([a-z0-9\\/-]+\\.[a-z0-9]+)$");
|
||||||
var validPathThumbsRe = new RegExp("^([a-z0-9\\/-]+\\.png)$");
|
var validPathThumbsRe = new RegExp("^([0-9]+\\.png)$");
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// SERVE UPLOADS FILES
|
// SERVE UPLOADS FILES
|
||||||
|
@ -23,12 +23,15 @@ var paths = {
|
|||||||
'./node_modules/jquery/dist/jquery.min.js',
|
'./node_modules/jquery/dist/jquery.min.js',
|
||||||
'./node_modules/vue/dist/vue.min.js',
|
'./node_modules/vue/dist/vue.min.js',
|
||||||
'./node_modules/jquery-smooth-scroll/jquery.smooth-scroll.min.js',
|
'./node_modules/jquery-smooth-scroll/jquery.smooth-scroll.min.js',
|
||||||
|
'./node_modules/jquery-contextmenu/dist/jquery.ui.position.min.js',
|
||||||
|
'./node_modules/jquery-contextmenu/dist/jquery.contextMenu.min.js',
|
||||||
'./node_modules/sticky-js/dist/sticky.min.js',
|
'./node_modules/sticky-js/dist/sticky.min.js',
|
||||||
'./node_modules/simplemde/dist/simplemde.min.js',
|
'./node_modules/simplemde/dist/simplemde.min.js',
|
||||||
'./node_modules/ace-builds/src-min-noconflict/ace.js',
|
'./node_modules/ace-builds/src-min-noconflict/ace.js',
|
||||||
'./node_modules/ace-builds/src-min-noconflict/ext-modelist.js',
|
'./node_modules/ace-builds/src-min-noconflict/ext-modelist.js',
|
||||||
'./node_modules/ace-builds/src-min-noconflict/mode-markdown.js',
|
'./node_modules/ace-builds/src-min-noconflict/mode-markdown.js',
|
||||||
'./node_modules/ace-builds/src-min-noconflict/theme-tomorrow_night.js',
|
'./node_modules/ace-builds/src-min-noconflict/theme-tomorrow_night.js',
|
||||||
|
'./node_modules/filesize.js/dist/filesize.min.js',
|
||||||
'./node_modules/lodash/lodash.min.js'
|
'./node_modules/lodash/lodash.min.js'
|
||||||
],
|
],
|
||||||
scriptlibs_acemodes: [
|
scriptlibs_acemodes: [
|
||||||
@ -97,7 +100,7 @@ gulp.task("scripts-libs", function () {
|
|||||||
return merge(
|
return merge(
|
||||||
|
|
||||||
gulp.src(paths.scriptlibs)
|
gulp.src(paths.scriptlibs)
|
||||||
.pipe(concat('libs.js'))
|
.pipe(concat('libs.js', {newLine: ';\n'}))
|
||||||
.pipe(uglify({ mangle: false }))
|
.pipe(uglify({ mangle: false }))
|
||||||
.pipe(gulp.dest("./assets/js")),
|
.pipe(gulp.dest("./assets/js")),
|
||||||
|
|
||||||
|
@ -201,9 +201,9 @@ module.exports = {
|
|||||||
*/
|
*/
|
||||||
getUploadsFiles(cat, fld) {
|
getUploadsFiles(cat, fld) {
|
||||||
|
|
||||||
return this._uploadsDb.Files.find({
|
return this._uploadsDb.Files.chain().find({
|
||||||
'$and': [{ 'category' : cat },{ 'folder' : fld }]
|
'$and': [{ 'category' : cat },{ 'folder' : fld }]
|
||||||
});
|
}).simplesort('filename').data();
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -91,10 +91,11 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ace-builds": "^1.2.5",
|
"ace-builds": "^1.2.5",
|
||||||
"babel-preset-es2015": "^6.14.0",
|
"babel-preset-es2015": "^6.14.0",
|
||||||
"bulma": "^0.2.0",
|
"bulma": "^0.1.2",
|
||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
"chai-as-promised": "^5.3.0",
|
"chai-as-promised": "^5.3.0",
|
||||||
"codacy-coverage": "^2.0.0",
|
"codacy-coverage": "^2.0.0",
|
||||||
|
"filesize.js": "^1.0.1",
|
||||||
"font-awesome": "^4.6.3",
|
"font-awesome": "^4.6.3",
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"gulp-babel": "^6.1.2",
|
"gulp-babel": "^6.1.2",
|
||||||
@ -110,6 +111,7 @@
|
|||||||
"gulp-zip": "^3.2.0",
|
"gulp-zip": "^3.2.0",
|
||||||
"istanbul": "^0.4.5",
|
"istanbul": "^0.4.5",
|
||||||
"jquery": "^3.1.1",
|
"jquery": "^3.1.1",
|
||||||
|
"jquery-contextmenu": "^2.2.4",
|
||||||
"jquery-smooth-scroll": "^2.0.0",
|
"jquery-smooth-scroll": "^2.0.0",
|
||||||
"merge-stream": "^1.0.0",
|
"merge-stream": "^1.0.0",
|
||||||
"mocha": "^3.0.2",
|
"mocha": "^3.0.2",
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
.columns
|
.columns
|
||||||
.column.is-one-quarter(style={'max-width':'350px'})
|
.column.is-one-quarter(style={'max-width':'350px'})
|
||||||
.box(style={'max-height': '400px', overflow: 'auto', 'overflow-x': 'hidden'})
|
.box.editor-modal-folderlist
|
||||||
aside.menu
|
aside.menu
|
||||||
p.menu-label
|
p.menu-label
|
||||||
| Folders
|
| Folders
|
||||||
@ -41,9 +41,25 @@
|
|||||||
a(v-on:click="selectFolder(fld)", v-bind:class="{ 'is-active': currentFolder === fld }")
|
a(v-on:click="selectFolder(fld)", v-bind:class="{ 'is-active': currentFolder === fld }")
|
||||||
span.icon.is-small: i.fa.fa-folder
|
span.icon.is-small: i.fa.fa-folder
|
||||||
span /{{ fld }}
|
span /{{ fld }}
|
||||||
.column
|
.box.editor-modal-imagealign
|
||||||
figure.image.is-128x128(v-for="img in images")
|
.control.is-grouped
|
||||||
img(v-bind:src="'/uploads/t/' + img.thumbpath")
|
.control
|
||||||
|
span Alignment
|
||||||
|
.control.has-addons
|
||||||
|
a.button.is-primary(title="Left", v-on:click="selectAlignment('left')", v-bind:class="{ 'is-outlined': currentAlign !== 'left' }")
|
||||||
|
span.icon.is-small: i.fa.fa-align-left
|
||||||
|
a.button.is-primary(title="Center", v-on:click="selectAlignment('center')", v-bind:class="{ 'is-outlined': currentAlign !== 'center' }")
|
||||||
|
span.icon.is-small: i.fa.fa-align-center
|
||||||
|
a.button.is-primary(title="Right", v-on:click="selectAlignment('right')", v-bind:class="{ 'is-outlined': currentAlign !== 'right' }")
|
||||||
|
span.icon.is-small: i.fa.fa-align-right
|
||||||
|
.control
|
||||||
|
a.button.is-primary(title="Page Logo", v-on:click="selectAlignment('logo')", v-bind:class="{ 'is-outlined': currentAlign !== 'logo' }")
|
||||||
|
span.icon.is-small: i.fa.fa-external-link-square
|
||||||
|
.column.editor-modal-imagechoices
|
||||||
|
figure(v-for="img in images", v-bind:class="{ 'is-active': currentImage === img.uid }", v-on:click="selectImage(img.uid)")
|
||||||
|
img(v-bind:src="'/uploads/t/' + img.uid + '.png'")
|
||||||
|
span: strong {{ img.basename }}
|
||||||
|
span {{ img.filesize | filesize }}
|
||||||
|
|
||||||
.modal(v-bind:class="{ 'is-active': newFolderShow }")
|
.modal(v-bind:class="{ 'is-active': newFolderShow }")
|
||||||
.modal-background
|
.modal-background
|
||||||
@ -61,3 +77,20 @@
|
|||||||
footer.card-footer
|
footer.card-footer
|
||||||
a.card-footer-item(v-on:click="newFolderDiscard") Discard
|
a.card-footer-item(v-on:click="newFolderDiscard") Discard
|
||||||
a.card-footer-item(v-on:click="newFolderCreate") Create
|
a.card-footer-item(v-on:click="newFolderCreate") Create
|
||||||
|
|
||||||
|
.modal(v-bind:class="{ 'is-active': fetchFromUrlShow }")
|
||||||
|
.modal-background
|
||||||
|
.modal-container
|
||||||
|
.modal-content
|
||||||
|
.card.is-fullwidth
|
||||||
|
header.card-header
|
||||||
|
p.card-header-title Fetch Image from URL
|
||||||
|
.card-content
|
||||||
|
.content
|
||||||
|
label.label Enter full URL path to the image:
|
||||||
|
p.control
|
||||||
|
input.input(type='text', placeholder='http://www.example.com/some-image.png', v-model='fetchFromUrlURL')
|
||||||
|
span.help.is-danger.is-hidden This URL path is invalid!
|
||||||
|
footer.card-footer
|
||||||
|
a.card-footer-item(v-on:click="fetchFromUrlDiscard") Discard
|
||||||
|
a.card-footer-item(v-on:click="fetchFromUrlFetch") Fetch
|
Loading…
x
Reference in New Issue
Block a user