0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-06 22:40:14 -05:00

Adds modal Image uploader on settings page

issue #432

adds a modal template for image uploads
adds buttons to settings page to upload images for blog logo and icon
once image is uploaded displays an 'X' to reset back to dropzone
saves image and renders settings page.

ToDo

add url field when clicking on url icon

fix position of 'X' for both settings and editor
This commit is contained in:
cobbspur 2013-09-04 18:42:01 +01:00
parent 362cd425cc
commit e61f3684d5
6 changed files with 110 additions and 73 deletions

View file

@ -7,19 +7,16 @@
UploadUi = function ($dropzone, settings) {
var source,
$link = $('<a class="js-edit-image image-edit" href="#" >' +
'<img src="/public/assets/img/add-image.png" width="16" height="16" alt="add, edit"></a>'),
$back = $('<a class="js-return-image image-edit" href="#" >' +
'<img src="/public/assets/img/return-image.png" width="16" height="16" alt="add, edit"></a>'),
$cancel = '<a class="image-cancel js-cancel"><span class="hidden">Delete</span></a>',
$progress = $('<div />', {
"class" : "js-upload-progress progress progress-success active",
"role": "progressbar",
"aria-valuemin": "0",
"aria-valuemax": "100"
}).append($("<div />", {
"class": "js-upload-progress-bar bar",
"style": "width:0%"
}));
"class": "js-upload-progress-bar bar",
"style": "width:0%"
}));
$.extend(this, {
bindFileUpload: function () {
@ -30,7 +27,6 @@
add: function (e, data) {
$progress.find('.js-upload-progress-bar').removeClass('fail');
$dropzone.trigger('uploadstart');
$dropzone.find('a.js-return-image').remove();
$dropzone.find('span.media, div.description, a.image-url, a.image-webcam')
.animate({opacity: 0}, 250, function () {
$dropzone.find('div.description').hide().css({"opacity": 100});
@ -55,10 +51,6 @@
$dropzone.find('div.js-fail, button.js-fail').fadeIn(1500);
$dropzone.find('button.js-fail').on('click', function () {
$dropzone.css({minHeight: 0});
if (source !== undefined && !$dropzone.find('a.js-return-image')[0]) {
$back.css({"opacity": 100});
$dropzone.find('.js-upload-target').after($back);
}
$dropzone.find('div.description').show();
self.removeExtras();
self.init();
@ -69,10 +61,6 @@
$dropzone.find('img.js-upload-target').attr({"width": width, "height": height}).css({"display": "block"});
$dropzone.find('.fileupload-loading').removeClass('fileupload-loading');
$dropzone.css({"height": "auto"});
if (!$dropzone.find('a.js-edit-image')[0]) {
$link.css({"opacity": 100});
$dropzone.find('.js-upload-target').after($link);
}
$dropzone.delay(250).animate({opacity: 100}, 1000, function () {
self.init();
});
@ -128,7 +116,7 @@
},
removeExtras: function () {
$dropzone.find('span.media, div.js-upload-progress, a.image-url, a.image-webcam, div.js-fail, button.js-fail').remove();
$dropzone.find('span.media, div.js-upload-progress, a.image-url, a.image-webcam, div.js-fail, button.js-fail, a.js-cancel').remove();
},
initWithDropzone: function () {
@ -136,18 +124,8 @@
//This is the start point if no image exists
$dropzone.find('img.js-upload-target').css({"display": "none"});
$dropzone.removeClass('pre-image-uploader').addClass('image-uploader');
this.removeExtras();
this.buildExtras();
$dropzone.find('a.js-edit-image').remove();
$back.on('click', function () {
$dropzone.find('a.js-return-image').remove();
$dropzone.find('img.js-upload-target').attr({"src": source}).css({"display": "block"});
self.removeExtras();
$dropzone.removeClass('image-uploader').addClass('pre-image-uploader');
self.init();
});
this.bindFileUpload();
},
@ -157,19 +135,11 @@
source = $dropzone.find('img.js-upload-target').attr('src');
$dropzone.removeClass('image-uploader').addClass('pre-image-uploader');
$dropzone.find('div.description').hide();
if (!$dropzone.find('a.js-edit-image')[0]) {
$link.css({"opacity": 100});
$dropzone.find('.js-upload-target').after($link);
}
$link.on('click', function () {
$dropzone.find('a.js-edit-image').remove();
$dropzone.find('img.js-upload-target').attr({"src": ""}).css({"display": "none"});
$back.css({"cursor": "pointer", "z-index": 9999, "opacity": 100});
$dropzone.find('.js-upload-target').after($back);
$dropzone.append($cancel);
$dropzone.find('.js-cancel').on('click', function () {
$dropzone.find('img.js-upload-target').attr({'src': ''});
$dropzone.find('div.description').show();
self.init();
self.initWithDropzone();
});
},

View file

@ -172,6 +172,10 @@
margin-left: 15px;
}
img {
max-width: 100%;
}
display: none;
&.active {display:block;}

View file

@ -1015,13 +1015,12 @@ body.blur > *:not(#modal-container) {
}
.modal-content {
padding: 20px;
padding: 0 20px;
}
.modal-footer {
padding: 20px;
padding-top: 0;
text-align: center;
}
.modal-style-wide {
@ -1176,17 +1175,6 @@ main {
padding-left:5px;
}
.image-edit {
line-height: 12px;
padding: 10px;
display: block;
position: absolute;
top: 0;
left: 0;
opacity: 0;
text-decoration: none;
}
.image-webcam {
@include icon($i-camera, 12px);
line-height: 12px;
@ -1251,7 +1239,7 @@ main {
@include box-sizing(border-box);
@include baseline;
position: relative;
overflow:hidden;
overflow: hidden;
height: auto;
color: $brown;
@ -1260,16 +1248,31 @@ main {
left: 9999px;
opacity: 0;
}
.image-edit {
line-height: 12px;
padding: 10px;
display: block;
position: absolute;
top: 0;
left: 0;
opacity: 0;
a {
z-index: 10000;
color: $brown;
text-decoration: none;
&:hover {
color: $darkgrey;
}
}
img {
max-width: 100%;
}
.image-cancel {
@include icon($i-x, 16px);
position: absolute;
color: white;
text-shadow: rgba(0,0,0,0.5) 0 0 1px;
top: 10px;
right: 10px;
text-decoration: none;
&:hover {
cursor: pointer;
color: white;
}
}
}

View file

@ -0,0 +1,4 @@
<section class="js-drop-zone">
<img id="{{options.val}}" class="js-upload-target" src="{{options.src}}"{{#unless options.src}} style="display: none"{{/unless}} alt="logo">
<input data-url="upload" class="js-fileupload" type="file" name="uploadimage">
</section>

View file

@ -15,19 +15,22 @@
<div class="form-group">
<label><strong>Blog Logo</strong></label>
<section class="js-drop-zone">
<img id="logo" class="js-upload-target" src="{{logo}}"{{#unless logo}} style="display: none"{{/unless}} alt="logo">
<input data-url="upload" class="js-fileupload" type="file" name="uploadimage">
</section>
{{#if logo}}
<a class="js-modal-logo"><img src="{{logo}}" alt="logo"></a>
{{else}}
<a class="button-add js-modal-logo" href="#">Upload Image</a>
{{/if}}
<p>Display a logo on your site in place of blog title</p>
</div>
<div class="form-group">
<label><strong>Blog Icon</strong></label>
<section class="js-drop-zone">
<img id="icon" class="js-upload-target" src="{{icon}}"{{#unless icon}} style="display: none"{{/unless}} style="display: none" alt="icon">
<input data-url="upload" class="js-fileupload" type="file" name="uploadimage">
</section>
{{#if icon}}
<a class="js-modal-icon"><img src="{{icon}}" alt="icon"></a>
{{else}}
<a class="button-add js-modal-icon" href="#">Upload Image</a>
{{/if}}
<p>The icon for your blog, used in your browser tab and elsewhere</p>
</div>

View file

@ -151,7 +151,9 @@
id: "general",
events: {
'click .button-save': 'saveSettings'
'click .button-save': 'saveSettings',
'click .js-modal-logo': 'showLogo',
'click .js-modal-icon': 'showIcon'
},
saveSettings: function () {
@ -169,7 +171,58 @@
});
this.model.set({availableThemes: themes});
},
showLogo: function () {
var settings = this.model.toJSON();
this.showUpload('#logo', 'logo', settings.logo);
},
showIcon: function () {
var settings = this.model.toJSON();
this.showUpload('#icon', 'icon', settings.icon);
},
showUpload: function (id, key, src) {
var self = this;
this.addSubview(new Ghost.Views.Modal({
model: {
options: {
close: false,
type: "action",
style: "wide",
animation: 'fadeIn',
afterRender: function () {
this.$('.js-drop-zone').upload();
},
confirm: {
accept: {
func: function () { // The function called on acceptance
var data = {};
data[key] = this.$('.js-upload-target').attr('src');
self.model.save(data, {
success: self.saveSuccess,
error: self.saveError
});
self.render();
return true;
},
buttonClass: "button-save right",
text: "Save" // The accept button text
},
reject: {
func: function () { // The function called on rejection
return true;
},
buttonClass: true,
text: "Cancel" // The reject button text
}
},
id: id,
src: src
},
content: {
template: 'uploadImage'
}
}
}));
},
templateName: 'settings/general',
beforeRender: function () {