Commit 86524e83 authored by NGPixel's avatar NGPixel

Insert Image + alignment

parent c0be18a8
......@@ -53,6 +53,7 @@ var path = require('path');
var cron = require('cron').CronJob;
var readChunk = require('read-chunk');
var fileType = require('file-type');
var farmhash = require('farmhash');
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) => {
let fPath = path.join(fldPath, f);
let fPathObj = path.parse(fPath);
let fUid = farmhash.fingerprint32(fldName + '/' + f);
return fs.statAsync(fPath)
.then((s) => {
......@@ -193,10 +195,11 @@ var job = new cron({
if(_.includes(['image/png', 'image/jpeg', 'image/gif', 'image/webp'], mimeInfo.mime)) {
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);
mData = _.pick(mData, ['format', 'width', 'height', 'density', 'hasAlpha', 'orientation']);
mData.uid = fUid;
mData.category = 'image';
mData.mime = mimeInfo.mime;
mData.folder = fldName;
......@@ -227,6 +230,7 @@ var job = new cron({
// Other Files
allFiles.push({
uid: fUid,
category: 'file',
mime: mimeInfo.mime,
folder: fldName,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -6,8 +6,12 @@ let vueImage = new Vue({
isLoadingText: '',
newFolderName: '',
newFolderShow: false,
fetchFromUrlURL: '',
fetchFromUrlShow: false,
folders: [],
currentFolder: '',
currentImage: '',
currentAlign: 'left',
images: []
},
methods: {
......@@ -20,12 +24,45 @@ let vueImage = new Vue({
mdeModalOpenState = false;
$('#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 = '![' + selImage.titleGuess + '](/uploads/' + selImage.normalizedPath + ' "' + selImage.titleGuess + '")';
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) => {
vueImage.newFolderShow = true;
},
newFolderDiscard: (ev) => {
vueImage.newFolderShow = false;
},
fetchFromUrl: (ev) => {
vueImage.fetchFromUrlShow = true;
},
fetchFromUrlDiscard: (ev) => {
vueImage.fetchFromUrlShow = false;
},
selectFolder: (fldName) => {
vueImage.currentFolder = fldName;
vueImage.loadImages();
......@@ -34,6 +71,7 @@ let vueImage = new Vue({
vueImage.isLoading = true;
vueImage.isLoadingText = 'Fetching folders list...';
vueImage.currentFolder = '';
vueImage.currentImage = '';
Vue.nextTick(() => {
socket.emit('uploadsGetFolders', { }, (data) => {
vueImage.folders = data;
......@@ -46,13 +84,16 @@ let vueImage = new Vue({
vueImage.isLoadingText = 'Fetching images...';
Vue.nextTick(() => {
socket.emit('uploadsGetImages', { folder: vueImage.currentFolder }, (data) => {
vueImage.images = _.map(data, (f) => {
f.thumbpath = (f.folder === '') ? f.basename + '.png' : _.join([ f.folder, f.basename + '.png' ], '/');
return f;
});
vueImage.images = data;
vueImage.isLoading = false;
});
});
},
selectImage: (imageId) => {
vueImage.currentImage = imageId;
},
selectAlignment: (align) => {
vueImage.currentAlign = align;
}
}
});
\ No newline at end of file
......@@ -8,6 +8,10 @@ if($('#mk-editor').length === 1) {
let mdeModalOpenState = false;
let mdeCurrentEditor = null;
Vue.filter('filesize', (v) => {
return _.toUpper(filesize(v));
})
//=include editor-image.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 {
border-left: none;
border-right: none;
......
......@@ -5,7 +5,7 @@ var router = express.Router();
var _ = require('lodash');
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
......
......@@ -23,12 +23,15 @@ var paths = {
'./node_modules/jquery/dist/jquery.min.js',
'./node_modules/vue/dist/vue.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/simplemde/dist/simplemde.min.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/mode-markdown.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'
],
scriptlibs_acemodes: [
......@@ -97,7 +100,7 @@ gulp.task("scripts-libs", function () {
return merge(
gulp.src(paths.scriptlibs)
.pipe(concat('libs.js'))
.pipe(concat('libs.js', {newLine: ';\n'}))
.pipe(uglify({ mangle: false }))
.pipe(gulp.dest("./assets/js")),
......
......@@ -201,9 +201,9 @@ module.exports = {
*/
getUploadsFiles(cat, fld) {
return this._uploadsDb.Files.find({
return this._uploadsDb.Files.chain().find({
'$and': [{ 'category' : cat },{ 'folder' : fld }]
});
}).simplesort('filename').data();
},
......
......@@ -91,10 +91,11 @@
"devDependencies": {
"ace-builds": "^1.2.5",
"babel-preset-es2015": "^6.14.0",
"bulma": "^0.2.0",
"bulma": "^0.1.2",
"chai": "^3.5.0",
"chai-as-promised": "^5.3.0",
"codacy-coverage": "^2.0.0",
"filesize.js": "^1.0.1",
"font-awesome": "^4.6.3",
"gulp": "^3.9.1",
"gulp-babel": "^6.1.2",
......@@ -110,6 +111,7 @@
"gulp-zip": "^3.2.0",
"istanbul": "^0.4.5",
"jquery": "^3.1.1",
"jquery-contextmenu": "^2.2.4",
"jquery-smooth-scroll": "^2.0.0",
"merge-stream": "^1.0.0",
"mocha": "^3.0.2",
......
......@@ -32,7 +32,7 @@
.columns
.column.is-one-quarter(style={'max-width':'350px'})
.box(style={'max-height': '400px', overflow: 'auto', 'overflow-x': 'hidden'})
.box.editor-modal-folderlist
aside.menu
p.menu-label
| Folders
......@@ -41,9 +41,25 @@
a(v-on:click="selectFolder(fld)", v-bind:class="{ 'is-active': currentFolder === fld }")
span.icon.is-small: i.fa.fa-folder
span /{{ fld }}
.column
figure.image.is-128x128(v-for="img in images")
img(v-bind:src="'/uploads/t/' + img.thumbpath")
.box.editor-modal-imagealign
.control.is-grouped
.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-background
......@@ -60,4 +76,21 @@
span.help.is-danger.is-hidden This folder name is invalid!
footer.card-footer
a.card-footer-item(v-on:click="newFolderDiscard") Discard
a.card-footer-item(v-on:click="newFolderCreate") Create
\ No newline at end of file
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
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment