1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2024-10-30 07:32:39 +01:00

Image uploads now quicker, and image sized reduced with links to originals

This commit is contained in:
Dan Brown 2015-10-18 18:48:51 +01:00
parent 6c4b4e1cf9
commit 8ea75b0fdf
4 changed files with 104 additions and 20 deletions

View File

@ -39,27 +39,40 @@ class ImageController extends Controller
$images = $this->image->orderBy('created_at', 'desc')
->skip($page * $pageSize)->take($pageSize)->get();
foreach ($images as $image) {
$image->thumbnail = $this->getThumbnail($image, 150, 150);
$this->loadSizes($image);
}
$hasMore = $this->image->orderBy('created_at', 'desc')
->skip(($page + 1) * $pageSize)->take($pageSize)->count() > 0;
return response()->json([
'images' => $images,
'images' => $images,
'hasMore' => $hasMore
]);
}
/**
* Loads the standard thumbnail sizes for an image.
* @param Image $image
*/
private function loadSizes(Image $image)
{
$image->thumbnail = $this->getThumbnail($image, 150, 150);
$image->display = $this->getThumbnail($image, 840, 0, true);
}
/**
* Get the thumbnail for an image.
* @param $image
* @param int $width
* @param int $height
* If $keepRatio is true only the width will be used.
* @param $image
* @param int $width
* @param int $height
* @param bool $keepRatio
* @return string
*/
public function getThumbnail($image, $width = 220, $height = 220)
public function getThumbnail($image, $width = 220, $height = 220, $keepRatio = false)
{
$explodedPath = explode('/', $image->url);
array_splice($explodedPath, 4, 0, ['thumbs-' . $width . '-' . $height]);
$dirPrefix = $keepRatio ? 'scaled-' : 'thumbs-';
array_splice($explodedPath, 4, 0, [$dirPrefix . $width . '-' . $height]);
$thumbPath = implode('/', $explodedPath);
$thumbFilePath = public_path() . $thumbPath;
@ -70,7 +83,14 @@ class ImageController extends Controller
// Otherwise create the thumbnail
$thumb = ImageTool::make(public_path() . $image->url);
$thumb->fit($width, $height);
if($keepRatio) {
$thumb->resize($width, null, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
});
} else {
$thumb->fit($width, $height);
}
// Create thumbnail folder if it does not exist
if (!file_exists(dirname($thumbFilePath))) {
@ -107,7 +127,7 @@ class ImageController extends Controller
$this->image->created_by = auth()->user()->id;
$this->image->updated_by = auth()->user()->id;
$this->image->save();
$this->image->thumbnail = $this->getThumbnail($this->image, 150, 150);
$this->loadSizes($this->image);
return response()->json($this->image);
}
@ -126,6 +146,7 @@ class ImageController extends Controller
$image = $this->image->findOrFail($imageId);
$image->fill($request->all());
$image->save();
$this->loadSizes($image);
return response()->json($this->image);
}

View File

