mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Added ability to upload integration icons (#1058)
no issue - add `{{aspect-ratio-box}}` to make it easier to adjust box sizes at a fixed ratio based on container height which isn't possible with CSS directly - used `{{gh-uploader}}` to add upload facility to the icon shown on the integration screen
This commit is contained in:
parent
513cddfaa3
commit
fce4aa9176
4 changed files with 125 additions and 8 deletions
51
ghost/admin/app/components/aspect-ratio-box.js
Normal file
51
ghost/admin/app/components/aspect-ratio-box.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
import Component from '@ember/component';
|
||||
import {assert} from '@ember/debug';
|
||||
import {debounce, run} from '@ember/runloop';
|
||||
|
||||
export default Component.extend({
|
||||
ratio: '1/1',
|
||||
base: 'height',
|
||||
isResizing: true,
|
||||
|
||||
_ratio: 1,
|
||||
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this._onResizeHandler = () => {
|
||||
debounce(this, this._resize, 200);
|
||||
};
|
||||
},
|
||||
|
||||
didReceiveAttrs() {
|
||||
assert(
|
||||
'{{aspect-ratio-box}} requires a `ratio` property in the format `"16/9"`',
|
||||
this.ratio.match(/\d+\/\d+/)
|
||||
);
|
||||
this._ratio = this.ratio.split('/').reduce((prev, curr) => prev / curr);
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._resize();
|
||||
window.addEventListener('resize', this._onResizeHandler);
|
||||
},
|
||||
|
||||
willDestroyElement() {
|
||||
this._super(...arguments);
|
||||
window.removeEventListener('resize', this._onResizeHandler);
|
||||
},
|
||||
|
||||
_resize() {
|
||||
this.set('isResizing', true);
|
||||
|
||||
run.schedule('afterRender', this, function () {
|
||||
if (this.base === 'height') {
|
||||
this.element.style.width = `${this.element.clientHeight * this._ratio}px`;
|
||||
} else {
|
||||
this.element.style.height = `${this.element.clientWidth * this._ratio}px`;
|
||||
}
|
||||
|
||||
this.set('isResizing', false);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
|
@ -1,9 +1,17 @@
|
|||
import Controller from '@ember/controller';
|
||||
import {
|
||||
IMAGE_EXTENSIONS,
|
||||
IMAGE_MIME_TYPES
|
||||
} from 'ghost-admin/components/gh-image-uploader';
|
||||
import {alias} from '@ember/object/computed';
|
||||
import {computed} from '@ember/object';
|
||||
import {htmlSafe} from '@ember/string';
|
||||
import {task, timeout} from 'ember-concurrency';
|
||||
|
||||
export default Controller.extend({
|
||||
imageExtensions: IMAGE_EXTENSIONS,
|
||||
imageMimeTypes: IMAGE_MIME_TYPES,
|
||||
|
||||
integration: alias('model'),
|
||||
|
||||
allWebhooks: computed(function () {
|
||||
|
@ -20,7 +28,29 @@ export default Controller.extend({
|
|||
});
|
||||
}),
|
||||
|
||||
iconImageStyle: computed('integration.iconImage', function () {
|
||||
let url = this.integration.iconImage;
|
||||
if (url) {
|
||||
let styles = [
|
||||
`background-image: url(${url})`,
|
||||
'background-size: 100%',
|
||||
'background-position: 50%',
|
||||
'background-repeat: no-repeat'
|
||||
];
|
||||
return htmlSafe(styles.join('; '));
|
||||
}
|
||||
}),
|
||||
|
||||
actions: {
|
||||
triggerIconFileDialog() {
|
||||
let input = document.querySelector('input[type="file"][name="iconImage"]');
|
||||
input.click();
|
||||
},
|
||||
|
||||
setIconImage([image]) {
|
||||
this.integration.set('iconImage', image.url);
|
||||
},
|
||||
|
||||
save() {
|
||||
return this.save.perform();
|
||||
},
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{{#unless isResizing}}
|
||||
{{yield}}
|
||||
{{/unless}}
|
|
@ -12,12 +12,45 @@
|
|||
</header>
|
||||
|
||||
<div class="flex flex-row">
|
||||
<figure class="flex items-center" style={{integration-icon-style integration}}>
|
||||
<div class="flex flex-column mr8">
|
||||
<label>Icon</label>
|
||||
<figure class="relative flex items-center h-100 ma0 br4 hide-child" style={{iconImageStyle}}>
|
||||
{{#aspect-ratio-box class="flex items-center h-100" ratio="1/1" base="height"}}
|
||||
{{#unless integration.iconImage}}
|
||||
{{svg-jar "integration" class="w-100"}}
|
||||
{{/unless}}
|
||||
{{/aspect-ratio-box}}
|
||||
|
||||
{{#gh-uploader
|
||||
extensions=imageExtensions
|
||||
onComplete=(action "setIconImage")
|
||||
as |uploader|
|
||||
}}
|
||||
{{#if uploader.isUploading}}
|
||||
<div class="absolute w-100 h-100 br4 bg-black-70 flex items-center">
|
||||
{{uploader.progressBar}}
|
||||
</div>
|
||||
{{else}}
|
||||
<button
|
||||
type="button"
|
||||
class="child absolute w-100 h-100 br4 b white text-center bg-black-70"
|
||||
{{action "triggerIconFileDialog"}}
|
||||
>
|
||||
Upload
|
||||
</button>
|
||||
{{/if}}
|
||||
<div style="display:none">
|
||||
{{gh-file-input
|
||||
name="iconImage"
|
||||
multiple=false
|
||||
action=uploader.setFiles
|
||||
accept=imageMimeTypes
|
||||
data-test-file-input="icon"}}
|
||||
</div>
|
||||
{{/gh-uploader}}
|
||||
</figure>
|
||||
<div class="flex flex-column w-100">
|
||||
</div>
|
||||
<div class="flex flex-column flex-grow-1">
|
||||
{{#gh-validation-status-container
|
||||
class="flex flex-column w-100 mr3"
|
||||
errors=integration.errors
|
||||
|
|
Loading…
Add table
Reference in a new issue