0
Fork 0
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:
Kevin Ansfield 2018-10-23 10:29:49 +01:00 committed by GitHub
parent 513cddfaa3
commit fce4aa9176
4 changed files with 125 additions and 8 deletions

View 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);
});
}
});

View file

@ -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();
},

View file

@ -0,0 +1,3 @@
{{#unless isResizing}}
{{yield}}
{{/unless}}

View file

@ -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