@ -14,7 +14,7 @@
"tests"
],
"dependencies": {
"tinymce-dist": "~4.2.1",
"tinymce-dist": "~4.2.6",
"bootstrap": "~3.3.5",
"jquery-sortable": "~0.9.13",
"material-design-iconic-font": "~2.1.1"

View File

@ -1,6 +1,6 @@
<template>
<div id="image-manager">
<div class="overlay" v-el="overlay" v-on="click: overlayClick" >
<div class="overlay" v-el="overlay" v-on="click: overlayClick">
<div class="image-manager-body">
<div class="image-manager-content">
<div class="image-manager-list">
@ -32,7 +32,8 @@
<hr class="even">
<div v-show="dependantPages">
<p class="text-neg text-small">
This image is used in the pages below, Click delete again to confirm you want to delete this image.
This image is used in the pages below, Click delete again to confirm you want to delete
this image.
</p>
<ul class="text-neg">
<li v-repeat="page: dependantPages">
@ -46,7 +47,9 @@
</form>
</div>
<div class="image-manager-bottom">
<button class="button pos anim fadeIn" v-show="selectedImage" v-on="click:selectButtonClick"><i class="zmdi zmdi-square-right"></i>Select Image</button>
<button class="button pos anim fadeIn" v-show="selectedImage" v-on="click:selectButtonClick"><i
class="zmdi zmdi-square-right"></i>Select Image
</button>
</div>
</div>
</div>
@ -59,7 +62,7 @@
var Dropzone = require('dropzone');
module.exports = {
data: function(){
data: function () {
return {
images: [],
hasMore: false,
@ -68,13 +71,12 @@
selectedImage: false,
dependantPages: false,
deleteForm: {},
token: document.querySelector('meta[name=token]').getAttribute('content')
token: document.querySelector('meta[name=token]').getAttribute('content'),
dataLoaded: false
}
},
created: function () {
// Get initial images
this.fetchData(this.page);
window.ImageManager = this;
},
@ -139,6 +141,11 @@
show: function (callback) {
this.callback = callback;
this.$$.overlay.style.display = 'block';
// Get initial images if they have not yet been loaded in.
if (!this.dataLoaded) {
this.fetchData(this.page);
this.dataLoaded = true;
}
},
overlayClick: function (e) {
@ -178,9 +185,9 @@
_this.images.splice(_this.images.indexOf(_this.selectedImage), 1);
_this.selectedImage = false;
$(_this.$$.imageTitle).showSuccess('Image Deleted');
}).fail(function(jqXHR, textStatus) {
}).fail(function (jqXHR, textStatus) {
// Pages failure
if(jqXHR.status === 400) {
if (jqXHR.status === 400) {
_this.dependantPages = jqXHR.responseJSON;
}
});

View File

@ -15,7 +15,7 @@ module.exports = {
automatic_uploads: false,
valid_children: "-div[p|pre|h1|h2|h3|h4|h5|h6|blockquote]",
plugins: "image table textcolor paste link imagetools fullscreen code hr",
toolbar: "undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image link hr | removeformat code fullscreen",
toolbar: "undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image-insert link hr | removeformat code fullscreen",
content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}",
style_formats: [
{title: "Header 1", format: "h1"},
@ -51,6 +51,62 @@ module.exports = {
}
},
setup: function(editor) {
( function() {
var wrap;
function hasTextContent( node ) {
return node && !! ( node.textContent || node.innerText );
}
editor.on( 'dragstart', function() {
var node = editor.selection.getNode();
if ( node.nodeName === 'IMG' ) {
wrap = editor.dom.getParent( node, '.mceTemp' );
if ( ! wrap && node.parentNode.nodeName === 'A' && ! hasTextContent( node.parentNode ) ) {
wrap = node.parentNode;
}
}
} );
editor.on( 'drop', function( event ) {
var dom = editor.dom,
rng = tinymce.dom.RangeUtils.getCaretRangeFromPoint( event.clientX, event.clientY, editor.getDoc() );
// Don't allow anything to be dropped in a captioned image.
if ( dom.getParent( rng.startContainer, '.mceTemp' ) ) {
event.preventDefault();
} else if ( wrap ) {
event.preventDefault();
editor.undoManager.transact( function() {
editor.selection.setRng( rng );
editor.selection.setNode( wrap );
dom.remove( wrap );
} );
}
wrap = null;
} );
} )();
// Image picker button
editor.addButton('image-insert', {
title: 'My title',
icon: 'image',
tooltip: 'Insert an image',
onclick: function() {
ImageManager.show(function(image) {
var html = '<p><a href="'+image.url+'" target="_blank">';
html += '<img src="'+image.display+'" alt="'+image.name+'">';
html += '</a></p>';
console.log(image);
editor.execCommand('mceInsertContent', false, html);
});
}
});
// Paste image-uploads
editor.on('paste', function(e) {
if(e.clipboardData) {